コード例 #1
0
ファイル: GUIdcm2nii.py プロジェクト: dpedrosac/cDBS
    def change_dicomdir(self):
        """A new window appears in which the working directory can be set; besides, data is stored in the preferences
        file so that they will be loaded automatically next time"""

        self.dicomdir = FileOperations.set_wdir_in_config(self.cfg, foldername='dicom')
        self.label_dicomdir.setText('dicomDIR: {}'.format(self.dicomdir))
        self.cfg['folders']['dicom'] = self.dicomdir

        self.mInput.clear()
        items = FileOperations.list_folders(inputdir=self.cfg['folders']['dicom'], prefix='', files2lookfor='')
        self.add_available_subj(items)
コード例 #2
0
    def change_wdir(self):
        """A new window appears in which the working directory for NIFTI-files can be set; if set, this is stored
         in the configuration file, so that upon the next start there is the same folder selected automatically"""

        self.niftidir = FileOperations.set_wdir_in_config(self.cfg, foldername='nifti')
        self.lblWdirTab.setText('wDIR: {}'.format(self.niftidir))
        self.cfg['folders']['nifti'] = self.niftidir

        self.availableNiftiTab.clear()
        itemsChanged = FileOperations.list_folders(self.niftidir, self.cfg['folders']['prefix'])
        self.add_available_items(self.availableNiftiTab, itemsChanged)
コード例 #3
0
    def run_reload_files(self):
        """Reloads files, e.g. after renaming them"""
        self.cfg = Configuration.load_config(ROOTDIR)
        self.availableNiftiTab.clear()

        itemsChanged = FileOperations.list_folders(self.cfg['folders']['nifti'], prefix=self.cfg['folders']['prefix'])
        self.add_available_items(self.availableNiftiTab, itemsChanged)
コード例 #4
0
ファイル: GuiTabTemplate.py プロジェクト: dpedrosac/cDBS
    def run_reload_files(self):
        """Reloads files, e.g. after renaming them"""

        self.cfg = Configuration.load_config(self.cfg['folders']['rootdir'])
        self.availableTemplates.clear()
        itemsTab = set(FileOperations.list_files_in_folder(self.wdirTemplate))
        self.add_available_templates(self.availableTemplates, itemsTab)
コード例 #5
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)
コード例 #6
0
ファイル: GuiTabTemplate.py プロジェクト: dpedrosac/cDBS
    def view_template(self):
        """this function opens a list dialog and enables selecting NIFTI files for e.g. check the content (identical
        function as in GUITabPreprocessANTs.py."""

        if not self.selected_subj_Gen:
            Output.msg_box(text="No image selected. Please indicate image(s) to load.", title="No templates selected")
            return
        else:
            template_list = [FileOperations.return_full_filename(self.wdirTemplate, x) for x in self.selected_subj_Gen]
            Imaging.load_imageviewer('itk-snap', template_list)  # to-date, only itk-snap available. could be changed
コード例 #7
0
ファイル: preprocANTSpy.py プロジェクト: dpedrosac/cDBS
    def CoregisterCT2MRI(self,
                         subjects,
                         input_folder,
                         fixed_image='reg_run[0-9]_bc_t1'):
        """Co-registration of postoperative CT to preoperative MRI for further analyses in same space; before registration
        presence of registered MRI data is ensured to avoid redundancy"""

        print('\nStarting co-registration for {} subject(s)'.format(
            len(subjects)))
        allfiles = FileOperations.get_filelist_as_tuple(inputdir=input_folder,
                                                        subjects=subjects)
        self.check_for_normalisation(subjects)

        regex_complete = ['CT_', '{}_'.format(fixed_image.upper())]
        included_sequences = [
            x for x in list(
                filter(re.compile(r"^(?!~).*").match, regex_complete))
        ]

        file_ID_CT, file_ID_MRI = ([] for _ in range(2))
        [
            file_ID_CT.append(x) for x in allfiles
            if 'run' not in x[0] and re.search(
                r'\w+{}.'.format(included_sequences[0]), x[0], re.IGNORECASE)
            and x[0].endswith('.nii')
        ]

        [
            file_ID_MRI.append(x) for x in
            allfiles  # for simplicity written in a second line as regexp is slightly different
            if re.search(r'\w+(?!_).({}).'.format(included_sequences[1]), x[0],
                         re.IGNORECASE) and x[0].endswith('.nii')
        ]

        if not file_ID_MRI:
            Output.msg_box(text="Bias-corrected MRI not found!",
                           title="Preprocessed MRI unavailable")
            return
        fileIDs = list(FileOperations.inner_join(file_ID_CT, file_ID_MRI))

        self.wrapper_multiprocessing(fileIDs, subjects, 'CT')
コード例 #8
0
ファイル: GuiTabTemplate.py プロジェクト: dpedrosac/cDBS
    def redefineDefault(self):
        """redefines which template is set as default on the right list and in the cfg-file"""

        if not self.selected_subj_Gen:
            Output.msg_box(text="No template selected. Please indicate new default one.", title="No data selected")
            return
        elif len(self.selected_subj_Gen) > 1:
            Output.msg_box(text="Please select only one image as default.", title="Too many templates selected")
            return
        else:
            default_template = [FileOperations.return_full_filename(self.wdirTemplate, x) for x in self.selected_subj_Gen]
            self.cfg['folders']['default_template'] = default_template[0]
            Configuration.save_config(ROOTDIR, self.cfg)

        self.run_reload_files()
