Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 1e79704

Browse files
authored
Merge pull request #1 from flywheel-apps/v0.1.4
V0.1.4
2 parents 15397e3 + 37d7eba commit 1e79704

File tree

3 files changed

+46
-29
lines changed

3 files changed

+46
-29
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[![Docker Pulls](https://img.shields.io/docker/pulls/flywheel/hcp-struct.svg)](https://hub.docker.com/r/flywheel/hcp-struct/)
2+
[![Docker Stars](https://img.shields.io/docker/stars/flywheel/hcp-struct.svg)](https://hub.docker.com/r/flywheel/hcp-struct/)
13
# flywheel/hcp-struct
24
[Flywheel Gear](https://github.com/flywheel-io/gears/tree/master/spec) that runs the structural preprocessing steps of the [Human Connectome Project](http://www.humanconnectome.org) Minimal Preprocessing Pipeline (MPP) described in [Glasser et al. 2013](http://www.ncbi.nlm.nih.gov/pubmed/23668970). Currently, this includes v4.0-alpha release of PreFreeSurfer, FreeSurfer, and PostFreeSurfer pipelines, as well as generating some helpful QC images. For more info on the pipelines, see [HCP Pipelines](https://github.com/Washington-University/Pipelines).
35

manifest.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
"description": "Runs the structural preprocessing steps of the Human Connectome Project Minimal Preprocessing Pipeline, described in Glasser et al. 2013. Currently this includes v4.0-alpha release of PreFreeSurfer, FreeSurfer, and PostFreeSurfer pipelines. This Gear also generates some helpful QC images.",
55
"author": "Human Connectome Project",
66
"maintainer": "Flywheel <[email protected]>",
7-
"license": "Apache-2.0",
7+
"license": "Other",
88
"url": "https://github.com/Washington-University/Pipelines",
99
"source": "https://github.com/flywheel-apps/hcp-struct",
10-
"version": "0.1.3",
10+
"cite": "Glasser M. F., Sotiropoulos S. N., Wilson J. A., Coalson T. S., Fischl B., Andersson J. L., … Consortium, W. U.-M. H. (2013). The minimal preprocessing pipelines for the Human Connectome Project. NeuroImage, 80, 105–124.",
11+
"version": "0.1.4",
1112
"custom": {
12-
"docker-image": "flywheel/hcp-struct:0.1.3"
13+
"docker-image": "flywheel/hcp-struct:0.1.4"
14+
},
15+
"flywheel": {
16+
"suite": "Human Connectome Project"
1317
},
1418
"inputs": {
1519
"T1": {

run

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,34 @@ source ${FLYWHEEL_BASE}/docker-env.sh
2121
source ${SCRIPT_DIR}/bash_functions.sh # some useful tools
2222

2323
##############################################################################
24-
# Parse configuration options
24+
# Parse configuration
2525

26-
# If config.json exists, then we parse config file and cast vals to ENV Vars
27-
# (Flywheel gear run). Otherwise we parse manifest.json and cast the values to
28-
# ENV Vars from manifest (Docker run) Note value.default is used to grab the
29-
# configured defaults.
26+
# If the config file does not exist (i.e., local run) then parse the config
27+
# options and values from the manifest. Those variables can be found in the
28+
# manifest.json file within the `config` map.
29+
30+
function parse_config {
31+
CONFIG_FILE=$FLYWHEEL_BASE/config.json
32+
MANIFEST_FILE=$FLYWHEEL_BASE/manifest.json
33+
34+
if [[ -f $CONFIG_FILE ]]; then
35+
echo -e "$(cat $CONFIG_FILE | jq -r '.config.'$1)"
36+
else
37+
CONFIG_FILE=$MANIFEST_FILE
38+
echo -e "$(cat $MANIFEST_FILE | jq -r '.config.'$1'.default')"
39+
fi
40+
}
41+
42+
FW_CONFIG_Subject="$(parse_config 'Subject')"
43+
FW_CONFIG_RegName="$(parse_config 'RegName')"
44+
FW_CONFIG_BrainSize="$(parse_config 'BrainSize')"
45+
FW_CONFIG_TemplateSize="$(parse_config 'TemplateSize')"
46+
FW_CONFIG_StructuralUnwarpDirection="$(parse_config 'StructuralUnwarpDirection')"
3047

31-
if [[ -f $CONFIG_FILE ]]; then
32-
eval $(jq -r '.config | to_entries[] | "FW_CONFIG_\(.key)=\(.value)"' $CONFIG_FILE)
33-
eval $(jq -r '.inputs | to_entries[] | "FW_INPUT_\(.key)=\(.value.location.path)"' $CONFIG_FILE)
34-
else
35-
CONFIG_FILE=$FLYWHEEL_BASE/manifest.json
36-
eval $(jq -r '.config | to_entries[] | "FW_CONFIG_\(.key)=\(.value.default)"' $CONFIG_FILE)
37-
fi
3848

3949
##############################################################################
4050
# use "echo" for testing arguments without running scripts
51+
4152
RUN_PRE=""
4253
RUN_FS=""
4354
RUN_POST=""
@@ -64,7 +75,7 @@ StructuralUnwarpDir="z" #z appears to be best or "NONE" if not used
6475
StructuralDeltaTE="NONE" #DeltaTE for GRE fieldmap used to correct STRUCTURAL
6576
StructuralDwellTime="NONE" # DwellTime for SpinEchoFieldMap when TOPUP is used for STRUCTURAL (ie: not T1wSampleSpacing)
6677

67-
AvgrdcSTRING="NONE" # = Distortion correction for Structural pipeline (NONE, FIELDMAP==SiemensFieldMap, GeneralElectricFieldMap, TOPUP)
78+
AvgrdcSTRING="NONE" # = Distortion correction for Structural pipeline (NONE, FIELDMAP==SiemensFieldMap, GeneralElectricFieldMap, TOPUP)
6879
# --> TOPUP requires SpinEchoPhaseEncodeNegative, SpinEchoPhaseEncodePositive
6980
# --> SiemensFieldMap requires MagnitudeInputName, PhaseInputName
7081
# --> GeneralElectricFieldMap requires GEB0InputName
@@ -77,7 +88,7 @@ PhaseInputName="NONE"
7788
UnwarpDir="NONE"
7889
SEUnwarpDir="NONE"
7990

80-
GradientDistortionCoeffs="NONE" #no gradient correction unless we are provided with a .grad file
91+
GradientDistortionCoeffs="NONE" #no gradient correction unless we are provided with a .grad file
8192

8293
#######################################
8394
# Process inputs and config options from app
@@ -113,26 +124,26 @@ if [[ -e "${FW_INPUT_SiemensGREPhase}" ]] && [[ -e "${FW_INPUT_SiemensGREMagnitu
113124
MagnitudeInputName="${FW_INPUT_SiemensGREMagnitude}"
114125
PhaseInputName="${FW_INPUT_SiemensGREPhase}"
115126
AvgrdcSTRING="SiemensFieldMap"
116-
127+
117128
#Ideally, FieldMap_Phase .json would contain EchoTime1 and EchoTime2
118129
#echotime1=$(jq -r '.inputs["SiemensGREPhase"].object.info.EchoTime1 // empty' ${CONFIG_FILE})
119130
#echotime2=$(jq -r '.inputs["SiemensGREPhase"].object.info.EchoTime2 // empty' ${CONFIG_FILE})
120-
131+
121132
echotime1=$(jq -r '.inputs["SiemensGREMagnitude"].object.info.EchoTime // empty' ${CONFIG_FILE})
122133
echotime2=$(jq -r '.inputs["SiemensGREPhase"].object.info.EchoTime // empty' ${CONFIG_FILE})
123-
134+
124135
if [[ -z "$echotime1" ]] || [[ -z "$echotime2" ]]; then
125136
echo -e "${CONTAINER} [$(timestamp)] No EchoTime metadata found in FieldMap input file! Exiting."
126137
exit 1
127138
elif [[ "$echotime1" == "$echotime2" ]]; then
128139
echo -e "${CONTAINER} [$(timestamp)] EchoTime1 and EchoTime2 are the same (Please ensure Magnitude input is TE1)! Exiting."
129140
exit 1
130141
fi
131-
142+
132143
echotime1=$(print_decimal_number $echotime1)
133144
echotime2=$(print_decimal_number $echotime2)
134145
StructuralDeltaTE=$(echo "($echotime2 - $echotime1)*1000.0" | bc -l)
135-
146+
136147
# For SpinEcho "TOPUP" FieldMap, must include both Pos and Neg phase encode
137148
elif [[ -e "${FW_INPUT_SpinEchoNegative}" ]] && [[ -e "${FW_INPUT_SpinEchoPositive}" ]]; then
138149
SpinEchoPhase1="${FW_INPUT_SpinEchoPositive}"
@@ -142,7 +153,7 @@ elif [[ -e "${FW_INPUT_SpinEchoNegative}" ]] && [[ -e "${FW_INPUT_SpinEchoPositi
142153
pedirSE2=$(jq -r '.inputs["SpinEchoNegative"].object.info.PhaseEncodingDirection // empty' ${CONFIG_FILE})
143154
pedirSE1=$( echo "$pedirSE1" | tr "[ijk]" "[xyz]" )
144155
pedirSE2=$( echo "$pedirSE2" | tr "[ijk]" "[xyz]" )
145-
156+
146157
if [[ -z "${pedirSE1}" ]]; then
147158
echo -e "${CONTAINER} [$(timestamp)] SpinEchoPositive input is missing PhaseEncodingDirection metadata!"
148159
exit 1
@@ -153,7 +164,7 @@ elif [[ -e "${FW_INPUT_SpinEchoNegative}" ]] && [[ -e "${FW_INPUT_SpinEchoPositi
153164
echo -e "${CONTAINER} [$(timestamp)] SpinEchoPositive and SpinEchoNegative have the same PhaseEncodingDirection (${pedirSE1})!"
154165
exit 1
155166
fi
156-
167+
157168
if [[ "${pedirSE1},${pedirSE2}" == "x,x-" ]] || [[ "${pedirSE1},${pedirSE2}" == "y,y-" ]]; then
158169
SpinEchoPhaseEncodePositive="${SpinEchoPhase1}"
159170
SpinEchoPhaseEncodeNegative="${SpinEchoPhase2}"
@@ -165,18 +176,18 @@ elif [[ -e "${FW_INPUT_SpinEchoNegative}" ]] && [[ -e "${FW_INPUT_SpinEchoPositi
165176
echo -e "${CONTAINER} [$(timestamp)] Unrecognized SpinEcho phase-encoding directions (${pedirSE1},${pedirSE2})!"
166177
exit 1
167178
fi
168-
179+
169180
StructuralDwellTime=$(print_decimal_number $(jq -r '.inputs["SpinEchoPositive"].object.info.EffectiveEchoSpacing // empty' ${CONFIG_FILE}))
170181
TopupDwellTime=$(print_decimal_number $(jq -r '.inputs["SpinEchoPositive"].object.info.EffectiveEchoSpacing // empty' ${CONFIG_FILE}))
171182
pedirSE_plane=$( echo "${pedirSE1}" | sed -E 's/[-+]//g' )
172183
SEUnwarpDir=${pedirSE_plane}
173184
AvgrdcSTRING="TOPUP"
174-
185+
175186
elif [[ -e "${FW_INPUT_GeneralElectricFieldMap}" ]]; then
176187
#TODO: how do we handle GE fieldmap? where do we get deltaTE?
177188
echo -e "${CONTAINER} [$(timestamp)] Cannot currently handle GeneralElectricFieldmap!"
178189
exit 1
179-
190+
180191
#GEB0InputName="${FW_INPUT_GeneralElectricFieldMap}"
181192
#AvgrdcSTRING="GeneralElectricFieldMap"
182193
fi
@@ -405,7 +416,7 @@ fi
405416
# - For now, don't copy full input json since it might contain identifiers from DICOM etc
406417
# - add/update .config.RegName since it might not have been included in config (pre-MSM availability)
407418
# - add/update .config.Subject since it might later be pulled from other session metadata
408-
# - This jq call does the value replacement, then selects just .config but stores it back into a
419+
# - This jq call does the value replacement, then selects just .config but stores it back into a
409420
# new element called ".config" so the new file can be read as though it was flywheel config.json
410421
OUTPUT_CONFIG_FILE=${StudyFolder}/${Subject}/${Subject}_hcpstruct_config.json
411422
jq -r '.config.RegName = "'"${RegName}"'" | .config.Subject = "'"${Subject}"'" | .config | {config: .}' $CONFIG_FILE \
@@ -415,7 +426,7 @@ jq -r '.config.RegName = "'"${RegName}"'" | .config.Subject = "'"${Subject}"'" |
415426
| jq -r '.config.LowResMesh = "'"${LowResMesh}"'"' > ${OUTPUT_CONFIG_FILE}
416427

417428
# If pipeline successful, zip outputs and clean up
418-
outputzipname=${Subject}_hcpstruct.zip
429+
outputzipname=${Subject}_hcpstruct.zip
419430
echo -e "${CONTAINER} [$(timestamp)] Zipping output file ${outputzipname}"
420431
cd ${StudyFolder}
421432
rm -f ${OUTPUT_DIR}/${outputzipname}

0 commit comments

Comments
 (0)