Example #1
0
def create_workflow(config, resource_pool, context):
    func = PythonJob(function=lambda x: {
        'y': x
    })
    func.x = Resource(config['msg'])
    resource_pool['T1w'] = func.y
    return 'test'
Example #2
0
def lesion_preproc(lesion_mask: str):
    lesion_deoblique = NipypeJob(interface=afni.Refit(deoblique=True),
                                 reference='lesion_deoblique')
    lesion_inverted = PythonJob(function=inverse_lesion,
                                reference='inverse_lesion')
    lesion_reorient = NipypeJob(interface=afni.Resample(orientation='RPI',
                                                        outputtype='NIFTI_GZ'),
                                reference='lesion_reorient')

    lesion_inverted.lesion_path = S3Resource(lesion_mask) if lesion_mask.lower(
    ).startswith('s3://') else lesion_mask
    lesion_deoblique.in_file = lesion_inverted.lesion_out
    lesion_reorient.in_file = lesion_deoblique.out_file
    return lesion_reorient.out_file
Example #3
0
    def test_parallel(self):

        wait = 3

        rp = ResourcePool()

        delayed1 = PythonJob(function=timestamp, reference='time1')
        delayed1.delay = Resource(wait)
        rp[R('T1w', label='time1')] = delayed1.time

        delayed2 = PythonJob(function=timestamp, reference='time2')
        delayed2.delay = Resource(wait)
        rp[R('T1w', label='time2')] = delayed2.time

        res_rp = DependencySolver(rp).execute(executor=DaskExecution())

        self.assertIn(R('label-time1_T1w'), res_rp)
        self.assertIn(R('label-time2_T1w'), res_rp)

        time1 = res_rp[R('label-time1_T1w')].content
        time2 = res_rp[R('label-time2_T1w')].content

        # To ensure parallelism, both tasks should be run 'at the same time'
        #  so the difference between their finish time execution will be
        #  lesser than the time each one took to compute
        self.assertLess(time1 - time2, wait)

        res_rp = DependencySolver(rp).execute(executor=Execution())

        self.assertIn(R('label-time1_T1w'), res_rp)
        self.assertIn(R('label-time2_T1w'), res_rp)

        time1 = res_rp[R('label-time1_T1w')].content
        time2 = res_rp[R('label-time2_T1w')].content

        self.assertGreaterEqual(abs(time1 - time2), wait)
Example #4
0
def create_workflow(config: AttrDict, resource_pool: ResourcePool,
                    context: Context):
    for _, rp in resource_pool[['label-reorient_T1w', 'brain']]:
        calculate_ants_warp = PythonJob(function=hardcoded_reg,
                                        reference='calc_ants_warp')
        # calculate_ants_warp.interface.num_threads = num_threads
        select_forward_initial = PythonJob(function=seperate_warps_list,
                                           reference='select_forward_initial')
        select_forward_initial.selection = "Initial"

        select_forward_rigid = PythonJob(function=seperate_warps_list,
                                         reference='select_forward_rigid')
        select_forward_rigid.selection = "Rigid"

        select_forward_affine = PythonJob(function=seperate_warps_list,
                                          reference='select_forward_affine')
        select_forward_affine.selection = "Affine"

        select_forward_warp = PythonJob(function=seperate_warps_list,
                                        reference='select_forward_warp')
        select_forward_warp.selection = "Warp"

        select_inverse_warp = PythonJob(function=seperate_warps_list,
                                        reference='select_inverse_warp')
        select_inverse_warp.selection = "Inverse"

        calculate_ants_warp.interp = config.interpolation
        calculate_ants_warp.ants_para = config.params

        if config.use_lesion_mask:
            calculate_ants_warp.fixed_image_mask = lesion_preproc(
                config.lesion_mask_path)
        else:
            calculate_ants_warp.fixed_image_mask = None

        calculate_ants_warp.moving_brain = rp[R('brain')].content
        calculate_ants_warp.reference_brain = config.template_brain

        if config.reg_with_skull:
            calculate_ants_warp.reference_skull = config.template_skull
            calculate_ants_warp.moving_skull = rp[R('T1w', label='reorient')]
        else:
            calculate_ants_warp.moving_skull = rp[R('brain')].content
            calculate_ants_warp.reference_skull = config.template_brain

        # inter-workflow connections
        select_forward_initial.warp_list = calculate_ants_warp.warp_list
        select_forward_rigid.warp_list = calculate_ants_warp.warp_list
        select_forward_affine.warp_list = calculate_ants_warp.warp_list
        select_forward_warp.warp_list = calculate_ants_warp.warp_list
        select_inverse_warp.warp_list = calculate_ants_warp.warp_list

        # connections to outputspec
        #
        # outputspec.ants_initial_xfm = select_forward_initial.selected_warp
        #
        # outputspec.ants_rigid_xfm = select_forward_rigid.selected_warp
        #
        # outputspec.ants_affine_xfm = select_forward_affine.selected_warp
        #
        # outputspec.warp_field = select_forward_warp.selected_warp
        #
        # outputspec.inverse_warp_field = select_inverse_warp.selected_warp

        rp[R('brain', space='MNI')] = calculate_ants_warp.warped_image
