Ejemplo n.º 1
0
def test_create_full_ants_subpipes_no_subpipes():

    params = {
        "general": {
            "template_name": "NMT_v2.0_asym"
        },
        "short_preparation_pipe": {
            "bet_crop": {}
        },
        "brain_extraction_pipe": {},
        "brain_segment_pipe": {}
    }

    # params template
    template_name = params["general"]["template_name"]

    template_dir = load_test_data(template_name, data_path)
    params_template = format_template(template_dir, template_name)

    # running workflow
    segment_pnh = create_full_ants_subpipes(
        params=params,
        params_template=params_template,
        name="test_create_full_ants_subpipes_no_subpipes")

    segment_pnh.base_dir = data_path

    segment_pnh.write_graph(graph2use="colored")
    assert op.exists(
        op.join(data_path, "test_create_full_ants_subpipes_no_subpipes",
                "graph.png"))
Ejemplo n.º 2
0
def test_create_full_ants_subpipes():

    params = {
        "general": {
            "template_name": "NMT_v2.0_asym"
        },
        "short_preparation_pipe": {
            "bet_crop": {
                "m": True,
                "aT2": True,
                "c": 10,
                "n": 2
            }
        },
        "brain_extraction_pipe": {
            "correct_bias_pipe": {
                "smooth": {
                    "args": "-bin -s 2"
                },
                "norm_smooth": {
                    "op_string": "-s 2 -div %s"
                },
                "smooth_bias": {
                    "sigma": 2
                }
            },
            "extract_pipe": {
                "atlas_brex": {
                    "f": 0.5,
                    "reg": 1,
                    "wrp": "10,10,10",
                    "msk": "a,0,0",
                    "dil": 2,
                    "nrm": 1
                }
            }
        },
        "brain_segment_pipe": {
            "masked_correct_bias_pipe": {
                "smooth": {
                    "args": "-bin -s 2"
                },
                "norm_smooth": {
                    "op_string": "-s 2 -div %s"
                },
                "smooth_bias": {
                    "sigma": 2
                }
            },
            "register_NMT_pipe": {
                "norm_intensity": {
                    "dimension": 3,
                    "bspline_fitting_distance": 200,
                    "n_iterations": [50, 50, 40, 30],
                    "convergence_threshold": 0.00000001,
                    "shrink_factor": 2,
                    "args": "-r 0 --verbose 1"
                }
            },
            "segment_atropos_pipe": {
                "Atropos": {
                    "dimension": 3,
                    "numberOfClasses": 3
                },
                "threshold_gm": {
                    "thresh": 0.5
                },
                "threshold_wm": {
                    "thresh": 0.5
                },
                "threshold_csf": {
                    "thresh": 0.5
                }
            }
        }
    }

    # params template
    template_name = params["general"]["template_name"]

    template_dir = load_test_data(template_name, data_path)
    params_template = format_template(template_dir, template_name)

    # running workflow
    segment_pnh = create_full_ants_subpipes(
        params=params,
        params_template=params_template,
        name="test_create_full_ants_subpipes")

    segment_pnh.base_dir = data_path

    segment_pnh.write_graph(graph2use="colored")
    assert op.exists(
        op.join(data_path, "test_create_full_ants_subpipes", "graph.png"))
