def __setitem__(self, key, value): if isinstance(key, int): setattr(self, self._dict[key][4], value) elif isinstance(key, str): setattr(self, key, value) elif isinstance(key, tuple): tag1, tag2 = key setattr((self, self._dict[tag1 * (16**4) + tag2][4], value)) else: raise LightError("This is not valid indexing. Try one of:\n" + \ " 1. dcm[0x10,0x10]\n" + \ " 2. dcm[0x100010]\n" + \ " 3. dcm.PatientName")
def __getitem__(self, tag: Union[str, int, tuple]) -> Any: if isinstance(tag, str): return getattr(self, tag) elif isinstance(tag, int): field = self._dict[tag][4] return getattr(self, field) elif isinstance(tag, tuple): tag1, tag2 = tag field = self._dict[tag1 * (16**4) + tag2][4] return getattr(self, field) else: raise LightError("This is not valid indexing. Try one of:\n"+\ " 1. dcm[0x10,0x10]\n"+\ " 2. dcm[0x100010]\n"+\ " 3. dcm.PatientName")
def parseUntilUID(tagClass:Tag, \ file:bin, \ idx=132) -> Tag: UID = None while True: idx = int(idx) _tag = getTag(file[idx:idx + 4], isLittle=True) isGroupLengthTag = ifGroupLengthTag(_tag) idx = idx + 4 vr = file[idx:idx + 2] # Refer "https://dicom.nema.org/dicom/2013/output/chtml/part05/chapter_7.html" for more details. if vr in [b'OB', b'OW', b'OF', b'SQ', b'UT', b'UN']: idx = idx + 2 + 2 # Last 2 is for reserved 2 bytes. vl = file[idx:idx + 4] idx = idx + 4 vl = _OBOW_vr(vl, _tag, isLittle=True) else: idx = idx + 2 # There are no reseved bytes. vl = file[idx:idx + 2] vl = _get_vr_length(vl, isLittle=True) idx = idx + 2 value = file[idx:idx + vl] if isGroupLengthTag: assert vr == b'UL', "Value Representation (VR) should be type of UL (Unsigned Long) for Group Length Tag."+\ f"Current VR : {vr}. Check your DICOM sanity." value = parseUL(value, isLittle=True) idx = idx + vl tagClass[_tag] = [vr, vl, value] if _tag == 131088: UID = hex(_tag) print(hex(_tag), vr, vl, value) if UID is not None: return tagClass, idx, UID if idx > len(file): raise LightError( "This file does not follow DICOM standard protocol. Check your DICOM sanity." )
def _exam_file(self, file, force): preamble = bytes([0]) * 128 if file[:128] != preamble: if self.print_warning == True: print( f"For {self.path}, first 128 bytes are not zeros. This is not usual DICOM type. Handle this file carefully." ) else: pass if file[128:132] != b'DICM': if force is False: raise LightError(f"For {self.path}, 129-th~133-th bytes should be 'DICM'. This is not valid DICOM file.\n"\ +"If you want to read this file anyway, try 'LightDCMClass(force=True)'") else: if self.print_warning is True: print( f"For {self.path}, 129-th~133-th bytes are not 'DICM'. This is not usual DICOM type. Handle this file carefully." ) else: pass
def parseImplicitVRLittleEndian(tagClass:Tag, \ file:bin, \ isLittle:bool,\ idx=132) -> Tag: while True: idx = int(idx) _tag = getTag(file[idx:idx + 4], isLittle=isLittle) isGroupLengthTag = ifGroupLengthTag(_tag) idx = idx + 4 # Refer "https://dicom.nema.org/dicom/2013/output/chtml/part05/chapter_7.html" for more details. print(hex(_tag)) vr = DicomDictionary[_tag][0] vl = file[idx:idx + 4] idx = idx + 4 vl = _get_vr_length(vl, isLittle=isLittle) value = file[idx:idx + vl] if isGroupLengthTag: assert vr == b'UL', "Value Representation (VR) should be type of UL (Unsigned Long) for Group Length Tag."+\ f"Current VR : {vr}. Check your DICOM sanity." value = parseUL(value, isLittle=isLittle) idx = idx + vl tagClass[_tag] = [vr, vl, value] print(hex(_tag), vr, vl, value) if idx == len(file): return tagClass if idx > len(file): raise LightError( "This file does not follow DICOM standard protocol. Check your DICOM sanity." )
def read_all(self, with_pixel=True, resize_pixel=True): if not os.path.isfile(self.path): raise LightError( f"{self.path} does not exist. Check your file path") if self.file == None: self.lightRead(self.path) idx = 132 self._check_endian() all_dict = {} while idx < len(self.file) - 4: find_tag = self._maketag(self.file[idx:idx + 4], idx) if 'Explicit' in self.endian: dtype = self.file[idx + 4:idx + 6] if find_tag == '0008,1140': vl = self.file[idx + 8:idx + 12] all_dict[find_tag] = self.file[idx + 12:idx + 12 + 8] idx = idx + 20 else: if dtype in [b'OB', b'OW', b'SQ', b'UN']: reserved = self.file[idx + 6:idx + 8] vl = self.file[idx + 8:idx + 12] if dtype in [b'OB', b'OW']: vl = self._OBOW_vr(vl, find_tag) else: vl = self._get_vr_length(vl) if find_tag == '7fe0,0010': if with_pixel: all_dict[find_tag] = self.file[idx + 12:idx + 12 + vl] idx = idx + 12 + vl else: all_dict[find_tag] = b'' idx = idx + 12 + vl else: all_dict[find_tag] = self.file[idx + 12:idx + 12 + vl] idx = idx + 12 + vl else: vl = self.file[idx + 6:idx + 8] vl = self._get_vr_length(vl) all_dict[find_tag] = self.file[idx + 8:idx + 8 + vl] idx = idx + 8 + vl if 'Implicit' in self.endian: if find_tag == '0008,1140': vl = self.file[idx + 8:idx + 12] all_dict[find_tag] = self.file[idx + 12:idx + 12 + 8] idx = idx + 20 else: try: if int(find_tag[:4]) < 8: dummy = 0 vl = self.file[idx + 6:idx + 8 + dummy] else: dummy = 2 vl = self.file[idx + 4:idx + 6 + dummy] except: dummy = 2 vl = self.file[idx + 4:idx + 6 + dummy] if find_tag == '7fe0,0010': if with_pixel: if resize_pixel: vl = self._OBOW_vr(vl, find_tag) all_dict[find_tag] = self.read_pixel() else: vl = self._OBOW_vr(vl, find_tag) value = self.file[idx + 8:idx + 8 + vl] all_dict[find_tag] = np.frombuffer( value, np.int16) else: vl = self._OBOW_vr(vl, find_tag) all_dict[find_tag] = '' else: vl = self._get_vr_length(vl) all_dict[find_tag] = self.file[idx + 8:idx + 8 + vl] try: if int(find_tag[:4]) < 8: idx = idx + 8 + vl + dummy else: idx = idx + 6 + vl + dummy except: idx = idx + 6 + dummy + vl return all_dict
def get_data(self, tag, path=None): if not os.path.isfile(self.path): raise LightError( f"{self.path} does not exist. Check your file path") if self.file == None: self.lightRead(path) tag = tag.replace(' ', '') idx = 132 self._check_endian() while True: find_tag = self._maketag(self.file[idx:idx + 4], idx) if 'Explicit' in self.endian: dtype = self.file[idx + 4:idx + 6] if find_tag == '0008,1140': if tag == '0008,1140': vl = self.file[idx + 8:idx + 12] return { 'tag': tag, 'dtype': dtype, 'length': vl, 'value': self.file[idx + 12:idx + 12 + 8] } else: idx = idx + 20 else: if dtype in [b'OB', b'OW', b'SQ', b'UN']: reserved = self.file[idx + 6:idx + 8] vl = self.file[idx + 8:idx + 12] if dtype in [b'OB', b'OW']: vl = self._OBOW_vr(vl, find_tag) else: vl = self._get_vr_length(vl) if find_tag == tag: return { 'tag': tag, 'dtype': dtype, 'reserved': reserved, 'length': vl, 'value': self.file[idx + 12:idx + 12 + vl] } else: idx = idx + 12 + vl else: vl = self.file[idx + 6:idx + 8] vl = self._get_vr_length(vl) if find_tag == tag: return { 'tag': tag, 'dtype': dtype, 'length': vl, 'value': self.file[idx + 8:idx + 8 + vl] } else: idx = idx + 8 + vl if 'Implicit' in self.endian: if find_tag == '0008,1140': if tag == '0008,1140': vl = self.file[idx + 8:idx + 12] return { 'tag': tag, 'dtype': dtype, 'length': vl, 'value': self.file[idx + 12:idx + 12 + 8] } else: idx = idx + 20 else: try: if int(find_tag[:4]) < 8: dummy = 0 vl = self.file[idx + 6:idx + 8 + dummy] else: dummy = 2 vl = self.file[idx + 4:idx + 6 + dummy] except: dummy = 2 vl = self.file[idx + 4:idx + 6 + dummy] if find_tag == '7fe0,0010': vl = self._OBOW_vr(vl, find_tag) value = self.file[idx + 8:idx + 8 + vl] return { 'tag': tag, 'length': vl, 'value': np.frombuffer(value, np.int16) } else: vl = self._get_vr_length(vl) if find_tag == tag: return { 'tag': tag, 'length': vl, 'value': self.file[idx + 8:idx + 8 + vl] } else: try: if int(find_tag[:4]) < 8: idx = idx + 8 + vl + dummy else: idx = idx + 6 + vl + dummy except: idx = idx + 6 + dummy + vl if idx >= len(self.file) - 4: raise LightError( f"No matching tag was founded for tag ({tag}) in file {self.path}." )