Example #5
0
    def test_initial(self):

        for strat, srp in self.rp[['T1w']]:
            anatomical_image = srp[R('T1w')]

            file_basename = PythonJob(function=basename)
            file_basename.path = anatomical_image
            srp[R('T1w', label='base')] = file_basename.path
            srp[R('T1w', label='dir')] = file_basename.dirname

            file_reversed = PythonJob(function=reversed_string)
            file_reversed.path = file_basename.path
            srp[R('T1w', label='baserev')] = file_reversed.reversed

            filename_subject_id = PythonJob(function=subject_id)
            filename_subject_id.filename = file_basename.path
            srp[R('T1w', label='sub')] = filename_subject_id.sub

            file_join_path = PythonJob(function=join_path)
            file_join_path.dirname = file_basename.dirname
            file_join_path.base = file_reversed.reversed
            srp[R('T1w', label='crazypath')] = file_join_path.path

        for executor in executors[1:]:
            res_rp = DependencySolver(self.rp).execute(executor=executor())

            self.assertIn(R('sub-A00008326_ses-BAS1_label-base_T1w'), res_rp)
            self.assertEqual(res_rp[R('sub-A00008326_ses-BAS1_label-base_T1w')].content, A00008326_base)
            self.assertEqual(res_rp[R('sub-A00008326_ses-BAS1_label-baserev_T1w')].content, A00008326_base[::-1])
            self.assertEqual(res_rp[R('sub-A00008326_ses-BAS1_label-sub_T1w')].content, 'sub-A00008326')
            self.assertEqual(res_rp[R('sub-A00008326_ses-BAS1_label-crazypath_T1w')].content,
                             f'{A00008326_dir}/{A00008326_base[::-1]}')

            self.assertIn(R('sub-A00008399_ses-BAS1_label-base_T1w'), res_rp)
            self.assertEqual(res_rp[R('sub-A00008399_ses-BAS1_label-base_T1w')].content, A00008399_base)
            self.assertEqual(res_rp[R('sub-A00008399_ses-BAS1_label-baserev_T1w')].content, A00008399_base[::-1])
            self.assertEqual(res_rp[R('sub-A00008399_ses-BAS1_label-sub_T1w')].content, 'sub-A00008399')
            self.assertEqual(res_rp[R('sub-A00008399_ses-BAS1_label-crazypath_T1w')].content,
                             f'{A00008399_dir}/{A00008399_base[::-1]}')
Example #6
0
    def test_cycle(self):

        rp = ResourcePool()

        file_basename1 = PythonJob(function=basename, reference='basename1')
        file_basename2 = PythonJob(function=basename, reference='basename2')
        file_basename3 = PythonJob(function=basename, reference='basename3')
        file_basename2.path = file_basename1.path
        file_basename3.path = file_basename2.path
        file_basename1.path = file_basename3.path

        rp[R('T1w')] = file_basename1.path

        with self.assertRaises(ValueError):
            G = DependencySolver(rp).graph

        rp = ResourcePool()

        file_basename1 = PythonJob(function=basename, reference='basename1')
        file_basename1.path = file_basename1.path

        rp[R('T1w')] = file_basename1.path

        with self.assertRaises(ValueError):
            G = DependencySolver(rp).graph