コード例 #9
0
ファイル: preprocANTSpy.py プロジェクト: dpedrosac/cDBS
    def CoregisterMRI2template(self, subjects):
        """Co-Registration of preoperative MRI to specific template"""

        print('\nStarting Co-Registration for {} subject(s)'.format(
            len(subjects)))
        all_files = FileOperations.get_filelist_as_tuple(
            inputdir=self.cfg['folders']['nifti'], subjects=subjects)
        sequences = self.cfg['preprocess']['normalisation']['sequences'].split(
            sep=',')  # sequences of interest
        template = glob.glob(
            os.path.join(
                ROOTDIR, 'ext', 'templates',
                self.cfg['preprocess']['normalisation']['template_image'] +
                '/*'))

        fileIDs = []
        for idx, seqs in enumerate(sequences):
            file_template = [
                x for x in template
                if re.search(r'\w+.({}).'.format(seqs), x, re.IGNORECASE)
            ]  # corresponding template
            if not file_template:
                Output.msg_box(
                    text=
                    "No template found. Please ensure templates are installed at './ext/templates'",
                    title="Template missing!"
                )  # TODO install templates by default!
                return

            regex_complete = '{}{}'.format(
                self.cfg['preprocess']['ANTsN4']['prefix'], seqs)
            files_subj = [
                x for x in all_files
                if x[0].endswith('.nii') and 'run' not in x[0]
                and re.search(r'\w+(?!_).({}).'.format(regex_complete), x[0],
                              re.IGNORECASE)
            ]
            fileIDs.extend(
                tuple([(file_template[0], file_id, subj)
                       for file_id, subj in files_subj]))

        if not fileIDs:
            Output.msg_box(
                text="No bias-corrected MRI found. Please double-check",
                title="Preprocessed MRI missing")
            return

        self.wrapper_multiprocessing(fileIDs, subjects, 'MRI')
コード例 #10
0
    def change_workingdir(self):
        """A new window appears in which the working directory can be set; besides, data is stored in the preferences
        file so that they will be loaded automatically next time"""

        self.working_dir = QFileDialog.getExistingDirectory(
            self,
            directory=self.working_dir,
            caption='Change working directory')
        self.label_workingdir.setText('Working DIR: {}'.format(
            self.working_dir))
        self.mInput.clear()

        items = FileOperations.list_folders(self.working_dir, prefix='')
        self.addAvailableItems(items)
        if self.option_gui == 'dcm2niix':
            self.cfg['folders']['dicom'] = self.working_dir
            Configuration.save_config(self.cfg['folders']["rootdir"], self.cfg)
コード例 #11
0
ファイル: preprocANTSpy.py プロジェクト: dpedrosac/cDBS
    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'])
コード例 #12
0
def PaCER_script(subjects, inputfolder=''):
    """wrapper script for all steps included in the PaCER algorithm"""

    print("\nLead detection of {} subject(s)".format(len(subjects)))
    inputfolder = cfg['folders']['nifti'] if not inputfolder else inputfolder  # select default input folder
    LW = LeadWorks()  # load the class including necessary functions

    # Look for data files containing CT imaging including the brainMask and load this into workspace
    available_files = FileOperations.get_filelist_as_tuple(inputdir=inputfolder, subjects=subjects)
    regex2lookfor = 'reg_' + 'run[0-9]', 'brainmask_'
    file_id_CTimaging = [file_tuple for file_tuple in available_files
                         if re.search(r'\w.({}).'.format(regex2lookfor[0]), file_tuple[0], re.IGNORECASE)
                         and file_tuple[0].endswith('.nii') and 'CT' in file_tuple[0]]

    file_id_brainMask = [file_tuple for file_tuple in available_files
                         if re.search(r'\w.({}).'.format(regex2lookfor[1]), file_tuple[0], re.IGNORECASE)
                         and file_tuple[0].endswith('.nii')]

    if any(t > 2 for t in [len(k) for k in file_id_CTimaging]):
        print("More than one files for imaging or brainmask available. Please double-check!")
        return

    if not file_id_brainMask:
        warnings.warn(message="\tNo brain mask was found, trying to obtain a mask using ANTSpyNET routines")
        regex2lookforT1 = cfg['preprocess']['normalisation']['prefix'] + 'run'
        file_id_T1 = [file_tuple for file_tuple in available_files
                      if re.search(r'\w.({}).'.format(regex2lookforT1), file_tuple[0], re.IGNORECASE)
                      and 't1' in file_tuple[0] and file_tuple[0].endswith('.nii')]
        if not file_id_T1:
            Output.msg_box(text='No T1-sequence imaging available. BrainMask extraction impossible.',
                           title='T1 sequences missing")')
            return
        else:
            T1imaging = ants.image_read(file_id_T1[0][0])
            file_id_brainMask = Imaging.create_brainmask(input_folder=inputfolder, subj=''.join(subjects),
                                                         registered_images=T1imaging)
            file_id_brainMask = [file_id_brainMask] if type(file_id_brainMask) == tuple else file_id_brainMask

    fileID = list(FileOperations.inner_join(file_id_brainMask, file_id_CTimaging))  # joins all to single list
    metal_threshold = int(cfg['lead_detection']['PaCER']['metal_threshold'])
    elecModels, intensityProfiles, skelSkalms = LW.electrodeEstimation(fileID[0], threshold=metal_threshold)
    elecModels, skelSkalms, intensityProfiles, _ = \
        LeadProperties.estimate_hemisphere(elecModels, intensityProfiles, skelSkalms)  # returns hemisphere from coords.

    filename_save = os.path.join(os.path.join(inputfolder, subjects[0]), 'elecModels_' + subjects[0] + '.pkl')
    with open(filename_save, "wb") as f:
        pickle.dump(elecModels, f)
        pickle.dump(intensityProfiles, f)
        pickle.dump(skelSkalms, f)

    sides = ['left', 'right']
    rotation_default, rotation_mod = [{k: [] for k in sides} for _ in range(2)]
    for s in sides:
        rotation_default[s] = function_wrapper(subj=subjects[0], side=s)
        rotation_mod[s] = Configuration.rotation_dict_mod()  # creates an empty array to save modified data later

    filename_save = os.path.join(os.path.join(inputfolder, subjects[0]), 'rotation_' + subjects[0] + '.pkl')
    with open(filename_save, "wb") as f:
        pickle.dump(rotation_default, f)
        pickle.dump(rotation_mod, f)

    print("Finished with lead detection!")
    # TODO: it does not return to the empty command line.
    return
