def test_zip_reader(): p = find_resource("resources") D = DcmDir(path=p) f = D.get("dcm/IM2263", view=DixelView.TAGS_FILE) gs = D.get_zipped("dcm_zip/test.zip") for _g in gs: if "2263" in _g.meta["FileName"]: g = _g break logging.debug(f) logging.debug(g) assert(f.tags["StudyInstanceUID"] == g.tags["StudyInstanceUID"]) from binascii import hexlify logging.debug("f file:") logging.debug( hexlify(f.file[1024:2048]) ) logging.debug("g file:") logging.debug( hexlify(g.file[1024:2048]) ) assert f.file == g.file
def test_psend(setup_orthanc0, setup_orthanc1): O = Orthanc(peername="peer0") print(O) O.check() O2 = Orthanc(port=8043, peername="peer0") print(O2) O2.check() dicom_dir = find_resource("resources/dcm") D = DcmDir(path=dicom_dir) d = D.get("IM2263", view=DixelView.TAGS_FILE) O2.put(d) logging.debug(O2.gateway._get("peers")) O2.psend(d.oid(), O) e = O.get(d.oid(), level=DicomLevel.INSTANCES) logging.debug(e) assert d.oid() == e.oid()
def test_view_classifier(): # These weights classify as AP (pos) or Lateral (neg) fp = find_resource("resources/models/pose/view_classifier.h5") _model = get_mobilenet(0, weights=None) _model.load_weights(fp) fp = find_resource("resources/scouts") D = DcmDir(path=fp) # This one is lateral d = D.get("ct_scout_01.dcm", view=DixelView.PIXELS) prediction = d.get_prediction(_model) logging.debug("Prediction is {}".format(prediction)) assert (prediction < 0.5) # prediction = get_prediction( model, image ) # positive = "AP" # negative = "Lateral" # if prediction >= 0.5: # logging.debug("Predicted: {} ({})".format( positive, round(prediction, 2) )) # else: # logging.debug("Predicted: {} ({})".format( negative, round(1.0-prediction, 2) )) # This one is an AP d = D.get("ct_scout_02.dcm", view=DixelView.PIXELS) prediction = d.get_prediction(_model) logging.debug("Prediction is {}".format(prediction)) assert (prediction >= 0.5)
def test_orthanc_upload(setup_orthanc0): logging.debug("Test Orthanc Upload") O = Orthanc() dicom_dir = find_resource("resources/dcm") D = DcmDir(path=dicom_dir) d = D.get("IM2263", view=DixelView.TAGS_FILE) O.put(d) q = {"PatientID": "AW15119516.678.1392297407"} result = O.find(q) if result: id = result[0] logging.debug(id) result = O.exists(id) logging.debug(result) assert (result) O.delete(d) result = O.exists(id) assert (not result)
def collect(ctx, project, data_path, source, domain, dest, anonymize, subpath_depth): """Create a PROJECT key at DATA_PATH, then pull data from SOURCE and send to DEST.""" services = ctx.obj.get('services') click.echo(click.style('Collect DICOM data', underline=True, bold=True)) C = Collector() _source = services[source] source_inst = Orthanc(**_source) if not dest: path = data_path / Path("data") dest_inst = DcmDir(path=path, subpath_width=2, subpath_depth=subpath_depth) elif dest.startswith("path:"): path = dest.split(":")[-1] dest_inst = DcmDir(path=path, subpath_width=2, subpath_depth=subpath_depth) else: _dest = services[dest] dest_inst = Orthanc(**_dest) C.run(project, data_path, source_inst, domain, dest_inst, anonymize)
def orth_test_runner(): O = Orthanc() dicom_dir = find_resource("resources/dcm") D = DcmDir(path=dicom_dir) print("Starting script") time.sleep(1) d = D.get("IM2263", view=DixelView.FILE) O.put(d) O.check() print("Ending script")
def ssde(path, images): """Estimate patient dimensions from CT-localizer IMAGES for size-specific dose estimation.""" click.echo(click.style('Measuring scout images', underline=True, bold=True)) D = DcmDir(path=path) for image in images: d = D.get(image, view=DixelView.PIXELS) result = d.measure_scout() click.echo("{} ({}): {}cm".format(image, result[0], round(result[1])))
def test_measurement(): path = find_resource("resources/scouts") D = DcmDir(path=path) fn_s1 = "ct_scout_01.dcm" d_s1 = D.get(fn_s1, view=DixelView.PIXELS) ret = d_s1.measure_scout() logging.debug(ret) assert (ret[0] == 'AP' and round(ret[1]) == 28) fn_s2 = "ct_scout_02.dcm" d_s2 = D.get(fn_s2, view=DixelView.PIXELS) ret = d_s2.measure_scout() logging.debug(ret) assert (ret[0] == 'LATERAL' and round(ret[1]) == 43)
def test_anon(setup_orthanc0): O = Orthanc() dicom_dir = find_resource("resources/dcm") D = DcmDir(path=dicom_dir) d = D.get("IM2263", view=DixelView.TAGS_FILE) O.put(d) d.tags["AccessionNumber"] = "123456" d.tags["PatientBirthDate"] = "20000101" d.tags["PatientID"] = "ABC" d.tags["PatientName"] = "XYZ" d.level = DicomLevel.STUDIES e = ShamDixel.from_dixel(d) rep = e.orthanc_sham_map() O.anonymize("959e4e9f-e954be4e-11917c87-09d0f98f-7cc39128", level=DicomLevel.STUDIES, replacement_map=rep)
def message(ctx, messenger, dixel, to_addrs, template, template_file, meta, dryrun): """Call MESSENGER SEND with data from **DIXEL.meta and **META. DIXEL may be a local path to an instance or a curl command to an Orthanc \b $ diana-cli message smtp path:/data/images/my_file.dcm \ -m "{{ tags.accession_number }}" -t "*****@*****.**" $ diana-cli message smtp http:orthanc:orthanc@host/studies/oid... \ -m "{{ tags.accession_number }}" -t "*****@*****.**" """ services = ctx.obj.get('services') click.echo(click.style('Calling messenger send', underline=True, bold=True)) if dixel.startswith("path:"): D = DcmDir() d = D.get(dixel) elif dixel.startswith("http"): resp = requests.get(dixel) if resp: d = Dixel.from_orthanc(resp.json()) else: click.echo(click.style("No such dixel {}".format(dixel), fg="red")) exit(1) if not services.get(messenger): click.echo( click.style("No such service {}".format(messenger), fg="red")) exit(1) _messenger = SmtpMessenger(**services[messenger]) _messenger.send(d, to_addrs=to_addrs, msg_t=template, dryrun=dryrun) if dryrun: click.echo(messenger.get(d, to_addrs=to_addrs, msg_t=template))
def classify(model, path, images, positive, negative): """Apply a classification MODEL to PATH with IMAGES""" click.echo(click.style('Classifying images', underline=True, bold=True)) os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' _model = get_mobilenet(0, weights=None) _model.load_weights(model.name) D = DcmDir(path=path) for image in images: d = D.get(image, view=DixelView.PIXELS) # prediction = get_prediction( model, image ) prediction = d.get_prediction(_model) if prediction >= 0.5: click.echo("Predicted: {} ({})".format(positive, round(prediction, 2))) else: click.echo("Predicted: {} ({})".format(negative, round(1.0 - prediction, 2)))
def test_conversion(tmp_path): resources_dir = find_resource("resources/dcm") D = DcmDir(path=resources_dir) logging.debug(D) d = D.get("IM2263", view=DixelView.PIXELS) E = ImageDir(path=tmp_path) E.put(d) fn = "1.2.840.113619.2.181.90581140298.2577.1392297407726.4-0004-0002.png" fp = Path( tmp_path / fn ) assert( fp.is_file() ) os.remove(fp) F = ImageDir(path=tmp_path, anonymizing=True) F.put(d) fn = "6ee6f414e4c779c8bb1f90baf45c000c-0004-0002.png" fp = Path( tmp_path / fn ) assert( fp.is_file() ) os.remove(fp)
def test_subdirs(): D = DcmDir(recurse_style="ORTHANC") # for fp in D.recurse(): # logging.debug(fp) subdirs = list(D.subdirs()) assert (len(subdirs) == 256 * 256) assert ("./ff/ff" in subdirs) assert ("./00/00" in subdirs) p = find_resource("resources") D = DcmDir(path=p) subdirs = list(D.subdirs()) logging.debug(subdirs) assert (len(subdirs) >= 8)
def test_exists(): resources_dir = find_resource("resources/dcm") D = DcmDir(path=resources_dir) logging.debug(D) assert (D.check()) assert (D.exists("IM2263")) assert (not D.exists("abcd")) D = DcmDir(path=resources_dir, subpath_width=3, subpath_depth=2) assert (D.check()) assert (D.exists("IM2263")) assert (not D.exists("abcd")) logging.debug("Checking round-trip") d = D.get("IM2263") logging.debug(pformat(d.tags)) dd = d.json() ee = json.loads(dd) e = Serializable.Factory.create(**ee) logging.debug(d) logging.debug(e) assert (d.tags == e.tags)
def pull_and_save(self, items: Iterable, source: Orthanc, domain: str, dest: DcmDir, anonymize=False): def mkq(d: Dixel): return {"StudyInstanceUID": d.tags["StudyInstanceUID"]} for d in items: working_level = DicomLevel.STUDIES if anonymize: if working_level == DicomLevel.SERIES: d_fn = "{}-{}.zip".format( d.meta["ShamAccessionNumber"][0:6], d.meta["ShamSeriesDescription"]) else: d_fn = "{}.zip".format(d.meta["ShamAccessionNumber"][0:16]) else: if working_level == DicomLevel.SERIES: d_fn = "{}-{}-{}.zip".format( d.tags["PatientName"][0:6], d.tags["AccessionNumber"][0:8], d.tags["SeriesDescription"]) else: d_fn = "{}-{}.zip".format(d.tags["PatientName"][0:6], d.tags["AccessionNumber"][0:8]) if dest.exists(d_fn): logging.debug("SKIPPING {}".format(d.tags["PatientName"])) continue if not source.exists(d): source.rfind(mkq(d), domain, level=working_level, retrieve=True) else: logging.debug("SKIPPING PULL for {}".format( d.tags["PatientName"])) if anonymize: try: replacement_map = ShamDixel.orthanc_sham_map(d) anon_id = source.anonymize(d, replacement_map=replacement_map) e = source.get(anon_id, level=working_level, view=DixelView.FILE) e.meta["FileName"] = d_fn logging.debug(e) dest.put(e) source.delete(e) except (HTTPError, GatewayConnectionError) as e: logging.error("Failed to anonymize dixel") logging.error(e) with open("errors.txt", "a+") as f: f.write(d.tags["AccessionNumber"] + "\n") else: d = source.get(d, level=working_level, view=DixelView.FILE) dest.put(d) try: source.delete(d) except GatewayConnectionError as e: logging.error("Failed to delete dixel") logging.error(e)
def convert_file(infile: Path, outfile: Path): dixel = DcmDir().get(infile, get_pixels=True) ImageFileHandler().put(dixel.get_pixels(), outfile)
def convert_file(infile: Path, outfile: Path): dixel = DcmDir().get(infile)
This script filters a set of zipped studies and removes unwanted items. Any zip internal folder structure is destroyed since filtering is done at the Dixel-set level, not the file-set data level. """ import os, logging from pprint import pformat from diana.apis import DcmDir logging.basicConfig(level=logging.DEBUG) location = "/Users/derek/Desktop" ep = DcmDir(path=location) files = ["test.dum-1.zip"] # for fi in ep.files(rex="*.zip"): for fi in files: contents = ep.get_zipped(fi) # for item in contents: # logging.debug("{}: {}: {}".format(item.fn, item.tags.get("Modality"), item.tags.get("SeriesNumber"))) # contents = list(filter(lambda x: int(x.tags.get("SeriesNumber")) < 9999, contents)) contents = list(filter(lambda x: x.tags.get("Modality") == "CT", contents)) # logging.debug(pformat(contents))
import os, yaml from diana.apis import DcmDir, Orthanc D = DcmDir(path="/data") svcs_t = os.environ.get("DIANA_SERVICES") svcs = yaml.load(svcs_t) print(svcs) args = svcs.get("renalstone") O = Orthanc(**args) for d in D.files(rex="*.zip"): file_set = D.get_zipped(d) for f in file_set: O.put(f)