Example #1
0
 def test_genenerated_method_pickle_fail(self):
     cls_dct = {
         'add_sub_study_specs': [
             SubStudySpec('ss1', BasicTestClass),
             SubStudySpec('ss2', BasicTestClass)
         ],
         'default_fileset_pipeline':
         MultiStudy.translate('ss1', 'pipeline')
     }
     MultiGeneratedClass = MultiStudyMetaClass('MultiGeneratedClass',
                                               (MultiStudy, ), cls_dct)
     study = self.create_study(MultiGeneratedClass,
                               'multi_gen_cls',
                               inputs=[
                                   FilesetSelector('ss1_fileset',
                                                   text_format, 'fileset'),
                                   FilesetSelector('ss2_fileset',
                                                   text_format, 'fileset')
                               ])
     pkl_path = os.path.join(self.work_dir, 'multi_gen_cls.pkl')
     with open(pkl_path, 'w') as f:
         self.assertRaises(ArcanaCantPickleStudyError, pkl.dump, study, f)
Example #2
0
 def test_multi_study_generated_cls_pickle(self):
     cls_dct = {
         'add_sub_study_specs': [
             SubStudySpec('ss1', BasicTestClass),
             SubStudySpec('ss2', BasicTestClass)
         ]
     }
     MultiGeneratedClass = MultiStudyMetaClass('MultiGeneratedClass',
                                               (MultiStudy, ), cls_dct)
     study = self.create_study(MultiGeneratedClass,
                               'multi_gen_cls',
                               inputs=[
                                   FilesetSelector('ss1_fileset',
                                                   text_format, 'fileset'),
                                   FilesetSelector('ss2_fileset',
                                                   text_format, 'fileset')
                               ])
     pkl_path = os.path.join(self.work_dir, 'multi_gen_cls.pkl')
     with open(pkl_path, 'wb') as f:
         pkl.dump(study, f)
     del MultiGeneratedClass
     with open(pkl_path, 'rb') as f:
         regen = pkl.load(f)
     self.assertContentsEqual(regen.data('ss2_out_fileset'), 'foo')
Example #3
0
def create_fmri_study_class(name,
                            t1,
                            epis,
                            epi_number,
                            echo_spacing,
                            fm_mag=None,
                            fm_phase=None,
                            run_regression=False):

    inputs = []
    dct = {}
    data_specs = []
    parameter_specs = []
    output_files = []
    distortion_correction = False

    if fm_mag and fm_phase:
        logger.info('Both magnitude and phase field map images provided. EPI '
                    'ditortion correction will be performed.')
        distortion_correction = True
    elif fm_mag or fm_phase:
        logger.info(
            'In order to perform EPI ditortion correction both magnitude '
            'and phase field map images must be provided.')
    else:
        logger.info(
            'No field map image provided. Distortion correction will not be'
            'performed.')

    study_specs = [SubStudySpec('t1', T1Study)]
    ref_spec = {'t1_brain': 'coreg_ref_brain'}
    inputs.append(
        DatasetMatch('t1_primary', dicom_format, t1, is_regex=True, order=0))
    epi_refspec = ref_spec.copy()
    epi_refspec.update({
        't1_wm_seg': 'coreg_ref_wmseg',
        't1_preproc': 'coreg_ref_preproc',
        'train_data': 'train_data'
    })
    study_specs.append(SubStudySpec('epi_0', FunctionalMRIStudy, epi_refspec))
    if epi_number > 1:
        epi_refspec.update({
            't1_wm_seg': 'coreg_ref_wmseg',
            't1_preproc': 'coreg_ref_preproc',
            'train_data': 'train_data',
            'epi_0_coreg_to_atlas_warp': 'coreg_to_atlas_warp',
            'epi_0_coreg_to_atlas_mat': 'coreg_to_atlas_mat'
        })
        study_specs.extend(
            SubStudySpec('epi_{}'.format(i), FunctionalMRIStudy, epi_refspec)
            for i in range(1, epi_number))

    for i in range(epi_number):
        inputs.append(
            DatasetMatch('epi_{}_primary'.format(i),
                         dicom_format,
                         epis,
                         order=i,
                         is_regex=True))
        parameter_specs.append(
            ParameterSpec('epi_{}_fugue_echo_spacing'.format(i), echo_spacing))

    if distortion_correction:
        inputs.extend(
            DatasetMatch('epi_{}_field_map_mag'.format(i),
                         dicom_format,
                         fm_mag,
                         dicom_tags={IMAGE_TYPE_TAG: MAG_IMAGE_TYPE},
                         is_regex=True,
                         order=0) for i in range(epi_number))
        inputs.extend(
            DatasetMatch('epi_{}_field_map_phase'.format(i),
                         dicom_format,
                         fm_phase,
                         dicom_tags={IMAGE_TYPE_TAG: PHASE_IMAGE_TYPE},
                         is_regex=True,
                         order=0) for i in range(epi_number))
    if run_regression:
        output_files.extend('epi_{}_smoothed_ts'.format(i)
                            for i in range(epi_number))
    else:
        output_files.extend('epi_{}_fix_dir'.format(i)
                            for i in range(epi_number))

    dct['add_sub_study_specs'] = study_specs
    dct['add_data_specs'] = data_specs
    dct['add_parameter_specs'] = parameter_specs
    dct['__metaclass__'] = MultiStudyMetaClass
    return (MultiStudyMetaClass(name, (FunctionalMRIMixin, ),
                                dct), inputs, output_files)