コード例 #13
0
    def N4BiasCorrection(self, subjects):
        """N4BiasCorrection according to N.J. Tustison, ..., and J.C. Gee.
        "N4ITK: Improved N3 Bias Correction" IEEE Transactions on Medical Imaging, 29(6):1310-1320, June 2010."""

        print('\nDebiasing imaging of {} subject(s)'.format(len(subjects)))
        allfiles = FileOperations.get_filelist_as_tuple(inputdir=self.cfg['folders']['nifti'], subjects=subjects)
        strings2exclude = ['CT', self.cfg['preprocess']['ANTsN4']['prefix'], 'reg_run', 'Mask', 'Warp', 'Registration']

        allfiles = [x for x in allfiles if x[0].endswith('.nii') and not
        any(re.search(r'\w+(?!_).({})|^({})\w+.'.format(z, z), os.path.basename(x[0]), re.IGNORECASE)
            for z in strings2exclude)]

        file_id_DTI = [x for x in allfiles if (x[0].endswith('.nii') and self.cfg['preprocess']['ANTsN4']['dti_prefix']
                                               in x[0]) and not
                       any(re.search(r'\w+(?!_).({})|^({})\w+.'.format(z, z), os.path.basename(x[0]), re.IGNORECASE)
                           for z in strings2exclude)]

        file_id_noDTI = [x for x in allfiles if (x[0].endswith('.nii') and not
        self.cfg['preprocess']['ANTsN4']['dti_prefix'] in x[0]) and not
                         any(re.search(r'\w+(?!_).({})|^({})\w+.'.format(z, z), os.path.basename(x[0]), re.IGNORECASE)
                             for z in strings2exclude)]

        seq = 'struct'  # For debugging purposes
        if not seq:
            fileIDs = allfiles
        elif seq == 'struct':
            fileIDs = list(set(allfiles) - set(file_id_DTI))
        elif seq == 'dwi':
            fileIDs = list(set(allfiles) - set(file_id_noDTI))

        start_multi = time.time()
        status = mp.Queue()
        processes = [mp.Process(target=self.N4BiasCorrection_multiprocessing,
                                args=(name_file, no_subj, os.path.join(self.cfg['folders']['nifti'], no_subj), status))
                     for name_file, no_subj in fileIDs]

        for p in processes:
            p.start()

        while any([p.is_alive() for p in processes]):
            while not status.empty():
                process, no_subj, filename = status.get()
                print("Process: {}; Debiasing {}, filename: {}".format(process, no_subj, filename))
            time.sleep(0.1)

        for p in processes:
            p.join()

        # Functions creating/updating pipeline log, which document individually all steps along with settings
        for subjID in subjects:
            allfiles_subj = [os.path.split(files_subj)[1] for files_subj, subj_no in fileIDs if subj_no == subjID]
            log_text = "{} files successfully processed (@{}): {}, \n\n Mean Duration per subject: {:.2f} secs" \
                .format(len(set(allfiles_subj)), time.strftime("%Y%m%d-%H%M%S"),
                        '\n\t{}'.format('\n\t'.join(os.path.split(x)[1] for x in sorted(set(allfiles_subj)))),
                        (time.time() - start_multi) / len(subjects))
            Output.logging_routine(text=Output.split_lines(log_text), cfg=self.cfg,
                                   subject=str(subjID), module='N4BiasCorrection',
                                   opt=self.cfg['preprocess']['ANTsN4'], project="")

        print('\nIn total, a list of {} subject(s) was processed \nOverall, bias correction took '
              '{:.1f} secs.'.format(len(subjects), time.time() - start_multi))
