Beispiel #1
0
    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()
Beispiel #2
0
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"
Beispiel #3
0
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()
Beispiel #4
0
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}))
Beispiel #6
0
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
Beispiel #7
0
    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
Beispiel #8
0
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)