예제 #1
0
    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)
예제 #2
0
    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="")
예제 #3
0
    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'])