コード例 #14
0
ファイル: GuiTabTemplate.py プロジェクト: dpedrosac/cDBS
    def __init__(self, parent=None):
        super(GuiTabTemplate, self).__init__(parent)
        self.selected_subj_Gen = ''
        self.wdirTemplate = os.path.join(ROOTDIR, 'ext', 'templates')

        # General settings/variables/helper files needed needed at some point
        self.cfg = Configuration.load_config(ROOTDIR)
        if os.path.isdir(self.cfg['folders']['nifti']):
            self.niftidir = self.cfg['folders']['nifti']
        else:
            self.niftidir = FileOperations.set_wdir_in_config(self.cfg, foldername='nifti', init=True)
        self.cfg['folders']['rootdir'] = ROOTDIR
        Configuration.save_config(ROOTDIR, self.cfg)

        self.lay = QHBoxLayout(self)
        self.tab = QWidget()

        # Customize tab
        # ==============================    Tab 1 - General   ==============================
        self.tab.layout = QHBoxLayout()
        self.tab.setLayout(self.tab.layout)
        # ------------------------- Upper left part (Folder)  ------------------------- #
        self.FolderboxTab = QGroupBox("Directory (Templates)")
        self.HBoxUpperLeftTab = QVBoxLayout(self.FolderboxTab)

        self.dirTemplates = QLabel('wDIR: {}'.format(self.wdirTemplate))
        self.HBoxUpperLeftTab.addWidget(self.dirTemplates)

        self.btnChangeWdir = QPushButton('Change working directory')
        self.btnChangeWdir.setDisabled(True)

        self.btnReloadFilesTab = QPushButton('Reload files')
        self.btnReloadFilesTab.clicked.connect(self.run_reload_files)

        self.HBoxUpperLeftTab.addWidget(self.btnChangeWdir)
        self.HBoxUpperLeftTab.addWidget(self.btnReloadFilesTab)

        # ------------------------- Lower left part (Processing)  ------------------------- #
        self.ActionsTab = QGroupBox("Functions")
        self.HBoxLowerLeftTab = QVBoxLayout(self.ActionsTab)
        self.btn_new_default = QPushButton('Set new \ndefault')
        # self.btn_subj_details.setToolTip(setToolTips.subjectDetails()) TODO: new ToolTip needed
        self.btn_new_default.clicked.connect(self.redefineDefault)

        self.btn_viewer = QPushButton('View selected \nTemplate in viewer')
        # self.btn_viewer.setToolTip(setToolTips.displayFolderContent()) TODO: new ToolTip needed
        self.btn_viewer.clicked.connect(self.view_template)

        self.create_SST = QPushButton('Create Study-specific\ntemplate')
        # self.btn_renaming.setToolTip(setToolTips.renameFolders()) TODO: new ToolTip needed
        self.create_SST.clicked.connect(self.create_StudySpecificTemplate)

        self.HBoxLowerLeftTab.addWidget(self.btn_viewer)
        self.HBoxLowerLeftTab.addWidget(self.btn_new_default)
        self.HBoxLowerLeftTab.addWidget(self.create_SST)

        # -------------------- Right part (Subject list)  ----------------------- #
        self.listbox = QGroupBox('Available subjects')
        self.HBoxUpperRightTab = QVBoxLayout(self.listbox)
        self.availableTemplates = QListWidget()
        self.availableTemplates.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.availableTemplates.itemSelectionChanged.connect(self.change_list_item)
        itemsTab = set(FileOperations.list_files_in_folder(self.wdirTemplate))
        self.add_available_templates(self.availableTemplates, itemsTab)
        self.HBoxUpperRightTab.addWidget(self.availableTemplates)

        # Combine all Boxes for General Tab Layout
        self.LeftboxTab = QGroupBox()
        self.HBoxTabLeft = QVBoxLayout(self.LeftboxTab)
        self.HBoxTabLeft.addWidget(self.FolderboxTab)
        self.HBoxTabLeft.addStretch()
        self.HBoxTabLeft.addWidget(self.ActionsTab)

        self.tab.layout.addWidget(self.LeftboxTab)
        self.tab.layout.addWidget(self.listbox)

        self.lay.addWidget(self.tab)
コード例 #15
0
    def __init__(self, working_directory, _option_gui, parent=None):
        super(QWidget, self).__init__(parent)
        self.cfg = Configuration.load_config(ROOTDIR)
        self.option_gui = _option_gui

        # ============================    Different options available   ============================
        if self.option_gui == 'dcm2niix':
            working_dir = self.cfg['folders']['dicom']
            self.working_dir = working_dir if os.path.isdir(
                working_dir) else os.getcwd()
            options = {
                'folderbox_title': "Directory (DICOM-files)",
                'str_labelDir': 'DICOM DIR: {}'.format(self.working_dir),
                'runBTN_label': 'Run processing'
            }

        elif self.option_gui == 'displayNiftiFiles':
            if not working_directory:
                Output.msg_box(
                    text="Please provide a valid folder. Terminating this GUI.",
                    title="No folder provided")
                self.close()
                return
            else:
                self.working_dir = working_directory
            options = {
                'folderbox_title': "Directory (nifti-files)",
                'str_labelDir': 'subjects\' DIR: {}'.format(self.working_dir),
                'runBTN_label': 'View files'
            }
        else:
            Output.msg_box(
                text=
                "Please provide a valid option such as 'dcm2niix' or 'displayNiftiFiles'. "
                "Terminating the GUI",
                title="Wrong input as option")
            self.close()
            return

        # ============================    Start creating layout   ============================
        # Create general layout
        self.tot_layout = QVBoxLayout(self)
        self.mid_layout = QHBoxLayout(self)

        # ============================    Create upper of  GUI, i.e. working directory   ============================
        self.label_folderbox = QGroupBox(options["folderbox_title"])
        self.HBoxUpperTwoListGUI = QVBoxLayout(self.label_folderbox)
        self.label_workingdir = QLabel(options["str_labelDir"])
        self.HBoxUpperTwoListGUI.addWidget(self.label_workingdir)

        self.btn_workingdir = QPushButton('Change working \ndirectory')
        self.btn_workingdir.setFixedSize(150, 40)
        self.btn_workingdir.setDisabled(True)
        if self.option_gui == 'dcm2niix':
            self.btn_workingdir.setEnabled(True)
        self.btn_workingdir.clicked.connect(self.change_workingdir)

        self.btn_savedir = QPushButton('Save directory \nto config file')
        self.btn_savedir.setFixedSize(150, 40)
        self.btn_savedir.setDisabled(True)
        if self.option_gui == 'dcm2niix':
            self.btn_savedir.setEnabled(True)
            self.btn_savedir.setToolTip(
                Output.split_lines(setToolTips.saveDirButton()))
        self.btn_savedir.clicked.connect(self.save_cfg_dicomdir)

        hlay_upper = QHBoxLayout()
        hlay_upper.addWidget(self.btn_workingdir)
        hlay_upper.addWidget(self.btn_savedir)
        hlay_upper.addStretch(1)
        self.HBoxUpperTwoListGUI.addLayout(hlay_upper)

        # ====================    Create Content for Lists, i.e. input/output      ====================
        self.listboxInputGUITwoList = QGroupBox(
            'Available items in working directory')
        self.listboxInput = QVBoxLayout(self.listboxInputGUITwoList)
        self.mInput = QListWidget()
        self.listboxInput.addWidget(self.mInput)

        self.mButtonToAvailable = QPushButton("<<")
        self.mBtnMoveToAvailable = QPushButton(">")
        self.mBtnMoveToSelected = QPushButton("<")
        self.mButtonToSelected = QPushButton(">>")
        self.mBtnUp = QPushButton("Up")
        self.mBtnDown = QPushButton("Down")

        self.listboxOutputGUITwoLIst = QGroupBox('Items to process')
        self.listboxOutput = QVBoxLayout(self.listboxOutputGUITwoLIst)
        self.mOutput = QListWidget()
        self.listboxOutput.addWidget(self.mOutput)

        # First column (Left side)
        vlay = QVBoxLayout()
        vlay.addStretch()
        vlay.addWidget(self.mBtnMoveToAvailable)
        vlay.addWidget(self.mBtnMoveToSelected)
        vlay.addStretch()
        vlay.addWidget(self.mButtonToAvailable)
        vlay.addWidget(self.mButtonToSelected)
        vlay.addStretch()

        # Second column (Right side)
        vlay2 = QVBoxLayout()
        vlay2.addStretch()
        vlay2.addWidget(self.mBtnUp)
        vlay2.addWidget(self.mBtnDown)
        vlay2.addStretch()

        # ====================    Lower part of GUI, i.e. Preferences/Start estimation      ====================
        self.btn_preferences = QPushButton("Preferences")
        self.btn_preferences.setDisabled(True)
        self.btn_preferences.clicked.connect(self.settings_show)
        if self.option_gui == 'dcm2niix':
            self.btn_preferences.setEnabled(True)

        self.btn_run_command = QPushButton(options["runBTN_label"])
        if self.option_gui == 'dcm2niix':
            self.btn_run_command.setToolTip(setToolTips.run_dcm2niix())
        else:
            self.btn_run_command.setToolTip(
                setToolTips.run_CheckRegistration())
        self.btn_run_command.clicked.connect(self.start_process)

        hlay_bottom = QHBoxLayout()
        hlay_bottom.addStretch(1)
        hlay_bottom.addWidget(self.btn_preferences)
        hlay_bottom.addWidget(self.btn_run_command)
        hlay_bottom.addStretch()

        # ====================    Set all contents to general Layout     =======================
        self.mid_layout.addWidget(self.listboxInputGUITwoList)
        self.mid_layout.addLayout(vlay)
        self.mid_layout.addWidget(self.listboxOutputGUITwoLIst)
        self.mid_layout.addLayout(vlay2)

        self.tot_layout.addWidget(self.label_folderbox)
        self.tot_layout.addLayout(self.mid_layout)
        self.tot_layout.addLayout(hlay_bottom)

        try:
            self.mInput.clear()
            if self.option_gui == 'dcm2niix':
                items = FileOperations.list_folders(self.working_dir,
                                                    prefix='')
            else:
                items = FileOperations.list_files_in_folder(
                    inputdir=self.working_dir, contains='', suffix='nii')
            self.addAvailableItems(items)
        except FileExistsError:
            print('{} without any valid files/folders, continuing ...'.format(
                self.working_dir))

        self.update_buttons_status()
        self.connections()
