rc-qlc 0.3.24__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.
Files changed (113) hide show
  1. qlc/__init__.py +8 -0
  2. qlc/cli/__init__.py +21 -0
  3. qlc/cli/installer.py +16 -0
  4. qlc/cli/qlc_main.py +185 -0
  5. qlc/cli/qlc_py_main.py +74 -0
  6. qlc/config/json/qlc_config.json +41 -0
  7. qlc/config/json/qlc_config_example_1a_all-obs.json +237 -0
  8. qlc/config/json/qlc_config_example_1b_all-mod.json +353 -0
  9. qlc/config/json/qlc_config_example_1c_all-coll.json +266 -0
  10. qlc/config/json/qlc_config_example_2a_all-obs.json +237 -0
  11. qlc/config/json/qlc_config_example_2b_all-mod.json +353 -0
  12. qlc/config/json/qlc_config_example_2c_all-coll.json +265 -0
  13. qlc/config/json/qlc_config_example_3a-us_obs.json +82 -0
  14. qlc/config/json/qlc_config_example_3b-us_mod.json +122 -0
  15. qlc/config/json/qlc_config_example_3c-us_coll.json +46 -0
  16. qlc/config/json/qlc_config_example_4a_eu-obs.json +41 -0
  17. qlc/config/json/qlc_config_example_4b_eu-mod.json +122 -0
  18. qlc/config/json/qlc_config_example_4c_eu-coll.json +45 -0
  19. qlc/config/nml/mars_A1_sfc.nml +19 -0
  20. qlc/config/nml/mars_A2_sfc.nml +19 -0
  21. qlc/config/nml/mars_A3_sfc.nml +19 -0
  22. qlc/config/nml/mars_B1_pl.nml +19 -0
  23. qlc/config/nml/mars_B2_pl.nml +19 -0
  24. qlc/config/nml/mars_C1_pl.nml +19 -0
  25. qlc/config/nml/mars_C2_pl.nml +19 -0
  26. qlc/config/nml/mars_C3_ml.nml +19 -0
  27. qlc/config/nml/mars_D.nml +19 -0
  28. qlc/config/nml/mars_E.nml +19 -0
  29. qlc/config/nml/mars_F.nml +19 -0
  30. qlc/config/nml/mars_G.nml +19 -0
  31. qlc/config/qlc_cams.conf +26 -0
  32. qlc/config/qlc_test.conf +26 -0
  33. qlc/config/qlc_tex.conf +107 -0
  34. qlc/doc/CONTRIBUTING.md +105 -0
  35. qlc/doc/README.md +116 -0
  36. qlc/doc/USAGE.md +58 -0
  37. qlc/examples/cams_case_1/config/json/qlc_config.json +41 -0
  38. qlc/examples/cams_case_1/config/nml/mars_A3_sfc.nml +19 -0
  39. qlc/examples/cams_case_1/config/nml/mars_B1_pl.nml +19 -0
  40. qlc/examples/cams_case_1/config/nml/mars_C1_pl.nml +19 -0
  41. qlc/examples/cams_case_1/config/qlc_cams.conf +122 -0
  42. qlc/examples/cams_case_1/mod/b2ro/2018/b2ro_20181215-20181231_A3_sfc.grb +0 -0
  43. qlc/examples/cams_case_1/mod/iqi9/2018/iqi9_20181215-20181231_A3_sfc.grb +0 -0
  44. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181201.nc +0 -0
  45. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181202.nc +0 -0
  46. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181203.nc +0 -0
  47. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181204.nc +0 -0
  48. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181205.nc +0 -0
  49. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181206.nc +0 -0
  50. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181207.nc +0 -0
  51. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181208.nc +0 -0
  52. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181209.nc +0 -0
  53. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181210.nc +0 -0
  54. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181211.nc +0 -0
  55. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181212.nc +0 -0
  56. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181213.nc +0 -0
  57. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181214.nc +0 -0
  58. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181215.nc +0 -0
  59. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181216.nc +0 -0
  60. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181217.nc +0 -0
  61. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181218.nc +0 -0
  62. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181219.nc +0 -0
  63. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181220.nc +0 -0
  64. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181221.nc +0 -0
  65. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181222.nc +0 -0
  66. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181223.nc +0 -0
  67. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181224.nc +0 -0
  68. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181225.nc +0 -0
  69. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181226.nc +0 -0
  70. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181227.nc +0 -0
  71. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181228.nc +0 -0
  72. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181229.nc +0 -0
  73. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181230.nc +0 -0
  74. qlc/examples/cams_case_1/obs/ebas_daily/v_20240216/201812/ebas_20181231.nc +0 -0
  75. qlc/examples/cams_case_1/obs/ebas_station-locations.csv +50 -0
  76. qlc/install.py +285 -0
  77. qlc/py/__main__.cp311-win32.pyd +0 -0
  78. qlc/py/averaging.cp311-win32.pyd +0 -0
  79. qlc/py/bias_plots.cp311-win32.pyd +0 -0
  80. qlc/py/control.cp311-win32.pyd +0 -0
  81. qlc/py/io.cp311-win32.pyd +0 -0
  82. qlc/py/loadmod.cp311-win32.pyd +0 -0
  83. qlc/py/loadobs.cp311-win32.pyd +0 -0
  84. qlc/py/logging_utils.cp311-win32.pyd +0 -0
  85. qlc/py/map_plots.cp311-win32.pyd +0 -0
  86. qlc/py/matched.cp311-win32.pyd +0 -0
  87. qlc/py/plot_config.cp311-win32.pyd +0 -0
  88. qlc/py/plotting.cp311-win32.pyd +0 -0
  89. qlc/py/plugin_loader.cp311-win32.pyd +0 -0
  90. qlc/py/processing.cp311-win32.pyd +0 -0
  91. qlc/py/scatter_plots.cp311-win32.pyd +0 -0
  92. qlc/py/stations.cp311-win32.pyd +0 -0
  93. qlc/py/statistics.cp311-win32.pyd +0 -0
  94. qlc/py/style.cp311-win32.pyd +0 -0
  95. qlc/py/timeseries_plots.cp311-win32.pyd +0 -0
  96. qlc/py/utils.cp311-win32.pyd +0 -0
  97. qlc/py/version.cp311-win32.pyd +0 -0
  98. qlc/sh/qlc_A1.sh +127 -0
  99. qlc/sh/qlc_B1a.sh +123 -0
  100. qlc/sh/qlc_B2.sh +258 -0
  101. qlc/sh/qlc_C5.sh +825 -0
  102. qlc/sh/qlc_D1.sh +130 -0
  103. qlc/sh/qlc_Z1.sh +165 -0
  104. qlc/sh/qlc_common_functions.sh +157 -0
  105. qlc/sh/qlc_main.sh +127 -0
  106. qlc/sh/qlc_start.sh +23 -0
  107. qlc/sh/qlc_start_batch.sh +46 -0
  108. rc_qlc-0.3.24.dist-info/METADATA +142 -0
  109. rc_qlc-0.3.24.dist-info/RECORD +113 -0
  110. rc_qlc-0.3.24.dist-info/WHEEL +5 -0
  111. rc_qlc-0.3.24.dist-info/entry_points.txt +6 -0
  112. rc_qlc-0.3.24.dist-info/licenses/LICENSE +21 -0
  113. rc_qlc-0.3.24.dist-info/top_level.txt +1 -0
