/ 4dConcatSubBriks
4dConcatSubBriks
  1  #!/usr/bin/env bash
  2  set -euo pipefail
  3  trap 'e=$?; [ $e -ne 0 ] && echo "$0 exited in error"' EXIT
  4  env | grep -q ^DRYRUN=. && DRYRUN=echo || DRYRUN=""
  5  env | grep -q ^NOAFNI= || NOAFNI=1
  6  
  7  usage(){
  8    cat >&2 <<HEREDOC
  9  USAGE:
 10    $(basename $0) [options] output.nii.gz 'gl*ob' [subbrik]"
 11  
 12  EXAMPLE:
 13    $(basename $0) allmprage.nii.gz '1*_2*/struct/*/*_G2_256x240*/mprage_warp_linear.nii.gz'
 14    $(basename $0) -n 2 -p '\\d' all_3rdvol.nii.gz  'file*.nii.gz'
 15    $(basename $0)  -p '\\d' all_3rdvol.nii.gz  -- file1.nii.gz file2.nii.gz
 16  
 17  SYNOPSIS:
 18   wrap around 3dbucket and 3drefit
 19   extract a subbrick from a list of nifti 
 20   label with luna ids
 21  
 22   Useful for quality checking many structurals, subject masks,  or individual contrasts
 23  
 24  OPTIONS: (are optional)
 25   -a                # show afni afteward
 26   -p '\d{5}_\d{8}'  # change id pattern
 27   -h                # this help
 28   -n SUBBRICKIDX    # use zero-index subbrick instead of first (0)
 29   -o output.nii.gz  # can use -o. if not assumed first argument will be output file name
 30   -- file1 file2 ...# instead of using 'gl*b', expliclty list input files after --
 31  
 32  ARGUMENTS:
 33   output.nii.gz - final file to create
 34   'gl*ob' - file glob matching all images to concat. MUST BE QUOTED. 
 35  
 36  NOTES:
 37    * options must come before arguments.
 38       good: 4dConcatSubBriks -n 2 output.nii.gz '/path/to/*nii.gz'
 39       bad: 4dConcatSubBriks output.nii.gz '/path/to/*nii.gz' -n 2 
 40    * 'gl*ob' should be quoted. if you want to expliclty enumerate files, use -- file1 file2 ....
 41    * cant mix '--' and '-n'
 42  HEREDOC
 43    exit 1
 44  }
 45  
 46  [ $# -lt 2 ] && usage
 47  PATTERN='\d{5}_\d{8}'
 48  FILES=
 49  prefix=
 50  subbrik=0
 51  
 52  while [ $# -gt 0 ]; do
 53     case $1 in
 54       -p) PATTERN="$2"; shift 2;;
 55       -a) NOAFNI=""; shift;;
 56       -h) usage;;
 57       -n) subbrik="$2"; shift 2;;
 58       -o) prefix="$2"; shift 2;;
 59       --) shift; FILES=("$@"); set -- ;;
 60        *) break;; # nothing to do. will use stuff later
 61     esac
 62  done
 63  
 64  # initially allowed prefix to be first argument (after options)
 65  # continue allowing that if we didn't specify with -o
 66  [ $# -eq 0 ] && [ -z "$prefix" ] && echo "output prefix not specified! For help, see $0 -h" && exit 1
 67  [ -z "$prefix" ] && prefix="$1" && shift
 68  
 69  if [ -z "$FILES" ]; then
 70     [ $# -eq 0 ] && echo "no files specified! For help, see $0 -h" && exit 1
 71     glob="$1"; shift
 72     [ $# -gt 0 ] && echo "too many input argumetns ($#)! maybe you need single quotes around the 'gl*ob'?" >&2 && exit 1
 73     ! [[ $prefix =~ nii$|nii.gz$|.HEAD$ ]] && echo "prefix '$prefix' must end in .nii, .nii.gz, or .HEAD" && exit 1
 74     [ -z "$(ls $glob)" ] && echo "bad glob provided ('$glob'). afni files? maybe add '.HEAD' to glob?" >&2 && exit 1
 75     ids=($(ls $glob | grep -Po "$PATTERN" || :))
 76     [ -z "$ids" ] && echo "could not find ID using pattern '$PATTERN' in provided glob '$glob'" >&2 && exit 1
 77     FILES=($(ls $glob | sed "s/$/[$subbrik]/"))
 78  else
 79    [ $subbrik -ne 0 ] && echo "ERROR: -n not supported with '--' explicit file list. add it with sed if you must" && exit 1
 80    # check all exist -- might have [] or other afni syntax. use 3dinfo instead of just [ -f ... ]
 81    for f in "${FILES[@]}"; do  ! 3dinfo -space $f >/dev/null && echo "ERROR: cannot read $f" && exit 1; done
 82    # extract ids
 83    ids=($(for f in "${FILES[@]}"; do echo $f; done | grep -Po "$PATTERN" || :))
 84  fi
 85  
 86  echo "# Input Files: ${FILES[*]}"
 87  
 88  [ ${#ids[@]} -ne ${#FILES[@]} ] && echo "ERROR: have ${#ids[@]} ids but ${#FILES[@]} files. Consider modifying pattern '$PATTERN' with -p."
 89   
 90  if [ ! -r "$prefix" ]; then
 91     echo "3dbucket: combine"
 92     $DRYRUN 3dbucket -prefix "$prefix" "${FILES[@]}"
 93     echo "3drefit: relabel"
 94     $DRYRUN 3drefit -relabel_all_str "${ids[*]}" "$prefix"
 95  else 
 96     echo "rm $prefix # to regenerate; skipping 3dbucket and 3drefit"
 97  fi
 98  
 99  [ -n "$DRYRUN" ] && exit 0
100  [ -n "$NOAFNI" ] && exit 0
101  
102  afni -com 'OPEN_WINDOW axialgraph' "$prefix"  >/dev/null 2>&1
103  
104  outidx=$(3dROIstats -quiet  -mask "3dcalc( -expr step(a) -a $prefix[0] )"  $prefix |
105           Rscript -e 'd<-read.table("stdin");cat(paste(sep=",",collapse=",",which( abs(d$V1) > abs(mean(d$V1))+2*sd(d$V1) )-1))')
106  if [ -n "$outidx" ]; then
107     echo "outlier idxes: $outidx"
108     echo -n "outlier labels: "
109     3dinfo -label "$prefix[$outidx]"
110  fi
111