/ 4dConcatDataTable
4dConcatDataTable
1 #!/usr/bin/env bash 2 set -euo pipefail 3 trap 'e=$?; [ $e -ne 0 ] && echo "$0 exited in error"' EXIT 4 5 # wrap around 3dbucket and 3drefit 6 # extract a subbrick from a list of nifti 7 # label with luna ids 8 # 20200430 - like 4dConcatSubBriks but for a datatable file 9 # 20231016 - add stdin option 10 # 11 usage(){ 12 cat <<HEREDOC 13 use 3dMVM/3dLME datatable to create 4d concat image 14 Useful for quality checking many structurals, subject masks, or individual contrasts. 15 Wraps (1) 3dbucket InputFile column (2) 3drefit w/ Subj column 16 17 USAGE: 18 $(basename "$0") output.nii.gz datatable.tsv [extraidcol] 19 20 OPTIONS: 21 output.nii.gz the file to create 22 will not overwrite (must rm to rerun) 23 24 datatable.tsv input file as used by AFNI's 3dMVM or 3dLME 25 tab separated. 26 must have header w/ 'Subj' and 'InputFile' columns 27 can be '-' to read from stdin 28 29 extraidcol optional extra column(s) to add to 3drefit ids (regexp) 30 '|' to seprate multiples: 'Sess|Sex' (id is combined Subj,Sess,Sex) 31 32 EXAMPLES: 33 4dConcatDataTable /tmp/all.nii.gz r2p.tsv 34 35 4dConcatDataTable /tmp/all.nii.gz r2p.tsv 'session|shapes' 36 37 mlr --tsv filter '\$InputFile =~ "ses-01"' r2p.tsv| 4dConcatDataTable /tmp/ses1.nii.gz - 38 39 HEREDOC 40 } 41 42 [ $# -lt 2 -o $# -gt 3 ] && usage >&2 && exit 1 43 44 prefix="$1"; shift 45 datatable="$1"; shift 46 47 ! [[ $prefix =~ .nii$|.nii.gz$|.HEAD$ ]] && 48 echo "prefix '$prefix' must end in .nii, .nii.gz, or .HEAD" && exit 1 49 50 [ -r "$prefix" ] && 51 echo "rm $prefix # to regenerate; skipping 3dbucket and 3drefit" && 52 exit 0 53 54 if [ "$datatable" = "-" ]; then 55 tty >/dev/null && 56 echo -e "ERROR: using '$datatable' as datatable requires pipe;\n\t grep thing | $(basename "$0") $prefix $datatable $*" && 57 exit 1 58 datatable=$(mktemp "${TMPDIR:-/tmp}/4dConcatTable_XXXX.tsv") 59 cat > "$datatable" 60 # TODO: this disables original exit in error trap 61 trap 'echo "# removing $datatable" && rm "$datatable"; exit' EXIT 62 fi 63 64 [ ! -r "$datatable" ] && 65 echo "$datatable file doesn't exist!" && exit 1 66 #read ididx fileidx <<< $(sed 1q $datatable | sed 's/[ \t]\+/\n/g' | perl -lne 'print $. if m/(Subj|InputFile)/i') 67 68 # if we want to use an extra id 69 extraid=""; extraidpatt=""; awkextra="" 70 [ $# -eq 1 ] && extraid="$1" && extraidpatt="|$extraid" 71 72 mapfile -t idxs < <(sed 1q "$datatable" | sed 's/[ \t]\+/\n/g' | perl -lne "print $. if m/(Subj$extraidpatt|InputFile)/i") 73 # index of the file index is last item 74 # but 0-based. so minus 1 75 fii=${#idxs[@]} 76 ! let fii-- && echo "ERROR: no files in $datatable!? Does input have a header?" && exit 1 77 78 # TODO: test only 2 if not $3, 3 otherwise? 79 80 ididx=${idxs[0]} 81 fileidx=${idxs[$fii]} 82 [ ${#idxs[@]} -eq 3 ] && awkextra=' "_"'"\$${idxs[1]}" 83 84 [ -z "$fileidx" ] && echo "no InputFile in '$datatable' header?! (idxs '$ididx' '$fileidx')" && exit 1 85 mapfile -t ids < <(awk "(NR>1) { print \$$ididx$awkextra}" "$datatable") 86 mapfile -t files < <(awk "(NR>1){ print \$$fileidx}" "$datatable") 87 [ ${#ids[@]} -ne "${#files[@]}" ] && 88 echo "error parsing '$datatable'. have different number of ids and files!" && 89 exit 1 90 91 92 echo "3dbucket: combine" 93 dryrun 3dbucket -prefix "$prefix" "${files[@]}" 94 echo "3drefit: relabel" 95 dryrun 3drefit -relabel_all_str "${ids[*]}" "$prefix"