#!/usr/bin/env tcsh @global_parse `basename $0` "$*" ; if ($status) exit 0 # --------------------- revision history ------------------------- # Jan, 2017 # + rename # # Jan 27, 2017 # + update opts # + # #set version = "2.0"; set rev_dat = "Apr 11, 2017" # + majorly updating I/O # + wdir stuff # #set version = "2.1"; set rev_dat = "Apr 14, 2017" # + try to anonymize # + qc snapshotting #set version = "2.8"; set rev_dat = "Apr 19, 2017" # + switch to dcm2niix from dcm2nii # -> motivated by Philips scaling requirements # -> prob better to stick with newer, anyways # #set version = "2.9"; set rev_dat = "Apr 21, 2017" # + no more automask in 3dCM # #set version = "3.0"; set rev_dat = "Apr 26, 2017" # + dcm2niix -> dcm2niix_afni # #set version = "3.1"; set rev_dat = "May 24, 2017" # + dcm2niix_afni: in multiecho DCMs, the echo number # automatically gets put in *somehow*, whether asked for or not # ... so now this is controlled for # #set version = "3.2"; set rev_dat = "Sep 04, 2017" # + work with new @chauffeur*, '-prefix ...' only # #set version = "3.3"; set rev_dat = "Feb 20, 2018" # + output QC dir for images # + default orientation RAI # #set version = "3.4"; set rev_dat = "June 26, 2018" # + allow a NIFTI anatomical to be input, and then do rest of # niceifying steps # #set version = "3.5"; set rev_dat = "Feb 12, 2019" # + [PT] change "checks" to use '3dinfo -prefix ...' as a better # methodology # set version = "3.52"; set rev_dat = "Sep 27, 2021" # + [PT] chauffeur label_size 3 -> 4, bc imseq.c shifted all sizes # down one level # # ---------------------------------------------------------------- set this_prog = "fat_proc_convert_dcm_anat" set tpname = "${this_prog:gas/fat_proc_//}" set here = "$PWD" # ----------------- find AFNI and set viewer --------------------- # find AFNI binaries directory and viewer location set adir = "" set my_viewer = "" which afni >& /dev/null if ( $status ) then echo "** ERROR: Cannot find 'afni'." goto BAD_EXIT else set aa = `which afni` set adir = $aa:h endif # default location of viewer: user could modify! set my_viewer = "$adir/@chauffeur_afni" # ----------------- find dcm2niix --------------------- which dcm2niix_afni >& /dev/null if ( $status ) then echo "** ERROR: Cannot find 'dcm2niix_afni'." goto BAD_EXIT endif # ----------------------- set defaults -------------------------- set idir = "" set inii = "" set odir = "" set tpref = "ttt" set ori_new = "RAI" set ofile = "" set opref = "" set DO_REORI = 1 set wdir = "__WORKING_$tpname" set WDIR_EX = "1" # put opref on wdir (unless user names) set output_cmd = 1 # def: output copy of this command set cmd_file = "" # def: same name as viewer set DO_CLEAN = "1" # def: do delete temp files set DO_VIEWER = "1" # def: do QC image visualization set qc_prefix = "" # def: autoname; user can enter set npref = "nnn" # ------------------- process options, a la rr ---------------------- if ( $#argv == 0 ) goto SHOW_HELP set ac = 1 while ( $ac <= $#argv ) # terminal options if ( ("$argv[$ac]" == "-h" ) || ("$argv[$ac]" == "-help" )) then goto SHOW_HELP endif if ( "$argv[$ac]" == "-ver" ) then goto SHOW_VERSION endif # ------------- input(s) ---------------- if ( "$argv[$ac]" == "-indir" ) then if ( $ac >= $#argv ) goto FAIL_MISSING_ARG @ ac += 1 set idir = "$argv[$ac]" # [PT: June 26, 2018] Input nifti instead of just directory to be # converted else if ( "$argv[$ac]" == "-innii" ) then if ( $ac >= $#argv ) goto FAIL_MISSING_ARG @ ac += 1 set inii = "$argv[$ac]" # ------------- output(s) ---------------- else if ( "$argv[$ac]" == "-prefix" ) then if ( $ac >= $#argv ) goto FAIL_MISSING_ARG @ ac += 1 set opref = "$argv[$ac]" else if ( "$argv[$ac]" == "-workdir" ) then if ( $ac >= $#argv ) goto FAIL_MISSING_ARG @ ac += 1 set wdir = "$argv[$ac]" set WDIR_EX = "0" # -------------- other opts ---------------- else if ( "$argv[$ac]" == "-orient" ) then if ( $ac >= $#argv ) goto FAIL_MISSING_ARG @ ac += 1 set ori_new = "$argv[$ac]" # -------------- more other opts ---------------- else if ( "$argv[$ac]" == "-no_clean" ) then set DO_CLEAN = "0" else if ( "$argv[$ac]" == "-reorig_reorient_off" ) then set DO_REORI = 0 # leave 'em alone! # -------------- qc stuff ---------------- else if ( "$argv[$ac]" == "-qc_prefix" ) then if ( $ac >= $#argv ) goto FAIL_MISSING_ARG @ ac += 1 set qc_prefix = "$argv[$ac]" else if ( "$argv[$ac]" == "-no_qc_view" ) then set DO_VIEWER = 0 else if ( "$argv[$ac]" == "-no_cmd_out" ) then set output_cmd = 0 else echo "** unexpected option #$ac = '$argv[$ac]'" goto BAD_EXIT endif @ ac += 1 end # ======================================================================= # ============================ ** SETUP ** ============================== # ======================================================================= echo "++ Start script version: $version" # ============================= dicom dir =============================== if ( "$idir" == "" && "$inii" == "" ) then echo "** ERROR: need to either" echo " A) input DICOM directory, after '-indir'; or" echo " B) input NIFTI file, after '-innii'" goto BAD_EXIT else if ( "$idir" != "" && "$inii" != "" ) then echo "** ERROR: need to choose *either* '-indir' or '-innii' input." goto BAD_EXIT endif # ---------- if input dir, check existence, and more if ( "$idir" != "" ) then if ( ! -e "$idir" ) then echo "\n** ERROR: can't find input DICOM directory: $idir !" goto BAD_EXIT endif # check for old relics cd $idir echo "++ Checking $PWD for preexisting NIFTIs ... " if ( (`find . -maxdepth 1 -type f -name "*nii" | wc -l` > 0 ) || \ (`find . -maxdepth 1 -type f -name "*nii.gz" | wc -l` > 0 ) ) then echo "\n** ERROR: already some NIFTI files in $idir !" goto BAD_EXIT endif # get back home for running stuff cd "$here" endif # ---------- if input nifti, check existence if ( "$inii" != "" ) then set ff = "$inii" set check = `3dinfo -prefix "$ff"` if ( "$check" == "NO-DSET" ) then echo "** ERROR: can't find input file: $ff" goto BAD_EXIT else echo "++ Found input file: $ff" endif endif # ========================= output/working dir ========================== # check output directory, use input one if nothing given if ( "$opref" == "" ) then echo "** ERROR: need '-prefix ...' option provided!" echo " See the helpfile for more information." goto BAD_EXIT else set odir = `dirname $opref` set opref = `basename $opref` echo "" echo "++ Based on prefix, the output directory will be:" echo " $odir" echo "++ Based on prefix, the output prefix will be:" echo " $opref" echo "" endif # default output dir, if nothing input. if ( ! -e "$odir" ) then echo "+* Output directory didn't exist. Trying to make it now." mkdir "$odir" endif set odirqc = "$odir/QC" if ( "$DO_VIEWER" == "1" ) then if ( ! -e "$odirqc" ) then mkdir "$odirqc" endif endif # and put working directory as subdirectory. if ( "$WDIR_EX" == "1" ) then set wdir = "$odir/${wdir}_$opref" else set wdir = "$odir/$wdir" endif # make the working directory if ( ! -e "$wdir" ) then echo "++ Making working directory: $wdir" \mkdir -p "$wdir" else echo "+* WARNING: Somehow found a premade working directory (?):" echo " $wdir" # don't clean preexisting directories-- could be user mistake. echo " NB: will *not* clean it afterwards." set DO_CLEAN = "0" endif set ocmd = "${opref}_cmd.txt" # name for output command set ofile = "${opref}.nii.gz" # name for output command # ======================================================================= # =========================== ** PROCESS ** ============================= # ======================================================================= echo "\n-----> STARTING $this_prog ---->" # ---------------------------- CMD --------------------------------- echo "\n\nThis command:" echo "$this_prog $argv\n\n" if ( "$cmd_file" == "" ) then set cmd_file = "$odir/$ocmd" endif # copy original command: # dump copy of command into workdir/.. if ( $output_cmd == 1 ) then echo "++ Echoing the command to: $cmd_file" set rec_afni_ver = `afni -ver` echo "### AFNI version:" > $cmd_file echo "# $rec_afni_ver\n" >> $cmd_file echo "### Executed from the directory location:" >> $cmd_file echo "# $here\n" >> $cmd_file echo "### The command was:" >> $cmd_file echo "# $this_prog $argv" >> $cmd_file echo "\n" >> $cmd_file endif # ======================== convert dicoms =============================== if ( "$idir" != "" ) then # place output into wdir, using gzipped files. # [PT: May 24, 2017] Control for multiecho files now dcm2niix_afni \ -z y \ -x n \ -p y \ -f ${npref}_%e \ -o "$wdir" \ $idir/ # clean up possible extraneous files cd "$wdir" set all_nii = `\ls ${npref}*.nii.gz` if ( ${#all_nii} < "1" ) then echo "\n** ERROR: no anatomical found" echo "\t(at least not with expected filename '2*')\n" goto BAD_EXIT else if ( ${#all_nii} >= "2" ) then echo "" echo "+* Warning: multiple possible vols, just choosing first one (?)" echo "" endif endif # ======================== copy input vol to wdir ======================= if ( "$inii" != "" ) then # just copy the vol to the wdir set fout = "_init_vol.nii.gz" 3dcalc \ -overwrite \ -a "$inii" \ -expr 'a' \ -prefix "$wdir/$fout" # ... and match with where things would be from "$idir" input cd "$wdir" set all_nii = "$fout" endif # ======================== process! ================================== # ---------- try to anonymize ------------- echo "++ Using nifti_tool to remove ID info, if possible." set fin = $all_nii[1] set fout = ${tpref}_empty.nii nifti_tool \ -strip_extras \ -prefix $fout \ -infiles $fin # ---------- reorient + center nicely, if desired ------------- if ( $DO_REORI ) then 3dresample \ -orient $ori_new \ -inset $fout \ -prefix ../$ofile \ -overwrite # put (0, 0, 0) at center of mass. (Aug, 2016) 3dCM -set 0 0 0 ../$ofile else # chicken... 3dcalc \ -a $fout \ -expr 'a' \ -prefix ../$ofile \ -overwrite endif cd "$here" set check = `3dinfo -prefix "$odir/$ofile"` if ( "$check" == "NO-DSET" ) then echo "Whoa, badness outputting: $odir/$ofile" goto BAD_EXIT else echo "\nAll done!" cd $odir echo "\nYour output anatomical is:\n\t$PWD/$ofile\n" cd "$here" endif # ---------------- imager ------------------- if ( "$DO_VIEWER" == "1" ) then if ( $qc_prefix == "" ) then set vpref0 = ${opref}_qc_anat else set vpref0 = ${qc_prefix}_qc_anat endif echo "\n\n" echo "++ QC image 00 ($odir/$ofile): $vpref0" echo "\n\n" # need to put '[0]' on $iref? $my_viewer \ -ulay "$odir/$ofile" \ -ulay_range "2%" "98%" \ -olay_off \ -prefix "$odirqc/$vpref0" \ -montx 5 -monty 3 \ -set_xhairs OFF \ -label_mode 1 -label_size 4 \ -do_clean endif # --------------- clean -------------------- if ( "$DO_CLEAN" == "1" ) then echo "\n++ Cleaning working directory!\n" cd "$here" \rm -rf "$wdir" else echo "\n++ NOT removing working directory '$wdir'.\n" endif goto GOOD_EXIT # ======================================================================== # ======================================================================== SHOW_HELP: cat << EOF ------------------------------------------------------------------------- The purpose of this function is to help convert an anatomical data set from DICOM files into a volume. Ummm, yep, that's about it. (But it will be done in a way to fit in line with other processing, particularly with DTI analysis, so it might not be *totally* useless; more options while converting might be added over time, as well.) REQUIRES: AFNI (which should now contain dcm2niix_afni, the version of dcm2niix [by C. Rorden] distributed in AFNI). Ver. $version (PA Taylor, ${rev_dat}) ------------------------------------------------------------------------- RUNNING: $this_prog \ {-indir DIR_IN | -innii NII_IN} \ -prefix PPP \ {-workdir WWW} \ {-orient ORIENT} \ {-no_clean} \ {-reorig_reorient_off} \ {-qc_prefix QCPREF} \ {-no_cmd_out} \ {-no_qc_view} where: -indir DIR_IN :input as dicom directory; DIR_IN should contain only DICOM files; all will be selected. -innii NII_IN :input as NIFTI file (zipped or unzipped fine). Alternative to '-indir ..'. The point of this option is to have all other "niceifying" steps applied to an already-converted volume. -prefix PPP :set prefix (and path) for output data; required. -workdir WWW :specify a working directory, which can be removed; (default name = '$wdir'). -orient ORIENT :optional chance to reset orientation of the volume files (default is currently '$ori_new'). -reorig_reorient_off :switch to turn of the nicety of putting (0, 0, 0) at brain's center of mass (-> 'reorigin' calc) and to not reorient data (-> 'reorient' calc). Could lead to weirdness later on down the road, depending on the data and headers (ergo, not recommended.) -qc_prefix QCPREF :can set the prefix of the QC image files separately (default is '$opref'). -no_qc_view :can turn off generating QC image files (why?) -no_cmd_out :don't save the command line call of this program and the location where it was run (otherwise, it is saved by default in the ODIR/). ------------------------------------------------------------------------- OUTPUTS: a single anatomical volume in the DIR_OUT. In some cases of anatomical volume acquisition, the DICOMS get converted to more than one format of volumetric output (one total acquired volume, one centered around the head, etc.); these usually have different formats of file name, starting with '2*', 'co*' and 'o*'. Basically, the '2*' is chosen for outputting, and the others are stored in a subdirectory called DIR_OUT/WWW/. ------------------------------------------------------------------------- EXAMPLES: $this_prog \ -indir "ANAT_DICOMS" \ -prefix outdir/anat \ -orient RAI $this_prog \ -innii t1w.nii.gz \ -prefix outdir/anat \ -orient RAI ------------------------------------------------------------------------- EOF goto GOOD_EXIT SHOW_VERSION: echo "version $version (${rev_dat})" goto GOOD_EXIT FAIL_MISSING_ARG: echo "** ERROR! Missing an argument after option flag: '$argv[$ac]'" goto BAD_EXIT BAD_EXIT: exit 1 GOOD_EXIT: exit 0