def N4BiasCorrection_multiprocessing(self, file2rename, subj, input_folder, status): """Does the Bias correction taking advantage of the multicores, so that multiple subjects can be processed in parallel; For that a list of tuples including the entire filename and the subject to be processed are entered""" status.put(tuple([mp.current_process().name, subj, os.path.split(file2rename)[1]])) filename_save = os.path.join(input_folder, self.cfg['preprocess']['ANTsN4']['prefix'] + os.path.split(file2rename)[1]) # Start with N4 Bias correction for sequences specified before original_image = ants.image_read(os.path.join(input_folder, file2rename)) rescaler_nonneg = ants.contrib.RescaleIntensity(10, 100) # to avoid values <0 causing problems w/ log data if self.cfg['preprocess']['ANTsN4']['denoise'] == 'yes': # takes forever and therefore not used by default original_image = ants.denoise_image(image=original_image, noise_model='Rician') min_orig, max_orig = original_image.min(), original_image.max() if not os.path.split(file2rename)[1].startswith(self.cfg['preprocess']['ANTsN4']['dti_prefix']): original_image_nonneg = rescaler_nonneg.transform(original_image) else: original_image_nonneg = original_image bcorr_image = n4biascorr(original_image_nonneg, mask=None, shrink_factor=self.cfg['preprocess']['ANTsN4']['shrink-factor'], convergence={'iters': self.cfg['preprocess']['ANTsN4']['convergence'], 'tol': self.cfg['preprocess']['ANTsN4']['threshold']}, spline_param=self.cfg['preprocess']['ANTsN4']['bspline-fitting'], verbose=bool(self.verbose), weight_mask=None) if not os.path.split(file2rename)[1].startswith(self.cfg['preprocess']['ANTsN4']['dti_prefix']): rescaler = ants.contrib.RescaleIntensity(min_orig, max_orig) bcorr_image = rescaler.transform(bcorr_image) # difference between both images is saved for debugging purposes diff_image = original_image - bcorr_image FileOperations.create_folder(os.path.join(input_folder, "debug")) # only creates folder if not present ants.image_write(diff_image, filename=os.path.join(input_folder, "debug", "diff_biasCorr_" + os.path.split(file2rename)[1])) spacing = self.cfg['preprocess']['registration']['resample_spacing'] bcorr_image = Imaging.resampleANTs(mm_spacing=spacing, ANTsImageObject=bcorr_image, file_id=filename_save, method=int(self.cfg['preprocess'] ['registration'] ['resample_method'])) ants.image_write(bcorr_image, filename=filename_save)
def dcm2niix_multiprocessing(self, name_subj, no_subj, dcm2niix_bin, last_idx, total_subj, status): """function intended to provide multiprocessing approach to speed up extraction of DICOM data to nifti files""" modalities = ['CT', 'MRI'] if self.logfile: log_filename = os.path.join( ROOTDIR, 'logs', 'log_DCM2NII_' + str(no_subj + last_idx) + time.strftime("%Y%m%d-%H%M%S")) else: log_filename = os.devnull subj_outdir = os.path.join( self.outdir, self.cfg['folders']['prefix'] + str(no_subj + last_idx)) FileOperations.create_folder(subj_outdir) start_time_subject = time.time() keptfiles, deletedfiles = ([] for _ in range(2)) for mod in modalities: status.put((name_subj, mod, no_subj, total_subj)) input_folder_name = os.path.join(self.inputdir, name_subj + mod) # input_folder_files = [f.path for f in os.scandir(input_folder_name) # if (f.is_dir() and ('100' in f.path or 'DICOM' in f.path or '001' in f.path))] input_folder_files = [] [ input_folder_files.append(item) for item in os.listdir(input_folder_name) if (os.path.isdir(os.path.join(input_folder_name, item)) and ( '100' in item or 'DICOM' in item or '001' in item)) ] orig_stdout = sys.stdout sys.stdout = open(log_filename, 'w') for folder in input_folder_files: subprocess.call( [ dcm2niix_bin, '-a', 'y', # anonimisation of DICOM data '-b', self.cfg['preprocess']['dcm2nii']['BIDSsidecar'][0], '-z', self.cfg['preprocess']['dcm2nii']['OutputCompression'] [0], '-f', self.cfg['preprocess']['dcm2nii']['OutputFileStruct'], '-o', subj_outdir, '-w', str(self.cfg['preprocess']['dcm2nii'] ['NameConflicts']), '-v', str(self.cfg['preprocess']['dcm2nii']['Verbosity']), '-x', str(self.cfg['preprocess']['dcm2nii']['ReorientCrop']), folder ], stdout=sys.stdout, stderr=subprocess.STDOUT) sys.stdout.close() sys.stdout = orig_stdout files_kept, files_deleted = self.select_sequences(subj_outdir) keptfiles.extend(files_kept) deletedfiles.extend(files_deleted) # Functions creating/updating pipeline log, which document individually all steps along with settings log_text = "{} files successfully converted: {}, \n\nand {} deleted: {}.\nDuration: {:.2f} secs" \ .format(len(set(keptfiles)), '\n\t{}'.format('\n\t'.join(os.path.split(x)[1] for x in sorted(set(keptfiles)))), len(set(deletedfiles)), '\n\t{}'.format('\n\t'.join(os.path.split(x)[1] for x in sorted(set(deletedfiles)))), time.time() - start_time_subject) Output.logging_routine(text=Output.split_lines(log_text), cfg=self.cfg, subject=self.cfg['folders']['prefix'] + str(no_subj), module='dcm2nii', opt=self.cfg['preprocess']['dcm2nii'], project="")
def ANTsCoregisterMultiprocessing(self, file_fixed, file_moving, subj, input_folder, flag, step, status, run=1): """Performs Co-Registration taking advantage of multicores, i.e. multiple subjects processed in parallel""" status.put(tuple([file_fixed, file_moving, subj])) prev_reg = glob.glob( os.path.join(input_folder + "/" + self.cfg['preprocess'][flag]['prefix'] + 'run*' + os.path.basename(file_moving))) if not prev_reg: print('\tNo previous registration found, starting with first run') filename_save = os.path.join( input_folder, self.cfg['preprocess'][flag]['prefix'] + 'run' + str(run) + '_' + os.path.basename(file_moving)) elif re.search(r'\w+{}.'.format('CT_'), file_moving, re.IGNORECASE) and file_moving.endswith('.nii'): print('\tNo second run for CT-MRI registrations possible.') return else: allruns = [ re.search(r'\w+(run)([\d.]+)', x).group(2) for x in prev_reg ] lastrun = int(sorted(allruns)[-1]) file_moving = os.path.join( input_folder, self.cfg["preprocess"]["registration"]["prefix"] + 'run' + str(lastrun) + '_' + os.path.basename(file_moving)) # update for second run run = lastrun + 1 n4prefix = self.cfg['preprocess']['ANTsN4']['prefix'] basename = '{}{}'.format(n4prefix, file_moving.split(n4prefix)[1]) filename_save = os.path.join( input_folder, self.cfg['preprocess'][flag]['prefix'] + 'run' + str(run) + '_' + basename) print(filename_save) log_filename = os.path.join( ROOTDIR, 'logs', "log_Registration_using_ANTs_{}_run_{}_".format(subj, str(run)) + time.strftime("%Y%m%d-%H%M%S") + '.txt') imaging = dict() for idx, file_id in enumerate([file_fixed, file_moving]): sequence = ants.image_read( file_id) # load data and resample images if necessary imaging[idx] = Imaging.resampleANTs( mm_spacing=self.cfg['preprocess']['registration'] ['resample_spacing'], ANTsImageObject=sequence, file_id=file_id, method=int( self.cfg['preprocess']['registration']['resample_method'])) if run == 1: metric = self.cfg['preprocess']['registration']['metric'][0] else: self.cfg['preprocess']['registration'][ 'default_registration'] = 'yes' # TODO: must be changed if non-default works metric = self.cfg['preprocess']['registration']['metric'][0] if self.cfg['preprocess']['registration'][ 'default_registration'] == 'yes': registered_images = self.default_registration(imaging, file_fixed, file_moving, log_filename, metric=metric, step=step) else: registered_images = self.custom_registration( imaging, file_fixed, file_moving, input_folder + '/', log_filename, run) key2rename = { 'fwdtransforms': ['{}_0GenericAffineRegistration.mat'.format(step), 1], 'invtransforms': ['{}_1InvWarpMatrix.mat'.format(step), 0] } for key, value in key2rename.items(): Transform = ants.read_transform(registered_images[key][value[1]]) ants.write_transform(Transform, os.path.join(input_folder, value[0])) ants.image_write(registered_images['warpedmovout'], filename=filename_save) FileOperations.create_folder(os.path.join(input_folder, "debug")) if run > 1: # Previous registrations are moved to debug-folder prev_reg = ''.join(prev_reg) if type( prev_reg) == list else prev_reg filename_dest = re.sub( r'({}run[0-9]_)+({})'.format( self.cfg['preprocess']['registration']['prefix'], self.cfg['preprocess']['ANTsN4']['prefix']), '{}RUNPREV{}_{}'.format( self.cfg['preprocess']['registration']['prefix'], lastrun, self.cfg['preprocess']['ANTsN4']['prefix']), os.path.basename(prev_reg)) shutil.move(prev_reg, os.path.join(input_folder, 'debug', filename_dest)) create_mask = True if create_mask and 't1' in file_moving and not os.path.isfile( os.path.join(input_folder, 'brainmask_T1.nii')): Imaging.create_brainmask( input_folder, subj=subj, registered_images=registered_images['warpedmovout'])