Implementing Worklist - Using dcmtk and Orthanc

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
Stephen D. Scotti
Posts: 16
Joined: Fri, 2020-06-19, 07:56

Implementing Worklist - Using dcmtk and Orthanc

#1 Post by Stephen D. Scotti »

I've started to implement MWL's using dcmtk and the Orthanc Open Source server. I have a template, and I'm extracting most of the data from an HL7 message. The template is below, using PHP. Most of the values are derived from the HL7 in the constructor. CharSet is $this->CharSet = 'ISO_IR 100';

I am a relative novice with MWL's, so I am not certain about most of the values for the Header, and some in the Data-Set.

Specifically, all of the header items, and mostly the ' . $this->StudyInstanceUID . '] in the body.

I do have a DICOM conformance statement for one of the modalities that will be used, an Esaote MRI scanner, https://www.esaote.com/uploads/tx_esaot ... 3-6_03.pdf, and Orthanc https://hg.orthanc-server.com/orthanc/f ... tement.txt,

and I also have what I think is a ROOT ID obtained from IANA of the format 1.3.6.1.4.1.xxxxx, where the xxxxx is our IANA ID. Not sure that is necessary and valid for use, although it was very easy to obtain. If we need to or can generate UID's using that ROOT, we can do that on the fly. I am using a BUILD of Orthanc that apparently uses dcmtk 3.6.5, but I also have dcmtk on the system, most recent version, for converting the .txt file template to a .wl file.

I've started testing, and creating the .txt file, converting to .wl format and storing on the Orthanc server all works, and I can also query the worklist using:

findscu -W -aec CML_ORTHANC -k "(0040,0001)=AETITLE_MRI" 127.0.0.1 4242

So what I really need is clarification of what values go into the header, which are dynamic / static, and where I get the values from for the dynamic ones in the header.

Also, some clarification on where I need to or should use our own ROOT ID for StudyInstanceUID's. Thanks.

(0002,0000) UL 202
(0002,0001) OB 00\01
(0002,0002) UI [' . $this->MediaStorageSOPClassUID . ']
(0002,0003) UI [' . $this->MediaStorageSOPInstanceUID . ']
(0002,0010) UI =LittleEndianExplicit # 20, 1 TransferSyntaxUID
(0002,0012) UI [1.2.276.0.7230010.3.0.3.6.0] # 28, 1 ImplementationClassUID
(0002,0013) SH [OFFIS_DCMTK_360] # 16, 1 ImplementationVersionName