コード例 #16
0
    def __init__(self, parent=None):
        super(GuiTabPreprocessANTs, self).__init__(parent)
        self.selected_subj_ANT = ''

        self.cfg = Configuration.load_config(ROOTDIR)
        if os.path.isdir(self.cfg['folders']['nifti']):
            self.niftidir = self.cfg['folders']['nifti']
        else:
            self.niftidir = FileOperations.set_wdir_in_config(self.cfg, foldername='nifti', init=True)

        self.cfg['folders']['nifti'] = self.niftidir
        self.cfg['folders']['rootdir'] = ROOTDIR
        Configuration.save_config(ROOTDIR, self.cfg)

        # Customize tab
        self.lay = QHBoxLayout(self)
        self.tab = QWidget()
        self.tab.layout = QHBoxLayout()
        self.tab.setLayout(self.tab.layout)

        # ------------------------- Upper left part (Folder)  ------------------------- #
        self.FolderboxTab = QGroupBox('Directory (NIFTI-files)')
        self.HBoxUpperLeftTab = QVBoxLayout(self.FolderboxTab)
        self.lblWdirTab = QLabel('wDIR: {}'.format(self.niftidir))
        self.HBoxUpperLeftTab.addWidget(self.lblWdirTab)

        self.btnChangeWdir = QPushButton('Change working directory')
        self.btnChangeWdir.setToolTip(setToolTips.ChangeWdirNIFTI())
        self.btnChangeWdir.clicked.connect(self.change_wdir)

        self.btnReloadFilesTab = QPushButton('Reload files')
        self.btnReloadFilesTab.clicked.connect(self.run_reload_files)

        self.HBoxUpperLeftTab.addWidget(self.btnChangeWdir)
        self.HBoxUpperLeftTab.addWidget(self.btnReloadFilesTab)

        # ------------------------- Middle left part (Preferences)  ------------------------- #
        self.SettingsTabANTs = QGroupBox('Preferences')
        self.HBoxMiddleLeftTabExt = QVBoxLayout(self.SettingsTabANTs)
        self.btn_ANTsettings = QPushButton('ANT Settings')
        self.btn_ANTsettings.clicked.connect(self.run_ANTsPreferences)
        self.btn_ANTsettings.setToolTip(setToolTips.ANTsSettings())
        self.HBoxMiddleLeftTabExt.addWidget(self.btn_ANTsettings)

        # ------------------------- Middle left part (ANTs routines)  ------------------------- #
        self.ActionsTabANTs = QGroupBox('ANTs routines')
        self.HBoxMiddleLeftTab = QVBoxLayout(self.ActionsTabANTs)
        self.btn_N4BiasCorr = QPushButton('N4BiasCorrect')
        self.btn_N4BiasCorr.setToolTip(setToolTips.N4BiasCorrection())
        self.btn_N4BiasCorr.clicked.connect(self.run_n4Bias_corr)

        self.btn_MRIreg = QPushButton('MR-Registration')
        self.btn_MRIreg.setToolTip(setToolTips.RegisterMRI2template())
        self.btn_MRIreg.clicked.connect(self.run_RegisterMRI2template)

        self.btn_CTreg = QPushButton('CT-Registration')
        self.btn_CTreg.setToolTip(setToolTips.RegisterCT2MRI())
        self.btn_CTreg.clicked.connect(self.run_RegisterCT2MRI)

        self.HBoxMiddleLeftTab.addWidget(self.btn_N4BiasCorr)
        self.HBoxMiddleLeftTab.addWidget(self.btn_MRIreg)
        self.HBoxMiddleLeftTab.addWidget(self.btn_CTreg)

        # ------------------------- Lower left part (Processing)  ------------------------- #
        self.QualityTabANTs = QGroupBox('Quality checks for ANTs preprocessing')
        self.HBoxLowerLeftTab = QVBoxLayout(self.QualityTabANTs)
        self.btn_QC_ANTsPreproc = QPushButton('View available \nNIFTI-files in viewer')
        self.btn_QC_ANTsPreproc.setToolTip(setToolTips.compareNIFTIfiles())
        self.btn_QC_ANTsPreproc.clicked.connect(self.display_nifti_files)
        self.HBoxLowerLeftTab.addWidget(self.btn_QC_ANTsPreproc)

        # -------------------- Right part (Subject list)  ----------------------- #
        self.listbox = QGroupBox('Available subjects')
        self.HBoxUpperRightTab = QVBoxLayout(self.listbox)
        self.availableNiftiTab = QListWidget()
        self.availableNiftiTab.setSelectionMode(QAbstractItemView.ExtendedSelection)
        itemsTab = FileOperations.list_folders(self.niftidir, prefix=self.cfg['folders']['prefix'])
        self.add_available_items(self.availableNiftiTab, itemsTab, msg='no')
        self.availableNiftiTab.itemSelectionChanged.connect(self.change_list_item)
        self.HBoxUpperRightTab.addWidget(self.availableNiftiTab)

        # Combine all Boxes for Tab 2 Layout
        self.LeftboxTabANTs = QGroupBox()
        self.HBoxTabANTsLeft = QVBoxLayout(self.LeftboxTabANTs)
        self.HBoxTabANTsLeft.addWidget(self.FolderboxTab)
        self.HBoxTabANTsLeft.addStretch(1)
        self.HBoxTabANTsLeft.addWidget(self.SettingsTabANTs)
        self.HBoxTabANTsLeft.addWidget(self.ActionsTabANTs)
        self.HBoxTabANTsLeft.addWidget(self.QualityTabANTs)

        self.tab.layout.addWidget(self.LeftboxTabANTs)
        self.tab.layout.addWidget(self.listbox)

        self.lay.addWidget(self.tab)
