rc-qlc 0.3.24__cp311-cp311-win32.whl → 0.3.27__cp311-cp311-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qlc/cli/__init__.py +100 -9
- qlc/cli/installer.py +23 -5
- qlc/cli/qlc_main.py +54 -32
- qlc/cli/qlc_py_main.py +43 -38
- qlc/config/json/qlc_config.json +94 -10
- qlc/config/nml/mars_A1_sfc.nml +4 -5
- qlc/config/nml/mars_A3_sfc.nml +0 -1
- qlc/config/nml/mars_B1_pl.nml +2 -2
- qlc/{examples/cams_case_1/config/nml/mars_A3_sfc.nml → config/nml/mars_B1_sfc.nml} +7 -8
- qlc/config/nml/mars_C1_pl.nml +1 -1
- qlc/{examples/cams_case_1/config/nml/mars_C1_pl.nml → config/nml/mars_C1_sfc.nml} +7 -8
- qlc/config/nml/mars_C2_pl.nml +1 -1
- qlc/{examples/cams_case_1/config/qlc_cams.conf → config/qlc.conf} +80 -18
- qlc/{examples/cams_case_1/mod/b2ro/2018/b2ro_20181215-20181231_A3_sfc.grb → doc/CAMS_b2ro-b2rn_20181201-20181221_qlc_Z1-png_202509090814.pdf} +0 -0
- qlc/doc/README.md +213 -49
- qlc/doc/USAGE.md +266 -29
- qlc/examples/cams_case_1/mod/b2rn/2018/b2rn_20181201-20181221_B1_pl.grb +0 -0
- qlc/examples/cams_case_1/mod/b2rn/2018/b2rn_20181201-20181221_C1_sfc.grb +0 -0
- qlc/examples/cams_case_1/mod/b2ro/2018/b2ro_20181201-20181221_B1_pl.grb +0 -0
- qlc/examples/cams_case_1/mod/b2ro/2018/b2ro_20181201-20181221_C1_sfc.grb +0 -0
- qlc/install.py +272 -107
- qlc/py/__main__.cp311-win32.pyd +0 -0
- qlc/py/averaging.cp311-win32.pyd +0 -0
- qlc/py/bias_plots.cp311-win32.pyd +0 -0
- qlc/py/control.cp311-win32.pyd +0 -0
- qlc/py/io.cp311-win32.pyd +0 -0
- qlc/py/loadmod.cp311-win32.pyd +0 -0
- qlc/py/loadobs.cp311-win32.pyd +0 -0
- qlc/py/logging_utils.cp311-win32.pyd +0 -0
- qlc/py/map_plots.cp311-win32.pyd +0 -0
- qlc/py/matched.cp311-win32.pyd +0 -0
- qlc/py/plot_config.cp311-win32.pyd +0 -0
- qlc/py/plotting.cp311-win32.pyd +0 -0
- qlc/py/plugin_loader.cp311-win32.pyd +0 -0
- qlc/py/processing.cp311-win32.pyd +0 -0
- qlc/py/scatter_plots.cp311-win32.pyd +0 -0
- qlc/py/stations.cp311-win32.pyd +0 -0
- qlc/py/statistics.cp311-win32.pyd +0 -0
- qlc/py/style.cp311-win32.pyd +0 -0
- qlc/py/timeseries_plots.cp311-win32.pyd +0 -0
- qlc/py/utils.cp311-win32.pyd +0 -0
- qlc/py/version.cp311-win32.pyd +0 -0
- qlc/sh/qlc_A1.sh +30 -11
- qlc/sh/qlc_B1a.sh +1 -18
- qlc/sh/qlc_B2.sh +8 -1
- qlc/sh/qlc_C5.sh +90 -65
- qlc/sh/qlc_D1.sh +287 -56
- qlc/sh/qlc_Z1.sh +6 -6
- qlc/sh/qlc_batch.sh +61 -0
- qlc/sh/qlc_common_functions.sh +17 -29
- qlc/sh/qlc_main.sh +49 -26
- qlc/sh/tex_template/beamercolorthemeCAMS2_35.sty +51 -0
- qlc/sh/tex_template/beamerfontthemeCAMS2_35.sty +166 -0
- qlc/sh/tex_template/beamerthemeCAMS2_35.sty +25 -0
- qlc/sh/tex_template/subcaption.sty +170 -0
- qlc/sh/tex_template/template.tex +109 -0
- rc_qlc-0.3.27.dist-info/METADATA +309 -0
- rc_qlc-0.3.27.dist-info/RECORD +103 -0
- qlc/config/json/qlc_config_example_1a_all-obs.json +0 -237
- qlc/config/json/qlc_config_example_1b_all-mod.json +0 -353
- qlc/config/json/qlc_config_example_1c_all-coll.json +0 -266
- qlc/config/json/qlc_config_example_2a_all-obs.json +0 -237
- qlc/config/json/qlc_config_example_2b_all-mod.json +0 -353
- qlc/config/json/qlc_config_example_2c_all-coll.json +0 -265
- qlc/config/json/qlc_config_example_3a-us_obs.json +0 -82
- qlc/config/json/qlc_config_example_3b-us_mod.json +0 -122
- qlc/config/json/qlc_config_example_3c-us_coll.json +0 -46
- qlc/config/json/qlc_config_example_4a_eu-obs.json +0 -41
- qlc/config/json/qlc_config_example_4b_eu-mod.json +0 -122
- qlc/config/json/qlc_config_example_4c_eu-coll.json +0 -45
- qlc/config/qlc_cams.conf +0 -26
- qlc/config/qlc_test.conf +0 -26
- qlc/config/qlc_tex.conf +0 -107
- qlc/examples/cams_case_1/config/json/qlc_config.json +0 -41
- qlc/examples/cams_case_1/config/nml/mars_B1_pl.nml +0 -19
- qlc/examples/cams_case_1/mod/iqi9/2018/iqi9_20181215-20181231_A3_sfc.grb +0 -0
- qlc/sh/qlc_start.sh +0 -23
- qlc/sh/qlc_start_batch.sh +0 -46
- rc_qlc-0.3.24.dist-info/METADATA +0 -142
- rc_qlc-0.3.24.dist-info/RECORD +0 -113
- {rc_qlc-0.3.24.dist-info → rc_qlc-0.3.27.dist-info}/WHEEL +0 -0
- {rc_qlc-0.3.24.dist-info → rc_qlc-0.3.27.dist-info}/entry_points.txt +0 -0
- {rc_qlc-0.3.24.dist-info → rc_qlc-0.3.27.dist-info}/licenses/LICENSE +0 -0
- {rc_qlc-0.3.24.dist-info → rc_qlc-0.3.27.dist-info}/top_level.txt +0 -0
qlc/sh/qlc_B2.sh
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/bin/
|
1
|
+
#!/bin/bash -e
|
2
2
|
|
3
3
|
# Source the configuration file to load the settings
|
4
4
|
. "$CONFIG_FILE"
|
@@ -64,6 +64,8 @@ for exp in $exps ; do
|
|
64
64
|
mkdir -p "$tpath"
|
65
65
|
fi
|
66
66
|
|
67
|
+
log "----------------------------------------------------------------------------------------"
|
68
|
+
|
67
69
|
for name in "${MARS_RETRIEVALS[@]}"; do
|
68
70
|
|
69
71
|
# Define the corresponding arrays based on the name
|
@@ -76,12 +78,16 @@ for exp in $exps ; do
|
|
76
78
|
ncvar=("${!ncvar_var}")
|
77
79
|
myvar=("${!myvar_var}")
|
78
80
|
|
81
|
+
log "ipath : ${ipath}"
|
82
|
+
log "tpath : ${tpath}"
|
83
|
+
|
79
84
|
log "name : ${name}"
|
80
85
|
log "param: ${param}"
|
81
86
|
log "ncvar: ${ncvar}"
|
82
87
|
log "myvar: ${myvar}"
|
83
88
|
|
84
89
|
cd $ipath
|
90
|
+
pwd -P
|
85
91
|
|
86
92
|
set +e
|
87
93
|
# List available NC-files
|
@@ -92,6 +98,7 @@ for exp in $exps ; do
|
|
92
98
|
log "ncfiles : ${ncfiles}"
|
93
99
|
|
94
100
|
cd $tpath
|
101
|
+
pwd -P
|
95
102
|
|
96
103
|
# Loop through the variables for this $name
|
97
104
|
for ((i = 0; i < ${#ncvar[@]}; i++)); do
|
qlc/sh/qlc_C5.sh
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/bin/
|
1
|
+
#!/bin/bash -e
|
2
2
|
|
3
3
|
# Source the configuration file to load the settings
|
4
4
|
. "$CONFIG_FILE"
|
@@ -23,21 +23,56 @@ done
|
|
23
23
|
log "$0 ANALYSIS_DIRECTORY = $ANALYSIS_DIRECTORY"
|
24
24
|
|
25
25
|
# module load for ATOS
|
26
|
-
myOS="
|
27
|
-
HOST
|
28
|
-
log
|
29
|
-
log
|
30
|
-
|
31
|
-
|
26
|
+
myOS="$(uname -s)"
|
27
|
+
HOST="$(hostname -s | cut -c 1)"
|
28
|
+
log "HOST = ${HOST} | $(hostname -s)"
|
29
|
+
log "myOS = ${myOS}"
|
30
|
+
|
31
|
+
if [ "${HOST}" = "a" ] && [ "${myOS}" != "Darwin" ]; then
|
32
|
+
# Only on ATOS-like hosts (non-macOS, short host starting with 'a')
|
33
|
+
if command -v module >/dev/null 2>&1; then
|
34
|
+
module load ferret/7.6.3
|
35
|
+
else
|
36
|
+
log "[WARN] 'module' command not found; skipping ferret module load"
|
37
|
+
fi
|
38
|
+
else
|
39
|
+
# Conda activation for pyferret_env
|
40
|
+
if [ -f "$HOME/miniforge3/etc/profile.d/conda.sh" ]; then
|
41
|
+
. "$HOME/miniforge3/etc/profile.d/conda.sh"
|
42
|
+
conda activate pyferret_env
|
43
|
+
elif [ -f "$HOME/miniforge3/bin/activate" ]; then
|
44
|
+
. "$HOME/miniforge3/bin/activate" "pyferret_env"
|
45
|
+
else
|
46
|
+
log "[WARN] Conda activation scripts not found; relying on PATH for pyferret"
|
47
|
+
fi
|
32
48
|
fi
|
33
49
|
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
50
|
+
# Determine the pyferret command to use.
|
51
|
+
# First, check if pyferret is in the PATH (e.g., from "pip install 'rc-qlc[ferret]'").
|
52
|
+
# If not, fall back to the direct path in the conda environment as per the README.
|
53
|
+
PYFERRET_CMD=""
|
54
|
+
if command -v pyferret &> /dev/null; then
|
55
|
+
log "Using 'pyferret' found in system PATH."
|
56
|
+
PYFERRET_CMD="pyferret"
|
57
|
+
elif [ -x "$HOME/miniforge3/envs/pyferret_env/bin/pyferret" ]; then
|
58
|
+
log "Using 'pyferret' from dedicated conda environment."
|
59
|
+
PYFERRET_CMD="$HOME/miniforge3/envs/pyferret_env/bin/pyferret"
|
60
|
+
fi
|
61
|
+
|
62
|
+
# Check if we found a valid pyferret command
|
63
|
+
if [ -z "$PYFERRET_CMD" ]; then
|
64
|
+
log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
65
|
+
log "WARNING: pyferret command not found."
|
66
|
+
log "The qlc_C5.sh script requires pyferret for generating global map plots."
|
67
|
+
log "You can install it as an optional dependency with:"
|
68
|
+
log " pip install 'rc-qlc[ferret]'"
|
69
|
+
log "For more detailed instructions (e.g., for macOS), please see the"
|
70
|
+
log "'Advanced Topics' section in the main README.md file."
|
71
|
+
log "Alternatively, you can disable this script by commenting out 'C5' in the"
|
72
|
+
log "SUBSCRIPT_NAMES array in your qlc.conf file."
|
73
|
+
log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
74
|
+
log "Skipping pyferret plots and exiting script gracefully."
|
75
|
+
exit 0
|
41
76
|
fi
|
42
77
|
|
43
78
|
# Create output directory if not existent
|
@@ -59,6 +94,7 @@ sDate="${sDat//[-:]/}"
|
|
59
94
|
eDate="${eDat//[-:]/}"
|
60
95
|
mDate="$sDate-$eDate"
|
61
96
|
ext="$PLOTEXTENSION"
|
97
|
+
ulev="$UTLS"
|
62
98
|
|
63
99
|
hpath="$PLOTS_DIRECTORY/${exp1}-${exp2}_${mDate}"
|
64
100
|
|
@@ -80,14 +116,15 @@ for exp in $exps ; do
|
|
80
116
|
log "Processing ${PLOTTYPE} plot for experiment: $exp"
|
81
117
|
|
82
118
|
log "QLTYPE : $QLTYPE"
|
83
|
-
log "TEAM_PREFIX : $TEAM_PREFIX"
|
84
|
-
log "EVALUATION_PREFIX: $EVALUATION_PREFIX"
|
85
|
-
log "MODEL_RESOLUTION : $MODEL_RESOLUTION"
|
86
|
-
log "TIME_RESOLUTION : $TIME_RESOLUTION"
|
119
|
+
log "TEAM_PREFIX : ${TEAM_PREFIX}"
|
120
|
+
log "EVALUATION_PREFIX: ${EVALUATION_PREFIX}"
|
121
|
+
log "MODEL_RESOLUTION : ${MODEL_RESOLUTION}"
|
122
|
+
log "TIME_RESOLUTION : ${TIME_RESOLUTION}"
|
87
123
|
log "mDate : $mDate"
|
88
124
|
log "ext : $ext"
|
89
125
|
log "exp1 : $exp1"
|
90
126
|
log "exp2 : $exp2"
|
127
|
+
log "ulev : $ulev"
|
91
128
|
|
92
129
|
# definition of plot file base name
|
93
130
|
pfile="${TEAM_PREFIX}_${exp1}-${exp2}_${mDate}_${QLTYPE}"
|
@@ -198,7 +235,7 @@ for exp in $exps ; do
|
|
198
235
|
else
|
199
236
|
plev="${nlev}"
|
200
237
|
fi
|
201
|
-
log "${plev}
|
238
|
+
log "Model level array index ${plev} for: $pvar"
|
202
239
|
|
203
240
|
# definition of plot files for each exp + variable (log, diff for exp1)
|
204
241
|
# tfile="${pfile}_${name}_${pvar}_${exp}"
|
@@ -213,15 +250,7 @@ for exp in $exps ; do
|
|
213
250
|
lat='`lat`'
|
214
251
|
lev='`lev`'
|
215
252
|
tim='`tim`'
|
216
|
-
|
217
|
-
# plev="21" # 1000 hPa
|
218
|
-
if [ "${plev}" == "21" ]; then
|
219
|
-
ulev="11:15" # 100:300 hPa
|
220
|
-
elif [ "${plev}" == "16" ]; then
|
221
|
-
ulev="11:13" # 100:300 hPa
|
222
|
-
else
|
223
|
-
ulev="11:12" # default
|
224
|
-
fi
|
253
|
+
ulev="${ulev}"
|
225
254
|
facS="1*"
|
226
255
|
facB="1*"
|
227
256
|
facZ="1*"
|
@@ -618,51 +647,51 @@ EOF
|
|
618
647
|
if [ -f "$ferret.jnl" ]; then
|
619
648
|
cp -p $ferret.jnl .
|
620
649
|
rm -f ${tfile}_burden.${ext} ${tfile}_burden_log.${ext}
|
621
|
-
log "
|
622
|
-
|
650
|
+
log "$PYFERRET_CMD -nodisplay -script $ferret.jnl ${ifile} ${pvar} ${MODEL_RESOLUTION} ${exp} ${tfile}_burden ${ext}"
|
651
|
+
$PYFERRET_CMD -nodisplay -script $ferret.jnl ${ifile} ${pvar} ${MODEL_RESOLUTION} ${exp} ${tfile}_burden ${ext}
|
623
652
|
else
|
624
653
|
# ferret plots for default journal file
|
625
654
|
rm -f ${tfile}_burden.${ext} ${tfile}_burden_log.${ext}
|
626
|
-
log "
|
627
|
-
|
655
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_burden_1x1.jnl"
|
656
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_burden_1x1.jnl
|
628
657
|
|
629
658
|
rm -f ${tfile}_zonal.${ext} ${tfile}_zonal_log.${ext}
|
630
|
-
log "
|
631
|
-
|
659
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_zonal_1x1.jnl"
|
660
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_zonal_1x1.jnl
|
632
661
|
|
633
662
|
rm -f ${tfile}_meridional.${ext} ${tfile}_meridional_log.${ext}
|
634
|
-
log "
|
635
|
-
|
663
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_meridional_1x1.jnl"
|
664
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_meridional_1x1.jnl
|
636
665
|
|
637
666
|
rm -f ${tfile}_surface.${ext} ${tfile}_surface_log.${ext}
|
638
|
-
log "
|
639
|
-
|
667
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_surface_1x1.jnl"
|
668
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_surface_1x1.jnl
|
640
669
|
|
641
670
|
rm -f ${tfile}_utls.${ext} ${tfile}_utls_log.${ext}
|
642
|
-
log "
|
643
|
-
|
671
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_utls_1x1.jnl"
|
672
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_utls_1x1.jnl
|
644
673
|
fi
|
645
674
|
|
646
675
|
if [ "${exp}" == "${exp1}" ]; then
|
647
676
|
rm -f ${tfile}_burden_diff.${ext} ${tfile}_burden_log_diff.${ext}
|
648
|
-
log "
|
649
|
-
|
677
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_burden_1x1_diff.jnl"
|
678
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_burden_1x1_diff.jnl
|
650
679
|
|
651
680
|
rm -f ${tfile}_zonal_diff.${ext} ${tfile}_zonal_log_diff.${ext}
|
652
|
-
log "
|
653
|
-
|
681
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_zonal_1x1_diff.jnl"
|
682
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_zonal_1x1_diff.jnl
|
654
683
|
|
655
684
|
rm -f ${tfile}_meridional_diff.${ext} ${tfile}_meridional_log_diff.${ext}
|
656
|
-
log "
|
657
|
-
|
685
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_meridional_1x1_diff.jnl"
|
686
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_meridional_1x1_diff.jnl
|
658
687
|
|
659
688
|
rm -f ${tfile}_surface_diff.${ext} ${tfile}_surface_log_diff.${ext}
|
660
|
-
log "
|
661
|
-
|
689
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_surface_1x1_diff.jnl"
|
690
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_surface_1x1_diff.jnl
|
662
691
|
|
663
692
|
rm -f ${tfile}_utls_diff.${ext} ${tfile}_utls_log_diff.${ext}
|
664
|
-
log "
|
665
|
-
|
693
|
+
log "$PYFERRET_CMD -nodisplay -script ${tfile}_utls_1x1_diff.jnl"
|
694
|
+
$PYFERRET_CMD -nodisplay -script ${tfile}_utls_1x1_diff.jnl
|
666
695
|
|
667
696
|
# files=("${tfile}" "${tfile}_log" "${tfile}_diff" "${tfile}_log_diff")
|
668
697
|
files=("${tfile}_surface" "${tfile}_surface_log" "${tfile}_surface_diff" "${tfile}_surface_log_diff" \
|
@@ -736,20 +765,15 @@ file_name="${file_name%.*}" # Remove extension
|
|
736
765
|
# Split the file name into parts
|
737
766
|
IFS="_" read -ra parts <<< "$file_name"
|
738
767
|
|
739
|
-
pqlc="${parts[
|
740
|
-
pnml="${parts[
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
pvar2="${parts[8]}"
|
749
|
-
pexp="${parts[9]}"
|
750
|
-
ptyp="${parts[10]}"
|
751
|
-
plog="${parts[11]}"
|
752
|
-
pdif="${parts[12]}"
|
768
|
+
pqlc="${parts[4]}"
|
769
|
+
pnml="${parts[5]}"
|
770
|
+
tlev="${parts[6]}"
|
771
|
+
pvar2="${parts[7]}"
|
772
|
+
pexp="${parts[8]}"
|
773
|
+
ptyp="${parts[9]}"
|
774
|
+
plog="${parts[10]}"
|
775
|
+
pdif="${parts[11]}"
|
776
|
+
|
753
777
|
if [[ "$pvar2" == *"-"* ]]; then
|
754
778
|
# echo "INFO: variable name '$pvar2' contains dash, display as underscore."
|
755
779
|
pvar=$pvar2
|
@@ -779,7 +803,7 @@ fi
|
|
779
803
|
if [ "${tlev}" != "sfc" ] ; then
|
780
804
|
GO="GO"
|
781
805
|
fi
|
782
|
-
|
806
|
+
#log "${GO} = GO | ${pexp} = ${exp1} | ${plog}"
|
783
807
|
if [ "${GO}" == "GO" ] && [ "${pexp}" == "${exp1}" ] && [ "${plog}" == "" ] ; then
|
784
808
|
plot1="$PLOTS_DIRECTORY/${exp1}/${TEAM_PREFIX}_${exp1}-${exp2}_${mDate}_${QLTYPE}_${pnml}_${tlev}_${pvar}_${exp1}_${ptyp}.${ext}"
|
785
809
|
plot2="$PLOTS_DIRECTORY/${exp2}/${TEAM_PREFIX}_${exp1}-${exp2}_${mDate}_${QLTYPE}_${pnml}_${tlev}_${pvar}_${exp2}_${ptyp}.${ext}"
|
@@ -812,6 +836,7 @@ cat >> ${texFile} <<EOF
|
|
812
836
|
EOF
|
813
837
|
fi
|
814
838
|
done # plot
|
839
|
+
|
815
840
|
log "----------------------------------------------------------------------------------------"
|
816
841
|
log "${texFile}"
|
817
842
|
cat ${texFile}
|
qlc/sh/qlc_D1.sh
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/bin/
|
1
|
+
#!/bin/bash -e
|
2
2
|
|
3
3
|
# Source the configuration file to load the settings
|
4
4
|
. "$CONFIG_FILE"
|
@@ -31,13 +31,13 @@ if [ "${HOST}" == "a" ] && [ "${myOS}" != "Darwin" ]; then
|
|
31
31
|
module load python3/3.10.10-01
|
32
32
|
fi
|
33
33
|
|
34
|
-
# Check if
|
35
|
-
if ! command_exists
|
36
|
-
log "Error:
|
34
|
+
# Check if qlc-py exists
|
35
|
+
if ! command_exists qlc-py; then
|
36
|
+
log "Error: qlc-py command not found" >&2
|
37
37
|
exit 1
|
38
38
|
else
|
39
|
-
log "Success:
|
40
|
-
which
|
39
|
+
log "Success: qlc-py command found"
|
40
|
+
which qlc-py
|
41
41
|
fi
|
42
42
|
|
43
43
|
# Create output directory if not existent
|
@@ -60,68 +60,299 @@ eDate="${eDat//[-:]/}"
|
|
60
60
|
mDate="$sDate-$eDate"
|
61
61
|
ext="${QLTYPE}.pdf"
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
log "EVALUATION_PREFIX: $EVALUATION_PREFIX"
|
69
|
-
log "MODEL_RESOLUTION : $MODEL_RESOLUTION"
|
70
|
-
log "TIME_RESOLUTION : $TIME_RESOLUTION"
|
71
|
-
log "mDate : $mDate"
|
72
|
-
log "ext : $ext"
|
73
|
-
log "exp1 : $exp1"
|
74
|
-
log "exp2 : $exp2"
|
75
|
-
|
76
|
-
ipath="$ANALYSIS_DIRECTORY/$exp"
|
77
|
-
tpath="$PLOTS_DIRECTORY/$exp"
|
78
|
-
hpath="$PLOTS_DIRECTORY/${exp1}-${exp2}_${mDate}"
|
79
|
-
|
80
|
-
# Create help directory if not existent
|
81
|
-
if [ ! -d "$hpath" ]; then
|
82
|
-
mkdir -p "$hpath"
|
83
|
-
fi
|
84
|
-
|
85
|
-
# Create output directory if not existent
|
86
|
-
if [ ! -d "$tpath" ]; then
|
87
|
-
mkdir -p "$tpath"
|
88
|
-
fi
|
63
|
+
# Create a temporary list for TeX files and a temporary JSON config
|
64
|
+
hpath="$PLOTS_DIRECTORY/${exp1}-${exp2}_${mDate}"
|
65
|
+
texPlotsfile="${hpath}/texPlotfiles_${QLTYPE}.list"
|
66
|
+
texFile="${texPlotsfile%.list}.tex"
|
67
|
+
temp_config_file="${hpath}/temp_qlc_D1_config.json"
|
89
68
|
|
69
|
+
# Ensure the output directory exists
|
70
|
+
mkdir -p "$hpath"
|
71
|
+
rm -f "$texPlotsfile" "$temp_config_file" "$texFile"
|
72
|
+
touch "$texPlotsfile"
|
73
|
+
|
74
|
+
# Dynamically discover variables from config, validated against existing .nc files.
|
75
|
+
log "Discovering variables from config and validating against files in ${ANALYSIS_DIRECTORY}/${exp1}..."
|
76
|
+
validated_vars=()
|
77
|
+
if [[ -z "${MARS_RETRIEVALS[*]}" ]]; then
|
78
|
+
log "Warning: MARS_RETRIEVALS array is not defined in the configuration. Falling back to filename parsing."
|
79
|
+
# Fallback to the old method if config arrays are missing
|
80
|
+
myvar_list_array=($(find "${ANALYSIS_DIRECTORY}/${exp1}" -type f -name "*.nc" ! -name "*_tavg.nc" -print0 | \
|
81
|
+
xargs -0 -n 1 basename | \
|
82
|
+
sed -E 's/.*_[A-Z][0-9]+_[a-z]+_(.*)\.nc/\1/' | \
|
83
|
+
sort -u))
|
84
|
+
else
|
90
85
|
for name in "${MARS_RETRIEVALS[@]}"; do
|
86
|
+
myvar_array_name="myvar_${name}[@]"
|
87
|
+
myvars=("${!myvar_array_name}")
|
88
|
+
|
89
|
+
for var_name in "${myvars[@]}"; do
|
90
|
+
# Check if a file for this variable exists for the first experiment.
|
91
|
+
# The pattern looks for any file ending in _<var_name>.nc
|
92
|
+
if compgen -G "${ANALYSIS_DIRECTORY}/${exp1}/*_${var_name}.nc" > /dev/null; then
|
93
|
+
validated_vars+=("$var_name")
|
94
|
+
fi
|
95
|
+
done
|
96
|
+
done
|
97
|
+
# De-duplicate the results
|
98
|
+
myvar_list_array=($(printf "%s\n" "${validated_vars[@]}" | sort -u))
|
99
|
+
fi
|
100
|
+
|
101
|
+
|
102
|
+
if [ ${#myvar_list_array[@]} -eq 0 ]; then
|
103
|
+
log "Error: Could not find any variables to process. Check config and analysis files. Exiting."
|
104
|
+
exit 1
|
105
|
+
fi
|
106
|
+
myvar_list_string=$(IFS=,; echo "${myvar_list_array[*]}")
|
107
|
+
log "Found variables: ${myvar_list_string}"
|
108
|
+
|
109
|
+
# Dynamically create a temporary JSON config file with three entries.
|
110
|
+
cat > "$temp_config_file" << EOM
|
111
|
+
[
|
112
|
+
{
|
113
|
+
"name": "${TEAM_PREFIX}",
|
114
|
+
"logdir": "${QLC_HOME}/log",
|
115
|
+
"workdir": "${QLC_HOME}/run",
|
116
|
+
"output_base_name": "${hpath}/${QLTYPE}",
|
117
|
+
"station_file": "${STATION_FILE:-""}",
|
118
|
+
"obs_path": "${OBS_DATA_PATH:-""}",
|
119
|
+
"obs_dataset_type": "${OBS_DATASET_TYPE:-""}",
|
120
|
+
"obs_dataset_version": "${OBS_DATASET_VERSION:-""}",
|
121
|
+
"start_date": "${sDat}",
|
122
|
+
"end_date": "${eDat}",
|
123
|
+
"variable": "${myvar_list_string}",
|
124
|
+
"plot_region": "${REGION:-""}",
|
125
|
+
"station_radius_deg": ${STATION_RADIUS_DEG:-0.5},
|
126
|
+
"plot_type": "${PLOT_TYPE:-""}",
|
127
|
+
"time_average": "${TIME_AVERAGE:-""}",
|
128
|
+
"station_plot_group_size": ${STATION_PLOT_GROUP_SIZE:-5},
|
129
|
+
"show_stations": false,
|
130
|
+
"show_min_max": true,
|
131
|
+
"log_y_axis": false,
|
132
|
+
"fix_y_axis": true,
|
133
|
+
"show_station_map": true,
|
134
|
+
"load_station_timeseries_obs": true,
|
135
|
+
"show_station_timeseries_obs": true,
|
136
|
+
"show_station_timeseries_mod": false,
|
137
|
+
"show_station_timeseries_com": false,
|
138
|
+
"save_plot_format": "${PLOTEXTENSION}",
|
139
|
+
"save_data_format": "nc",
|
140
|
+
"multiprocessing": ${MULTIPROCESSING:-false},
|
141
|
+
"n_threads": ${N_THREADS:-4},
|
142
|
+
"debug": ${DEBUG:-false},
|
143
|
+
"global_attributes": {
|
144
|
+
"title": "Air pollutants over ${REGION:-""}, ${myvar_list_string}",
|
145
|
+
"summary": "netCDF output: ${OBS_DATASET_TYPE:-""} observations for selected stations.",
|
146
|
+
"author": "$(echo $USER)",
|
147
|
+
"history": "Processed for CAMS2_35bis (qlc_v${QLC_VERSION})",
|
148
|
+
"Conventions": "CF-1.8"
|
149
|
+
}
|
150
|
+
},
|
151
|
+
{
|
152
|
+
"name": "${TEAM_PREFIX}",
|
153
|
+
"logdir": "${QLC_HOME}/log",
|
154
|
+
"workdir": "${QLC_HOME}/run",
|
155
|
+
"output_base_name": "${hpath}/${QLTYPE}",
|
156
|
+
"station_file": "${STATION_FILE:-""}",
|
157
|
+
"mod_path": "${ANALYSIS_DIRECTORY:-""}",
|
158
|
+
"model": "${MODEL:-""}",
|
159
|
+
"experiments": "${exp1},${exp2}",
|
160
|
+
"exp_labels": "${EXP_LABELS:-""}",
|
161
|
+
"start_date": "${sDat}",
|
162
|
+
"end_date": "${eDat}",
|
163
|
+
"variable": "${myvar_list_string}",
|
164
|
+
"plot_region": "${REGION:-""}",
|
165
|
+
"station_radius_deg": ${STATION_RADIUS_DEG:-0.5},
|
166
|
+
"model_level": ${MODEL_LEVEL:-null},
|
167
|
+
"plot_type": "${PLOT_TYPE:-""}",
|
168
|
+
"time_average": "${TIME_AVERAGE:-""}",
|
169
|
+
"station_plot_group_size": ${STATION_PLOT_GROUP_SIZE:-5},
|
170
|
+
"show_stations": false,
|
171
|
+
"show_min_max": true,
|
172
|
+
"log_y_axis": false,
|
173
|
+
"fix_y_axis": true,
|
174
|
+
"show_station_map": true,
|
175
|
+
"show_station_timeseries_obs": false,
|
176
|
+
"show_station_timeseries_mod": true,
|
177
|
+
"show_station_timeseries_com": false,
|
178
|
+
"save_plot_format": "${PLOTEXTENSION}",
|
179
|
+
"save_data_format": "nc",
|
180
|
+
"multiprocessing": ${MULTIPROCESSING:-false},
|
181
|
+
"n_threads": ${N_THREADS:-4},
|
182
|
+
"debug": ${DEBUG:-false},
|
183
|
+
"global_attributes": {
|
184
|
+
"title": "Air pollutants over ${REGION:-""}, ${myvar_list_string}",
|
185
|
+
"summary": "netCDF output: Model data for ${exp1},${exp2} for selected stations.",
|
186
|
+
"author": "$(echo $USER)",
|
187
|
+
"history": "Processed for CAMS2_35bis (qlc_v${QLC_VERSION})",
|
188
|
+
"Conventions": "CF-1.8"
|
189
|
+
}
|
190
|
+
},
|
191
|
+
{
|
192
|
+
"name": "${TEAM_PREFIX}",
|
193
|
+
"logdir": "${QLC_HOME}/log",
|
194
|
+
"workdir": "${QLC_HOME}/run",
|
195
|
+
"output_base_name": "${hpath}/${QLTYPE}",
|
196
|
+
"station_file": "${STATION_FILE:-""}",
|
197
|
+
"obs_path": "${OBS_DATA_PATH:-""}",
|
198
|
+
"obs_dataset_type": "${OBS_DATASET_TYPE:-""}",
|
199
|
+
"obs_dataset_version": "${OBS_DATASET_VERSION:-""}",
|
200
|
+
"mod_path": "${ANALYSIS_DIRECTORY:-""}",
|
201
|
+
"model": "${MODEL:-""}",
|
202
|
+
"experiments": "${exp1},${exp2}",
|
203
|
+
"exp_labels": "${EXP_LABELS:-""}",
|
204
|
+
"start_date": "${sDat}",
|
205
|
+
"end_date": "${eDat}",
|
206
|
+
"variable": "${myvar_list_string}",
|
207
|
+
"plot_region": "${REGION:-""}",
|
208
|
+
"station_radius_deg": ${STATION_RADIUS_DEG:-0.5},
|
209
|
+
"model_level": ${MODEL_LEVEL:-null},
|
210
|
+
"plot_type": "${PLOT_TYPE:-""}",
|
211
|
+
"time_average": "${TIME_AVERAGE:-""}",
|
212
|
+
"station_plot_group_size": ${STATION_PLOT_GROUP_SIZE:-5},
|
213
|
+
"show_stations": false,
|
214
|
+
"show_min_max": true,
|
215
|
+
"log_y_axis": false,
|
216
|
+
"fix_y_axis": true,
|
217
|
+
"show_station_map": true,
|
218
|
+
"load_station_timeseries_obs": false,
|
219
|
+
"show_station_timeseries_obs": false,
|
220
|
+
"show_station_timeseries_mod": false,
|
221
|
+
"show_station_timeseries_com": true,
|
222
|
+
"save_plot_format": "${PLOTEXTENSION}",
|
223
|
+
"save_data_format": "nc",
|
224
|
+
"multiprocessing": ${MULTIPROCESSING:-false},
|
225
|
+
"n_threads": ${N_THREADS:-4},
|
226
|
+
"debug": ${DEBUG:-false},
|
227
|
+
"global_attributes": {
|
228
|
+
"title": "Air pollutants over ${REGION:-""}, ${myvar_list_string}",
|
229
|
+
"summary": "netCDF output: Collocated model and observation data for selected stations.",
|
230
|
+
"author": "$(echo $USER)",
|
231
|
+
"history": "Processed for CAMS2_35bis (qlc_v${QLC_VERSION})",
|
232
|
+
"Conventions": "CF-1.8"
|
233
|
+
}
|
234
|
+
}
|
235
|
+
]
|
236
|
+
EOM
|
91
237
|
|
92
|
-
|
238
|
+
log "Generated temporary config file for qlc-py: ${temp_config_file}"
|
93
239
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
240
|
+
# Execute qlc-py with the temporary config file.
|
241
|
+
# Note: qlc-py expects the config via stdin when using '--config -'
|
242
|
+
log "Executing qlc-py with the multi-entry config file..."
|
243
|
+
qlc-py --config "${temp_config_file}"
|
98
244
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
245
|
+
# After the run, find the specific final collocation plot(s) and add them to the TeX list.
|
246
|
+
log "Searching for final collocation plots in ${hpath}..."
|
247
|
+
rm -f "$texPlotsfile" # Start with an empty list
|
248
|
+
touch "$texPlotsfile" # Ensure the file exists before grep is called
|
103
249
|
|
104
|
-
|
250
|
+
# Loop through each variable to control the order of plots in the TeX file
|
251
|
+
for var in "${myvar_list_array[@]}"; do
|
252
|
+
log "Ordering plots for variable: $var"
|
105
253
|
|
106
|
-
|
107
|
-
|
254
|
+
# Helper function to find a plot and add it to the list if it exists and is not already there
|
255
|
+
add_plot_if_found() {
|
256
|
+
local plot_pattern=$1
|
257
|
+
# Use find and sort to ensure a consistent order if multiple files match
|
258
|
+
find "${hpath}" -maxdepth 1 -type f -name "${plot_pattern}" 2>/dev/null | sort | while IFS= read -r plot_file; do
|
259
|
+
if [ -n "$plot_file" ] && ! grep -qF "$plot_file" "$texPlotsfile"; then
|
260
|
+
echo "$plot_file" >> "$texPlotsfile"
|
261
|
+
log "Added plot to TeX list: $plot_file"
|
262
|
+
fi
|
263
|
+
done
|
264
|
+
}
|
108
265
|
|
109
|
-
|
110
|
-
|
266
|
+
# Find plots in the specified order using more precise patterns
|
267
|
+
# 1. Time series plots (individual experiments first, then collocated)
|
268
|
+
add_plot_if_found "*${var}*collocated*regional_mean*.${PLOTEXTENSION}"
|
269
|
+
|
270
|
+
# 2. Bias plot
|
271
|
+
add_plot_if_found "*${var}*collocated*regional_bias*.${PLOTEXTENSION}"
|
272
|
+
|
273
|
+
# 3. All statistics plots
|
274
|
+
add_plot_if_found "*${var}*collocated*stats_plot_Error_Metrics*.${PLOTEXTENSION}"
|
275
|
+
add_plot_if_found "*${var}*collocated*stats_plot_Correlation_Metrics*.${PLOTEXTENSION}"
|
276
|
+
add_plot_if_found "*${var}*collocated*stats_plot_Descriptive_Statistics*.${PLOTEXTENSION}"
|
111
277
|
|
112
|
-
|
113
|
-
|
114
|
-
|
278
|
+
# 4. Value map plots (individual experiments)
|
279
|
+
add_plot_if_found "*${var}*val.${PLOTEXTENSION}"
|
280
|
+
|
281
|
+
done
|
282
|
+
|
283
|
+
# ----------------------------------------------------------------------------------------
|
284
|
+
# Generate a .tex file with frames for each plot found, for inclusion in the final presentation.
|
285
|
+
# ----------------------------------------------------------------------------------------
|
286
|
+
log "Generating TeX file for plots: ${texFile}"
|
287
|
+
|
288
|
+
# Create the main .tex file for this section with a subsection header
|
289
|
+
tQLTYPE=$(echo "$QLTYPE" | sed 's/_/\\_/g')
|
290
|
+
cat > "$texFile" <<EOF
|
291
|
+
%===============================================================================
|
292
|
+
\subsection{${tQLTYPE} -- ${mDate} (${TIME_AVERAGE})}
|
293
|
+
EOF
|
294
|
+
|
295
|
+
# Loop through the found plot files and generate a TeX frame for each
|
296
|
+
if [ -s "$texPlotsfile" ]; then
|
297
|
+
# Read from the ordered file list
|
298
|
+
while IFS= read -r plot_path; do
|
299
|
+
plot_filename=$(basename -- "$plot_path")
|
300
|
+
var_name_tex=""
|
301
|
+
title_prefix=""
|
115
302
|
|
116
|
-
|
117
|
-
|
303
|
+
# Extract the variable name for the title
|
304
|
+
for var in "${myvar_list_array[@]}"; do
|
305
|
+
if [[ "$plot_filename" == *"${var}"* ]]; then
|
306
|
+
var_name_tex=$(echo "$var" | sed 's/_/\\_/g')
|
307
|
+
break
|
308
|
+
fi
|
309
|
+
done
|
310
|
+
|
311
|
+
# Use a case statement for robust title generation
|
312
|
+
case "$plot_filename" in
|
313
|
+
*regional_bias*)
|
314
|
+
title_prefix="Collocation time series bias" ;;
|
315
|
+
*stats_plot_Error_Metrics*)
|
316
|
+
title_prefix="Collocation error stats" ;;
|
317
|
+
*stats_plot_Correlation_Metrics*)
|
318
|
+
title_prefix="Collocation correlation stats" ;;
|
319
|
+
*stats_plot_Descriptive_Statistics*)
|
320
|
+
title_prefix="Collocation descriptive stats" ;;
|
321
|
+
*val.*)
|
322
|
+
title_prefix="Collocation map value plot" ;;
|
323
|
+
*regional_mean*)
|
324
|
+
title_prefix="Collocation time series" ;;
|
325
|
+
*)
|
326
|
+
title_prefix="Collocation station plot" ;;
|
327
|
+
esac
|
328
|
+
|
329
|
+
title_final="${title_prefix} for ${var_name_tex} of ${exp1} vs ${exp2}"
|
330
|
+
|
331
|
+
# Append the frame to the main .tex file
|
332
|
+
cat >> "$texFile" <<EOF
|
333
|
+
%===============================================================================
|
334
|
+
\frame{
|
335
|
+
\frametitle{${title_final}}
|
336
|
+
\vspace{0mm}
|
337
|
+
\centering
|
338
|
+
\includegraphics[width=0.9\textwidth]{${plot_path}}
|
339
|
+
}
|
340
|
+
EOF
|
341
|
+
log "Generated TeX frame for $plot_filename"
|
342
|
+
done < "$texPlotsfile"
|
343
|
+
log "Finished generating TeX file."
|
344
|
+
log "${texFile}"
|
345
|
+
cat "${texFile}"
|
346
|
+
else
|
347
|
+
log "No plots found to generate TeX file."
|
348
|
+
fi
|
118
349
|
|
119
|
-
|
120
|
-
|
121
|
-
|
350
|
+
# ----------------------------------------------------------------------------------------
|
351
|
+
# End of TeX file generation
|
352
|
+
# ----------------------------------------------------------------------------------------
|
122
353
|
|
123
|
-
log "$
|
124
|
-
log "$
|
354
|
+
log "$ANALYSIS_DIRECTORY"
|
355
|
+
log "$PLOTS_DIRECTORY"
|
125
356
|
|
126
357
|
log "----------------------------------------------------------------------------------------"
|
127
358
|
log "End ${SCRIPT} at `date`"
|