From 56ea4d0d897831da04d80bcba026d0d91bc8291c Mon Sep 17 00:00:00 2001 From: Fidel Alfaro Almagro <falmagro@fmrib.ox.ac.uk> Date: Fri, 24 Feb 2023 17:47:44 +0000 Subject: [PATCH] Adding last IDP scripts --- bip/data/FileTree.tree | 4 +- bip/data/IDPs/IDPs.json | 3 + bip/pipelines/IDPs_gen/IDP_diff_autoPtx.py | 130 +++++++-------------- bip/pipelines/IDPs_gen/IDPs_gen.py | 24 +++- bip/pipelines/dMRI_diff/diff_autoptx.py | 12 +- 5 files changed, 73 insertions(+), 100 deletions(-) create mode 100755 bip/data/IDPs/IDPs.json diff --git a/bip/data/FileTree.tree b/bip/data/FileTree.tree index d7f4238..d87f4a5 100644 --- a/bip/data/FileTree.tree +++ b/bip/data/FileTree.tree @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:30abf95478fe8611d0162a4bce17d4cabae1471ea0d322398d1071a8417e0009 -size 23361 +oid sha256:6f9005fcde92e75653faa54de4e45f5bb29367989e01dadd2344bf52a67bd74e +size 23447 diff --git a/bip/data/IDPs/IDPs.json b/bip/data/IDPs/IDPs.json new file mode 100755 index 0000000..0b5725d --- /dev/null +++ b/bip/data/IDPs/IDPs.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8005353f07fe3d5cf09f29f9faf45e42182ab1317f45d1370cb0e3623a9883c9 +size 244014 diff --git a/bip/pipelines/IDPs_gen/IDP_diff_autoPtx.py b/bip/pipelines/IDPs_gen/IDP_diff_autoPtx.py index 786285e..31b3d40 100755 --- a/bip/pipelines/IDPs_gen/IDP_diff_autoPtx.py +++ b/bip/pipelines/IDPs_gen/IDP_diff_autoPtx.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# IDP_diff_autoPtx.py - Generating IDP file with autoPtx metrics +# IDP_diff_autoPtx.py - Generating IDP file with autoPtx metrics # # Author: Fidel Alfaro Almagro <fidel.alfaroalmagro@ndcn.ox.ac.uk> # Author: Paul McCarthy <pauldmccarthy@gmail.com> @@ -10,111 +10,59 @@ # import os -import json import logging -from pipe_tree import In, Out, Ref -from bip.utils.log_utils import redirect_logging +import nibabel as nib +from fsl import wrappers +from pipe_tree import In, Out, Ref, Var +from bip.utils.log_utils import redirect_logging, tempdir log = logging.getLogger(__name__) def run(ctx, - T1_orig: In, logs_dir: Ref, - IDP_diff_autoPtx: Out): - - with redirect_logging('IDP_diff_autoPtx', outdir=logs_dir): + TBSS_prefix: Ref, + aptx_txt_prefix: Ref, + tmp_dir: Ref, + aptx_tract_tmp: In(no_iter=True), + IDP_diff_autoPtx: Out): + with redirect_logging('IDP_diff_autoPtx', outdir=logs_dir),\ + tempdir(tmp_dir): -set -x + autoPtx_all = tmp_dir + '/autoPtx_all.nii.gz' + autoPtx_tmp = tmp_dir + '/autoPtx_tmp.nii.gz' -origDir=`pwd` -scriptName=`basename "$0"` -direc=$1 + result_NaN = ("NaN " * 27).strip() + result = "" -cd $direc + # TODO: See if it is possible to generate the aptx_tract_tmp files here + wrappers.fslmerge(autoPtx_all, *list(aptx_tract_tmp.data)) + tractnorm = wrappers.fslstats(autoPtx_all, t=True).m.run() -basedMRI="dMRI" -#if [ -d $basedMRI/unusable ] ; then -# basedMRI="$basedMRI/unusable" -#elif [ -d $basedMRI/incompatible ] ; then -# basedMRI="$basedMRI/incompatible" -#fi + for suffix in ['FA','L1','L2','L3','MO','MD','ICVF','OD','ISOVF']: + all_file = TBSS_prefix + suffix + ".nii.gz" + APTX_file = aptx_txt_prefix + suffix + ".txt" -#Setting the string of NaN in case there is a problem. -numVars="27" -nanResult=""; -for i in $(seq 1 $numVars) ; do - nanResult="NaN $nanResult" ; -done + if os.path.exists(all_file): + wrappers.fslmaths(autoPtx_all).mul(all_file).run(autoPtx_tmp) + tractmeas = wrappers.fslstats(autoPtx_tmp, t=True).m.run() -result="" + img = nib.load(autoPtx_all) + jmax = int(round(img.header['dim'][4])) -allgood=1 -for i in FA MD MO L1 L2 L3 ICVF OD ISOVF ; do - if [ ! -f $basedMRI/autoptx_preproc/APTX_${i}.txt ] || [ `cat $basedMRI/autoptx_preproc/APTX_${i}.txt | wc -w` != 27 ] ; then - allgood=0 - fi -done + cad = "" + for i in range(jmax): + cad += " " + str(tractmeas[i] / tractnorm[i]) + cad = cad.strip() -if [ $allgood = 0 ] ; then - if [ -f $basedMRI/autoptx_preproc/tracts/mcp/tracts/tractsNorm.nii.gz ] ; then + with open(APTX_file, 'wt', encoding="utf-8") as f: + f.write(f'{cad}\n') - ntracts=`echo $basedMRI/autoptx_preproc/tracts/*/tracts/tractsNorm.nii.gz | wc -w` - if [ $ntracts != 27 ] ; then - >&2 echo only found $ntracts tracts - fi - - # hack to ameliorate partial misalignment of mcp - fslmaths $FSLDIR/data/standard/FMRIB58_FA_1mm -thr 1000 -bin -ero -ero -mul $basedMRI/autoptx_preproc/tracts/mcp/tracts/tractsNorm $basedMRI/autoptx_preproc/tracts/mcp/tracts/tractsNorm -odt float - - for p in ar_l ar_r atr_l atr_r cgc_l cgc_r cgh_l cgh_r cst_l cst_r fma fmi ifo_l ifo_r ilf_l ilf_r mcp ml_l ml_r ptr_l ptr_r slf_l slf_r str_l str_r unc_l unc_r ; do - if [ -f $basedMRI/autoptx_preproc/tracts/$p/tracts/tractsNorm.nii.gz ] ; then - t=`fslstats $basedMRI/autoptx_preproc/tracts/$p/tracts/tractsNorm -P 99` - fslmaths $basedMRI/autoptx_preproc/tracts/$p/tracts/tractsNorm -min $t -mul 1e6 -div $t -thr 1e5 $basedMRI/autoptx_preproc/tmp_$p - fi - done - - cad="" - - fslmerge -t $basedMRI/autoptx_preproc/tmp_all \ - $basedMRI/autoptx_preproc/tmp_{ar_l,ar_r,atr_l,atr_r,cgc_l,cgc_r,cgh_l,cgh_r,cst_l,cst_r,fma,fmi,ifo_l,ifo_r,ilf_l,ilf_r,mcp,ml_l,ml_r,ptr_l,ptr_r,slf_l,slf_r,str_l,str_r,unc_l,unc_r}.nii.gz - tractnorm=`fslstats -t $basedMRI/autoptx_preproc/tmp_all -m` - - if [ -f $basedMRI/autoptx_preproc/tmp_all.nii.gz ] ; then - for i in FA MD MO L1 L2 L3 ICVF OD ISOVF ; do - /bin/rm -f $basedMRI/autoptx_preproc/APTX_${i}.txt - if [ -f $basedMRI/TBSS/stats/all_${i}.nii.gz ] ; then - fslmaths $basedMRI/autoptx_preproc/tmp_all -mul $basedMRI/TBSS/stats/all_${i} $basedMRI/autoptx_preproc/tmp - tractmeas=`fslstats -t $basedMRI/autoptx_preproc/tmp -m | sed 's/-/_/g'` - jmax=`fslnvols $basedMRI/autoptx_preproc/tmp_all` - for (( j=1; j <= $jmax; ++j )) ; do - tm=`echo $tractmeas | cut -d " " -f$j` - tn=`echo $tractnorm | cut -d " " -f$j` - echo "10 k $tm $tn / p" | dc - >> $basedMRI/autoptx_preproc/APTX_${i}.txt - done - fi - done - rm $basedMRI/autoptx_preproc/tmp_*.nii.gz - fi - else - >&2 echo "mcp tract missing" - fi -fi - -for i in FA MD MO L1 L2 L3 ICVF OD ISOVF ; do - if [ -f $basedMRI/autoptx_preproc/APTX_${i}.txt ] && [ `cat $basedMRI/autoptx_preproc/APTX_${i}.txt | wc -w` = 27 ] ; then - miniResult=`cat $basedMRI/autoptx_preproc/APTX_${i}.txt` - else - miniResult="$nanResult" - fi - result="$result $miniResult" -done - -mkdir -p IDP_files - -echo $result > IDP_files/$scriptName.txt -echo $result - -cd $origDir + result += cad + else: + result += " " + result_NaN + result = result.strip() + with open(IDP_diff_autoPtx, 'wt', encoding="utf-8") as f: + f.write(f'{result}\n') diff --git a/bip/pipelines/IDPs_gen/IDPs_gen.py b/bip/pipelines/IDPs_gen/IDPs_gen.py index 769243a..a1b41ce 100755 --- a/bip/pipelines/IDPs_gen/IDPs_gen.py +++ b/bip/pipelines/IDPs_gen/IDPs_gen.py @@ -11,17 +11,24 @@ import logging from bip.utils.log_utils import redirect_logging -from bip.pipelines.IDPs_gen import IDP_subject_ID, IDP_subject_centre +from bip.pipelines.IDPs_gen import IDP_subject_ID +from bip.pipelines.IDPs_gen import IDP_subject_centre from bip.pipelines.IDPs_gen import IDP_subject_COG_table from bip.pipelines.IDPs_gen import IDP_all_align_to_T1 -from bip.pipelines.IDPs_gen import IDP_T1_FIRST_vols, IDP_T1_SIENAX -from bip.pipelines.IDPs_gen import IDP_T1_GM_parcellation, IDP_T1_SIENAX -from bip.pipelines.IDPs_gen import IDP_T1_align_to_std, IDP_T1_noise_ratio +from bip.pipelines.IDPs_gen import IDP_T1_FIRST_vols +from bip.pipelines.IDPs_gen import IDP_T1_SIENAX +from bip.pipelines.IDPs_gen import IDP_T1_GM_parcellation +from bip.pipelines.IDPs_gen import IDP_T1_SIENAX +from bip.pipelines.IDPs_gen import IDP_T1_align_to_std +from bip.pipelines.IDPs_gen import IDP_T1_noise_ratio from bip.pipelines.IDPs_gen import IDP_T2_FLAIR_WMH from bip.pipelines.IDPs_gen import IDP_SWI_T2star -from bip.pipelines.IDPs_gen import IDP_func_head_motion, IDP_func_TSNR +from bip.pipelines.IDPs_gen import IDP_func_head_motion +from bip.pipelines.IDPs_gen import IDP_func_TSNR from bip.pipelines.IDPs_gen import IDP_func_task_activation -from bip.pipelines.IDPs_gen import IDP_diff_eddy_outliers, IDP_diff_TBSS +from bip.pipelines.IDPs_gen import IDP_diff_eddy_outliers +from bip.pipelines.IDPs_gen import IDP_diff_TBSS +from bip.pipelines.IDPs_gen import IDP_diff_autoPtx log = logging.getLogger(__name__) @@ -102,6 +109,11 @@ def add_to_pipeline(ctx, pipe, tree, targets): kwargs={'ctx' : ctx}) targets.append('IDP_diff_TBSS') + pipe(IDP_diff_autoPtx.run, + submit=dict(jobtime=200, name="BIP_IDP_diff_autoPtx_"+ subj), + kwargs={'ctx' : ctx}) + targets.append('IDP_diff_autoPtx') + pipe(IDP_subject_COG_table.run, submit=dict(jobtime=200, name="BIP_IDP_subject_COG_table_" + subj), kwargs={'ctx' : ctx}) diff --git a/bip/pipelines/dMRI_diff/diff_autoptx.py b/bip/pipelines/dMRI_diff/diff_autoptx.py index 894dc2d..017bd35 100755 --- a/bip/pipelines/dMRI_diff/diff_autoptx.py +++ b/bip/pipelines/dMRI_diff/diff_autoptx.py @@ -39,7 +39,8 @@ def run(ctx, aptx_exclude: Out, density: Out, waytotal: Out, - tractsNorm: Out): + tractsNorm: Out, + aptx_tract_tmp: Out): with redirect_logging('diff_autoptx_' + autoptx_tract.value, outdir=logs_dir): @@ -49,6 +50,7 @@ def run(ctx, t_seeds = int(ctx.tract_struct[t_name]["num_seeds"] * 300) orig_tract_dir = ctx.get_data('dMRI/autoptx/protocols/' + t_name + '/') + FMRIB58_FA_1mm = ctx.get_standard('FMRIB58_FA_1mm.nii.gz') # Does the protocol defines a second # run with inverted seed / target masks? @@ -120,3 +122,11 @@ def run(ctx, f.write(f'{way}\n') wrappers.fslmaths(density).div(way).range().run(tractsNorm) + + # Hack to ameliorate partial misalignment of mcp + if t_name == "mcp": + wrappers.fslmaths(FMRIB58_FA_1mm).thr(1000).bin().ero(2).mul(tractsNorm).run(tractsNorm) + + # This will be needed for IDP generation + val = wrappers.fslstats(tractsNorm).P(99).run() + wrappers.fslmaths(tractsNorm).min(val).mul(1e6).div(val).thr(1e5).run(aptx_tract_tmp) -- GitLab