def update(self, dixel, **kwargs): meta = dixel.meta.copy() dixel.id = dixel.id.rstrip() if dixel.level != DicomLevel.SERIES: url = "{}/{}/{}/tags?simplify".format(self.url, str(dixel.level), dixel.id) else: url = "{}/{}/{}/shared-tags?simplify".format( self.url, str(dixel.level), dixel.id) # r = self.session.get(url) r = self.do_get(url) if r.status_code != 200: return dixel tags = r.json() tags = DixelTools.simplify_tags(tags) meta.update(tags) # Check anon status url = "{}/{}/{}/metadata".format(self.url, str(dixel.level), dixel.id) r = self.do_get(url) # try: # r = self.session.get(url) # except requests.exceptions.ConnectionError: # logging.warn(r.content) if r.status_code != 200: return Dixel(dixel.id, meta=meta, level=dixel.level) return dixel items = r.json() if "AnonymizedFrom" in items: meta['Anonymized'] = True if dixel.level == "instance": url = "{}/{}/{}/metadata/TransferSyntaxUID".format( self.url, str(dixel.level), dixel.id) # r = self.session.get(url) r = self.do_get(url) meta['TransferSyntaxUID'] = r.json() url = "{}/{}/{}/metadata/SopClassUid".format( self.url, str(dixel.level), dixel.id) # r = self.session.get(url) r = self.do_get(url) meta['SOPClassUID'] = DixelTools.DICOM_SOPS.get( r.json(), r.json()) # Text or return val return Dixel(dixel.id, meta=meta, level=dixel.level)
def update(self, dixel, **kwargs): meta = dixel.meta.copy() if dixel.level != "series": url = "{}/{}/{}/tags?simplify".format(self.url, str(dixel.level), dixel.id) else: url = "{}/{}/{}/shared-tags?simplify".format( self.url, str(dixel.level), dixel.id) r = self.session.get(url) tags = r.json() tags = DixelTools.simplify_tags(tags) meta.update(tags) if dixel.level == "instance": url = "{}/{}/{}/metadata/TransferSyntaxUID".format( self.url, str(dixel.level), dixel.id) r = self.session.get(url) meta['TransferSyntaxUID'] = r.json() url = "{}/{}/{}/metadata/SopClassUid".format( self.url, str(dixel.level), dixel.id) r = self.session.get(url) meta['SOPClassUID'] = DixelTools.DICOM_SOPS.get( r.json(), r.json()) # Text or return val return Dixel(dixel.id, meta=meta, level=dixel.level)
def initialize_inventory(self): res = set() r = self.session.get("{0}/instances".format(self.url)).json() for item in r: res.add(Dixel(id=item, level=DicomLevel.INSTANCES)) # self.logger.debug(res) return res
def anonymize(self, dixel, replacement_dict=None): url = "{}/{}/{}/anonymize".format(self.url, str(dixel.level), dixel.id) replacement_json = json.dumps(replacement_dict) logging.debug(replacement_json) headers = {'content-type': 'application/json'} r = self.do_post(url, data=replacement_json, headers=headers) # r = requests.post() self.logger.debug(r.content) if r.status_code == 200: self.logger.debug('Anonymized {0} successfully!'.format(dixel)) e = Dixel(id=r.json()['ID'], level=dixel.level) return e else: self.logger.warning('Could not anonymize {0}!'.format(dixel))
def load_csv(csv_file, secondary_id=None): with open(csv_file, 'rU') as f: items = csv.DictReader(f) s = set() for item in items: # Need to create a unique identifier without having tags # 1. Use OID if available id = item.get('OID') # 2. Use AN if available if not id: id = item.get('AccessionNumber') # 3. If no AN, try PatientID + secondary_id (ie, Treatment Time) if not id: if not secondary_id: raise ValueError("Needs AccessionNumber or MRN+Ref") id = item.get('PatientID') + item.get(secondary_id) d = Dixel(id, level=DicomLevel.STUDIES, meta=item) s.add(d) return s, items.fieldnames
def make_worklist(self, qdict): # Return a set of predixel results r = self.query(qdict) logging.debug(pformat(r)) res = set() for item in r: meta = { 'AccessionNumber': item[0]["accession_number"], 'PatientID': item[0]["id"], # Montage ID 'ReportText': item[0]['text'], 'ExamType': item[0]['exam_type']['code'] # IMG code } res.add( Dixel(id=meta['AccessionNumber'], meta=meta, level=DicomLevel.STUDIES)) return res
def initialize_preinventory(self): self.logger.debug('Walking file tree') all_paths = [] all_files = [] for paths, _, files in os.walk(self.loc): all_paths = all_paths + list( itertools.repeat(paths, times=len(files))) all_files = all_files + files preinventory = set() for path, fn in zip(all_paths, all_files): full_path = os.path.join(path, fn) id = full_path meta = {'fn': fn, 'path': path, 'full_path': full_path} preinventory.add(Dixel(id, meta=meta)) # self.logger.debug(preinventory) return preinventory
def update(self, dixel): magic_type = magic.from_file(dixel.meta['full_path'], mime=True) if magic_type == 'application/dicom': tags = pydicom.read_file(dixel.meta['full_path']) # self.logger.debug(tags) meta = { 'PatientID': tags[0x0010, 0x0020].value, 'StudyInstanceUID': tags[0x0020, 0x000d].value, 'SeriesInstanceUID': tags[0x0020, 0x000e].value, 'SOPInstanceUID': tags[0x0008, 0x0018].value, 'TransferSyntaxUID': tags.file_meta.TransferSyntaxUID, 'MediaStorage': tags.file_meta.MediaStorageSOPClassUID, 'AccessionNumber': tags[0x0008, 0x0050].value, 'HasPixels': 'PixelData' in tags } try: meta['Dimensions'] = [ tags[0x0028, 0x0010].value, tags[0x0028, 0x0011].value ] except KeyError: pass meta['id'] = DixelTools.orthanc_id(meta['PatientID'], meta['StudyInstanceUID'], meta['SeriesInstanceUID'], meta['SOPInstanceUID']) # Keep other meta data, such as file path meta.update(dixel.meta) self.logger.debug('{0} ({1}) id: {2}'.format( dixel.meta['fn'], magic_type, meta['id'])) return Dixel(meta['id'], meta=meta, level=DicomLevel.INSTANCES)
def update(self, dixel, time_delta=0, **kwargs): # if dixel.meta['mid']: # # Already looked this exam up # return dixel qdict = kwargs.get('qdict', {}) PatientID = dixel.meta['PatientID'] earliest, latest = DixelTools.daterange(dixel.meta['ReferenceTime'], time_delta) AccessionNumber = None q = PatientID if dixel.meta.get("AccessionNumber"): AccessionNumber = dixel.meta["AccessionNumber"] q = q + "+" + AccessionNumber qdict["q"] = q qdict["start_date"] = earliest qdict["end_date"] = latest r = self.query(qdict) # Got some hits if r: self.logger.debug(pformat(r)) data = None if AccessionNumber: # Check and see if there is a match in r found = False for r_item in r: if r_item["accession_number"] == AccessionNumber: # Use this data data = r_item found = True break if found == False: self.logger.warning( "Can't find Accession {0} in results!".format( AccessionNumber)) return dixel else: # If there is no AN, just use the first study returned data = r[0] # TODO: Should really take extractions as an argument # dmap = kwargs.get('dmap', {}) # # for k, v in dmap: # dixel.meta[k] suffix = kwargs.get('suffix', '') dixel.meta["Age"] = data["patient_age"] dixel.meta["First Name"] = data["patient_first_name"].capitalize() dixel.meta["Last Name"] = data["patient_last_name"].capitalize() dixel.meta["AccessionNumber" + suffix] = data["accession_number"] dixel.meta["MID" + suffix] = data["id"] # Montage ID dixel.meta["Report" + suffix] = data['text'] # Report text dixel.meta["ExamCode" + suffix] = data['exam_type']['code'] # IMG code # Try to find exam completed time for event in data['events']: if event['event_type'] == 5: dixel.meta["ExamCompleted" + suffix] = event['date'] return Dixel(id=dixel.meta["AccessionNumber" + suffix], meta=dixel.meta, level=DicomLevel.STUDIES) # No results else: return dixel
def initialize_studies(self): res = set() r = self.do_get("{0}/studies".format(self.url)).json() for item in r: res.add(Dixel(id=item, level=DicomLevel.SERIES)) return res