def dicom_to_sql(start_path=None, force_update=False, move_files=True, update_dicom_catalogue_table=True): start_time = datetime.now() print(str(start_time), 'Beginning import', sep=' ') dicom_catalogue_update = [] # Read SQL configuration file abs_file_path = get_settings('import') import_settings = parse_settings_file(abs_file_path) if start_path: abs_file_path = os.path.join(SCRIPT_DIR, start_path) import_settings['inbox'] = abs_file_path sqlcnx = DVH_SQL() file_paths = get_file_paths(import_settings['inbox']) for uid in list(file_paths): if is_uid_imported(uid): print("The UID from the following files is already imported.") if not force_update: print( "Must delete content associated with this UID from database before reimporting." ) print( "These files have been moved into the 'misc' folder within your 'imported' folder." ) for file_type in FILE_TYPES: print(file_paths[uid][file_type]['file_path']) print("The UID is %s" % uid) continue else: print("Force Update set to True. Processing with import.") print( "WARNING: This import may contain duplicate data already in the database." ) dicom_catalogue_update.append(uid) # Collect and print the file paths plan_file = file_paths[uid]['rtplan']['latest_file'] struct_file = file_paths[uid]['rtstruct']['latest_file'] dose_file = file_paths[uid]['rtdose']['latest_file'] if IMPORT_LATEST_PLAN_ONLY: print("plan file: %s" % plan_file) else: for f in file_paths[uid]['rtplan']['file_path']: print("plan file: %s" % f) print("struct file: %s" % struct_file) print("dose file: %s" % dose_file) # Process DICOM files into Python objects plan, beams, dvhs, rxs = [], [], [], [] mp, ms, md = [], [], [] if plan_file: mp = dicom.read_file(plan_file).ManufacturerModelName.lower() if struct_file: ms = dicom.read_file(struct_file).ManufacturerModelName.lower() if dose_file: md = dicom.read_file(dose_file).ManufacturerModelName.lower() if 'gammaplan' in "%s %s %s" % (mp, ms, md): print( "Leksell Gamma Plan is not currently supported. Skipping import." ) continue if plan_file and struct_file and dose_file: if IMPORT_LATEST_PLAN_ONLY: plan = PlanRow(plan_file, struct_file, dose_file) sqlcnx.insert_plan(plan) else: for f in file_paths[uid]['rtplan']['file_path']: plan = PlanRow(f, struct_file, dose_file) sqlcnx.insert_plan(plan) else: print( 'WARNING: Missing complete set of plan, struct, and dose files for uid %s' % uid) if not force_update: print( 'WARNING: Skipping this import. If you wish to import an incomplete DICOM set, use Force Update' ) print( 'WARNING: The current file will be moved to the misc folder with in your imported folder' ) continue if plan_file: if not hasattr(dicom.read_file(plan_file), 'BrachyTreatmentType'): if IMPORT_LATEST_PLAN_ONLY: beams = BeamTable(plan_file) sqlcnx.insert_beams(beams) else: for f in file_paths[uid]['rtplan']['file_path']: sqlcnx.insert_beams(BeamTable(f)) if struct_file and dose_file: dvhs = DVHTable(struct_file, dose_file) setattr(dvhs, 'ptv_number', rank_ptvs_by_D95(dvhs)) sqlcnx.insert_dvhs(dvhs) if plan_file and struct_file: if IMPORT_LATEST_PLAN_ONLY: rxs = RxTable(plan_file, struct_file) sqlcnx.insert_rxs(rxs) else: for f in file_paths[uid]['rtplan']['file_path']: sqlcnx.insert_rxs(RxTable(f, struct_file)) # get mrn for folder name, can't assume a complete set of dose, plan, struct files mrn = [] if dose_file: mrn = dicom.read_file(dose_file).PatientID elif plan_file: mrn = dicom.read_file(plan_file).PatientID elif struct_file: mrn = dicom.read_file(struct_file).PatientID if mrn: mrn = "".join(x for x in mrn if x.isalnum()) # remove any special characters else: mrn = 'NoMRN' # convert file_paths[uid] into a list of file paths if move_files: files_to_move = [] move_types = list(FILE_TYPES) + ['other'] for file_type in move_types: files_to_move.extend(file_paths[uid][file_type]['file_path']) new_folder = os.path.join(import_settings['imported'], mrn) move_files_to_new_path(files_to_move, new_folder) if plan_file: plan_file = os.path.basename(plan_file) if struct_file: struct_file = os.path.basename(struct_file) if dose_file: dose_file = os.path.basename(dose_file) if update_dicom_catalogue_table: if not IMPORT_LATEST_PLAN_ONLY: plan_file = ', '.join([ os.path.basename(fp) for fp in file_paths[uid]['rtplan']['file_path'] ]) update_dicom_catalogue(mrn, uid, new_folder, plan_file, struct_file, dose_file) # Move remaining files, if any if move_files: move_all_files(import_settings['imported'], import_settings['inbox']) remove_empty_folders(import_settings['inbox']) sqlcnx.close() end_time = datetime.now() print(str(end_time), 'Import complete', sep=' ') total_time = end_time - start_time seconds = total_time.seconds m, s = divmod(seconds, 60) h, m = divmod(m, 60) if h: print("This import took %dhrs %02dmin %02dsec to complete" % (h, m, s)) elif m: print("This import took %02dmin %02dsec to complete" % (m, s)) else: print("This import took %02dsec to complete" % s)
def dicom_to_sql(**kwargs): \ start_time = datetime.now() print(str(start_time), 'Beginning import', sep=' ') dicom_catalogue_update = [] # Read SQL configuration file script_dir = os.path.dirname(__file__) rel_path = "preferences/import_settings.txt" abs_file_path = os.path.join(script_dir, rel_path) with open(abs_file_path, 'r') as document: import_settings = {} for line in document: line = line.split() if not line: continue import_settings[line[0]] = line[1:][0] # Convert strings to boolean if line[1:][0].lower() == 'true': import_settings[line[0]] = True elif line[1:][0].lower() == 'false': import_settings[line[0]] = False if 'start_path' in kwargs and kwargs['start_path']: rel_path = kwargs['start_path'] abs_file_path = os.path.join(script_dir, rel_path) import_settings['inbox'] = abs_file_path sqlcnx = DVH_SQL() if 'force_update' in kwargs and kwargs['force_update']: force_update = True else: force_update = False file_paths = get_file_paths(import_settings['inbox']) for uid in list(file_paths): if is_uid_imported(uid): print("The UID from the following files is already imported.") if not force_update: print("Must delete content associated with this UID from database before reimporting.") print("These files have been moved into the 'misc' folder within your 'imported' folder.") for file_type in file_types: print(file_paths[uid][file_type]['file_path']) print("The UID is %s" % uid) continue else: print("Force Update set to True. Processing with import.") print("WARNING: This import may contain duplicate data already in the database.") dicom_catalogue_update.append(uid) # Collect and print the file paths plan_file = file_paths[uid]['rtplan']['latest_file'] struct_file = file_paths[uid]['rtstruct']['latest_file'] dose_file = file_paths[uid]['rtdose']['latest_file'] print("plan file: %s" % plan_file) print("struct file: %s" % struct_file) print("dose file: %s" % dose_file) # Process DICOM files into Python objects plan, beams, dvhs, rxs = [], [], [], [] mp, ms, md = [], [], [] if plan_file: mp = dicom.read_file(plan_file).ManufacturerModelName.lower() if struct_file: ms = dicom.read_file(struct_file).ManufacturerModelName.lower() if dose_file: md = dicom.read_file(dose_file).ManufacturerModelName.lower() if 'gammaplan' in "%s %s %s" % (mp, ms, md): print("Leksell Gamma Plan is not currently supported. Skipping import.") continue if plan_file and struct_file and dose_file: plan = PlanRow(plan_file, struct_file, dose_file) else: print('WARNING: Missing complete set of plan, struct, and dose files for uid %s' % uid) if not force_update: print('WARNING: Skipping this import. If you wish to import an incomplete DICOM set, use Force Update') print('WARNING: The current file will be moved to the misc folder with in your imported folder') continue if plan_file: if not hasattr(dicom.read_file(plan_file), 'BrachyTreatmentType'): beams = BeamTable(plan_file) if struct_file and dose_file: dvhs = DVHTable(struct_file, dose_file) setattr(dvhs, 'ptv_number', rank_ptvs_by_D95(dvhs)) if plan_file and struct_file: rxs = RxTable(plan_file, struct_file) # Insert data from Python objects into SQL tables if plan: sqlcnx.insert_plan(plan) if beams: sqlcnx.insert_beams(beams) if dvhs: sqlcnx.insert_dvhs(dvhs) if rxs: sqlcnx.insert_rxs(rxs) # get mrn for folder name, can't assume a complete set of dose, plan, struct files mrn = [] if dose_file: mrn = dicom.read_file(dose_file).PatientID elif plan_file: mrn = dicom.read_file(plan_file).PatientID elif struct_file: mrn = dicom.read_file(struct_file).PatientID if mrn: mrn = "".join(x for x in mrn if x.isalnum()) # remove any special characters else: mrn = 'NoMRN' # convert file_paths[uid] into a list of file paths files_to_move = [] move_types = [i for i in file_types] + ['other'] for file_type in move_types: files_to_move.extend(file_paths[uid][file_type]['file_path']) new_folder = os.path.join(import_settings['imported'], mrn) move_files_to_new_path(files_to_move, new_folder) if plan_file: plan_file = os.path.basename(plan_file) if struct_file: struct_file = os.path.basename(struct_file) if dose_file: dose_file = os.path.basename(dose_file) update_dicom_catalogue(mrn, uid, new_folder, plan_file, struct_file, dose_file) # Move remaining files, if any move_all_files(import_settings['imported'], import_settings['inbox']) remove_empty_folders(import_settings['inbox']) sqlcnx.cnx.close() end_time = datetime.now() print(str(end_time), 'Import complete', sep=' ') total_time = end_time - start_time seconds = total_time.seconds m, s = divmod(seconds, 60) h, m = divmod(m, 60) if h: print("This import took %dhrs %02dmin %02dsec to complete" % (h, m, s)) elif m: print("This import took %02dmin %02dsec to complete" % (m, s)) else: print("This import took %02dsec to complete" % s)