Example #4
0
def create_motion_detection_class(name,
                                  ref=None,
                                  ref_type=None,
                                  t1s=None,
                                  t2s=None,
                                  dwis=None,
                                  epis=None,
                                  pet_data_dir=None):

    inputs = []
    dct = {}
    data_specs = []
    run_pipeline = False
    param_specs = [ParamSpec('ref_resampled_resolution', [1])]

    if pet_data_dir is not None:
        inputs.append(
            InputFilesets('pet_data_dir', 'pet_data_dir', directory_format))

    if not ref:
        raise Exception('A reference image must be provided!')
    if ref_type == 't1':
        ref_study = T1Study
    elif ref_type == 't2':
        ref_study = T2Study
    else:
        raise Exception('{} is not a recognized ref_type!The available '
                        'ref_types are t1 or t2.'.format(ref_type))

    study_specs = [SubStudySpec('ref', ref_study)]
    ref_spec = {'coreg_ref_brain': 'ref_brain'}
    inputs.append(InputFilesets('ref_magnitude', ref, dicom_format))

    if t1s:
        study_specs.extend([
            SubStudySpec('t1_{}'.format(i), T1Study, ref_spec)
            for i in range(len(t1s))
        ])
        inputs.extend(
            InputFilesets('t1_{}_magnitude'.format(i), t1_scan, dicom_format)
            for i, t1_scan in enumerate(t1s))
        run_pipeline = True

    if t2s:
        study_specs.extend([
            SubStudySpec('t2_{}'.format(i), T2Study, ref_spec)
            for i in range(len(t2s))
        ])
        inputs.extend(
            InputFilesets('t2_{}_magnitude'.format(i), t2_scan, dicom_format)
            for i, t2_scan in enumerate(t2s))
        run_pipeline = True

    if epis:
        epi_refspec = ref_spec.copy()
        epi_refspec.update({
            'coreg_ref_wmseg': 'ref_wm_seg',
            'coreg_ref': 'ref_mag_preproc'
        })
        study_specs.extend(
            SubStudySpec('epi_{}'.format(i), EpiSeriesStudy, epi_refspec)
            for i in range(len(epis)))
        inputs.extend(
            InputFilesets('epi_{}_series'.format(i), epi_scan, dicom_format)
            for i, epi_scan in enumerate(epis))
        run_pipeline = True
    if dwis:
        unused_dwi = []
        dwis_main = [x for x in dwis if x[-1] == '0']
        dwis_ref = [x for x in dwis if x[-1] == '1']
        dwis_opposite = [x for x in dwis if x[-1] == '-1']
        b0_refspec = ref_spec.copy()
        b0_refspec.update({
            'coreg_ref_wmseg': 'ref_wm_seg',
            'coreg_ref': 'ref_mag_preproc'
        })
        if dwis_main and not dwis_opposite:
            logger.warning(
                'No opposite phase encoding direction b0 provided. DWI '
                'motion correction will be performed without distortion '
                'correction. THIS IS SUB-OPTIMAL!')
            study_specs.extend(
                SubStudySpec('dwi_{}'.format(i), DwiStudy, ref_spec)
                for i in range(len(dwis_main)))
            inputs.extend(
                InputFilesets('dwi_{}_series'.format(i), dwis_main_scan[0],
                              dicom_format)
                for i, dwis_main_scan in enumerate(dwis_main))
        if dwis_main and dwis_opposite:
            study_specs.extend(
                SubStudySpec('dwi_{}'.format(i), DwiStudy, ref_spec)
                for i in range(len(dwis_main)))
            inputs.extend(
                InputFilesets('dwi_{}_series'.format(i), dwis_main[i][0],
                              dicom_format) for i in range(len(dwis_main)))
            if len(dwis_main) <= len(dwis_opposite):
                inputs.extend(
                    InputFilesets('dwi_{}_magnitude'.format(i),
                                  dwis_opposite[i][0], dicom_format)
                    for i in range(len(dwis_main)))
            else:
                inputs.extend(
                    InputFilesets('dwi_{}_magnitude'.format(i),
                                  dwis_opposite[0][0], dicom_format)
                    for i in range(len(dwis_main)))
        if dwis_opposite and dwis_main and not dwis_ref:
            study_specs.extend(
                SubStudySpec('b0_{}'.format(i), DwiRefStudy, b0_refspec)
                for i in range(len(dwis_opposite)))
            inputs.extend(
                InputFilesets('b0_{}_magnitude'.format(i), dwis_opposite[i][0],
                              dicom_format) for i in range(len(dwis_opposite)))
            if len(dwis_opposite) <= len(dwis_main):
                inputs.extend(
                    InputFilesets('b0_{}_reverse_phase'.format(i), dwis_main[i]
                                  [0], dicom_format)
                    for i in range(len(dwis_opposite)))
            else:
                inputs.extend(
                    InputFilesets('b0_{}_reverse_phase'.format(i), dwis_main[0]
                                  [0], dicom_format)
                    for i in range(len(dwis_opposite)))
        elif dwis_opposite and dwis_ref:
            min_index = min(len(dwis_opposite), len(dwis_ref))
            study_specs.extend(
                SubStudySpec('b0_{}'.format(i), DwiRefStudy, b0_refspec)
                for i in range(min_index * 2))
            inputs.extend(
                InputFilesets('b0_{}_magnitude'.format(i), scan[0],
                              dicom_format)
                for i, scan in enumerate(dwis_opposite[:min_index] +
                                         dwis_ref[:min_index]))
            inputs.extend(
                InputFilesets('b0_{}_reverse_phase'.format(i), scan[0],
                              dicom_format)
                for i, scan in enumerate(dwis_ref[:min_index] +
                                         dwis_opposite[:min_index]))
            unused_dwi = [
                scan
                for scan in dwis_ref[min_index:] + dwis_opposite[min_index:]
            ]
        elif dwis_opposite or dwis_ref:
            unused_dwi = [scan for scan in dwis_ref + dwis_opposite]
        if unused_dwi:
            logger.info(
                'The following scans:\n{}\nwere not assigned during the DWI '
                'motion detection initialization (probably a different number '
                'of main DWI scans and b0 images was provided). They will be '
                'processed os "other" scans.'.format('\n'.join(
                    s[0] for s in unused_dwi)))
            study_specs.extend(
                SubStudySpec('t2_{}'.format(i), T2Study, ref_spec)
                for i in range(len(t2s),
                               len(t2s) + len(unused_dwi)))
            inputs.extend(
                InputFilesets('t2_{}_magnitude'.format(i), scan[0],
                              dicom_format)
                for i, scan in enumerate(unused_dwi, start=len(t2s)))
        run_pipeline = True

    if not run_pipeline:
        raise Exception('At least one scan, other than the reference, must be '
                        'provided!')

    dct['add_substudy_specs'] = study_specs
    dct['add_data_specs'] = data_specs
    dct['__metaclass__'] = MultiStudyMetaClass
    dct['add_param_specs'] = param_specs
    return MultiStudyMetaClass(name, (MotionDetectionMixin, ), dct), inputs