Example #7
0
    def test_err(self):

        rp = ResourcePool()
        rp['sub-A00008399_ses-BAS1_T1w'] = Resource(A00008326_file)

        r_key = R('sub-A00008399_ses-BAS1_T1w')
        anatomical_image = rp[r_key]

        file_basename = PythonJob(function=basename, reference='basename')
        file_basename.path = anatomical_image
        rp[R(r_key, label='base')] = file_basename.path
        rp[R(r_key, label='dir')] = file_basename.dirname

        def err(message, path):
            raise Exception(message)

        erred = PythonJob(function=err, reference='erring_job')
        erred.message = Resource('This jobs has erred')
        erred.path = file_basename.dirname
        rp[R('T1w', label='err')] = erred.no_return

        err_file_reversed = PythonJob(function=reversed_string, reference='err_reversed_string')
        err_file_reversed.path = erred.no_return
        rp[R('T1w', label='errbaserev')] = err_file_reversed.reversed

        file_reversed = PythonJob(function=reversed_string, reference='reversed_string')
        file_reversed.path = file_basename.dirname
        rp[R('T1w', label='baserev')] = file_reversed.reversed

        for executor in executors:
            res_rp = DependencySolver(rp).execute(executor=executor())

            self.assertIsInstance(res_rp[R('T1w', label='err')], InvalidResource)
            self.assertIsInstance(res_rp[R('T1w', label='errbaserev')], InvalidResource)
            self.assertNotIsInstance(res_rp[R('T1w', label='baserev')], InvalidResource)
Example #8
0
    def test_intermediary(self):

        for strat, srp in self.rp[[
            R('T1w'),
        ]]:
            anatomical_image = srp[R('T1w')]

            file_basename = PythonJob(function=basename)
            file_basename.path = anatomical_image
            srp[R('T1w', label='base')] = file_basename.path
            srp[R('T1w', label='dir')] = file_basename.dirname

            file_reversed = PythonJob(function=reversed_string)
            file_reversed.path = file_basename.path

            filename_subject_id = PythonJob(function=subject_id)
            filename_subject_id.filename = file_basename.path

            file_join_path = PythonJob(function=join_path)
            file_join_path.dirname = file_basename.dirname
            file_join_path.base = file_reversed.reversed
            srp[R('T1w', label='crazypath')] = file_join_path.path

        # Create footprint for file_reversed, filename_subject_id and file_join_path
        # Since file_join_path is cached, file_reversed and filename_subject_id should not execute
        #
        # * Requires a ExecutionLogger
        # * Maybe this policy could be parametrized

        res_rp = DependencySolver(self.rp).execute(executor=Execution())

        self.assertIn(R('sub-A00008326_ses-BAS1_label-base_T1w'), res_rp)
        self.assertEqual(res_rp[R('sub-A00008326_ses-BAS1_label-crazypath_T1w')].content,
                         f'{A00008326_dir}/{A00008326_base[::-1]}')

        self.assertIn(R('sub-A00008399_ses-BAS1_label-base_T1w'), res_rp)
        self.assertEqual(res_rp[R('sub-A00008399_ses-BAS1_label-crazypath_T1w')].content,
                         f'{A00008399_dir}/{A00008399_base[::-1]}')