Ejemplo n.º 3
0
def create_main_workflow(data_dir, process_dir, soft, species, subjects, sessions,
                         acquisitions, reconstructions, params_file,
                         indiv_params_file, mask_file, nprocs,
                         wf_name="macapype",
                         deriv=False, pad=False):

    # macapype_pipeline
    """ Set up the segmentatiopn pipeline based on ANTS

    Arguments
    ---------
    data_path: pathlike str
        Path to the BIDS directory that contains anatomical images

    out_path: pathlike str
        Path to the ouput directory (will be created if not alredy existing).
        Previous outputs maybe overwritten.

    soft: str
        Indicate which analysis should be launched; so for, only spm and ants
        are accepted; can be extended

    subjects: list of str (optional)
        Subject's IDs to match to BIDS specification (sub-[SUB1], sub-[SUB2]...)

    sessions: list of str (optional)
        Session's IDs to match to BIDS specification (ses-[SES1], ses-[SES2]...)

    acquisitions: list of str (optional)
        Acquisition name to match to BIDS specification (acq-[ACQ1]...)

    indiv_params_file: path to a JSON file
        JSON file that specify some parameters of the pipeline,
        unique for the subjects/sessions.

    params_file: path to a JSON file
        JSON file that specify some parameters of the pipeline.


    Returns
    -------
    workflow: nipype.pipeline.engine.Workflow


    """

    soft = soft.lower()

    ssoft = soft.split("_")

    new_ssoft = ssoft.copy()
    
    if 'test' in ssoft:
        new_ssoft.remove('test')
        
    if 'prep' in ssoft:
        new_ssoft.remove('prep')
        
    soft = "_".join(new_ssoft)

    # formating args
    data_dir = op.abspath(data_dir)


    try:
        os.makedirs(process_dir)
    except OSError:
        print("process_dir {} already exists".format(process_dir))

    # species
    # params
    params = {}

    if params_file is None:

        if species is not None:

            species = species.lower()

            rep_species = {"marmoset":"marmo", "chimpanzee":"chimp"}

            if species in list(rep_species.keys()):
                species = rep_species[species]

            list_species = ["macaque", "marmo", "baboon", "chimp"]

            assert species in list_species, \
                "Error, species {} should in the following list {}".format(
                    species, list_species)

            package_directory = os.path.dirname(os.path.abspath(__file__))

            params_file = "{}/params_segment_{}_{}.json".format(
                package_directory, species, soft)

        else:
            print("Error, no -params or no -species was found (one or the \
                other is mandatory)")
            exit(-1)

    print("Params:", params_file)

    assert os.path.exists(params_file), "Error with file {}".format(
        params_file)

    params = json.load(open(params_file))

    # indiv_params
    indiv_params = {}

    if indiv_params_file is None:

        print("No indiv params where found, modifing pipepline to default")

        if "short_preparation_pipe" in params.keys():
            if "crop_T1" in params["short_preparation_pipe"].keys():
                print("Deleting crop_T1")
                del params["short_preparation_pipe"]["crop_T1"]

                print("Adding automated bet_crop")

                params["short_preparation_pipe"]["bet_crop"] = {"m": True, "aT2": True, "c": 10, "n": 2}

                print("Using default bet_crop parameters: {}".format(
                    params["short_preparation_pipe"]["bet_crop"]))

                print("New params after modification")
                pprint.pprint(params)

                wf_name+="_bet_crop"

    else:

        assert "short_preparation_pipe" in params.keys(),\
            "Error, short_preparation_pipe not found in params"

        prep_pipe = "short_preparation_pipe"
        count_all_sessions=0
        count_T1_crops=0
        count_long_crops=0
        count_multi_long_crops=0

        print("Indiv Params:", indiv_params_file)

        assert os.path.exists(indiv_params_file), "Error with file {}".format(
            indiv_params_file)

        indiv_params = json.load(open(indiv_params_file))

        wf_name+="_indiv_params"

        pprint.pprint(indiv_params)

        if subjects is None or sessions is None:
            print("For whole BIDS dir, unable to assess if the indiv_params is correct")
            print("Running with params as it is")
            
        else:
                
            print("Will modify params if necessary, given specified subjects and sessions;\n")
            
            for sub in indiv_params.keys():

                if sub.split('-')[1] not in subjects:
                    continue

                for ses in indiv_params[sub].keys():

                    if ses.split('-')[1] not in sessions:
                        continue

                    count_all_sessions+=1

                    print (indiv_params[sub][ses].keys())

                    if "crop_T1" in indiv_params[sub][ses].keys():
                        count_T1_crops+=1

                        if "crop_T2" in indiv_params[sub][ses].keys() \
                            and 't1' not in ssoft:

                            count_long_crops+=1

                            if isinstance(
                                indiv_params[sub][ses]["crop_T1"]["args"],
                                list) and isinstance(
                                    indiv_params[sub][ses]["crop_T2"]["args"],
                                    list):

                                count_multi_long_crops+=1

            print("count_all_sessions {}".format(count_all_sessions))

            print("count_T1_crops {}".format(count_T1_crops))
            print("count_long_crops {}".format(count_long_crops))
            print("count_multi_long_crops {}".format(count_multi_long_crops))

            if count_multi_long_crops==count_all_sessions:
                print("**** Found list of crops for T1 and T2 for all sub/ses \
                    in indiv -> long_multi_preparation_pipe")

                wf_name+="_multi_crop_T1_T2"

                prep_pipe = "long_multi_preparation_pipe"

            elif count_long_crops==count_all_sessions:

                print("**** Found crop for T1 and crop for T2 for all sub/ses \
                    in indiv -> long_single_preparation_pipe")

                wf_name+="_crop_T1_T2"

                prep_pipe = "long_single_preparation_pipe"

            elif count_T1_crops==count_all_sessions:

                print("**** Found crop for T1 for all sub/ses in indiv \
                    -> keeping short_preparation_pipe")

                wf_name+="_crop_T1"

            else:
                print("**** not all sub/ses have T1 and T2 crops ")
                print("Error")
                exit(0)

            if prep_pipe != "short_preparation_pipe":

                params[prep_pipe]={
                    "prep_T1": {"crop_T1": {"args": "should be defined in indiv"}},
                    "prep_T2": {"crop_T2": {"args": "should be defined in indiv"}},
                    "align_T2_on_T1": {"dof": 6, "cost": "normmi"}}

                if "norm_intensity" in params["short_preparation_pipe"].keys():
                    norm_intensity= params["short_preparation_pipe"]["norm_intensity"]

                    params[prep_pipe]["prep_T1"]["norm_intensity"]=norm_intensity
                    params[prep_pipe]["prep_T2"]["norm_intensity"]=norm_intensity


                if "denoise" in params["short_preparation_pipe"].keys():
                    denoise= params["short_preparation_pipe"]["denoise"]

                    params[prep_pipe]["prep_T1"]["denoise"]=denoise
                    params[prep_pipe]["prep_T2"]["denoise"]=denoise

                del params["short_preparation_pipe"]


    # prep for testing only preparation part
    if "prep" in ssoft:
        print("Found prep in soft")
        
        if "brain_extraction_pipe" in params.keys():
            del params["brain_extraction_pipe"]
            print("Deleting brain_extraction_pipe")
        
            
        if "brain_segment_pipe" in params.keys():
            del params["brain_segment_pipe"]
            print("Deleting brain_segment_pipe")
            
    pprint.pprint(params)
            
    # params_template
    assert ("general" in params.keys() and \
        "template_name" in params["general"].keys()), \
            "Error, the params.json should contains a general/template_name"

    template_name = params["general"]["template_name"]

    if "general" in params.keys() and "my_path" in params["general"].keys():
        my_path = params["general"]["my_path"]
    else:
        my_path = ""

    nmt_dir = load_test_data(template_name, path_to = my_path)
    params_template = format_template(nmt_dir, template_name)
    print (params_template)

    # soft
    wf_name += "_{}".format(soft)

    if mask_file is not None:
         wf_name += "_mask"

    assert "spm" in ssoft or "spm12" in ssoft or "ants" in ssoft, \
        "error with {}, should be among [spm12, spm, ants]".format(ssoft)

    # main_workflow
    main_workflow = pe.Workflow(name= wf_name)

    main_workflow.base_dir = process_dir

    if "spm" in ssoft or "spm12" in ssoft:
        if 'native' in ssoft:
            space='native'
        else:
            space='template'

        segment_pnh_pipe = create_full_spm_subpipes(
            params_template=params_template, params=params, pad=pad,
            space=space)

    elif "ants" in ssoft:
        if "template" in ssoft:
            space="template"
        else:
            space="native"

        if "t1" in ssoft:
            segment_pnh_pipe = create_full_T1_ants_subpipes(
                params_template=params_template, params=params, space=space,
                pad=pad)
        else:
            segment_pnh_pipe = create_full_ants_subpipes(
                params_template=params_template, params=params,
                mask_file=mask_file, space=space, pad=pad)

    # list of all required outputs
    output_query = {}

    # T1 (mandatory, always added)
    output_query['T1'] = {
            "datatype": "anat", "suffix": "T1w",
            "extension": ["nii", ".nii.gz"]
        }

    # T2 is optional, if "_T1" is added in the -soft arg
    if not 't1' in ssoft:
        output_query['T2'] = {
            "datatype": "anat", "suffix": "T2w",
            "extension": ["nii", ".nii.gz"]}

    # FLAIR is optional, if "_FLAIR" is added in the -soft arg
    if 'flair' in ssoft:
        output_query['FLAIR'] = {
            "datatype": "anat", "suffix": "FLAIR",
            "extension": ["nii", ".nii.gz"]}

    # MD and b0mean are optional, if "_MD" is added in the -soft arg
    if 'md' in ssoft:
        output_query['MD'] =  {
            "datatype": "dwi", "acquisition": "MD", "suffix": "dwi",
            "extension": ["nii", ".nii.gz"]}

        output_query['b0mean'] = {
            "datatype": "dwi", "acquisition": "b0mean", "suffix": "dwi",
            "extension": ["nii", ".nii.gz"]}

    # indiv_params
    if indiv_params:
        datasource = create_datasource_indiv_params(
            output_query, data_dir, indiv_params, subjects, sessions,
            acquisitions, reconstructions)

        main_workflow.connect(datasource, "indiv_params",
                              segment_pnh_pipe,'inputnode.indiv_params')
    else:
        datasource = create_datasource(
            output_query, data_dir, subjects,  sessions, acquisitions,
            reconstructions)

    main_workflow.connect(datasource, 'T1',
                          segment_pnh_pipe, 'inputnode.list_T1')

    if not "t1" in ssoft:
        main_workflow.connect(datasource, 'T2', 
                              segment_pnh_pipe, 'inputnode.list_T2')
    elif "t1" in ssoft and "spm" in ssoft:
        # cheating using T2 as T1
        main_workflow.connect(datasource, 'T1',
                              segment_pnh_pipe, 'inputnode.list_T2')

    if "flair" in ssoft:

        transfo_FLAIR_pipe = create_transfo_FLAIR_pipe(params=params,
                                        params_template=params_template)

        if "t1" in ssoft:
            main_workflow.connect(segment_pnh_pipe, "short_preparation_pipe.outputnode.preproc_T1",
                                transfo_FLAIR_pipe, 'inputnode.orig_T1')

        else:
            main_workflow.connect(segment_pnh_pipe, "debias.t1_debiased_file",
                                transfo_FLAIR_pipe, 'inputnode.orig_T1')


        main_workflow.connect(segment_pnh_pipe, "reg.transfo_file",
                              transfo_FLAIR_pipe, 'inputnode.lin_transfo_file')

        main_workflow.connect(datasource, ('FLAIR', get_first_elem),
                              transfo_FLAIR_pipe, 'inputnode.FLAIR')

    if 'md' in ssoft:

        transfo_MD_pipe = create_transfo_MD_pipe(params=params,
                                        params_template=params_template)

        main_workflow.connect(segment_pnh_pipe,
                                "old_segment_pipe.outputnode.threshold_wm",
                                transfo_MD_pipe, 'inputnode.threshold_wm')

        main_workflow.connect(datasource, ('MD', get_first_elem),
                                transfo_MD_pipe, 'inputnode.MD')

        main_workflow.connect(datasource, ('b0mean', get_first_elem),
                                transfo_MD_pipe, 'inputnode.b0mean')

        main_workflow.connect(segment_pnh_pipe, "debias.t1_debiased_file",
                            transfo_MD_pipe, 'inputnode.orig_T1')

        main_workflow.connect(segment_pnh_pipe, "debias.t2_debiased_brain_file",
                            transfo_MD_pipe, 'inputnode.SS_T2')

        main_workflow.connect(segment_pnh_pipe, "reg.transfo_file",
                            transfo_MD_pipe, 'inputnode.lin_transfo_file')

        main_workflow.connect(segment_pnh_pipe, "reg.inv_transfo_file",
                            transfo_MD_pipe, 'inputnode.inv_lin_transfo_file')

    if deriv:

        datasink_name = os.path.join("derivatives", "macapype_" + soft)

        if "regex_subs" in params.keys():
            params_regex_subs = params["regex_subs"]
        else:
            params_regex_subs={}

        if "subs" in params.keys():
            params_subs = params["rsubs"]
        else:
            params_subs={}

        datasink = create_datasink(iterables=datasource.iterables,
                                   name=datasink_name,
                                   params_subs=params_subs,
                                   params_regex_subs=params_regex_subs)

        datasink.inputs.base_directory = process_dir

        main_workflow.connect(
            segment_pnh_pipe, 'outputnode.brain_mask',
            datasink, '@brain_mask')

        main_workflow.connect(
            segment_pnh_pipe, 'outputnode.segmented_brain_mask',
            datasink, '@segmented_brain_mask')

        if 'flair' in ssoft :

            main_workflow.connect(
                transfo_FLAIR_pipe, 'outputnode.norm_FLAIR',
                datasink, '@norm_flair')

    main_workflow.write_graph(graph2use="colored")
    main_workflow.config['execution'] = {'remove_unnecessary_outputs': 'false'}

    if nprocs is None:
        nprocs = 4

    if not "test" in ssoft:
        if "seq" in ssoft or nprocs==0:
            main_workflow.run()
        else:
            main_workflow.run(plugin='MultiProc',
                              plugin_args={'n_procs' : nprocs})