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