Code: Select all

		$template = 
			'# Dicom-File-Format
			# Dicom-Meta-Information-Header
			# Used TransferSyntax: Little Endian Explicit
			(0002,0000) UL 202                                       #   4, 1 FileMetaInformationGroupLength
			(0002,0001) OB 00\01                                     #   2, 1 FileMetaInformationVersion
			(0002,0002) UI [' . $this->MediaStorageSOPClassUID .  '] #  MediaStorageSOPClassUID 1.2.276.0.7230010.3.1.0.1 vs 1.2.840.10008.3.1.2.3.3 for Easote
			(0002,0003) UI [' . $this->MediaStorageSOPInstanceUID .  '] #  58, 1 MediaStorageSOPInstanceUID
			(0002,0010) UI =LittleEndianExplicit                     #  20, 1 TransferSyntaxUID
			(0002,0012) UI [1.2.276.0.7230010.3.0.3.6.0]             #  28, 1 ImplementationClassUID
			(0002,0013) SH [OFFIS_DCMTK_360]                         #  16, 1 ImplementationVersionName

			# Dicom-Data-Set
			# Used TransferSyntax: Little Endian Explicit
			(0008,0005) CS [' . $this->CharSet . ']                             #  SpecificCharacterSet, 16 Bytes Uppercase and #s _ and space
			(0008,0050) SH [' . $this->AccessionNumber . ']                     # 16 Characters max
			(0008,0060) CS [' . $this->Modality . ']                            #   Modality
			(0008,0090) PN [' . $this->RequestingPhysician . ']                  #   6, 1 Referring Physician’s Name, PN, ^ 5 components, 64 chars
			(0010,0010) PN [' . $this->PatientName . ']                         # PatientName, ^ 5 components, 64 chars
			(0010,0020) LO [' . $this->PatientID . ']                           #  PatientID, 64 max
			(0010,0030) DA [' . $this->PatientBirthDate . ']                    # PatientBirthDate, YYYYMMDD, 8 bytes fixed
			(0010,0040) CS [' . $this->PatientSex . ']                          #   2, 1 PatientSex
			(0010,2000) LO [' . $this->MedicalAlerts . ']                       #  MedicalAlerts, 64 max
			(0010,2110) LO [' . $this->Allergies . ']                           #  Allergies, 64 max
			(0010,21B0) LT [' . $this->AdditionalPatientHistory . ']            #  AdditionalPatientHistory, 10240 char max
			(0020,000d) UI [' . $this->StudyInstanceUID . ']                    # StudyInstanceUID, 64 bytes max
			(0020,0010) SH [' . $this->AccessionNumber . ']                      #  Study ID, 16 Characters max
			(0032,1032) PN [' . $this->RequestingPhysician . ']                  #   6, 1 RequestingPhysician, PN, ^ 5 components, 64 chars
			(0032,1060) LO [' . $this->RequestedProcedureDescription . ']        #  RequestedProcedureDescription, 64 max
			(0040,0001) AE [' . $this->ScheduleStationAETitle . ']               #  Station AET, 16 bytes max
			(0040,0002) DA [' . $this->ScheduledProcedureStepStartDate . ']      #  Scheduled DATE, YYYYMMDD, 8 bytes fixed
			(0040,0003) TM [' . $this->ScheduledProcedureStepStartTime . ']      #  Scheduled TIME,  HHMMSS.FFFFFF, 16 bytes max
			(0040,1001) SH [' . $this->RequestedProcedureID . ']                 # RequestedProcedureID, 16 Characters max
			(0040,1003) SH [' . $this->RequestedProcedurePriority . ']           # RequestedProcedurePriority, 16 Characters max';
			
			//echo $template;dump2dcm.exe sampleWorklist.txt newWorklist.wl
			file_put_contents (self::$ORTHANC_MWL . $this->AccessionNumber . '.txt', $template);
			self::dcmtk_command('dump2dcm ' . self::$ORTHANC_MWL . $this->AccessionNumber . '.txt ' . self::$ORTHANC_MWL . $this->AccessionNumber  . ".wl");

J. Riesmeier
DCMTK Developer
Posts: 2496
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: Implementing Worklist - Using dcmtk and Orthanc

#2 Post by J. Riesmeier »