コード例 #17
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="")
コード例 #18
0
ファイル: GuiTabDetectLeads.py プロジェクト: dpedrosac/cDBS
    def __init__(self, parent=None):
        super(GuiTabDetectLeads, self).__init__(parent)
        self.selected_subj_ANT = ''

        # General settings/variables/helper files needed at some point
        self.cfg = Configuration.load_config(ROOTDIR)
        if os.path.isdir(self.cfg['folders']['nifti']):
            self.niftidir = self.cfg['folders']['nifti']
        else:
            self.niftidir = FileOperations.set_wdir_in_config(
                self.cfg, foldername='nifti', init=True)

        self.cfg['folders']['nifti'] = self.niftidir
        self.cfg['folders']['rootdir'] = ROOTDIR
        Configuration.save_config(ROOTDIR, self.cfg)

        self.lay = QHBoxLayout(self)
        self.tab = QWidget()

        # Customize tab
        # ==============================    Tab 3 - Lead detection routines   ==============================
        self.tab.layout = QHBoxLayout()
        self.tab.setLayout(self.tab.layout)

        # ------------------------- Upper left part (Folder)  ------------------------- #
        self.FolderboxTab = QGroupBox("Directory")
        self.HBoxUpperLeftTab = QVBoxLayout(self.FolderboxTab)
        self.lblWdirTab = QLabel('wDIR: {}'.format(self.niftidir))
        self.HBoxUpperLeftTab.addWidget(self.lblWdirTab)

        self.btnChangeWdir = QPushButton('Change working directory')
        self.btnChangeWdir.clicked.connect(self.change_wdir)
        self.btnReloadFilesTab = QPushButton('Reload files')
        self.btnReloadFilesTab.clicked.connect(self.run_reload_files)

        self.HBoxUpperLeftTab.addWidget(self.btnChangeWdir)
        self.HBoxUpperLeftTab.addWidget(self.btnReloadFilesTab)

        # ------------------------- Middle left part (Settings)  ------------------------- #
        self.SettingsTabLeadDetect = QGroupBox("Preferences")
        self.HBoxMiddleLeftTabExt = QVBoxLayout(self.SettingsTabLeadDetect)

        self.btn_LeadDetectSettings = QPushButton('Settings \nLead detection')
        self.btn_LeadDetectSettings.clicked.connect(
            self.run_PreferencesLeadDetection)
        self.btn_LeadDetectSettings.setToolTip(setToolTips.ANTsSettings())

        self.HBoxMiddleLeftTabExt.addWidget(self.btn_LeadDetectSettings)

        # ------------------------- Middle left part (Processing)  ------------------------- #
        self.ActionsTabANTs = QGroupBox("Lead detection routines")
        self.HBoxMiddleLeftTab = QVBoxLayout(self.ActionsTabANTs)
        self.btn_LeadDetectPacer = QPushButton('PaCER algorithm')
        self.btn_LeadDetectPacer.clicked.connect(self.run_LeadDetectionPaCER)

        self.btn_RefineDetectedLeads = QPushButton('Refine detected leads')
        self.btn_RefineDetectedLeads.clicked.connect(self.run_ManualCorrection)

        self.HBoxMiddleLeftTab.addWidget(self.btn_LeadDetectPacer)
        self.HBoxMiddleLeftTab.addWidget(self.btn_RefineDetectedLeads)

        # ------------------------- Lower left part (Processing)  ------------------------- #
        self.QualityTabLeadDetect = QGroupBox(
            "Quality checks for Lead detection")
        self.HBoxLowerLeftTab = QVBoxLayout(self.QualityTabLeadDetect)
        self.btn_QC_LeadDetect = QPushButton(
            'Check lead detection \nin viewer')
        self.btn_QC_LeadDetect.setToolTip(setToolTips.compareNIFTIfiles())
        self.btn_QC_LeadDetect.clicked.connect(self.VisualiseLeadDetection)
        self.HBoxLowerLeftTab.addWidget(self.btn_QC_LeadDetect)

        # -------------------- Right part (Subject list)  ----------------------- #
        self.listbox = QGroupBox('Available subjects')
        self.HBoxUpperRightTab = QVBoxLayout(self.listbox)
        self.availableNiftiTab = QListWidget()
        self.availableNiftiTab.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        itemsTab = FileOperations.list_folders(
            self.niftidir, prefix=self.cfg['folders']['prefix'])
        self.add_available_items(self.availableNiftiTab, itemsTab, msg='no')
        self.availableNiftiTab.itemSelectionChanged.connect(
            self.change_list_item)

        self.HBoxUpperRightTab.addWidget(self.availableNiftiTab)

        # Combine all Boxes for Tab 2 Layout
        self.LeftboxTabANTs = QGroupBox()
        self.HBoxTabLeadDetectLeft = QVBoxLayout(self.LeftboxTabANTs)
        self.HBoxTabLeadDetectLeft.addWidget(self.FolderboxTab)
        self.HBoxTabLeadDetectLeft.addStretch(1)
        self.HBoxTabLeadDetectLeft.addWidget(self.SettingsTabLeadDetect)
        self.HBoxTabLeadDetectLeft.addWidget(self.ActionsTabANTs)
        self.HBoxTabLeadDetectLeft.addWidget(self.QualityTabLeadDetect)

        self.tab.layout.addWidget(self.LeftboxTabANTs)
        self.tab.layout.addWidget(self.listbox)

        self.lay.addWidget(self.tab)
