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)
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')
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)
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
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)