Skip to content

Commit f52cf18

Browse files
Add biobank merge code (#1304)
* Add biobank merge code * Skip biobank merge non-fatally when S3 download or combine fails * Add try_upload/download S3 helpers while preserving fatal wrappers Co-authored-by: Manda Wilson <1458628+mandawilson@users.noreply.github.com>
1 parent 55310ae commit f52cf18

2 files changed

Lines changed: 98 additions & 16 deletions

File tree

import-scripts/fetch-dmp-data-for-import.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,36 @@ MY_FLOCK_FILEPATH="/data/portal-cron/cron-lock/fetch-dmp-data-for-import.lock"
1313
# localize global variables / jar names and functions
1414
source $PORTAL_HOME/scripts/dmp-import-vars-functions.sh
1515

16+
# Merge biobank patient clinical data when present (already synced via downloadFromS3AllStudies).
17+
# Clinical merge failure is non-fatal; an existing biobank timeline file is kept for CDM timeline merge.
18+
function merge_biobank_clinical_data() {
19+
local study_data_home="$1"
20+
21+
local input_clinical_file="$study_data_home/data_clinical_patient.txt"
22+
local biobank_clinical_file="$study_data_home/data_clinical_patient_biobank.txt"
23+
local biobank_timeline_file="$study_data_home/data_timeline_biobank_specimen.txt"
24+
local merged_clinical_file="$study_data_home/data_clinical_patient_merged.txt"
25+
26+
if [ -f "$biobank_clinical_file" ]; then
27+
$PYTHON3_BINARY $PORTAL_HOME/scripts/combine_files_py3.py -i "$input_clinical_file" "$biobank_clinical_file" -o "$merged_clinical_file" -c "PATIENT_ID" -m left
28+
if [ $? -gt 0 ]; then
29+
echo "`date`: Warning: failed to merge biobank patient clinical data for ${study_data_home}; skipping biobank clinical merge for this import."
30+
rm -f "$merged_clinical_file"
31+
else
32+
mv "$merged_clinical_file" "$input_clinical_file"
33+
rm -f "$biobank_clinical_file"
34+
fi
35+
else
36+
echo "`date`: Warning: biobank patient clinical file not found in ${study_data_home}; skipping biobank clinical merge for this import."
37+
fi
38+
39+
if [ -f "$biobank_timeline_file" ]; then
40+
echo "`date`: Biobank timeline data present in ${study_data_home}."
41+
fi
42+
43+
return 0
44+
}
45+
1646
## STATUS FLAGS
1747

1848
# Flags indicating whether a study can be updated
@@ -733,6 +763,9 @@ MY_FLOCK_FILEPATH="/data/portal-cron/cron-lock/fetch-dmp-data-for-import.lock"
733763
else
734764
echo "UNLINKED_ARCHER subset successful! Creating cancer type case lists..."
735765
echo $(date)
766+
767+
merge_biobank_clinical_data "$MSK_ARCHER_DATA_HOME"
768+
736769
# add metadata headers and overrides before importing
737770
$PYTHON_BINARY $PORTAL_HOME/scripts/add_clinical_attribute_metadata_headers.py -s mskarcher -f $MSK_ARCHER_DATA_HOME/data_clinical* -i $PORTAL_HOME/scripts/cdm_metadata.json
738771
if [ $? -gt 0 ] ; then
@@ -806,6 +839,9 @@ MY_FLOCK_FILEPATH="/data/portal-cron/cron-lock/fetch-dmp-data-for-import.lock"
806839
else
807840
echo "MSKSOLIDHEME merge successful! Creating cancer type case lists..."
808841
echo $(date)
842+
843+
merge_biobank_clinical_data "$MSK_SOLID_HEME_DATA_HOME"
844+
809845
# add metadata headers and overrides before importing
810846
$PYTHON_BINARY $PORTAL_HOME/scripts/add_clinical_attribute_metadata_headers.py -s mskimpact -f $MSK_SOLID_HEME_DATA_HOME/data_clinical_sample.txt -i $PORTAL_HOME/scripts/cdm_metadata.json
811847
$PYTHON_BINARY $PORTAL_HOME/scripts/add_clinical_attribute_metadata_headers.py -s mskimpact -f $MSK_SOLID_HEME_DATA_HOME/data_clinical_patient.txt -i $PORTAL_HOME/scripts/cdm_metadata.json

import-scripts/s3_functions.sh

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,25 @@ if ! [ -n "$PORTAL_HOME" ] ; then
55
exit 1
66
fi
77

8-
# Uploads a file or directory to an S3 bucket (from local to S3)
9-
# If a directory is provided, files removed locally will be deleted from S3
10-
# PATH_TO_UPLOAD must end in the same path as PATH_IN_S3, or the script exits with an error
11-
function upload_to_s3() {
8+
# Uploads a file or directory to an S3 bucket (from local to S3).
9+
# If a directory is provided, files removed locally will be deleted from S3.
10+
# Returns 0 on success, 1 on failure (does not exit the shell).
11+
#
12+
# Args:
13+
# $1 PATH_TO_UPLOAD Local file or directory to upload (must exist).
14+
# $2 PATH_IN_S3 S3 key prefix within the bucket (no s3:// prefix). Must match
15+
# the trailing path of PATH_TO_UPLOAD, unless empty to sync the
16+
# bucket root (e.g. upload_to_s3 "$DMP_DATA_HOME" "" "mskimpact-databricks").
17+
# $3 BUCKET_NAME S3 bucket name (e.g. mskimpact-databricks).
18+
function try_upload_to_s3() {
1219
PATH_TO_UPLOAD="$1"
1320
PATH_IN_S3="$2"
1421
BUCKET_NAME="$3"
1522

1623
# Check if path exists
1724
if [ ! -e "$PATH_TO_UPLOAD" ]; then
1825
echo "`date`: Path '$PATH_TO_UPLOAD' does not exist, exiting..."
19-
exit 1
26+
return 1
2027
fi
2128

2229
# Normalize paths
@@ -28,7 +35,7 @@ function upload_to_s3() {
2835
if [ -n "$PATH_IN_S3_CLEAN" ]; then
2936
if [[ "$PATH_TO_UPLOAD_ABS" != *"/$PATH_IN_S3_CLEAN" && "$PATH_TO_UPLOAD_ABS" != "$PATH_IN_S3_CLEAN" ]]; then
3037
echo "`date`: ERROR – PATH_IN_S3 ('$PATH_IN_S3') must exactly match the trailing path of '$PATH_TO_UPLOAD_ABS'. Exiting..."
31-
exit 1
38+
return 1
3239
fi
3340
fi
3441

@@ -56,38 +63,61 @@ function upload_to_s3() {
5663
--profile saml
5764
else
5865
echo "`date`: '$PATH_TO_UPLOAD' is neither a file nor a directory, exiting..."
59-
exit 1
66+
return 1
6067
fi
6168

6269
if [ $? -ne 0 ]; then
6370
echo "`date`: Failed to upload '$PATH_TO_UPLOAD' to S3, exiting..."
71+
return 1
72+
fi
73+
}
74+
75+
# Uploads a file or directory to an S3 bucket (from local to S3).
76+
# If a directory is provided, files removed locally will be deleted from S3.
77+
# Exits 1 on failure.
78+
#
79+
# Args:
80+
# $1 PATH_TO_UPLOAD Local file or directory to upload (must exist).
81+
# $2 PATH_IN_S3 S3 key prefix within the bucket (no s3:// prefix). Must match
82+
# the trailing path of PATH_TO_UPLOAD, unless empty to sync the
83+
# bucket root (e.g. upload_to_s3 "$DMP_DATA_HOME" "" "mskimpact-databricks").
84+
# $3 BUCKET_NAME S3 bucket name (e.g. mskimpact-databricks).
85+
function upload_to_s3() {
86+
if ! try_upload_to_s3 "$1" "$2" "$3"; then
6487
exit 1
6588
fi
6689
}
6790

68-
# Syncs a file or directory from S3 to a local path
69-
# Files not in S3 will be removed from the local destination (for directories)
70-
# PATH_TO_OVERWRITE must end in PATH_IN_S3 (if provided), and cannot be "/"
71-
function download_from_s3() {
91+
# Syncs a file or directory from S3 to a local path.
92+
# Files not in S3 will be removed from the local destination (for directories).
93+
# Returns 0 on success, 1 on failure (does not exit the shell).
94+
#
95+
# Args:
96+
# $1 PATH_TO_OVERWRITE Local file or directory to sync into (must already exist; cannot be "/").
97+
# $2 PATH_IN_S3 S3 key prefix within the bucket (no s3:// prefix). Must match
98+
# the trailing path of PATH_TO_OVERWRITE, unless empty to sync the
99+
# bucket root (e.g. download_from_s3 "$DMP_DATA_HOME" "" "mskimpact-databricks").
100+
# $3 BUCKET_NAME S3 bucket name (e.g. mskimpact-databricks).
101+
function try_download_from_s3() {
72102
PATH_TO_OVERWRITE="$1"
73103
PATH_IN_S3="$2"
74104
BUCKET_NAME="$3"
75105

76106
# Normalize local path
77107
if [ -z "$PATH_TO_OVERWRITE" ]; then
78108
echo "`date`: PATH_TO_OVERWRITE is empty, exiting..."
79-
exit 1
109+
return 1
80110
fi
81111

82112
PATH_TO_OVERWRITE_ABS=$(realpath "$PATH_TO_OVERWRITE" 2>/dev/null)
83113
if [ $? -ne 0 ]; then
84114
echo "`date`: '$PATH_TO_OVERWRITE' does not exist, exiting..."
85-
exit 1
115+
return 1
86116
fi
87117

88118
if [ "$PATH_TO_OVERWRITE_ABS" == "/" ]; then
89119
echo "`date`: Refusing to sync to root directory '/', exiting..."
90-
exit 1
120+
return 1
91121
fi
92122

93123
# Clean PATH_IN_S3
@@ -97,7 +127,7 @@ function download_from_s3() {
97127
if [ -n "$PATH_IN_S3_CLEAN" ]; then
98128
if [[ "$PATH_TO_OVERWRITE_ABS" != *"/$PATH_IN_S3_CLEAN" && "$PATH_TO_OVERWRITE_ABS" != "$PATH_IN_S3_CLEAN" ]]; then
99129
echo "`date`: ERROR – PATH_IN_S3 ('$PATH_IN_S3') must exactly match the trailing path of '$PATH_TO_OVERWRITE_ABS'. Exiting..."
100-
exit 1
130+
return 1
101131
fi
102132
fi
103133

@@ -129,11 +159,27 @@ function download_from_s3() {
129159

130160
else
131161
echo "`date`: '$PATH_TO_OVERWRITE_ABS' is neither a file nor a directory, exiting..."
132-
exit 1
162+
return 1
133163
fi
134164

135165
if [ $? -ne 0 ]; then
136166
echo "`date`: Failed to download from '$S3_SOURCE', exiting..."
167+
return 1
168+
fi
169+
}
170+
171+
# Syncs a file or directory from S3 to a local path.
172+
# Files not in S3 will be removed from the local destination (for directories).
173+
# Exits 1 on failure.
174+
#
175+
# Args:
176+
# $1 PATH_TO_OVERWRITE Local file or directory to sync into (must already exist; cannot be "/").
177+
# $2 PATH_IN_S3 S3 key prefix within the bucket (no s3:// prefix). Must match
178+
# the trailing path of PATH_TO_OVERWRITE, unless empty to sync the
179+
# bucket root (e.g. download_from_s3 "$DMP_DATA_HOME" "" "mskimpact-databricks").
180+
# $3 BUCKET_NAME S3 bucket name (e.g. mskimpact-databricks).
181+
function download_from_s3() {
182+
if ! try_download_from_s3 "$1" "$2" "$3"; then
137183
exit 1
138184
fi
139185
}

0 commit comments

Comments
 (0)