Strictly speaking, the file meta information (0002,xxxx) is not needed for the worklist files since only the data set (starting with data element (0008,xxxx) is sent with the C-FIND response message. Storing the datasets as files (with file extension ".wl") was a design decision during the implementation of DCMTK's worklist SCP.

However, your worklist data seems to use an incorrect structure (nesting of data elements), e.g. (0040,0001) Scheduled Station AE Title is nested in a item of the Scheduled Procedure Step Sequence. Please check for the ">" character in the first column of DICOM PS3.6 Table K.6-1.

Regarding the creation of unique identifiers, see Section 9 of DICOM PS3.5.

Stephen D. Scotti
Posts: 16
Joined: Fri, 2020-06-19, 07:56

Re: Implementing Worklist - Using dcmtk and Orthanc

#3 Post by Stephen D. Scotti »

Thanks. Sorry about not checking back sooner. Still in development actually. I am using Orthanc as a PACS server for development. It apparently supports MWL's, and the acquisition device is going to be an Esaote G-scan Brio. Still working through using the MWL. Here is a plain text example. I'm actually not sure how to use the MWL Step ID's since we won't have that. Just the scheduled data and time. There are some issues with what is shown below with:

(0008,0090) PN [0001^Scotti^Stephen] # ReferringPhysiciansName
(0008,0100) SH [0001] # CodeValue
(0008,0102) SH [L] # CodingSchemeDesignator

and probably others since I I want to find a place to put a physician ID. (0008,0090) is a PN and should not have the 0001 prefix, and (0008,0100) & (0008,0102) look like they belong in a sequence hierarchy like by using:

dcmodify -nb -i "(0008,0096)[0].(0040,1101)[0].(0008,0100)=0001" "/Users/sscotti/Downloads/W_KNEE_LAT_Right_4/IM-0002-0001.dcm"
dcmodify -nb -i "(0008,0096)[0].(0040,1101)[0].(0008,0102)=L" "/Users/sscotti/Downloads/W_KNEE_LAT_Right_4/IM-0002-0001.dcm"

not in the root hierarchy.

I don't quite understand how the nesting works really after reading the docs there. Is it possible to construct an MWL similar to what I have such that there is a place for a referring physician ID and such that the MR scanner will be able to read the data that I have. The RIS actually has a physician ID and I want to put that into a searchable field in the DICOM tags.

Thanks.

# Dicom-File-Format

# Dicom-Meta-Information-Header
(0002,0000) UL 202 # FileMetaInformationGroupLength
(0002,0001) OB 00\01 # FileMetaInformationVersion
(0002,0002) UI [1.2.840.10008.3.1.2.3.3] # MediaStorageSOPClassUID
(0002,0003) UI [1.2.276.0.7230010.3.1.4.2831176407.11154.1448031138.805061] # MediaStorageSOPInstanceUID
(0002,0010) UI =LittleEndianExplicit # TransferSyntaxUID
(0002,0012) UI [1.2.276.0.7230010.3.0.3.6.0] # ImplementationClassUID
(0002,0013) SH [OFFIS_DCMTK_360] # ImplementationVersionName

# Dicom-Data-Set
(0008,0005) CS [ISO_IR 100] # SpecificCharacterSet
(0008,0050) SH [DEVACC00000001] # AccessionNumber
(0008,0060) CS [MR] # Modality
(0008,0080) LO [Cayman Medical Ltd.] # InstitutionName
(0008,0090) PN [0001^Scotti^Stephen] # ReferringPhysiciansName
(0008,0100) SH [0001] # CodeValue
(0008,0102) SH [L] # CodingSchemeDesignator

(0010,0010) PN [Scotti^Stephen^Douglas] # PatientName
(0010,0020) LO [DEV0000001] # PatientID
(0010,0030) DA [19571116] # PatientBirthDate
(0010,0040) CS [M] # PatientSex
(0010,2000) LO [] # MedicalAlerts
(0010,2110) LO [] # Allergies
(0010,21B0) LT [test] # AdditionalPatientHistory
(0020,000d) UI [1.3.6.1.4.1.56016.1.20200423113000] # StudyInstanceUID
(0032,1060) LO [MRI BRAIN / BRAIN STEM WITHOUT CONTRAST] # RequestedProcedureDescription
(0040,0001) AE [AETITLE_MRI] # ScheduleStationAETitle
(0040,0002) DA [20200423] # ScheduledProcedureStepStartDate
(0040,0003) TM [113000] # ScheduledProcedureStepStartTime
(0040,1001) SH [0001] # RequestedProcedureID
(0040,1003) SH [routine] # RequestedProcedurePriority

J. Riesmeier
DCMTK Developer
Posts: 2496
Joined: Tue, 2011-05-03, 14:38
Location: Oldenburg, Germany
Contact:

Re: Implementing Worklist - Using dcmtk and Orthanc

#4 Post by J. Riesmeier »

Is it possible to construct an MWL similar to what I have such that there is a place for a referring physician ID and such that the MR scanner will be able to read the data that I have. The RIS actually has a physician ID and I want to put that into a searchable field in the DICOM tags.
First of all, you should check which DICOM attributes are actually queried by the MR scanner. This has to be documented in the corresponding DICOM Conformance Statement.

Stephen D. Scotti
Posts: 16
Joined: Fri, 2020-06-19, 07:56

Re: Implementing Worklist - Using dcmtk and Orthanc

#5 Post by Stephen D. Scotti »

Hi again, stopped working on that since the MR scanner install got really delayed because of COVID. I did revisit and started experimenting around again a bit using sequences in the MWL. An example of the dcmdump of the text file created is here: The sequences that I added are:

(0008,0096) SQ (Sequence with explicit length #=1) # 252, 1 ReferringPhysicianIdentificationSequence
&
(0040,0100) SQ (Sequence with explicit length #=1) # 110, 1 ScheduledProcedureStepSequence

It seems to convert the text file with dump2dcm and back with dcmdump, so at least it isn't complaining about the formt. I remove the Header for now.

Just wondering if that seems to basically conform to the format.

I'll have to consult the Conformance Statement and hopefully the Esaote technicians once they get rolling:

Here is their Conformance:

https://www.esaote.com/fileadmin/user_u ... 3-1_3_.pdf

Code: Select all

# Dicom-File-Format

# Dicom-Meta-Information-Header
# Used TransferSyntax: Unknown Transfer Syntax

# Dicom-Data-Set
# Used TransferSyntax: Little Endian Explicit
(0008,0005) CS [ISO_IR 100]                             #  10, 1 SpecificCharacterSet
(0008,0050) SH [DEVACC00000002]                         #  14, 1 AccessionNumber
(0008,0060) CS [MR]                                     #   2, 1 Modality
(0008,0080) LO [Cayman Medical Ltd.]                    #  20, 1 InstitutionName
(0008,0090) PN [0001:Scotti^Stephen^^Dr.^,M.D.]         #  30, 1 ReferringPhysicianName
(0008,0096) SQ (Sequence with explicit length #=1)      # 252, 1 ReferringPhysicianIdentificationSequence
  (fffe,e000) na (Item with explicit length #=4)          # 244, 1 Item
    (0008,0080) LO [Cayman Medical Ltd.]                    #  20, 1 InstitutionName
    (0040,1101) SQ (Sequence with explicit length #=1)      #  48, 1 PersonIdentificationCodeSequence
      (fffe,e000) na (Item with explicit length #=3)          #  40, 1 Item
        (0008,0100) SH [0001]                                   #   4, 1 CodeValue
        (0008,0102) SH [L]                                      #   2, 1 CodingSchemeDesignator
        (0008,0104) LO [Local Code]                             #  10, 1 CodeMeaning
      (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
    (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
    (0040,1103) LO [US-Phone^WPN^PH^email] #  40, 1 PersonTelephoneNumbers
    (0040,1104) LT [US-Phone^WPN^PH^email]           # PersonTeleco... # 100, 1 PersonTelecomInformation
  (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
(0008,1030) LO [MRI BRAIN / BRAIN STEM]                 #  22, 1 StudyDescription
(0010,0010) PN [Scotti^Stephen^Douglas]                 #  22, 1 PatientName
(0010,0020) LO [D]                                      #   2, 1 PatientID
(0010,0030) DA [YYYYMMDD]                               #   8, 1 PatientBirthDate
(0010,0040) CS [M]                                      #   2, 1 PatientSex
(0010,1040) LO [Address] #  52, 1 PatientAddress
(0010,2000) LO (no value available)                     #   0, 0 MedicalAlerts
(0010,2110) LO (no value available)                     #   0, 0 Allergies
(0010,2154) SH [US-Phone^PRN^PH^email]   #  36, 1 PatientTelephoneNumbers
(0010,2155) LT [US-Phone^WPN^PH^email]   #  36, 1 PatientTelecomInformation
(0010,21b0) LT [test]                                   #   4, 1 AdditionalPatientHistory
(0020,000d) UI [1.3.6.1.4.1.56016.1.20210127000000]     #  34, 1 StudyInstanceUID
(0020,0010) SH [0001]                                   #   4, 1 StudyID
(0032,1060) LO [MRI BRAIN / BRAIN STEM]                 #  22, 1 RequestedProcedureDescription
(0040,0100) SQ (Sequence with explicit length #=1)      # 110, 1 ScheduledProcedureStepSequence
  (fffe,e000) na (Item with explicit length #=6)          # 102, 1 Item
    (0008,0060) CS [MR]                                     #   2, 1 Modality
    (0040,0001) AE [AETITLE_MRI]                            #  12, 1 ScheduledStationAETitle
    (0040,0002) DA [20210127]                               #   8, 1 ScheduledProcedureStepStartDate
    (0040,0003) TM [000000]                                 #   6, 1 ScheduledProcedureStepStartTime
    (0040,0007) LO [MRI BRAIN / BRAIN STEM]                 #  22, 1 ScheduledProcedureStepDescription
    (0040,0009) SH [0001]                                   #   4, 1 ScheduledProcedureStepID
  (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
(0040,1001) SH [0001]                                   #   4, 1 RequestedProcedureID
(0040,1003) SH [R]  
As a side note, I've been working on a python script to integrate with Orthanc that creates the MWL file from an HL7 messages sent to Orthanc. That uses the PIP module:

import hl7 # https://python-hl7.readthedocs.io/en/latest/, and the MWL plug-in from Orthanc. Still a work in progress, but hoping to develop it further to process the HL7 message to create the MWL file for use with Orthanc.

Code: Select all

def CreateAndSave(output, uri, **request):

	if request['method'] != 'POST':
		output.SendMethodNotAllowed('POST')
	else:
	
		query = json.loads(request['body'])
		pathtodump2dcm = shutil.which("dump2dcm")
		pathtoworklist = json.loads(orthanc.GetConfiguration())['Worklists']['Database']
		
		if not os.path.exists(pathtoworklist):
			os.makedirs(pathtoworklist)

		charset = "ISO_IR 100"

		if "HL7" in query:
			message = hl7.parse(query['HL7'])

# family name complex, given name complex, middle name, name prefix, name suffix. in dicom
			query = dict()
			print(message['PID1.F2.R1.C1'])
			query['AccessionNumber'] = str(message.segments('OBR')[0][3]); #field 3 of first obr
			query['Modality'] = str(message.segments('IPC')[0][5]);  #field 4 of first IPC
			query['InstitutionName'] = str(message.segment('PV1')[39]); #field 39 of first PV!
			query['ReferringPhysiciansName'] = str(message.segment('PV1')[8][0][0]) + ':' + str(message.segment('PV1')[8][0][1]) + '^' + str(message.segment('PV1')[8][0][2]) + '^' + str(message.segment('PV1')[8][0][3]) + '^' + str(message.segment('PV1')[8][0][5]) + '^' + str(message.segment('PV1')[8][0][4]) + ',' + str(message.segment('PV1')[8][0][6]) # ReferringPhysiciansName
			query['PatientName'] = str(message.segment('PID')[5]); #field 5
			query['PatientID'] = str(message.segment('PID')[2][0][0]); #field 2, first R, component 0
			query['PatientBirthDate'] = str(message.segment('PID')[7]);
			query['PatientSex'] = str(message.segment('PID')[8]);
			query['PatientAddress'] = str(message.segment('PID')[11]);
			query['PatientTelephoneNumbers'] = str(message.segment('PID')[13]);
			query['PatientTelecomInformation'] = str(message.segment('PID')[14]);
			query['MedicalAlerts'] = "" # message.segments('OBR')[0][8];
			query['Allergies'] = ""# message.segments('OBR')[0][8];
			query['AdditionalPatientHistory'] = str(message.segments('OBR')[0][13]) # message.segments('OBR')[0][8];
			query['StudyInstanceUID'] = str(message.segments('IPC')[0][3]) #
			query['RequestingPhysician'] = str(message.segment('PV1')[8]) # RequestingPhysician
			query['RequestedProcedureDescription'] = str(message.segments('OBR')[0][4][0][1])
			query['ScheduleStationAETitle'] = str(message.segments('IPC')[0][9])
			query['ScheduledProcedureStepStartDate'] = str(message.segments('OBR')[0][36])[:8]
			query['ScheduledProcedureStepStartTime'] = str(message.segments('OBR')[0][36])[-6:]
			query['RequestedProcedureID'] = str(message.segments('OBR')[0][4][0][0])
			query['RequestedProcedurePriority'] =str(message.segments('OBR')[0][5])
			query['MediaStorageSOPClassUID'] = "NONE" # might need this
			query['PhysicianIDforSequence'] =str(message.segment('PV1')[8][0][0])
			query['PersonTelephoneNumbers'] =str(message.segments('OBR')[0][17])
			query['PersonTelecomInformation'] = str(message.segments('OBR')[0][17])

		mwl = [];
		mwl.append("# Dicom-File-Format")
		mwl.append("")
		mwl.append("# Dicom-Meta-Information-Header")
		#mwl.append("(0002,0000) UL 202                                        # FileMetaInformationGroupLength")
		#mwl.append("(0002,0001) OB 00\\01                                     # FileMetaInformationVersion")
		#mwl.append("(0002,0002) UI [" + query['MediaStorageSOPClassUID'] + "] # MediaStorageSOPClassUID")
		#mwl.append("(0002,0003) UI [1.2.276.0.7230010.3.1.4.2831176407.11154.1448031138.805061] # MediaStorageSOPInstanceUID")
		#mwl.append("(0002,0010) UI =LittleEndianExplicit                     # TransferSyntaxUID")
		#mwl.append("(0002,0012) UI [1.2.276.0.7230010.3.0.3.6.0]             # ImplementationClassUID")
		#mwl.append("(0002,0013) SH [OFFIS_DCMTK_360]                         # ImplementationVersionName")
		#mwl.append("")
		mwl.append("# Dicom-Data-Set")
		mwl.append("(0008,0005) CS [" +charset + "]                  # SpecificCharacterSet")
		mwl.append("(0008,0050) SH [" + query['AccessionNumber'] + "]          # AccessionNumber")
		mwl.append("(0008,0060) CS [" + query['Modality'] + "]                 # Modality")
		mwl.append("(0008,0080) LO [" + query['InstitutionName'] + "]          # InstitutionName")
		# PN format is last,first,middle,prefix,suffix, HL7 format is "ID^LAST^FIRST^MIDDLE^SUFFIX^PREFIX^DEGREE"
		# Want this to be ID:Last^First^Middle^Prefix^Suffix for DICOM
		mwl.append("(0008,0090) PN [" + query['ReferringPhysiciansName'] + "]      # ReferringPhysiciansName")
		mwl.append("(0008,1030) LO  [" + query['RequestedProcedureDescription'] + "]      # RequestedProcedureDescription")
		
		mwl.append("(0010,0010) PN [" + query['PatientName'] + "]              # PatientName")
		mwl.append("(0010,0020) LO [" + query['PatientID'] + "]                # PatientID")
		mwl.append("(0010,0030) DA [" + query['PatientBirthDate'] + "]         # PatientBirthDate")
		mwl.append("(0010,0040) CS [" + query['PatientSex'] + "]               # PatientSex")
		
		mwl.append("(0010,1040) LO [" + query['PatientAddress'] + "]               # PatientAddress")
		mwl.append("(0010,2154) SH [" + query['PatientTelephoneNumbers'] + "]               # PatientTelephoneNumbers")
		mwl.append("(0010,2155) LT [" + query['PatientTelecomInformation'] + "]               # PatientTelecomInformation")
		
		mwl.append("(0010,2000) LO [" + query['MedicalAlerts'] + "]            # MedicalAlerts")
		mwl.append("(0010,2110) LO [" + query['Allergies'] + "]                # Allergies")
		mwl.append("(0010,21B0) LT [" + query['AdditionalPatientHistory'] + "] # AdditionalPatientHistory")
		mwl.append("(0020,000d) UI [" + query['StudyInstanceUID'] + "]         # StudyInstanceUID")
		mwl.append("(0020,0010) SH [" + query['RequestedProcedureID'] + "]         # StudyID")
		mwl.append("(0032,1060) LO [" + query['RequestedProcedureDescription'] + "]        #  RequestedProcedureDescription")
		#mwl.append("(0040,0001) AE [" + query['ScheduleStationAETitle'] + "]               #  ScheduleStationAETitle")
		#mwl.append("(0040,0002) DA [" + query['ScheduledProcedureStepStartDate'] + "]      #  ScheduledProcedureStepStartDate")
		#mwl.append("(0040,0003) TM [" + query['ScheduledProcedureStepStartTime'] + "]      #  ScheduledProcedureStepStartTime")
		mwl.append("(0040,1001) SH [" + query['RequestedProcedureID'] + "]                 # RequestedProcedureID")
		mwl.append("(0040,1003) SH [" + query['RequestedProcedurePriority'] + "]           # RequestedProcedurePriority")
		
		mwl.append("(0040,0100) SQ (Sequence with explicit length #=1)           # ScheduledProcedureStepSequence")
		mwl.append("(fffe,e000) na (Item with explicit length #=6)           # Item")
		mwl.append("(0040,0001) AE [" + query['ScheduleStationAETitle'] + "]           # ScheduledStationAETitle")
		mwl.append("(0040,0002) DA [" + query['ScheduledProcedureStepStartDate'] + "]           # ScheduledProcedureStepStartDate")
		mwl.append("(0040,0003) TM [" + query['ScheduledProcedureStepStartTime'] + "]           # ScheduledProcedureStepStartTime")
		mwl.append("(0040,0007) LO [" + query['RequestedProcedureDescription'] + "]           # ScheduledProcedureStepDescription")
		mwl.append("(0040,0009) SH [" + query['RequestedProcedureID'] + "]           # ScheduledProcedureStepID")
		mwl.append("(0008,0060) CS [" + query['Modality'] + "]           # Modality")
		mwl.append("(fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem")
		mwl.append("(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem")

		mwl.append("(0008,0096) SQ (Sequence with explicit length #=1)           # ReferringPhysicianIdentificationSequence")
		mwl.append("(fffe,e000) na (Item with explicit length #=4)           # Item")
		mwl.append("(0008,0080) LO [" + query['InstitutionName'] + "]           # InstitutionName")
		mwl.append("(0040,1101) SQ (Sequence with explicit length #=1)           # PersonIdentificationCodeSequence")
		mwl.append("(fffe,e000) na (Item with explicit length #=3)           # Item")
		mwl.append("(0008,0100) SH [" + query['PhysicianIDforSequence'] + "]           # CodeValue")
		mwl.append("(0008,0102) SH [L]           # CodingSchemeDesignator")
		mwl.append("(0008,0104) LO [Local Code]           # CodeMeaning")
		mwl.append("(fffe,e00d) na (ItemDelimitationItem for re-encoding)           # ItemDelimitationItem")
		mwl.append("(fffe,e0dd) na (SequenceDelimitationItem for re-encoding)           # SequenceDelimitationItem")
		mwl.append("(0040,1103) LO [" + query['PersonTelephoneNumbers'] + "]           # PersonTelephoneNumbers")
		mwl.append("(0040,1104) LT [" + query['PersonTelecomInformation'] + "]           # PersonTelecomInformation, [Phone^WPN^CP^email]")
		mwl.append("(fffe,e00d) na (ItemDelimitationItem for re-encoding)           # ItemDelimitationItem")
		mwl.append("(fffe,e0dd) na (SequenceDelimitationItem for re-encoding.)           # SequenceDelimitationItem")

		try:
			errorstatus = False
			response = dict()
			filename = pathtoworklist + '/' + query['AccessionNumber']
			returnedtext = ""
			original = sys.stdout
			for line in mwl:
				returnedtext = returnedtext + line + "\n"

			with open(filename + ".txt", 'w+') as filehandle:
				# set the new output channel
				sys.stdout = filehandle
				for line in mwl:
					print(line)
				# restore the old output channel
				sys.stdout = original
				filehandle.close()
				subprocess.Popen(pathtodump2dcm +' -F +te ' + filename + ".txt " + filename + ".wl", shell = True)
				# raise Exception("Testing Error.") 
				
		except Exception as e:
		
			errorstatus = True
			response['error'] =  str(e)
			response['status'] = 'Problem with MWL:  ' + query['AccessionNumber']

	if errorstatus == False:
		response['status'] = 'MWL File Written  ' + query['AccessionNumber']
		response['error'] =  "OK"
	output.AnswerBuffer(json.dumps(response, indent = 3), 'application/json')

orthanc.RegisterRestCallback('/mwl/file/make', CreateAndSave)

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest