def rename_reshape_pdt2_scans(quar_dir, is_whicap_V1=False, is_whicap_V2=False , is_whicap_V3=False): files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if is_whicap_V2: for path in nifti_paths: if os.path.basename(path).startswith('x'): os.unlink(path) continue files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 1: shape = getshape(nifti_paths[0]) if shape[3] != 2: raise Bad_Nifti_Error(path, "DWI Nifti has {} timepoints but should have 2".format(shape[3])) split = fslsplit() split.split(nifti_paths[0], os.path.join(quar_dir, 'pdt2sp_')) splits1 = [os.path.join(quar_dir, "pdt2sp_{0:04d}.nii.gz".format(x)) for x in range(0, 30)] os.unlink(nifti_paths[0]) return elif len(nifti_paths) == 3: sizes = [(x, os.stat(x).st_size) for x in nifti_paths] sizes.sort(key=lambda x :x[1]) os.unlink(sizes[2][0]) elif len(nifti_paths) == 2: return else: raise Wrong_Number_Of_Files_Error(quar_dir, "Wrong number of DWI files left after pruning stage, expected 1, got {}".format(len(nifti_paths)))
def rename_reshape_dwi_scans(quar_dir, is_whicap_V1=False, is_whicap_V2=False , is_whicap_V3=False): files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if is_whicap_V1: for path in nifti_paths: if os.path.basename(path).startswith('x'): os.unlink(path) continue files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 1: shape = getshape(nifti_paths[0]) if shape[3] != 5 and shape[3] != 2: raise Bad_Nifti_Error(path, "DWI Nifti has {} timepoints but should have 2 or 5".format(shape[3])) return else: raise Wrong_Number_Of_Files_Error(quar_dir, "Wrong number of DWI files left after pruning stage, expected 1, got {}".format(len(nifti_paths))) if is_whicap_V2: for path in nifti_paths: if os.path.basename(path).startswith('x'): os.unlink(path) continue files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 1: shape = getshape(nifti_paths[0]) if shape[3] != 5 and shape[3] != 2: raise Bad_Nifti_Error(path, "DWI Nifti has {} timepoints but should have 2 or 5".format(shape[3])) return else: raise Wrong_Number_Of_Files_Error(quar_dir, "Wrong number of DWI files left after pruning stage, expected 1, got {}".format(len(nifti_paths))) if is_whicap_V3: if len(nifti_paths) == 1: shape = getshape(nifti_paths[0]) if shape[3] != 2: raise Bad_Nifti_Error(path, "DWI Nifti has {} timepoints but should have 2".format(shape[3])) return elif len(nifti_paths) == 2: for path in nifti_paths: if os.path.basename(path).startswith('x'): os.unlink(path) continue shape = getshape(path) if len(shape) < 4 or shape[3] != 2: #delete files that only have 1 image, should have two os.unlink(path) files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 0: raise Wrong_Number_Of_Files_Error(quar_dir, "Wrong number of DWI files left after pruning stage, expected 1, got {}".format(len(nifti_paths)))
def rename_reshape_pdt2_scans(quar_dir, is_whicap_V1=False, is_whicap_V2=False, is_whicap_V3=False): files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if is_whicap_V2: for path in nifti_paths: if os.path.basename(path).startswith('x'): os.unlink(path) continue files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 1: shape = getshape(nifti_paths[0]) if shape[3] != 2: raise Bad_Nifti_Error( path, "DWI Nifti has {} timepoints but should have 2".format( shape[3])) split = fslsplit() split.split(nifti_paths[0], os.path.join(quar_dir, 'pdt2sp_')) splits1 = [ os.path.join(quar_dir, "pdt2sp_{0:04d}.nii.gz".format(x)) for x in range(0, 30) ] os.unlink(nifti_paths[0]) return elif len(nifti_paths) == 3: sizes = [(x, os.stat(x).st_size) for x in nifti_paths] sizes.sort(key=lambda x: x[1]) os.unlink(sizes[2][0]) elif len(nifti_paths) == 2: return else: raise Wrong_Number_Of_Files_Error( quar_dir, "Wrong number of DWI files left after pruning stage, expected 1, got {}" .format(len(nifti_paths)))
def rename_reshape_dti_scans(quar_dir, is_whicap_V3=False): files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if is_whicap_V3: if len(nifti_paths) == 1: shape = getshape(nifti_paths[0]) if shape[3] != 17: raise Bad_Nifti_Error(path, "DTI Nifti has {} timepoints but should have 17".format(shape[3])) return elif len(nifti_paths) == 2: for path in nifti_paths: if os.path.basename(path).startswith('x'): os.unlink(path) continue shape = getshape(path) if len(shape) < 4 or shape[3] != 17: #delete files that only have 1 image, should have two os.unlink(path) files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 0: raise Wrong_Number_Of_Files_Error(quar_dir, "Wrong number of DWI files left after pruning stage, expected 1, got {}".format(len(nifti_paths)))
def rename_reshape_asl_scans(quar_dir, is_whicap_V2=False): files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 2: if is_whicap_V2: return else: raise Wrong_Number_Of_Files_Error( series_folder.path, "Wrong number of ASL files to reshape and not whicap, expected 1, got {}" .format(len(nifti_paths))) elif len(nifti_paths) == 1: if is_whicap_V2: shape = getshape(nifti_paths[0]) if shape[3] > 60: raise Bad_Nifti_Error( quar_dir, "nifti has {} timepoints, expected 60".format(shape[3])) if shape[2] == 15: reshapeASL(nifti_paths[0], z_voxel_size_multiplier=0.5) os.unlink(nifti_paths[0]) else: split = fslsplit() merge = fslmerge() split.split(nifti_paths[0], os.path.join(quar_dir, 'aslsp_')) splits1 = [ os.path.join(quar_dir, "aslsp_{0:04d}.nii.gz".format(x)) for x in range(0, 30) ] splits2 = [ os.path.join(quar_dir, "aslsp_{0:04d}.nii.gz".format(x)) for x in range(30, 60) ] merge.merge(os.path.join(quar_dir, 'ASLOne.nii.gz'), splits1) merge.merge(os.path.join(quar_dir, 'ASLTwo.nii.gz'), splits2) [os.unlink(file) for file in splits1] [os.unlink(file) for file in splits2] os.unlink(nifti_paths[0]) else: reshapeASL(nifti_paths[0], z_voxel_size_multiplier=1) os.unlink(nifti_paths[0]) else: raise Wrong_Number_Of_Files_Error( quar_dir, "dcm2nii produced {} nifti paths, expected 1 or 2".format( len(nifti_paths)))
def move_non_niftis(series_folder, folder_name): 'bvecs and bvals' visit = series_folder.image.visit quar_dir = os.path.join(visit.path, 'Quarantine') target_folder = os.path.join(visit.path, folder_name) reconed_files = os.listdir(quar_dir) if not os.path.exists(target_folder): os.mkdir(target_folder) my_non_niftis = [x for x in reconed_files if not is_nifti(x)] for i in range(0, len(my_non_niftis)): old_name_fullpath = os.path.join(quar_dir, my_non_niftis[i]) extension = os.path.splitext(old_name_fullpath)[1] new_name_fullpath = os.path.join(target_folder, visit.image_basename(series_folder.image.series) + extension) if os.path.exists(new_name_fullpath): os.unlink(new_name_fullpath) shutil.move(old_name_fullpath, new_name_fullpath)
def check_recon_dicom_folder(series_folder, dcm2nii_object, folder_name, expected_image_quantity): reconstructed_image_quantity = -1 number_paths_to_generate = expected_image_quantity if expected_image_quantity < 0: reconstructed_image_quantity = recon_into_quarantine( series_folder, dcm2nii_object) number_paths_to_generate = reconstructed_image_quantity generated_nifti_paths = gen_nifti_basename_fullpaths( series_folder, folder_name, number_paths_to_generate) #if all niftis exist, delete all files in quarantine and exit niftis_exist = [nifti_exists(x) for x in generated_nifti_paths] if all(niftis_exist): visit = series_folder.image.visit quar_dir = os.path.join(visit.path, 'Quarantine') if os.path.exists(quar_dir): shutil.rmtree(quar_dir) os.mkdir(quar_dir) return #reconstruct into nifti if we havn't already elif reconstructed_image_quantity < 0: #not reconstructed into quarantine before reconstructed_image_quantity = recon_into_quarantine( series_folder, dcm2nii_object) #check that number of reconstructed images matches number expected if expected_image_quantity > 0 and expected_image_quantity != reconstructed_image_quantity: visit = series_folder.image.visit quar_dir = os.path.join(visit.path, 'Quarantine') reconed_files = os.listdir(quar_dir) reconstructed_niftis = [x for x in reconed_files if is_nifti(x)] quar_dir = os.path.join(visit.path, 'Quarantine') raise Wrong_Number_Of_Files_Error( quar_dir, "Unexpected number niftis produced by reconstruction. Expected:{0} Reconstructed:{1}\nReconstructedPaths\n{2}\nExpectedBasenames\n{3}" .format(expected_image_quantity, reconstructed_image_quantity, '\n'.join(reconstructed_niftis), '\n'.join(generated_nifti_paths))) move_niftis(series_folder, folder_name, generated_nifti_paths) move_non_niftis(series_folder, folder_name)
def move_niftis(series_folder, folder_name, expected_nifti_paths): visit = series_folder.image.visit quar_dir = os.path.join(visit.path, 'Quarantine') target_folder = os.path.join(visit.path, folder_name) reconed_files = os.listdir(quar_dir) if not os.path.exists(target_folder): os.mkdir(target_folder) myniftis = [x for x in reconed_files if is_nifti(x)] myniftis.sort() for i in range(0, len(expected_nifti_paths)): old_name_fullpath = os.path.join(quar_dir, reconed_files[i]) extension = get_nifti_extension(old_name_fullpath) new_name_fullpath = os.path.join(quar_dir, expected_nifti_paths[i] + extension) if os.path.exists(new_name_fullpath): os.unlink(new_name_fullpath) shutil.move(old_name_fullpath, new_name_fullpath) visit.check_add_nifti(folder_name, expected_nifti_paths[i])
def move_non_niftis(series_folder, folder_name): 'bvecs and bvals' visit = series_folder.image.visit quar_dir = os.path.join(visit.path, 'Quarantine') target_folder = os.path.join(visit.path, folder_name) reconed_files = os.listdir(quar_dir) if not os.path.exists(target_folder): os.mkdir(target_folder) my_non_niftis = [x for x in reconed_files if not is_nifti(x)] for i in range(0, len(my_non_niftis)): old_name_fullpath = os.path.join(quar_dir, my_non_niftis[i]) extension = os.path.splitext(old_name_fullpath)[1] new_name_fullpath = os.path.join( target_folder, visit.image_basename(series_folder.image.series) + extension) if os.path.exists(new_name_fullpath): os.unlink(new_name_fullpath) shutil.move(old_name_fullpath, new_name_fullpath)
def check_recon_dicom_folder(series_folder, dcm2nii_object, folder_name, expected_image_quantity): reconstructed_image_quantity = -1 number_paths_to_generate = expected_image_quantity if expected_image_quantity < 0: reconstructed_image_quantity = recon_into_quarantine(series_folder, dcm2nii_object) number_paths_to_generate = reconstructed_image_quantity generated_nifti_paths = gen_nifti_basename_fullpaths(series_folder, folder_name, number_paths_to_generate) #if all niftis exist, delete all files in quarantine and exit niftis_exist = [nifti_exists(x) for x in generated_nifti_paths] if all(niftis_exist): visit = series_folder.image.visit quar_dir = os.path.join(visit.path, 'Quarantine') if os.path.exists(quar_dir): shutil.rmtree(quar_dir) os.mkdir(quar_dir) return #reconstruct into nifti if we havn't already elif reconstructed_image_quantity < 0: #not reconstructed into quarantine before reconstructed_image_quantity = recon_into_quarantine(series_folder, dcm2nii_object) #check that number of reconstructed images matches number expected if expected_image_quantity > 0 and expected_image_quantity != reconstructed_image_quantity: visit = series_folder.image.visit quar_dir = os.path.join(visit.path, 'Quarantine') reconed_files = os.listdir(quar_dir) reconstructed_niftis = [x for x in reconed_files if is_nifti(x)] quar_dir = os.path.join(visit.path, 'Quarantine') raise Wrong_Number_Of_Files_Error(quar_dir, "Unexpected number niftis produced by reconstruction. Expected:{0} Reconstructed:{1}\nReconstructedPaths\n{2}\nExpectedBasenames\n{3}".format( expected_image_quantity, reconstructed_image_quantity, '\n'.join(reconstructed_niftis), '\n'.join(generated_nifti_paths) )) move_niftis(series_folder, folder_name, generated_nifti_paths) move_non_niftis(series_folder, folder_name)
def recon_into_quarantine(series_folder, dcm2nii_object): print "Recon {0.path}".format(series_folder) visit = series_folder.image.visit studyname = visit.subject.index.project.name #wipe contents of quarantine dir quar_dir = os.path.join(visit.path, 'Quarantine') if os.path.exists(quar_dir): shutil.rmtree(quar_dir) os.makedirs(quar_dir) #reconstruct dcm2nii_object.recon(input_path=series_folder.path, output_path=quar_dir) #treat ASL scans specially if studyname == 'WHICAP': if visit.visid == 'V1': if series_folder.image.series == 'DWI': rename_reshape_dwi_scans(quar_dir, is_whicap_V1=True) elif visit.visid == 'V2': if series_folder.image.series == 'ASL': rename_reshape_asl_scans(quar_dir, is_whicap_V2=True) elif series_folder.image.series == 'DWI': rename_reshape_dwi_scans(quar_dir, is_whicap_V2=True) elif series_folder.image.series == 'PDT2': rename_reshape_pdt2_scans(quar_dir, is_whicap_V2=True) elif visit.visid == 'V3': if series_folder.image.series == 'DWI': rename_reshape_dwi_scans(quar_dir, is_whicap_V3=True) elif series_folder.image.series == 'DTI_1': rename_reshape_dti_scans(quar_dir, is_whicap_V3=True) if series_folder.image.series == 'ASL': rename_reshape_asl_scans(quar_dir, is_whicap_V2=False) elif series_folder.image.series in ['pASL', 'ASL']: rename_reshape_asl_scans(quar_dir, is_whicap_V2=False) reconed_files = os.listdir(quar_dir) myniftis = [x for x in reconed_files if is_nifti(x)] return len(myniftis)
def rename_reshape_asl_scans(quar_dir, is_whicap_V2=False): files = os.listdir(quar_dir) nifti_paths = [os.path.join(quar_dir, x) for x in files if is_nifti(x)] if len(nifti_paths) == 2: if is_whicap_V2: return else: raise Wrong_Number_Of_Files_Error( series_folder.path, "Wrong number of ASL files to reshape and not whicap, expected 1, got {}".format(len(nifti_paths)), ) elif len(nifti_paths) == 1: if is_whicap_V2: shape = getshape(nifti_paths[0]) if shape[3] > 60: raise Bad_Nifti_Error(quar_dir, "nifti has {} timepoints, expected 60".format(shape[3])) if shape[2] == 15: reshapeASL(nifti_paths[0], z_voxel_size_multiplier=0.5) os.unlink(nifti_paths[0]) else: split = fslsplit() merge = fslmerge() split.split(nifti_paths[0], os.path.join(quar_dir, "aslsp_")) splits1 = [os.path.join(quar_dir, "aslsp_{0:04d}.nii.gz".format(x)) for x in range(0, 30)] splits2 = [os.path.join(quar_dir, "aslsp_{0:04d}.nii.gz".format(x)) for x in range(30, 60)] merge.merge(os.path.join(quar_dir, "ASLOne.nii.gz"), splits1) merge.merge(os.path.join(quar_dir, "ASLTwo.nii.gz"), splits2) [os.unlink(file) for file in splits1] [os.unlink(file) for file in splits2] os.unlink(nifti_paths[0]) else: reshapeASL(nifti_paths[0], z_voxel_size_multiplier=1) os.unlink(nifti_paths[0]) else: raise Wrong_Number_Of_Files_Error( quar_dir, "dcm2nii produced {} nifti paths, expected 1 or 2".format(len(nifti_paths)) )