コード例 #19
0
ファイル: GUIdcm2nii.py プロジェクト: dpedrosac/cDBS
    def __init__(self, parent=None):
        super(QWidget, self).__init__(parent)

        # Load configuration files and general settings
        self.cfg = Configuration.load_config(ROOTDIR)
        if os.path.isdir(self.cfg['folders']['dicom']):
            self.dicomdir = self.cfg['folders']['dicom']
        else:
            self.dicomdir = FileOperations.set_wdir_in_config(self.cfg, foldername='dicom', init=True)

        self.cfg['folders']['dicom'] = self.dicomdir
        self.cfg['folders']['rootdir'] = ROOTDIR
        Configuration.save_config(ROOTDIR, self.cfg)

        # Create general layout
        self.tot_layout = QVBoxLayout(self)
        self.mid_layout = QHBoxLayout(self)

        # ============================    Create upper of  GUI, i.e. working directory   ============================
        self.folderboxDcm2nii = QGroupBox("Directory (DICOM-files)")
        self.HBoxUpperDcm2nii = QVBoxLayout(self.folderboxDcm2nii)
        self.label_dicomdir = QLabel('dicom DIR: {}'.format(self.dicomdir))
        self.HBoxUpperDcm2nii.addWidget(self.label_dicomdir)

        self.btn_dicomdir = QPushButton('Change working \ndirectory')
        self.btn_dicomdir.setFixedSize(150, 40)
        self.btn_dicomdir.clicked.connect(self.change_dicomdir)
        self.btn_savedir = QPushButton('Save directory \nto config file')
        self.btn_savedir.setFixedSize(150, 40)
        self.btn_savedir.setToolTip(Output.split_lines(setToolTips.saveDirButton()))
        self.btn_savedir.clicked.connect(self.save_cfg)

        hlay_upper = QHBoxLayout()
        hlay_upper.addWidget(self.btn_dicomdir)
        hlay_upper.addWidget(self.btn_savedir)
        hlay_upper.addStretch(1)
        self.HBoxUpperDcm2nii.addLayout(hlay_upper)

        # ====================    Create Content for Lists, i.e. input/output      ====================
        self.listboxInputDcm2nii = QGroupBox('Available subjects in working directory')
        self.listboxInput = QVBoxLayout(self.listboxInputDcm2nii)
        self.mInput = QListWidget()
        self.listboxInput.addWidget(self.mInput)

        self.mButtonToAvailable = QPushButton("<<")
        self.mBtnMoveToAvailable = QPushButton(">")
        self.mBtnMoveToSelected = QPushButton("<")
        self.mButtonToSelected = QPushButton(">>")
        self.mBtnUp = QPushButton("Up")
        self.mBtnDown = QPushButton("Down")

        self.listboxOutputDcm2nii = QGroupBox('Subjects to process')
        self.listboxOutput = QVBoxLayout(self.listboxOutputDcm2nii)
        self.mOutput = QListWidget()
        self.listboxOutput.addWidget(self.mOutput)

        # First column on the left side
        vlay = QVBoxLayout()
        vlay.addStretch()
        vlay.addWidget(self.mBtnMoveToAvailable)
        vlay.addWidget(self.mBtnMoveToSelected)
        vlay.addStretch()
        vlay.addWidget(self.mButtonToAvailable)
        vlay.addWidget(self.mButtonToSelected)
        vlay.addStretch()

        # Second column on the right side
        vlay2 = QVBoxLayout()
        vlay2.addStretch()
        vlay2.addWidget(self.mBtnUp)
        vlay2.addWidget(self.mBtnDown)
        vlay2.addStretch()

        # ====================    Lower part of GUI, i.e. Preferences/Start estimation      ====================
        self.btn_preferences = QPushButton("Preferences")
        self.btn_preferences.clicked.connect(self.settings_show)
        self.btn_run_dcm2niix = QPushButton("Run dcm2niix")
        self.btn_run_dcm2niix.setToolTip(setToolTips.run_dcm2niix())
        self.btn_run_dcm2niix.clicked.connect(self.start_converting)

        hlay_bottom = QHBoxLayout()
        hlay_bottom.addStretch(1)
        hlay_bottom.addWidget(self.btn_preferences)
        hlay_bottom.addWidget(self.btn_run_dcm2niix)
        hlay_bottom.addStretch()

        # ====================    Set all contents to general Layout     =======================
        self.mid_layout.addWidget(self.listboxInputDcm2nii)
        self.mid_layout.addLayout(vlay)
        self.mid_layout.addWidget(self.listboxOutputDcm2nii)
        self.mid_layout.addLayout(vlay2)

        self.tot_layout.addWidget(self.folderboxDcm2nii)
        self.tot_layout.addLayout(self.mid_layout)
        self.tot_layout.addLayout(hlay_bottom)

        try:
            self.mInput.clear()
            items = FileOperations.list_folders(inputdir=self.cfg['folders']['dicom'], prefix='', files2lookfor='')
            items = self.check_for_complete_input(list(items))
            self.add_available_subj(items)
        except FileExistsError:
            print('{} without any valid files/folders, continuing ...'.format(self.dicomdir))

        self.update_buttons_status()
        self.connections()
