Hi Jason
I can do this with Pinnacle 16.2.1 and our Canon Aquilion LB. I had to write software to alter the MIP with some additional tags. Interestingly, our MIPs would not import at all without this intervention. The Pinnacle dicom conformance statement does tell you which tags are required, but I found a bit of trial and error was needed. Basically, I take the position data from the phase 0% series and use it to add the position to the MIP data.
In Python, using pydicom and a reading a MIPS CT dicom object called ct:
#add the phase0 coordinate value corresponding to the InstanceNumber key in the phase0_dict
ct.add_new([0x0020, 0x00032],'DS',phase0_dict[ct.InstanceNumber])
#add a whole bunch of required tags
ct[0x0008, 0x0016].value='1.2.840.10008.5.1.4.1.1.2' #CT Image Storage SOP, for Intensity Projection Image Datasets Only
try:
ct.add_new([0x0018, 0x0050],'DS','3.0')#(0018,0050) DS Slice Thickness
slice_thickness = True
except:
slice_thickness = False
#add kvp
try:
ct.add_new([0x0018, 0x0060],'DS','120')#(0018,0060) DS KVP
kvp = True
except:
kvp = False
#add frame of reference UID, should match primary image set (dummy value for now)
try:
ct.add_new([0x0020, 0x0052],'UI','1.2.392.200036.9116.2.6.1.1236.3294381536.1627371182.292774')#(0020,0052) UI Frame of Reference UID
frame_of_ref_uid = True
except:
frame_of_ref_uid = False
#add tags required as VNAP (vnap, value not always present) in the 'Presence of Module' category of the dicom conformance statement
##position reference indicator, table 64
try:
ct.add_new([0x0020, 0x1040],'LO', '')#(0020,1040) LO Position Reference Indicator
position_ref_indicator = True
except:
position_ref_indicator = False
#add tags required as ANAP (attribute present in specified condition, value must be present if attribute exists) in the 'Presence of Module' category of the dicom conformance statement
##note the specified condition is not known, but the 'examine dicom issues' option in Pinnacle lists the first problematic tag
##patient position, table 63 - note that I'm making an assumption about HFS, it's not in the file anywhere in this format, but could be worked out from ImageOrientationPatient
try:
ct.add_new([0x0018, 0x5100],'CS' ,'HFS')#(0018,5100) CS Patient Position
patient_position = True
except:
patient_position = False
#from section 8.5.3, table 200
#private creator codes
try:
ct.add_new([0x00F1, 0x0010],'LO','ELSCINT1')
s00f10010 = True
except:
s00f10010 = False
#couch id
try:
ct.add_new([0x00E1, 0x1042],'LO','Couch')
couch_id = True
except:
couch_id = False
#gating, specifies intensity projection type as MIP, MinIP or AIP
try:
ct.add_new([0x01F1, 0x1039],'LO','AIP')
gating_code = True
except:
gating_code = False
#add in a dummy acquisition number. This is Type 2 (non essential) but throws a warning when importing to Aria
#and we don't want people to ignore warnings.
try:
ct.add_new([0x0020, 0x0012],'IS','1') # 2023-03-09
acquisition_number = True
except:
acquisition_number = False
There's a bit more complexity to it - you need to get the corresponding position from the phase 0% slices etc, but happy to discuss further.
Kind regards
Robert