def index_directory(self, rootp: PathLike): D = DicomDirectory(root=rootp) file_names = D.inventory() # def check_bhashes(value): # _value = value[:NUM_KEY_CHARS] # return not (_value in self.bhashes) # True if its needed for fn in file_names: self.index_instance(D, fn) # # try: # # May raise "InvalidDicomException" if not dicom # # (or return None if ignore_errors flag is set) # inst = D.get(fn, bhash_validator=check_bhashes) # # Some instances are un-indexable # if inst.dhash == None: # print(f"No pixels found in {fn}") # self.bhashes[self.t(inst, KTy.BHASH)] = inst.mhash # continue # self.put(inst) # except FileExistsError: # # print(f"Already indexed {fn}") # continue # except InvalidDicomException: # print(f"Not a DICOM file {fn}") # continue # Safe to freeze after reading an entire dir self.freeze()
def test_get(): D = DicomDirectory(root=rootp) fn = "ibis1/01001_2.16.840.1.113669.632.21.1139687029.3025563835.31534914061935431.dcm" d = D.get(fn) assert d.tags["PatientID"] == "123456789" fn = "ibis2/IM100" d = D.get(fn) assert d.tags[ "PatientID"] == "15.03.26-07:44:14-STD-1.3.12.2.1107.5.1.4.66502"
def test_status_and_exceptions(): with tempfile.TemporaryDirectory() as tmp: D = DicomDirectory(root=tmp) assert (D.status()) (pathlib.Path(tmp) / "test").touch() with pytest.raises(InvalidDicomException): D.get("test") with pytest.raises(FileNotFoundError): D.get("testtesttest") assert D.get("test", ignore_errors=True) is None assert D.get("testtesttest", ignore_errors=True) is None assert not D.status()
def anonymize_and_upload(R: DicomRegistry, D: DicomDirectory, O: Orthanc): for d in R.instances.values(): ser_mhash = Dixel.from_child(d).mhash # Find the real ser ser = R.get(ser_mhash, dlvl=DLv.SERIES) stu_mhash = Dixel.from_child(d, DLv.STUDY).mhash # Find the real stu stu = R.get(stu_mhash, dlvl=DLv.STUDY) m = orthanc_sham_map( stu.mhash, stu.dhash, # Try patient id first, fall back to patient name, or use "UNKNOWN" patient_id=stu.tags.get("PatientID", stu.tags.get("PatientName", "UNKNOWN")), stu_dt=stu.timestamp, ser_mhash=ser.mhash, ser_dhash=ser.dhash, ser_dt=ser.timestamp, inst_mhash=d.mhash, inst_dhash=d.dhash, inst_dt=d.timestamp) dd = D.get(d.meta["fp"], binary=True) r = O.put(dd) # If no Patient ID, need to use returned value oid = r['ID'] print(f"Putting {dd.main_tags()} in {oid}") O.anonymize(oid, replacement_map=m) # Anon inst no longer returns image? O.delete(oid, dlvl=DLv.INSTANCE)
def register_path(D: DicomDirectory, H: HashRegistry, O: Orthanc = None, upload: bool = False): print(f"Registering path {D.root}") tic = time.time() m, n, o = 0, 0, 0 for fn in D.inventory(): m += 1 if m % ANNOUNCEMENT_INTERVAL == 0: print(f"Checked {m} files") H.shelve() dx = D.get(fn, binary=True, bhash_validator=lambda h: not H.exists(h), ignore_errors=True) if dx is not None: if not H.exists(dx.mhash): n += 1 if n % ANNOUNCEMENT_INTERVAL == 0: print(f"Registered {n} files") H.put(dx) if upload and O is not None: o += 1 if o % ANNOUNCEMENT_INTERVAL == 0: print(f"Uploaded {o} files") O.put(dx) toc = time.time() print(f"----------------------------") print(f"Checked {m} files") print(f"Registered new {n} instances") print(f"Uploaded {o} instances") print(f"Elapsed time: {toc-tic:.2f} ({max([n,1])/(toc-tic):.2f}dx/s)") print(f"----------------------------") H.shelve() pprint(H.find(q={"dlvl": DLv.STUDY}))
def test_orthanc_upload(): O = Orthanc() O.clear() ROOTP = "~/data/dcm/ibis2" D = DicomDirectory(ROOTP) d = D.get("IM1", binary=True) print(d.summary()) O.put(d) g = O.get(d.oid(), dlvl=DLv.INSTANCE) Dixel.comparator = CTy.METADATA assert d == g e = Dixel.from_child(d) h = O.get(e.oid(), dlvl=DLv.SERIES) assert e == h f = Dixel.from_child(e) i = O.get(f.oid(), dlvl=DLv.STUDY) assert f == i
def index_instance(self, D: DicomDirectory, fn: str): def check_bhashes(value): _value = value[:NUM_KEY_CHARS] return not (_value in self.bhashes) # True if its needed try: # May raise "InvalidDicomException" if not dicom # (or return None if ignore_errors flag is set) inst = D.get(fn, bhash_validator=check_bhashes) # Some instances are un-indexable if inst.dhash == None: print(f"No pixels found in {fn}") self.bhashes[self.t(inst, KTy.BHASH)] = inst.mhash return self.put(inst) except FileExistsError: # print(f"Already indexed {fn}") pass except InvalidDicomException: print(f"Not a DICOM file {fn}") return
def test_inventory(): D = DicomDirectory(root=rootp) inv = D.inventory() # Each has about 350+ studies assert len(inv) > 700
print(f"Registered {n} files") H.put(dx) if upload and O is not None: o += 1 if o % ANNOUNCEMENT_INTERVAL == 0: print(f"Uploaded {o} files") O.put(dx) toc = time.time() print(f"----------------------------") print(f"Checked {m} files") print(f"Registered new {n} instances") print(f"Uploaded {o} instances") print(f"Elapsed time: {toc-tic:.2f} ({max([n,1])/(toc-tic):.2f}dx/s)") print(f"----------------------------") H.shelve() pprint(H.find(q={"dlvl": DLv.STUDY})) if __name__ == "__main__": D = DicomDirectory(root=ROOT_PATH) H = HashRegistry(clear_cache=CLEAR_HASHES, cache_file=CACHE_FILE) O = Orthanc(url=ORTHANC_URL) if CLEAR_DICOM: input("Are you sure that you want to clear the queue?") O.clear() register_path(D, H, O, upload=UPLOAD_DICOM)