コード例 #20
0
    def __init__(self, parent=None):
        super(GuiTabGeneral, self).__init__(parent)
        self.selected_subj_Gen = ''

        # General settings/variables/helper files needed needed at some point
        self.cfg = Configuration.load_config(ROOTDIR)
        if os.path.isdir(self.cfg['folders']['nifti']):
            self.niftidir = self.cfg['folders']['nifti']
        else:
            self.niftidir = FileOperations.set_wdir_in_config(
                self.cfg, foldername='nifti', init=True)
        # self.cfg['folders']['rootdir'] = ROOTDIR  ## changed 2021/02/23
        Configuration.save_config(ROOTDIR, self.cfg)

        self.lay = QHBoxLayout(self)
        self.tab = QWidget()

        # Customize tab
        # ==============================    Tab 1 - General   ==============================
        self.tab.layout = QHBoxLayout()
        self.tab.setLayout(self.tab.layout)
        # ------------------------- Upper left part (Folder)  ------------------------- #
        self.FolderboxTab = QGroupBox("Directory (NIFTI-files)")
        self.HBoxUpperLeftTab = QVBoxLayout(self.FolderboxTab)

        self.lblWdirTab = QLabel('wDIR: {}'.format(self.niftidir))
        self.HBoxUpperLeftTab.addWidget(self.lblWdirTab)

        self.btnChangeWdir = QPushButton('Change working directory')
        self.btnChangeWdir.setToolTip(setToolTips.ChangeWdirDICOM())
        self.btnChangeWdir.clicked.connect(self.change_wdir)

        self.btnReloadFilesTab = QPushButton('Reload files')
        self.btnReloadFilesTab.clicked.connect(self.run_reload_files)

        self.HBoxUpperLeftTab.addWidget(self.btnChangeWdir)
        self.HBoxUpperLeftTab.addWidget(self.btnReloadFilesTab)

        # ------------------------- Lower left part (Processing)  ------------------------- #
        self.ActionsTab = QGroupBox("Functions")
        self.HBoxLowerLeftTab = QVBoxLayout(self.ActionsTab)
        self.btn_subj_details = QPushButton('Subject details')
        self.btn_subj_details.setToolTip(setToolTips.subjectDetails())
        self.btn_subj_details.clicked.connect(self.openDetails)

        self.btn_dcm2nii = QPushButton('Dcm2niix')
        self.btn_dcm2nii.setToolTip(setToolTips.runDCM2NII())
        self.btn_dcm2nii.clicked.connect(self.run_DCM2NII)

        self.btn_viewer = QPushButton('View available \nNIFTI-files in viewer')
        self.btn_viewer.setToolTip(setToolTips.displayFolderContent())
        self.btn_viewer.clicked.connect(self.show_nifti_files)

        self.btn_renaming = QPushButton('Rename\nfolders')
        self.btn_renaming.setToolTip(setToolTips.renameFolders())
        self.btn_renaming.clicked.connect(self.run_rename_folders)

        self.HBoxLowerLeftTab.addWidget(self.btn_subj_details)
        self.HBoxLowerLeftTab.addWidget(self.btn_dcm2nii)
        self.HBoxLowerLeftTab.addWidget(self.btn_viewer)
        self.HBoxLowerLeftTab.addWidget(self.btn_renaming)

        # -------------------- Right part (Subject list)  ----------------------- #
        self.listbox = QGroupBox('Available subjects')
        self.HBoxUpperRightTab = QVBoxLayout(self.listbox)
        self.availableNiftiTab = QListWidget()
        self.availableNiftiTab.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.availableNiftiTab.itemSelectionChanged.connect(
            self.change_list_item)

        itemsTab = FileOperations.list_folders(
            self.niftidir, prefix=self.cfg['folders']['prefix'])
        self.add_available_items(self.availableNiftiTab, itemsTab)
        self.HBoxUpperRightTab.addWidget(self.availableNiftiTab)

        # Combine all Boxes for General Tab Layout
        self.LeftboxTab = QGroupBox()
        self.HBoxTabLeft = QVBoxLayout(self.LeftboxTab)
        self.HBoxTabLeft.addWidget(self.FolderboxTab)
        self.HBoxTabLeft.addStretch()
        self.HBoxTabLeft.addWidget(self.ActionsTab)

        self.tab.layout.addWidget(self.LeftboxTab)
        self.tab.layout.addWidget(self.listbox)

        self.lay.addWidget(self.tab)