From b130576138a3ca7840c322cdecb696194dbdc71f Mon Sep 17 00:00:00 2001
From: Priscille
Date: Fri, 5 Jun 2020 11:59:04 +0200
Subject: [PATCH] ENH: Use of DataSinker node to save final results
---
notebooks/srr.ipynb | 132 ++++++++++++++++++++-------
pymialsrtk/interfaces/postprocess.py | 5 +
pymialsrtk/interfaces/preprocess.py | 2 +-
3 files changed, 104 insertions(+), 35 deletions(-)
diff --git a/notebooks/srr.ipynb b/notebooks/srr.ipynb
index c0caf2c87..88456341d 100644
--- a/notebooks/srr.ipynb
+++ b/notebooks/srr.ipynb
@@ -26,7 +26,7 @@
"import shutil\n",
"\n",
"# Imports from nipype\n",
- "from nipype.interfaces.io import BIDSDataGrabber,DataGrabber\n",
+ "from nipype.interfaces.io import BIDSDataGrabber,DataGrabber, DataSink\n",
"from nipype.pipeline import Node, Workflow\n",
"\n",
"# Import the implemented interface from pymialsrtk\n",
@@ -76,10 +76,8 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
+ "cell_type": "raw",
"metadata": {},
- "outputs": [],
"source": [
"# \n",
"# Copy result files to BIDS\n",
@@ -207,30 +205,31 @@
"outputs": [],
"source": [
"## Node linkage\n",
- "def create_workflow(bids_dir, subject, p_stacksOrder, session=None):\n",
+ "def create_workflow(bids_dir, process_dir, subject, p_stacksOrder, session=None, deltatTV = 0.01, lambdaTV = 0.75, primal_dual_loops=10):\n",
"# wf_base_dir = os.path.join(\"{}\".format(output_dir),\"superres-mri\",\"sub-{}\".format(subject),\"nipype\")\n",
- " output_dir = os.path.join(\"{}\".format(bids_dir),\"derivatives\",\"superres-mri\")\n",
" \n",
" if session is None:\n",
- " wf_base_dir = os.path.join(output_dir, subject)\n",
+ " wf_base_dir = os.path.join(process_dir, subject)\n",
+ " process_dir = os.path.join(process_dir, subject)\n",
" else:\n",
- " wf_base_dir = os.path.join(output_dir, subject, session)\n",
+ " wf_base_dir = os.path.join(process_dir, subject, session)\n",
+ " process_dir = os.path.join(process_dir, subject, session)\n",
"\n",
- " if not os.path.exists(output_dir):\n",
- " os.makedirs(output_dir)\n",
- " print(\"Ouput directory: {}\".format(wf_base_dir))\n",
+ " if not os.path.exists(process_dir):\n",
+ " os.makedirs(process_dir)\n",
+ " print(\"Process directory: {}\".format(wf_base_dir))\n",
"\n",
" wf = Workflow(name=\"srr_nipype\",base_dir=wf_base_dir)\n",
" srr_nipype_dir = os.path.join(wf.base_dir, wf.name )\n",
" \n",
" \n",
" # Initialization\n",
- " if os.path.isfile(os.path.join(output_dir,\"pypeline_\"+subject+\".log\")):\n",
- " os.unlink(os.path.join(output_dir,\"pypeline_\"+subject+\".log\"))\n",
- "# open(os.path.join(output_dir,\"pypeline.log\"), 'a').close()\n",
+ " if os.path.isfile(os.path.join(process_dir,\"pypeline_\"+subject+\".log\")):\n",
+ " os.unlink(os.path.join(process_dir,\"pypeline_\"+subject+\".log\"))\n",
+ "# open(os.path.join(process_dir,\"pypeline.log\"), 'a').close()\n",
" \n",
"\n",
- " config.update_config({'logging': {'log_directory': os.path.join(output_dir), 'log_to_file': True},\n",
+ " config.update_config({'logging': {'log_directory': os.path.join(process_dir), 'log_to_file': True},\n",
" 'execution': {\n",
" 'remove_unnecessary_outputs': False,\n",
" 'stop_on_first_crash': True,\n",
@@ -337,15 +336,14 @@
" if session != None:\n",
" sub_ses = ''.join([sub_ses, '_', session])\n",
" srtkImageReconstruction.inputs.sub_ses = sub_ses\n",
- "\n",
" \n",
" srtkTVSuperResolution = Node(interface=reconstruction.MialsrtkTVSuperResolution(), name='srtkTVSuperResolution') \n",
" srtkTVSuperResolution.inputs.bids_dir = bids_dir\n",
" srtkTVSuperResolution.inputs.stacksOrder = p_stacksOrder\n",
" srtkTVSuperResolution.inputs.sub_ses = sub_ses\n",
- " srtkTVSuperResolution.inputs.in_loop = 10\n",
- " srtkTVSuperResolution.inputs.in_deltat = 0.01\n",
- " srtkTVSuperResolution.inputs.in_lambda = 0.75\n",
+ " srtkTVSuperResolution.inputs.in_loop = primal_dual_loops\n",
+ " srtkTVSuperResolution.inputs.in_deltat = deltatTV\n",
+ " srtkTVSuperResolution.inputs.in_lambda = lambdaTV\n",
" \n",
" \n",
"\n",
@@ -360,6 +358,10 @@
" srtkMaskImage02 = Node(interface=preprocess.MialsrtkMaskImage(), name='srtkMaskImage02')\n",
" srtkMaskImage02.inputs.bids_dir = bids_dir\n",
" \n",
+ " datasink = Node(DataSink(), name='sinker')\n",
+ " output_dir = os.path.join(\"{}\".format(bids_dir),\"derivatives\",\"mialsrtk-py\")\n",
+ " datasink.inputs.base_directory = output_dir\n",
+ " \n",
" #\n",
" ## Nodes ready - Linking now\n",
" \n",
@@ -403,10 +405,10 @@
" wf.connect(srtkIntensityStandardization02_nlm, \"output_images\", srtkMaskImage01, \"input_images\")\n",
" wf.connect(dg, \"masks\", srtkMaskImage01, \"input_masks\")\n",
" \n",
+ " \n",
" wf.connect(srtkMaskImage01, \"output_images\", srtkImageReconstruction, \"input_images\")\n",
" wf.connect(dg, \"masks\", srtkImageReconstruction, \"input_masks\")\n",
" \n",
- " \n",
" wf.connect(srtkIntensityStandardization02, \"output_images\", srtkTVSuperResolution, \"input_images\")\n",
" wf.connect(srtkImageReconstruction, \"output_transforms\", srtkTVSuperResolution, \"input_transforms\")\n",
" wf.connect(dg, \"masks\", srtkTVSuperResolution, \"input_masks\")\n",
@@ -425,31 +427,93 @@
" wf.connect(srtkRefineHRMaskByIntersection, \"output_SRmask\", srtkMaskImage02, \"in_mask\")\n",
" \n",
" \n",
+ " \n",
+ " #\n",
+ " ### - Saving files\n",
+ " \n",
+ " \n",
+ " substitutions = []\n",
+ " for stack in stacksOrder:\n",
+ " \n",
+ " print( sub_ses+'_run-'+str(stack)+'_T2w_nlm_uni_bcorr_histnorm.nii.gz', ' ---> ',sub_ses+'_run-'+str(stack)+'_T2w_preproc.nii.gz')\n",
+ " substitutions.append( ( sub_ses+'_run-'+str(stack)+'_T2w_nlm_uni_bcorr_histnorm.nii.gz', sub_ses+'_run-'+str(stack)+'_T2w_preproc.nii.gz') )\n",
+ " \n",
+ " print( sub_ses+'_run-'+str(stack)+'_T2w_nlm_uni_bcorr_histnorm_transform_'+str(len(stacksOrder))+'V.txt', ' ---> ', sub_ses+'_run-'+str(stack)+'_T2w_from-origin_to-SDI_mode-image_xfm.txt')\n",
+ " substitutions.append( ( sub_ses+'_run-'+str(stack)+'_T2w_nlm_uni_bcorr_histnorm_transform_'+str(len(stacksOrder))+'V.txt', sub_ses+'_run-'+str(stack)+'_T2w_from-origin_to-SDI_mode-image_xfm.txt') )\n",
+ " \n",
+ " print( sub_ses+'_run-'+str(stack)+'_T2w_uni_bcorr_histnorm_LRmask.nii.gz', ' ---> ', sub_ses+'_run-'+str(stack)+'_T2w_desc-LRmask.nii.gz')\n",
+ " substitutions.append( ( sub_ses+'_run-'+str(stack)+'_T2w_uni_bcorr_histnorm_LRmask.nii.gz', sub_ses+'_run-'+str(stack)+'_T2w_desc-LRmask.nii.gz') )\n",
+ "\n",
+ " \n",
+ " print( 'SDI_'+sub_ses+'_'+str(len(stacksOrder))+'V_rad1.nii.gz', ' ---> ', sub_ses+'_rec-SDI_T2w.nii.gz')\n",
+ " substitutions.append( ( 'SDI_'+sub_ses+'_'+str(len(stacksOrder))+'V_rad1.nii.gz', sub_ses+'_rec-SDI_T2w.nii.gz') )\n",
+ "\n",
+ " print( 'SRTV_'+sub_ses+'_'+str(len(stacksOrder))+'V_rad1_gbcorr.nii.gz', ' ---> ', sub_ses+'_rec-SR_T2w.nii.gz')\n",
+ " substitutions.append( ( 'SRTV_'+sub_ses+'_'+str(len(stacksOrder))+'V_rad1_gbcorr.nii.gz', sub_ses+'_rec-SR_T2w.nii.gz') )\n",
+ " \n",
+ "\n",
+ " print( sub_ses+'_T2w_uni_bcorr_histnorm_srMask.nii.gz', ' ---> ', sub_ses+'_rec-SR_T2w_desc-brain_mask.nii.gz')\n",
+ " substitutions.append( ( sub_ses+'_T2w_uni_bcorr_histnorm_srMask.nii.gz', sub_ses+'_rec-SR_T2w_desc-SRmask.nii.gz') )\n",
+ "\n",
+ " \n",
+ " \n",
+ " datasink.inputs.substitutions = substitutions\n",
+ " \n",
+ " wf.connect(srtkMaskImage01, \"output_images\", datasink, 'preproc')\n",
+ " wf.connect(srtkImageReconstruction, \"output_transforms\", datasink, 'xfm')\n",
+ " wf.connect(srtkRefineHRMaskByIntersection, \"output_LRmasks\", datasink, 'postproc')\n",
+ " \n",
+ " wf.connect(srtkImageReconstruction, \"output_sdi\", datasink, 'anat')\n",
+ " wf.connect(srtkN4BiasFieldCorrection, \"output_image\", datasink, 'anat.@SR')\n",
+ " wf.connect(srtkRefineHRMaskByIntersection, \"output_SRmask\", datasink, 'postproc.@SRmask')\n",
+ " \n",
+ " \n",
+ " # JSON file SRTV\n",
+ " output_dict = {}\n",
+ "\n",
+ " output_dict[\"Description\"] = \"Isotropic high-resolution image reconstructed using the Total-Variation Super-Resolution algorithm provided by MIALSRTK\"\n",
+ " # output_dict[\"Sources\"] = sources\n",
+ " output_dict[\"Input sources run order\"] = stacksOrder\n",
+ " output_dict[\"CustomMetaData\"] = {}\n",
+ " output_dict[\"CustomMetaData\"][\"Number of scans used\"] = str(len(p_stacksOrder))\n",
+ " output_dict[\"CustomMetaData\"][\"TV regularization weight lambda\"] = lambdaTV\n",
+ " output_dict[\"CustomMetaData\"][\"Optimization time step\"] = deltatTV\n",
+ " output_dict[\"CustomMetaData\"][\"Primal/dual loops\"] = primal_dual_loops\n",
+ "\n",
+ " output_json = os.path.join(output_dir, 'anat', ''.join([subject, '_rec-SR.json']))\n",
+ " with open(output_json, 'w+', encoding='utf8') as outfile:\n",
+ " json.dump(output_dict, outfile, indent=4)\n",
" \n",
" return wf"
]
},
+ {
+ "cell_type": "raw",
+ "metadata": {},
+ "source": [
+ "%%bash\n",
+ "\n",
+ "\n",
+ "python srr.py /fetaldata /fetaldata/output participant --participant_label \"HK01\" \"ctrl0022\""
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "scrolled": true
- },
+ "metadata": {},
"outputs": [],
"source": [
- "# m_wf = create_workflow(bids_dir, subject, p_stacksOrder=stacsksOrder)\n",
- "m_wf = create_workflow(bids_dir, subject, p_stacksOrder=stacksOrder, session = session)\n",
+ "m_wf = create_workflow(bids_dir, process_dir='/fetaldata/derivatives/tmp_proc', subject=subject, p_stacksOrder=stacksOrder, session = session)\n",
"m_wf.write_graph()\n",
- "aa = m_wf.run()\n",
- "\n",
- "\n",
- "copy_results_to_bids(p_bids_dir= bids_dir, \n",
- " nipype_dir=os.path.join(m_wf.base_dir, m_wf.name), \n",
- " p_wf_base_dir=m_wf.base_dir, \n",
- " p_stacksOrder=stacksOrder, \n",
- " subject=subject, \n",
- " session=session)"
+ "aa = m_wf.run()\n"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
diff --git a/pymialsrtk/interfaces/postprocess.py b/pymialsrtk/interfaces/postprocess.py
index 25e01f611..591473033 100644
--- a/pymialsrtk/interfaces/postprocess.py
+++ b/pymialsrtk/interfaces/postprocess.py
@@ -96,6 +96,8 @@ def _run_interface(self, runtime):
cmd += ['-O', out_file]
_, name, ext = split_filename(os.path.abspath(self.inputs.input_images[0]))
+ run_id = (name.split('run-')[1]).split('_')[0]
+ name = name.replace('_run-'+run_id+'_', '_')
out_file = os.path.join(os.getcwd().replace(self.inputs.bids_dir,'/fetaldata'), ''.join((name, self.inputs.out_srmask_postfix, ext)))
cmd += ['-r', self.inputs.input_sr]
@@ -116,7 +118,10 @@ def _run_interface(self, runtime):
def _list_outputs(self):
outputs = self._outputs().get()
_, name, ext = split_filename(os.path.abspath(self.inputs.input_images[0]))
+ run_id = (name.split('run-')[1]).split('_')[0]
+ name = name.replace('_run-'+run_id+'_', '_')
outputs['output_SRmask'] = os.path.join(os.getcwd().replace(self.inputs.bids_dir,'/fetaldata'), ''.join((name, self.inputs.out_srmask_postfix, ext)))
+
outputs['output_LRmasks'] = glob(os.path.abspath(''.join(["*", self.inputs.out_LRmask_postfix, ext])))
return outputs
diff --git a/pymialsrtk/interfaces/preprocess.py b/pymialsrtk/interfaces/preprocess.py
index 607edabc4..91ae48fe7 100644
--- a/pymialsrtk/interfaces/preprocess.py
+++ b/pymialsrtk/interfaces/preprocess.py
@@ -518,7 +518,7 @@ class MialsrtkMaskImageInputSpec(BaseInterfaceInputSpec):
out_im_postfix = traits.Str("", usedefault=True)
class MialsrtkMaskImageOutputSpec(TraitedSpec):
- out_im_file = File(desc='Bias field corrected image')
+ out_im_file = File(desc='Masked image')
class MialsrtkMaskImage(BaseInterface):