Example #9
0
def create_workflow(config: AttrDict, resource_pool: ResourcePool,
                    context: Context):
    for _, rp in resource_pool[['label-reorient_T1w']]:
        anat = rp[R('T1w', label='reorient')]
        train_model = UNet2d(dim_in=config.dim_in,
                             num_conv_block=config.num_conv_block,
                             kernel_root=config.kernel_root)
        if config.unet_model.lower().startswith('s3://'):
            unet_path = S3Resource(config.unet_model,
                                   working_dir=tempfile.mkdtemp())()
        else:
            unet_path = config.unet_model
        checkpoint = torch.load(unet_path, map_location={'cuda:0': 'cpu'})
        train_model.load_state_dict(checkpoint['state_dict'])
        model = nn.Sequential(train_model, nn.Softmax2d())

        # create a node called unet_mask
        unet_mask = PythonJob(function=predict_volumes, reference='unet_mask')
        unet_mask.model = Resource(model)
        unet_mask.cimg_in = anat
        """
        Revised mask with ANTs
        """
        # fslmaths <whole head> -mul <mask> brain.nii.gz
        unet_masked_brain = NipypeJob(
            interface=fsl.MultiImageMaths(op_string="-mul %s"),
            reference='unet_masked_brain')
        unet_masked_brain.in_file = anat
        unet_masked_brain.operand_files = unet_mask.output_path

        # flirt -v -dof 6 -in brain.nii.gz -ref NMT_SS_0.5mm.nii.gz -o brain_rot2atl -omat brain_rot2atl.mat -interp sinc
        # TODO change it to ANTs linear transform
        native_brain_to_template_brain = NipypeJob(
            interface=fsl.FLIRT(reference=config.template_brain_only_for_anat,
                                dof=6,
                                interp='sinc'),
            reference='native_brain_to_template_brain')
        native_brain_to_template_brain.in_file = unet_masked_brain.out_file

        # flirt -in head.nii.gz -ref NMT_0.5mm.nii.gz -o head_rot2atl -applyxfm -init brain_rot2atl.mat
        # TODO change it to ANTs linear transform
        native_head_to_template_head = NipypeJob(
            interface=fsl.FLIRT(reference=config.template_skull_for_anat,
                                apply_xfm=True),
            reference='native_head_to_template_head')
        native_head_to_template_head.in_file = anat
        native_head_to_template_head.in_matrix_file = native_brain_to_template_brain.out_matrix_file

        # fslmaths NMT_SS_0.5mm.nii.gz -bin templateMask.nii.gz
        template_brain_mask = NipypeJob(
            interface=fsl.maths.MathsCommand(args='-bin'),
            reference='template_brain_mask')
        template_brain_mask.in_file = config.template_brain_only_for_anat

        # ANTS 3 -m  CC[head_rot2atl.nii.gz,NMT_0.5mm.nii.gz,1,5] -t SyN[0.25] -r Gauss[3,0] -o atl2T1rot -i 60x50x20 --use-Histogram-Matching  --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000
        ants_template_head_to_template = NipypeJob(
            interface=ants.Registration(),
            reference='template_head_to_template')
        ants_template_head_to_template.metric = ['CC']
        ants_template_head_to_template.metric_weight = [1, 5]
        ants_template_head_to_template.moving_image = config.template_skull_for_anat
        ants_template_head_to_template.transforms = ['SyN']
        ants_template_head_to_template.transform_parameters = [(0.25, )]
        ants_template_head_to_template.interpolation = 'NearestNeighbor'
        ants_template_head_to_template.number_of_iterations = [[60, 50, 20]]
        ants_template_head_to_template.smoothing_sigmas = [[0.6, 0.2, 0.0]]
        ants_template_head_to_template.shrink_factors = [[4, 2, 1]]
        ants_template_head_to_template.convergence_threshold = [1.e-8]

        ants_template_head_to_template.fixed_image = native_head_to_template_head.out_file

        # antsApplyTransforms -d 3 -i templateMask.nii.gz -t atl2T1rotWarp.nii.gz atl2T1rotAffine.txt -r brain_rot2atl.nii.gz -o brain_rot2atl_mask.nii.gz
        template_head_transform_to_template = NipypeJob(
            interface=ants.ApplyTransforms(dimension=3),
            reference='template_head_transform_to_template')
        template_head_transform_to_template.input_image = template_brain_mask.out_file
        template_head_transform_to_template.reference_image = native_brain_to_template_brain.out_file
        template_head_transform_to_template.transforms = ants_template_head_to_template.forward_transforms

        # convert_xfm -omat brain_rot2native.mat -inverse brain_rot2atl.mat
        invt = NipypeJob(interface=fsl.ConvertXFM(invert_xfm=True),
                         reference='convert_xfm')
        invt.in_file = native_brain_to_template_brain.out_matrix_file

        # flirt -in brain_rot2atl_mask.nii.gz -ref brain.nii.gz -o brain_mask.nii.gz -applyxfm -init brain_rot2native.mat
        template_brain_to_native_brain = NipypeJob(
            interface=fsl.FLIRT(apply_xfm=True),
            reference='template_brain_to_native_brain')
        template_brain_to_native_brain.in_file = template_head_transform_to_template.output_image
        template_brain_to_native_brain.reference = unet_masked_brain.out_file
        template_brain_to_native_brain.in_matrix_file = invt.out_file

        # fslmaths brain_mask.nii.gz -thr .5 -bin brain_mask_thr.nii.gz
        refined_mask = NipypeJob(interface=fsl.Threshold(thresh=0.5,
                                                         args='-bin'),
                                 reference='refined_mask')
        refined_mask.in_file = template_brain_to_native_brain.out_file

        # get a new brain with mask
        refined_brain = NipypeJob(
            interface=fsl.MultiImageMaths(op_string="-mul %s"),
            reference='refined_brain')
        refined_brain.in_file = anat
        refined_brain.operand_files = refined_mask.out_file

        rp[R('T1w', desc='skullstrip-unet',
             suffix='mask')] = refined_mask.out_file
        rp[R('T1w', desc='skullstrip-unet',
             suffix='brain')] = refined_brain.out_file