Example #5
0
def create_motion_correction_class(name,
                                   ref=None,
                                   ref_type=None,
                                   t1s=None,
                                   t2s=None,
                                   dwis=None,
                                   epis=None,
                                   umap=None,
                                   dynamic=False,
                                   umap_ref=None,
                                   pet_data_dir=None,
                                   pet_recon_dir=None,
                                   struct2align=None):

    inputs = []
    dct = {}
    data_specs = []
    run_pipeline = False
    param_specs = [ParamSpec('ref_resampled_resolution', [1])]
    switch_specs = []
    if struct2align is not None:
        struct_image = struct2align.split('/')[-1].split('.')[0]

    if pet_data_dir is not None:
        inputs.append(
            InputFilesets('pet_data_dir', 'pet_data_dir', directory_format))
    if pet_recon_dir is not None:
        inputs.append(
            InputFilesets('pet_data_reconstructed', 'pet_data_reconstructed',
                          directory_format))
        if struct2align is not None:
            inputs.append(
                InputFilesets('struct2align', struct_image, nifti_gz_format))
    if pet_data_dir is not None and pet_recon_dir is not None and dynamic:
        output_data = 'dynamic_motion_correction_results'
        param_specs.append(ParamSpec('dynamic_pet_mc', True))
        if struct2align is not None:
            inputs.append(
                InputFilesets('struct2align', struct_image, nifti_gz_format))
    elif (pet_recon_dir is not None and not dynamic):
        output_data = 'static_motion_correction_results'
    else:
        output_data = 'motion_detection_output'

    if not ref:
        raise Exception('A reference image must be provided!')
    if ref_type == 't1':
        ref_study = T1Study
    elif ref_type == 't2':
        ref_study = T2Study
    else:
        raise Exception('{} is not a recognized ref_type!The available '
                        'ref_types are t1 or t2.'.format(ref_type))

    study_specs = [SubStudySpec('ref', ref_study)]
    ref_spec = {'ref_brain': 'coreg_ref_brain'}
    inputs.append(InputFilesets('ref_primary', ref, dicom_format))

    if umap_ref and umap:
        if umap_ref.endswith('/'):
            umap_ref = umap_ref.split('/')[-2]
        else:
            umap_ref = umap_ref.split('/')[-1]
        if umap_ref in t1s:
            umap_ref_study = T1Study
            t1s.remove(umap_ref)
        elif umap_ref in t2s:
            umap_ref_study = T2Study
            t2s.remove(umap_ref)
        else:
            umap_ref = None

    if t1s:
        study_specs.extend([
            SubStudySpec('t1_{}'.format(i), T1Study, ref_spec)
            for i in range(len(t1s))
        ])
        inputs.extend(
            InputFilesets('t1_{}_primary'.format(i), dicom_format, t1_scan)
            for i, t1_scan in enumerate(t1s))
        run_pipeline = True

    if t2s:
        study_specs.extend([
            SubStudySpec('t2_{}'.format(i), T2Study, ref_spec)
            for i in range(len(t2s))
        ])
        inputs.extend(
            InputFilesets('t2_{}_primary'.format(i), t2_scan, dicom_format)
            for i, t2_scan in enumerate(t2s))
        run_pipeline = True

    if umap_ref and not umap:
        logger.info(
            'Umap not provided. The umap realignment will not be '
            'performed. Umap_ref will be trated as {}'.format(umap_ref_study))

    elif umap_ref and umap:
        logger.info('Umap will be realigned to match the head position in '
                    'each frame.')
        if type(umap) == list and len(umap) > 1:
            logger.info('More than one umap provided. Only the first one will '
                        'be used.')
            umap = umap[0]
        study_specs.append(SubStudySpec('umap_ref', umap_ref_study, ref_spec))
        inputs.append(InputFilesets('umap_ref_primary', dicom_format,
                                    umap_ref))
        inputs.append(InputFilesets('umap', dicom_format, umap))

        run_pipeline = True

    elif not umap_ref and umap:
        logger.warning('Umap provided without corresponding reference image. '
                       'Realignment cannot be performed without umap_ref. Umap'
                       ' will be ignored.')

    if epis:
        epi_refspec = ref_spec.copy()
        epi_refspec.update({
            'ref_wm_seg': 'coreg_ref_wmseg',
            'ref_preproc': 'coreg_ref'
        })
        study_specs.extend(
            SubStudySpec('epi_{}'.format(i), EpiSeriesStudy, epi_refspec)
            for i in range(len(epis)))
        inputs.extend(
            InputFilesets('epi_{}_primary'.format(i), epi_scan, dicom_format)
            for i, epi_scan in enumerate(epis))
        run_pipeline = True
    if dwis:
        unused_dwi = []
        dwis_main = [x for x in dwis if x[-1] == '0']
        dwis_ref = [x for x in dwis if x[-1] == '1']
        dwis_opposite = [x for x in dwis if x[-1] == '-1']
        dwi_refspec = ref_spec.copy()
        dwi_refspec.update({
            'ref_wm_seg': 'coreg_ref_wmseg',
            'ref_preproc': 'coreg_ref'
        })
        if dwis_main:
            switch_specs.extend(
                SwitchSpec('dwi_{}_brain_extract_method'.format(i), 'fsl', (
                    'mrtrix', 'fsl')) for i in range(len(dwis_main)))
        if dwis_main and not dwis_opposite:
            logger.warning(
                'No opposite phase encoding direction b0 provided. DWI '
                'motion correction will be performed without distortion '
                'correction. THIS IS SUB-OPTIMAL!')
            study_specs.extend(
                SubStudySpec('dwi_{}'.format(i), DwiStudy, dwi_refspec)
                for i in range(len(dwis_main)))
            inputs.extend(
                InputFilesets('dwi_{}_primary'.format(i), dwis_main_scan[0],
                              dicom_format)
                for i, dwis_main_scan in enumerate(dwis_main))
        if dwis_main and dwis_opposite:
            study_specs.extend(
                SubStudySpec('dwi_{}'.format(i), DwiStudy, dwi_refspec)
                for i in range(len(dwis_main)))
            inputs.extend(
                InputFilesets('dwi_{}_primary'.format(i), dwis_main[i][0],
                              dicom_format) for i in range(len(dwis_main)))
            if len(dwis_main) <= len(dwis_opposite):
                inputs.extend(
                    InputFilesets('dwi_{}_dwi_reference'.format(i),
                                  dwis_opposite[i][0], dicom_format)
                    for i in range(len(dwis_main)))
            else:
                inputs.extend(
                    InputFilesets('dwi_{}_dwi_reference'.format(i),
                                  dwis_opposite[0][0], dicom_format)
                    for i in range(len(dwis_main)))
        if dwis_opposite and dwis_main and not dwis_ref:
            study_specs.extend(
                SubStudySpec('b0_{}'.format(i), EpiSeriesStudy, dwi_refspec)
                for i in range(len(dwis_opposite)))
            inputs.extend(
                InputFilesets('b0_{}_primary'.format(i), dwis_opposite[i][0],
                              dicom_format) for i in range(len(dwis_opposite)))
            if len(dwis_opposite) <= len(dwis_main):
                inputs.extend(
                    InputFilesets('b0_{}_reverse_phase'.format(i), dwis_main[i]
                                  [0], dicom_format)
                    for i in range(len(dwis_opposite)))
            else:
                inputs.extend(
                    InputFilesets('b0_{}_reverse_phase'.format(i), dwis_main[0]
                                  [0], dicom_format)
                    for i in range(len(dwis_opposite)))
        elif dwis_opposite and dwis_ref:
            min_index = min(len(dwis_opposite), len(dwis_ref))
            study_specs.extend(
                SubStudySpec('b0_{}'.format(i), EpiSeriesStudy, dwi_refspec)
                for i in range(min_index * 2))
            inputs.extend(
                InputFilesets('b0_{}_primary'.format(i), scan[0], dicom_format)
                for i, scan in enumerate(dwis_opposite[:min_index] +
                                         dwis_ref[:min_index]))
            inputs.extend(
                InputFilesets('b0_{}_reverse_phase'.format(i), scan[0],
                              dicom_format)
                for i, scan in enumerate(dwis_ref[:min_index] +
                                         dwis_opposite[:min_index]))
            unused_dwi = [
                scan
                for scan in dwis_ref[min_index:] + dwis_opposite[min_index:]
            ]
        elif dwis_opposite or dwis_ref:
            unused_dwi = [scan for scan in dwis_ref + dwis_opposite]
        if unused_dwi:
            logger.info(
                'The following scans:\n{}\nwere not assigned during the DWI '
                'motion detection initialization (probably a different number '
                'of main DWI scans and b0 images was provided). They will be '
                'processed os "other" scans.'.format('\n'.join(
                    s[0] for s in unused_dwi)))
            study_specs.extend(
                SubStudySpec('t2_{}'.format(i), T2Study, ref_spec)
                for i in range(len(t2s),
                               len(t2s) + len(unused_dwi)))
            inputs.extend(
                InputFilesets('t2_{}_primary'.format(i), scan[0], dicom_format)
                for i, scan in enumerate(unused_dwi, start=len(t2s)))
        run_pipeline = True

    if not run_pipeline:
        raise Exception('At least one scan, other than the reference, must be '
                        'provided!')

    dct['add_substudy_specs'] = study_specs
    dct['add_data_specs'] = data_specs
    dct['__metaclass__'] = MultiStudyMetaClass
    dct['add_param_specs'] = param_specs
    dct['add_switch_specs'] = switch_specs
    return (MultiStudyMetaClass(name, (MotionDetectionMixin, ),
                                dct), inputs, output_data)