qlc/install.py ADDED
@@ -0,0 +1,285 @@
1
+ import os
2
+ import sys
3
+ import shutil
4
+ import argparse
5
+ import json
6
+ from pathlib import Path
7
+ try:
8
+ import tomllib # Python 3.11+
9
+ except ModuleNotFoundError:
10
+ import tomli as tomllib # Python < 3.11
11
+
12
+ def get_version_from_pyproject(pyproject_path: Path) -> str:
13
+ with pyproject_path.open("rb") as f:
14
+ config = tomllib.load(f)
15
+ return config["project"]["version"]
16
+
17
+ def read_version_json(version_json_path: Path) -> dict:
18
+ if not version_json_path.exists():
19
+ raise FileNotFoundError(f"[ERROR] VERSION.json not found: {version_json_path}")
20
+ with version_json_path.open("r", encoding="utf-8") as f:
21
+ return json.load(f)
22
+
23
+ def get_bin_path():
24
+ return Path(sys.executable).resolve().parent
25
+
26
+ def copy_or_link(src, dst, symlink=False):
27
+ dst.parent.mkdir(parents=True, exist_ok=True)
28
+ if dst.exists() or dst.is_symlink():
29
+ dst.unlink()
30
+ if symlink:
31
+ dst.symlink_to(src.resolve())
32
+ else:
33
+ shutil.copy(src, dst)
34
+
35
+ def copytree_with_symlinks(src: Path, dst: Path):
36
+ if dst.exists():
37
+ shutil.rmtree(dst)
38
+ dst.mkdir(parents=True)
39
+
40
+ for item in src.iterdir():
41
+ s = src / item.name
42
+ d = dst / item.name
43
+ if s.is_symlink():
44
+ target = os.readlink(s)
45
+ print(f"[LINK] Preserving symlink {d} → {target}")
46
+ d.symlink_to(target)
47
+ elif s.is_dir():
48
+ copytree_with_symlinks(s, d)
49
+ else:
50
+ shutil.copy2(s, d)
51
+
52
+ def safe_move_and_link(source: Path, target: Path):
53
+ """
54
+ Ensures `target` is a symlink to `source`.
55
+ If `target` exists but points elsewhere (or is a dir), it gets backed up first.
56
+ """
57
+ if target.is_symlink():
58
+ current = target.resolve()
59
+ if current == source.resolve():
60
+ print(f"[SKIP] {target} already links to {source}")
61
+ return
62
+ else:
63
+ print(f"[BACKUP] {target} symlink points to {current}, backing up")
64
+ elif target.exists():
65
+ if target.is_dir():
66
+ # Only backup if it's not the install root (we don't want to mv source itself)
67
+ if target.resolve() != source.resolve():
68
+ backup = target.with_name(f"{target.name}_backup")
69
+ count = 1
70
+ while backup.exists():
71
+ backup = target.with_name(f"{target.name}_backup{count}")
72
+ count += 1
73
+ print(f"[BACKUP] Moving existing directory {target} → {backup}")
74
+ shutil.move(str(target), str(backup))
75
+ else:
76
+ # File or other type — always back up
77
+ backup = target.with_name(f"{target.name}_backup")
78
+ count = 1
79
+ while backup.exists():
80
+ backup = target.with_name(f"{target.name}_backup{count}")
81
+ count += 1
82
+ print(f"[BACKUP] Moving existing file {target} → {backup}")
83
+ shutil.move(str(target), str(backup))
84
+
85
+ print(f"[LINK] {target} → {source}")
86
+ target.symlink_to(source, target_is_directory=True)
87
+
88
+ def update_qlc_version(config_path: Path, version: str):
89
+ if not config_path.exists():
90
+ raise FileNotFoundError(f"[ERROR] Config file not found: {config_path}")
91
+
92
+ lines = config_path.read_text(encoding="utf-8").splitlines()
93
+ new_lines = []
94
+ updated = False
95
+
96
+ for line in lines:
97
+ if line.strip().startswith("QLC_VERSION="):
98
+ new_lines.append(f'QLC_VERSION="{version}"')
99
+ updated = True
100
+ else:
101
+ new_lines.append(line)
102
+
103
+ if not updated:
104
+ print(f"[WARN] QLC_VERSION=... not found in {config_path}")
105
+ else:
106
+ config_path.write_text("\n".join(new_lines) + "\n", encoding="utf-8")
107
+ print(f"[UPDATED] QLC_VERSION set to {version} in {config_path}")
108
+
109
+ def setup(mode, config_file=None, version="latest"):
110
+
111
+ # Define source root
112
+ qlc_root = Path(__file__).resolve().parent.parent
113
+ config_src = qlc_root / "qlc" / "config"
114
+ example_src = qlc_root / "qlc" / "examples"
115
+ sh_src = qlc_root / "qlc" / "sh"
116
+ doc_src = qlc_root / "qlc" / "doc"
117
+
118
+ from qlc.py.version import QLC_VERSION as version
119
+
120
+ # Select appropriate configuration file
121
+ if mode == "cams":
122
+ perm_path = Path(os.environ.get("PERM", "/perm")) / os.environ.get("USER", "user")
123
+ user_home = perm_path
124
+ selected_conf = config_src / "qlc_cams.conf"
125
+ elif mode == "test":
126
+ user_home = Path.home()
127
+ selected_conf = config_src / "qlc_test.conf"
128
+ elif mode == "interactive":
129
+ if not config_file:
130
+ raise ValueError("You must provide a config file via --interactive=<path>")
131
+ selected_conf = Path(config_file)
132
+ else:
133
+ raise ValueError(f"Unsupported mode: {mode}")
134
+
135
+ source = user_home / f"qlc_v{version}"
136
+
137
+ if source.exists() and not source.is_symlink():
138
+ backup = source.with_name(f"{source.name}_backup")
139
+ count = 1
140
+ while backup.exists():
141
+ backup = source.with_name(f"{source.name}_backup{count}")
142
+ count += 1
143
+ print(f"[BACKUP] Moving existing install root {source} → {backup}")
144
+ shutil.move(str(source), str(backup))
145
+
146
+ root = source / mode
147
+ # safe_move_and_link(source, Path.home() / f"qlc_v{version}")
148
+
149
+ print(f"[SETUP] Mode: {mode}, Version: {version}")
150
+ print(f"[PATHS] QLC Root: {root}")
151
+
152
+ # Prepare paths
153
+ config_dst = root / "config"
154
+ example_dst = root / "examples"
155
+ bin_dst = root / "bin"
156
+ log_dst = root / "log"
157
+ mod_dst = root / "mod"
158
+ obs_dst = root / "obs"
159
+ doc_dst = root / "doc"
160
+ run_dst = root / "run"
161
+ out_dst = root / "output"
162
+ plug_dst = root / "plugin"
163
+
164
+ # Create distribution directories
165
+ for path in [bin_dst, log_dst, mod_dst, obs_dst, doc_dst, run_dst, out_dst, plug_dst, example_dst, config_dst]:
166
+ path.mkdir(parents=True, exist_ok=True)
167
+
168
+ # Copy config files
169
+ if config_dst.exists():
170
+ copytree_with_symlinks(config_src, config_dst)
171
+
172
+ # Copy example files
173
+ if example_src.exists():
174
+ # shutil.copytree(example_src, example_dst, dirs_exist_ok=True, symlinks=True)
175
+ copytree_with_symlinks(example_src, example_dst)
176
+
177
+ # Link all documentation files
178
+ # shutil.copytree(doc_src, doc_dst, dirs_exist_ok=True)
179
+ for doc_file in doc_src.glob("*"):
180
+ dst = doc_dst / doc_file.name
181
+ copy_or_link(doc_file, dst, symlink=True)
182
+
183
+ # Link all *.sh files to bin_dst (helpers included)
184
+ for sh_file in sh_src.glob("*.sh"):
185
+ dst = bin_dst / sh_file.name
186
+ copy_or_link(sh_file, dst, symlink=True)
187
+
188
+ # Create shell tool links (now handled by entry_points in setup.py)
189
+ pass
190
+
191
+ # In test mode: link obs and mod to examples
192
+ if mode == "test":
193
+ # Link sample observation data as requested
194
+ # 1. $HOME/qlc/obs/data/ver0d/ebas_daily/v_20240216 -> $HOME/qlc/examples/cams_case_1/obs/ebas_daily/v_20240216
195
+ # 2. $HOME/qlc/obs/data/ver0d/ebas_daily/latest -> v_20240216 (relative)
196
+
197
+ obs_data_source = root / "examples/cams_case_1/obs/ebas_daily/v_20240216"
198
+ obs_data_dest_dir = root / "obs/data/ver0d/ebas_daily"
199
+ obs_data_dest_dir.mkdir(parents=True, exist_ok=True)
200
+
201
+ # Create the v_20240216 symlink
202
+ link1_target = obs_data_dest_dir / "v_20240216"
203
+ if link1_target.exists() or link1_target.is_symlink():
204
+ link1_target.unlink()
205
+ link1_target.symlink_to(obs_data_source.resolve(), target_is_directory=True)
206
+ print(f"[LINK] {link1_target} -> {obs_data_source}")
207
+
208
+ # Create the latest symlink, relative to its location
209
+ link2_target = obs_data_dest_dir / "latest"
210
+ if link2_target.exists() or link2_target.is_symlink():
211
+ link2_target.unlink()
212
+ link2_target.symlink_to("v_20240216", target_is_directory=True)
213
+ print(f"[LINK] {link2_target} -> v_20240216")
214
+
215
+ # Copy the station file for the test case
216
+ station_file_source = root / "examples/cams_case_1/obs/ebas_station-locations.csv"
217
+ station_file_dest = root / "obs/data/ebas_station-locations.csv"
218
+ if station_file_source.exists():
219
+ copy_or_link(station_file_source, station_file_dest, symlink=False)
220
+ print(f"[COPY] {station_file_dest}")
221
+
222
+
223
+ # Link sample model data (unchanged)
224
+ mod_data_src_root = root / "examples" / "cams_case_1" / "mod"
225
+ mod_data_dst_root = root / "mod"
226
+ if mod_data_src_root.is_dir():
227
+ for model_dir in mod_data_src_root.iterdir():
228
+ if model_dir.is_dir():
229
+ mod_data_dst = mod_data_dst_root / model_dir.name
230
+ if mod_data_dst.exists() or mod_data_dst.is_symlink():
231
+ mod_data_dst.unlink()
232
+ mod_data_dst.symlink_to(model_dir.resolve(), target_is_directory=True)
233
+ print(f"[LINK] {mod_data_dst} -> {model_dir}")
234
+
235
+ # Create a generic qlc.conf symlink
236
+ config_dir = root / "config"
237
+ generic_config_path = config_dir / "qlc.conf"
238
+ if generic_config_path.exists() or generic_config_path.is_symlink():
239
+ generic_config_path.unlink()
240
+
241
+ if selected_conf.exists():
242
+ generic_config_path.symlink_to(selected_conf.name)
243
+ print(f"[LINK] {generic_config_path} -> {selected_conf.name}")
244
+
245
+ # Write install info
246
+ info = {
247
+ "version": version,
248
+ "mode": mode,
249
+ "config": selected_conf.name
250
+ }
251
+
252
+ # Preemptively remove 'qlc_latest' symlink to ensure clean update, mimicking `ln -sf`.
253
+ qlc_latest_link = Path.home() / "qlc_latest"
254
+ if qlc_latest_link.is_symlink():
255
+ qlc_latest_link.unlink()
256
+
257
+ safe_move_and_link(root, qlc_latest_link)
258
+ safe_move_and_link(qlc_latest_link, Path.home() / "qlc")
259
+
260
+ (root / "VERSION.json").write_text(json.dumps(info, indent=2))
261
+ print(f"[WRITE] VERSION.json at {root}")
262
+
263
+ version_info = read_version_json(Path.home() / "qlc" / "VERSION.json")
264
+ update_qlc_version(generic_config_path, version_info["version"])
265
+
266
+ print("\n[INFO] QLC installation complete.")
267
+ print("[INFO] To get started, you may need to open a new terminal or run 'rehash'.")
268
+ print("[INFO] The following commands are now available: qlc, qlc-py, sqlc, qlc-install")
269
+
270
+ if __name__ == "__main__":
271
+ parser = argparse.ArgumentParser(description="Install QLC runtime structure")
272
+ parser.add_argument("--cams", action="store_true", help="Install in CAMS mode")
273
+ parser.add_argument("--test", action="store_true", help="Install in TEST mode")
274
+ parser.add_argument("--interactive", type=str, help="Install using custom config path")
275
+ parser.add_argument("--version", type=str, help="Override QLC version")
276
+
277
+ args = parser.parse_args()
278
+ if args.cams:
279
+ setup("cams", version=args.version)
280
+ elif args.test:
281
+ setup("test", version=args.version)
282
+ elif args.interactive:
283
+ setup("interactive", config_file=args.interactive, version=args.version)
284
+ else:
285
+ parser.print_help()
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
qlc/sh/qlc_A1.sh ADDED
@@ -0,0 +1,127 @@
1
+ #!/bin/sh -e
2
+
3
+ # Source the configuration file to load the settings
4
+ . "$CONFIG_FILE"
5
+ # Include common functions
6
+ source $FUNCTIONS
7
+
8
+ SCRIPT="$0"
9
+ log "________________________________________________________________________________________"
10
+ log "Start ${SCRIPT} at `date`"
11
+ log "Retrieve grib data from MARS archive considering selected nml files (see $CONFIG_FILE) "
12
+ #log "----------------------------------------------------------------------------------------"
13
+ #log "Copyright (c) 2021-2025 ResearchConcepts io GmbH. All Rights Reserved. "
14
+ #log "Questions / comments to: Swen M. Metzger <sm@researchconcepts.io> "
15
+ log "----------------------------------------------------------------------------------------"
16
+
17
+ log "$0 MARS_RETRIEVALS = $CONFIG_DIR nml files: ${MARS_RETRIEVALS[*]}"
18
+ pwd -P
19
+
20
+ # Assign the command line input parameters to variables
21
+ exp1="$1"
22
+ exp2="$2"
23
+ sDat="$3"
24
+ eDat="$4"
25
+
26
+ myOS="`uname -s`"
27
+
28
+ exps="$exp1 $exp2"
29
+ for exp in $exps ; do
30
+ log "Processing experiment: $exp"
31
+
32
+ # Create experiment directory if not existent
33
+ if [ ! -d "$MARS_RETRIEVAL_DIRECTORY/$exp" ]; then
34
+ mkdir -p $MARS_RETRIEVAL_DIRECTORY/$exp
35
+ fi
36
+
37
+ EXPCLASS=`echo ${exp} | cut -c 1`
38
+ if [ "${EXPCLASS}" == "b" ]; then
39
+ XCLASS="nl"
40
+ elif [ "${EXPCLASS}" == "a" ]; then
41
+ XCLASS="be"
42
+ else
43
+ XCLASS="rd"
44
+ fi
45
+ log ${exp} ${XCLASS}
46
+
47
+ for name in "${MARS_RETRIEVALS[@]}"; do
48
+ nml_name="mars_${name}.nml"
49
+ log "Processing subscript: $nml_name"
50
+
51
+ if [ -f "$CONFIG_DIR/nml/$nml_name" ]; then
52
+ nml_template="$CONFIG_DIR/nml/$nml_name"
53
+ nml_file="$MARS_RETRIEVAL_DIRECTORY/$exp/$nml_name"
54
+
55
+ # Create a unique flag for this experiment and time period
56
+ data_retrieved_flag="$MARS_RETRIEVAL_DIRECTORY/$exp/data_retrieved_$sDat-$eDat.flag_${name}"
57
+
58
+ # Check for the control file in the mars retrieval directory
59
+ if [ -f "$data_retrieved_flag" ]; then
60
+ ls -lh "$data_retrieved_flag"
61
+ log "Data retrieval in progress or completed for experiment $exp and namelist case $name."
62
+ log "Proceeding without retrieval script qlc_${name}.sh for case $name"
63
+ else
64
+ log "Data has not been retrieved. Calling script:"
65
+ log "$0 for data retrieval for experiment $exp and namelist case $name"
66
+ # Replace placeholders in the namelist file
67
+ # EXP, SDATE, EDATE, MYPATH, MYFILE
68
+ sed -e "s/= EXP,/= $exp,/g" \
69
+ -e "s/= XCLASS/= $XCLASS/g" \
70
+ -e "s/= SDATE/= $sDat/g" \
71
+ -e "s|o/EDATE|o/$eDat|g" \
72
+ -e "s/MYFILE_/$exp\_${sDat//[-:]/}-${eDat//[-:]/}_/g" \
73
+ -e "s|MYPATH/|${MARS_RETRIEVAL_DIRECTORY}/$exp/|g" \
74
+ "$nml_template" > "$nml_file"
75
+ log "$nml_file"
76
+ cat "$nml_file" # Print the modified namelist
77
+ log MARS_RETRIEVAL_DIRECTORY $MARS_RETRIEVAL_DIRECTORY
78
+
79
+ # Extract the 'target' value and assign it to a variable
80
+ target=$(awk -F'=' '/target/ {gsub("\"", "", $2); print $2}' "$nml_file")
81
+ log "mars target file: $target"
82
+
83
+ # Create a batch job script
84
+ MARS_BATCH_SCRIPT="$MARS_RETRIEVAL_DIRECTORY/$exp/mars_$exp_$name.sh"
85
+ cat > "$MARS_BATCH_SCRIPT" <<EOF
86
+ #!/bin/ksh -e
87
+ #SBATCH --job-name=mars_$exp_$name.sh
88
+ #SBATCH --output=log-%J.out
89
+ #SBATCH --error=err-%J.out
90
+ mars < "$nml_file"
91
+ EOF
92
+
93
+ log "----------------------------------------------------------------------------------------"
94
+ cat "$MARS_BATCH_SCRIPT"
95
+ log "----------------------------------------------------------------------------------------"
96
+ log " $MARS_BATCH_SCRIPT"
97
+
98
+ # Check if pdflatex exists
99
+ if ! command_exists sbatch; then
100
+ log "Caution: sbatch command not found" >&2
101
+ log "Not submitting MARS request on $myOS ..."
102
+ # exit 1
103
+ else
104
+ log "Success: sbatch command found"
105
+ log "Submitting MARS request on $myOS:"
106
+ which sbatch mars squeue scancel
107
+ sbatch "$MARS_BATCH_SCRIPT"
108
+ squeue -u "$USER"
109
+ fi
110
+
111
+ # Create the control file in the retrieval directory
112
+ touch $data_retrieved_flag
113
+ log "----------------------------------------------------------------------------------------"
114
+ fi
115
+ else
116
+ log "Error: $nml_name not found in $CONFIG_DIR"
117
+ fi
118
+ done # name
119
+ log "$MARS_RETRIEVAL_DIRECTORY/$exp"
120
+ done # exps
121
+
122
+ log "----------------------------------------------------------------------------------------"
123
+ log "End ${SCRIPT} at `date`"
124
+ log "________________________________________________________________________________________"
125
+
126
+ exit 0
127
+
qlc/sh/qlc_B1a.sh ADDED
@@ -0,0 +1,123 @@
1
+ #!/bin/sh -e
2
+
3
+ # Source the configuration file to load the settings
4
+ . "$CONFIG_FILE"
5
+ # Include common functions
6
+ source $FUNCTIONS
7
+
8
+ SCRIPT="$0"
9
+ log "________________________________________________________________________________________"
10
+ log "Start ${SCRIPT} at `date`"
11
+ log "Process and convert retrieved grib data (MARS_RETRIEVALS as specified in $CONFIG_FILE) "
12
+ #log "----------------------------------------------------------------------------------------"
13
+ #log "Copyright (c) 2021-2025 ResearchConcepts io GmbH. All Rights Reserved. "
14
+ #log "Questions / comments to: Swen M. Metzger <sm@researchconcepts.io> "
15
+ log "----------------------------------------------------------------------------------------"
16
+
17
+ log "$0 MARS_RETRIEVAL_DIRECTORY = $MARS_RETRIEVAL_DIRECTORY"
18
+ pwd -P
19
+
20
+ # module load for ATOS
21
+ myOS="`uname -s`"
22
+ HOST=`hostname -s | awk '{printf $1}' | cut -c 1`
23
+ #log ${HOST} ${ARCH}
24
+ if [ "${HOST}" == "a" ] && [ "${myOS}" != "Darwin" ]; then
25
+ module load cdo
26
+ fi
27
+
28
+ # Check if cdo exists
29
+ if ! command_exists cdo; then
30
+ log "Error: cdo command not found" >&2
31
+ exit 1
32
+ else
33
+ log "Success: cdo command found"
34
+ which cdo
35
+ fi
36
+
37
+ # Check if ncdump exists
38
+ if ! command_exists ncdump; then
39
+ log "Error: ncdump command not found" >&2
40
+ exit 1
41
+ else
42
+ log "Success: ncdump command found"
43
+ which ncdump
44
+ fi
45
+
46
+ # Assign the command line input parameters to variables
47
+ exp1="$1"
48
+ exp2="$2"
49
+ sDat="$3"
50
+ eDat="$4"
51
+ sDate="${sDat//[-:]/}"
52
+ eDate="${eDat//[-:]/}"
53
+ mDate="$sDate-$eDate"
54
+
55
+ exps="$exp1 $exp2"
56
+ for exp in $exps ; do
57
+ log "Processing experiment: $exp"
58
+
59
+ # Create output directory if not existent
60
+ if [ ! -d "$ANALYSIS_DIRECTORY/$exp" ]; then
61
+ mkdir -p "$ANALYSIS_DIRECTORY/$exp"
62
+ fi
63
+
64
+ cd "$MARS_RETRIEVAL_DIRECTORY/$exp"
65
+
66
+ for name in "${MARS_RETRIEVALS[@]}"; do
67
+
68
+ set +e
69
+ # List available GRIB files for selected exp and time period
70
+ # grbfiles=($(ls *${mDate}*_${name}_*.grb))
71
+ grbfiles=($(ls *${mDate}*_${name}*.grb))
72
+ set -e
73
+
74
+ log "Processing grbfiles: $grbfiles"
75
+
76
+ if [ ${#grbfiles[@]} -eq 0 ]; then
77
+ log "No GRIB files found in $MARS_RETRIEVAL_DIRECTORY/$exp"
78
+ else
79
+ log "Files to convert: ${grbfiles[@]}"
80
+ log "----------------------------------------------------------------------------------------"
81
+ for file in "${grbfiles[@]}"; do
82
+ # convert grib files to netcdf
83
+ log "$file"
84
+ gribfile="$file"
85
+ ncfile="${gribfile%.grb}.nc"
86
+ if [ ! -f "$ncfile" ]; then
87
+ log "Converting $gribfile to $ncfile"
88
+ cdo -f nc copy "$gribfile" "$ncfile"
89
+ ls -lh "$ncfile"
90
+ ncdump -h "$ncfile"
91
+ else
92
+ log "Nothing to do! NC-file already exists: $ncfile"
93
+ ls -lh $ncfile
94
+ # ncdump -h $ncfile
95
+ fi
96
+ # conversion of tine averaged grib files to netcdf (seasmean)
97
+ ncfil2="${gribfile%.grb}_tavg.nc"
98
+ if [ ! -f "$ncfil2" ]; then
99
+ log "cdo timavg ${gribfile} ${gribfile%.grb}.grbtavg"
100
+ cdo timavg ${gribfile} ${gribfile%.grb}.grbtavg
101
+ log "cdo -f nc copy ${gribfile%.grb}.grbtavg $ncfil2"
102
+ cdo -f nc copy ${gribfile%.grb}.grbtavg $ncfil2
103
+ # rm -f "$gribfile" # Clean up GRIB file
104
+ ls -lh $ncfil2
105
+ ncdump -h $ncfil2
106
+ else
107
+ log "Nothing to do! NC-file already exists: $ncfil2"
108
+ ls -lh $ncfil2
109
+ # ncdump -h $ncfil2
110
+ fi
111
+ done # file
112
+ log "----------------------------------------------------------------------------------------"
113
+ fi
114
+
115
+ done # name
116
+ done # exps
117
+
118
+ log "----------------------------------------------------------------------------------------"
119
+ log "End ${SCRIPT} at `date`"
120
+ log "________________________________________________________________________________________"
121
+
122
+ exit 0
123
+