-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2_run_convoxel.sh
More file actions
executable file
·155 lines (129 loc) · 4.38 KB
/
2_run_convoxel.sh
File metadata and controls
executable file
·155 lines (129 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/bin/bash
usage() {
echo " Usage: $0 -c cohort_ISOVF.csv [-g /path/to/group_mask.nii.gz]"
exit 1
}
set -e # Exit on error
set -o pipefail
# Initialize variables
COHORT_FILE=""
GROUP_MASK_ARG=""
# Parse command-line options
#!/bin/bash
# Define debug function early
debug() {
if [ "$DEBUG" -eq 1 ]; then
echo -e "\033[1;36m[DEBUG] $*\033[0m" # Optional: color for visibility
fi
}
DEBUG=0 # Default; gets overridden by -d flag
while getopts ":c:g:d" opt; do
case $opt in
c) COHORT_FILE="$OPTARG" ;;
g) GROUP_MASK_ARG="$OPTARG" ;;
d) DEBUG=1 ;; # Enable debug mode
\?) echo "Invalid option -$OPTARG" >&2
exit 1 ;;
:) echo "Option -$OPTARG requires an argument." >&2
exit 1 ;;
esac
done
# Check if required options are provided
if [[ -z "$COHORT_FILE" ]]; then
echo "ERROR: Cohort file must be specified with -c option."
usage
exit 1
fi
echo "Your cohort file: $COHORT_FILE"
# Derive group mask: use explicit -g if provided, otherwise auto-detect from cohort CSV directory
if [[ -n "$GROUP_MASK_ARG" ]]; then
GROUP_MASK="$GROUP_MASK_ARG"
else
GROUP_MASK="$(dirname "$COHORT_FILE")/group_mask.nii.gz"
fi
RELATIVE_ROOT=$(dirname "$GROUP_MASK")
debug "Your root folder (auto-derived): $RELATIVE_ROOT"
debug "Group mask is located at: $GROUP_MASK"
if [[ ! -f "$COHORT_FILE" ]]; then
echo "ERROR: Cohort file not found: $COHORT_FILE"
exit 1
fi
if [[ ! -f "$GROUP_MASK" ]]; then
echo "ERROR: Group mask file not found: $GROUP_MASK"
exit 1
fi
# Extract scalar name from second line (first data row)
# Use sed to avoid tail|head SIGPIPE with set -o pipefail
SCALAR_NAME=$(sed -n '2p' "$COHORT_FILE" | cut -d',' -f1)
BASE_COHORT=$(basename "$COHORT_FILE" .csv)
# Write HDF5 next to the cohort CSV (use realpath so it works regardless of cwd)
OUTPUT_HDF5="$(realpath "$(dirname "$COHORT_FILE")")/${BASE_COHORT}.h5"
echo "Detected scalar: $SCALAR_NAME"
echo "Output will be written to: $OUTPUT_HDF5"
# Get group mask dimensions
GROUP_DIM=$(mrinfo "$GROUP_MASK" -quiet -size | tr -d '\n')
echo "Group mask dimension: $GROUP_DIM"
# Check each row in the cohort for existence and matching dimensions
echo "Validating cohort files..."
while IFS=',' read -r SCALAR FILE MASK_FILE SUBJECT_ID REST; do
debug "---"
debug "[DEBUG] SCALAR=$SCALAR, FILE=$FILE, MASK_FILE=$MASK_FILE, SUBJECT_ID=$SUBJECT_ID"
FULL_OD="${RELATIVE_ROOT}/${FILE}"
FULL_MASK="${RELATIVE_ROOT}/${MASK_FILE}"
debug "[CHECKPOINT] Checking files for $SUBJECT_ID"
debug " OD: $FULL_OD"
debug " MASK: $FULL_MASK"
if [[ ! -f "$FULL_OD" ]]; then
echo "❌ ERROR: Missing source file: $FULL_OD"
exit 1
fi
if [[ ! -f "$FULL_MASK" ]]; then
echo "❌ ERROR: Missing mask file: $FULL_MASK"
exit 1
fi
OD_DIM=$(mrinfo "$FULL_OD" -quiet -size | tr -d '\n')
MASK_DIM=$(mrinfo "$FULL_MASK" -quiet -size | tr -d '\n')
debug "[DEBUG] OD_DIM=$OD_DIM, MASK_DIM=$MASK_DIM"
if [[ "$OD_DIM" != "$GROUP_DIM" ]]; then
echo "❌ ERROR: Dimension mismatch for OD file ($SUBJECT_ID)"
exit 1
fi
if [[ "$MASK_DIM" != "$GROUP_DIM" ]]; then
echo "❌ ERROR: Dimension mismatch for MASK file ($SUBJECT_ID)"
exit 1
fi
done < <(tail -n +2 "$COHORT_FILE")
echo "All files validated successfully. Starting modelarray..."
# Resolve symlinks in the cohort so Singularity can bind their real locations.
# Collect real paths of all source files that live outside RELATIVE_ROOT.
EXTRA_BIND=""
REAL_PATHS=()
while IFS=',' read -r _scalar FILE _rest; do
ABS="${RELATIVE_ROOT}/${FILE}"
REAL=$(realpath -m "$ABS" 2>/dev/null || echo "$ABS")
if [[ "$REAL" != "${RELATIVE_ROOT}"* ]]; then
REAL_PATHS+=("$REAL")
fi
done < <(tail -n +2 "$COHORT_FILE")
if [[ ${#REAL_PATHS[@]} -gt 0 ]]; then
# Find the longest common path prefix across all resolved paths
COMMON="${REAL_PATHS[0]%/*}"
for p in "${REAL_PATHS[@]}"; do
while [[ "${p#${COMMON}}" == "${p}" ]]; do
COMMON="${COMMON%/*}"
[[ -z "$COMMON" ]] && COMMON="/" && break
done
done
EXTRA_BIND="-B ${COMMON}:${COMMON}"
echo "Extra bind mount (for symlinked data): $COMMON"
fi
singularity run --cleanenv \
-B "$RELATIVE_ROOT":"$RELATIVE_ROOT" \
$EXTRA_BIND \
/data/local/container/modelarray/modelarray_confixel_0.1.5.sif \
convoxel \
--group-mask-file "$GROUP_MASK" \
--cohort-file "$COHORT_FILE" \
--relative-root "$RELATIVE_ROOT" \
--output-hdf5 "$OUTPUT_HDF5"
echo "✅ Done: $OUTPUT_HDF5 created"