MPTRAC
tropo.c
Go to the documentation of this file.
1/*
2 This file is part of MPTRAC.
3
4 MPTRAC is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 MPTRAC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with MPTRAC. If not, see <http://www.gnu.org/licenses/>.
16
17 Copyright (C) 2013-2026 Forschungszentrum Juelich GmbH
18*/
19
25#include "mptrac.h"
26
27/* ------------------------------------------------------------
28 Functions...
29 ------------------------------------------------------------ */
30
32void usage(
33 void);
34
35/* ------------------------------------------------------------
36 Main...
37 ------------------------------------------------------------ */
38
39int main(
40 int argc,
41 char *argv[]) {
42
43 ctl_t ctl;
44
45 clim_t *clim;
46
47 met_t *met;
48
49 dd_t *dd;
50
51 static double ps[EX * EY], pt[EX * EY], qt[EX * EY], o3t[EX * EY],
52 zs[EX * EY], zt[EX * EY], tt[EX * EY], lon, lons[EX], lat, lats[EY];
53
54 static int init, nx, ny, nt, ncid, varid, dims[3];
55
56 static size_t count[10], start[10];
57
58 /* Print usage information... */
59 USAGE;
60
61 /* Check arguments... */
62 if (argc < 4)
63 ERRMSG("Missing or invalid command-line arguments.\n\n"
64 "Usage: tropo <ctl> <tropo.nc> <met0> [<met1> ...]\n\n"
65 "Use -h for full help.");
66
67 /* Allocate... */
68 mptrac_alloc(NULL, NULL, &clim, &met, NULL, NULL, NULL, &dd);
69
70 /* Read control parameters... */
71 mptrac_read_ctl(argv[1], argc, argv, &ctl);
72 double lon0 = scan_ctl(argv[1], argc, argv, "TROPO_LON0", -1, "-180", NULL);
73 double lon1 = scan_ctl(argv[1], argc, argv, "TROPO_LON1", -1, "180", NULL);
74 double dlon = scan_ctl(argv[1], argc, argv, "TROPO_DLON", -1, "-999", NULL);
75 double lat0 = scan_ctl(argv[1], argc, argv, "TROPO_LAT0", -1, "-90", NULL);
76 double lat1 = scan_ctl(argv[1], argc, argv, "TROPO_LAT1", -1, "90", NULL);
77 double dlat = scan_ctl(argv[1], argc, argv, "TROPO_DLAT", -1, "-999", NULL);
78 int h2o = (int) scan_ctl(argv[1], argc, argv, "TROPO_H2O", -1, "1", NULL);
79 int o3 = (int) scan_ctl(argv[1], argc, argv, "TROPO_O3", -1, "1", NULL);
80
81 /* Read climatological data... */
82 mptrac_read_clim(&ctl, clim);
83
84 /* Loop over files... */
85 for (int i = 3; i < argc; i++) {
86
87 /* Set control parameters... */
88 ctl.met_tropo = 0;
89
90 /* Read meteorological data... */
91 if (!mptrac_read_met(argv[i], &ctl, clim, met, dd))
92 continue;
93
94 /* Set horizontal grid... */
95 if (!init) {
96 init = 1;
97
98 /* Get grid... */
99 if (dlon <= 0)
100 dlon = fabs(met->lon[1] - met->lon[0]);
101 if (dlat <= 0)
102 dlat = fabs(met->lat[1] - met->lat[0]);
103 if (lon0 < -360 && lon1 > 360) {
104 lon0 = gsl_stats_min(met->lon, 1, (size_t) met->nx);
105 lon1 = gsl_stats_max(met->lon, 1, (size_t) met->nx);
106 }
107 nx = ny = 0;
108 for (lon = lon0; lon <= lon1 + 0.001; lon += dlon) {
109 lons[nx] = round(lon * 1e3) / 1e3;
110 if ((++nx) >= EX)
111 ERRMSG("Too many longitudes!");
112 }
113 if (lat0 < -90 && lat1 > 90) {
114 lat0 = gsl_stats_min(met->lat, 1, (size_t) met->ny);
115 lat1 = gsl_stats_max(met->lat, 1, (size_t) met->ny);
116 }
117 for (lat = lat0; lat <= lat1 + 0.001; lat += dlat) {
118 lats[ny] = round(lat * 1e3) / 1e3;
119 if ((++ny) >= EY)
120 ERRMSG("Too many latitudes!");
121 }
122
123 /* Create netCDF file... */
124 LOG(1, "Write tropopause data file: %s", argv[2]);
125 NC(nc_create(argv[2], NC_NETCDF4, &ncid));
126
127 /* Create dimensions... */
128 NC(nc_def_dim(ncid, "time", (size_t) NC_UNLIMITED, &dims[0]));
129 NC(nc_def_dim(ncid, "lat", (size_t) ny, &dims[1]));
130 NC(nc_def_dim(ncid, "lon", (size_t) nx, &dims[2]));
131
132 /* Create variables... */
133 NC_DEF_VAR("time", NC_DOUBLE, 1, &dims[0], "time",
134 "seconds since 2000-01-01 00:00:00 UTC", 0, 0);
135 NC_DEF_VAR("lat", NC_DOUBLE, 1, &dims[1], "latitude", "degrees_north",
136 0, 0);
137 NC_DEF_VAR("lon", NC_DOUBLE, 1, &dims[2], "longitude", "degrees_east",
138 0, 0);
139
140 NC_DEF_VAR("clp_z", NC_FLOAT, 3, &dims[0], "cold point height", "km", 0,
141 0);
142 NC_DEF_VAR("clp_p", NC_FLOAT, 3, &dims[0], "cold point pressure", "hPa",
143 0, 0);
144 NC_DEF_VAR("clp_t", NC_FLOAT, 3, &dims[0], "cold point temperature",
145 "K", 0, 0);
146 if (h2o)
147 NC_DEF_VAR("clp_q", NC_FLOAT, 3, &dims[0], "cold point water vapor",
148 "ppv", 0, 0);
149 if (o3)
150 NC_DEF_VAR("clp_o3", NC_FLOAT, 3, &dims[0], "cold point ozone",
151 "ppv", 0, 0);
152
153 NC_DEF_VAR("dyn_z", NC_FLOAT, 3, &dims[0],
154 "dynamical tropopause height", "km", 0, 0);
155 NC_DEF_VAR("dyn_p", NC_FLOAT, 3, &dims[0],
156 "dynamical tropopause pressure", "hPa", 0, 0);
157 NC_DEF_VAR("dyn_t", NC_FLOAT, 3, &dims[0],
158 "dynamical tropopause temperature", "K", 0, 0);
159 if (h2o)
160 NC_DEF_VAR("dyn_q", NC_FLOAT, 3, &dims[0],
161 "dynamical tropopause water vapor", "ppv", 0, 0);
162 if (o3)
163 NC_DEF_VAR("dyn_o3", NC_FLOAT, 3, &dims[0],
164 "dynamical tropopause ozone", "ppv", 0, 0);
165
166 NC_DEF_VAR("wmo_1st_z", NC_FLOAT, 3, &dims[0],
167 "WMO 1st tropopause height", "km", 0, 0);
168 NC_DEF_VAR("wmo_1st_p", NC_FLOAT, 3, &dims[0],
169 "WMO 1st tropopause pressure", "hPa", 0, 0);
170 NC_DEF_VAR("wmo_1st_t", NC_FLOAT, 3, &dims[0],
171 "WMO 1st tropopause temperature", "K", 0, 0);
172 if (h2o)
173 NC_DEF_VAR("wmo_1st_q", NC_FLOAT, 3, &dims[0],
174 "WMO 1st tropopause water vapor", "ppv", 0, 0);
175 if (o3)
176 NC_DEF_VAR("wmo_1st_o3", NC_FLOAT, 3, &dims[0],
177 "WMO 1st tropopause ozone", "ppv", 0, 0);
178
179 NC_DEF_VAR("wmo_2nd_z", NC_FLOAT, 3, &dims[0],
180 "WMO 2nd tropopause height", "km", 0, 0);
181 NC_DEF_VAR("wmo_2nd_p", NC_FLOAT, 3, &dims[0],
182 "WMO 2nd tropopause pressure", "hPa", 0, 0);
183 NC_DEF_VAR("wmo_2nd_t", NC_FLOAT, 3, &dims[0],
184 "WMO 2nd tropopause temperature", "K", 0, 0);
185 if (h2o)
186 NC_DEF_VAR("wmo_2nd_q", NC_FLOAT, 3, &dims[0],
187 "WMO 2nd tropopause water vapor", "ppv", 0, 0);
188 if (o3)
189 NC_DEF_VAR("wmo_2nd_o3", NC_FLOAT, 3, &dims[0],
190 "WMO 2nd tropopause ozone", "ppv", 0, 0);
191
192 NC_DEF_VAR("ps", NC_FLOAT, 3, &dims[0], "surface pressure", "hPa", 0,
193 0);
194 NC_DEF_VAR("zs", NC_FLOAT, 3, &dims[0], "surface height", "km", 0, 0);
195
196 /* End definition... */
197 NC(nc_enddef(ncid));
198
199 /* Write longitude and latitude... */
200 NC_PUT_DOUBLE("lat", lats, 0);
201 NC_PUT_DOUBLE("lon", lons, 0);
202 }
203
204 /* Write time... */
205 start[0] = (size_t) nt;
206 count[0] = 1;
207 start[1] = 0;
208 count[1] = (size_t) ny;
209 start[2] = 0;
210 count[2] = (size_t) nx;
211 NC_PUT_DOUBLE("time", &met->time, 1);
212
213 /* Get cold point... */
214 get_tropo(2, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
215 zs);
216 NC_PUT_DOUBLE("clp_z", zt, 1);
217 NC_PUT_DOUBLE("clp_p", pt, 1);
218 NC_PUT_DOUBLE("clp_t", tt, 1);
219 if (h2o)
220 NC_PUT_DOUBLE("clp_q", qt, 1);
221 if (o3)
222 NC_PUT_DOUBLE("clp_o3", o3t, 1);
223
224 /* Get dynamical tropopause... */
225 get_tropo(5, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
226 zs);
227 NC_PUT_DOUBLE("dyn_z", zt, 1);
228 NC_PUT_DOUBLE("dyn_p", pt, 1);
229 NC_PUT_DOUBLE("dyn_t", tt, 1);
230 if (h2o)
231 NC_PUT_DOUBLE("dyn_q", qt, 1);
232 if (o3)
233 NC_PUT_DOUBLE("dyn_o3", o3t, 1);
234
235 /* Get WMO 1st tropopause... */
236 get_tropo(3, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
237 zs);
238 NC_PUT_DOUBLE("wmo_1st_z", zt, 1);
239 NC_PUT_DOUBLE("wmo_1st_p", pt, 1);
240 NC_PUT_DOUBLE("wmo_1st_t", tt, 1);
241 if (h2o)
242 NC_PUT_DOUBLE("wmo_1st_q", qt, 1);
243 if (o3)
244 NC_PUT_DOUBLE("wmo_1st_o3", o3t, 1);
245
246 /* Get WMO 2nd tropopause... */
247 get_tropo(4, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
248 zs);
249 NC_PUT_DOUBLE("wmo_2nd_z", zt, 1);
250 NC_PUT_DOUBLE("wmo_2nd_p", pt, 1);
251 NC_PUT_DOUBLE("wmo_2nd_t", tt, 1);
252 if (h2o)
253 NC_PUT_DOUBLE("wmo_2nd_q", qt, 1);
254 if (o3)
255 NC_PUT_DOUBLE("wmo_2nd_o3", o3t, 1);
256
257 /* Write surface data... */
258 NC_PUT_DOUBLE("ps", ps, 1);
259 NC_PUT_DOUBLE("zs", zs, 1);
260
261 /* Increment time step counter... */
262 nt++;
263 }
264
265 /* Close file... */
266 NC(nc_close(ncid));
267
268 /* Free... */
269 mptrac_free(NULL, NULL, clim, met, NULL, NULL, NULL, dd);
270
271 return EXIT_SUCCESS;
272}
273
274/*****************************************************************************/
275
277void usage(
278 void) {
279
280 printf("\nMPTRAC tropo tool.\n\n");
281 printf("Create tropopause data sets from meteorological data.\n");
282 printf("\n");
283 printf("Usage:\n");
284 printf(" tropo <ctl> <tropo.nc> <met0> [<met1> ...]\n");
285 printf("\n");
286 printf("Arguments:\n");
287 printf(" <ctl> Control file.\n");
288 printf(" <tropo.nc> Output tropopause netCDF file.\n");
289 printf(" <met*> Meteorological input files.\n");
290 printf("\nFurther information:\n");
291 printf(" Manual: https://slcs-jsc.github.io/mptrac/\n");
292}
void mptrac_free(ctl_t *ctl, cache_t *cache, clim_t *clim, met_t *met0, met_t *met1, atm_t *atm, depo_t *depo, dd_t *dd)
Frees memory resources allocated for MPTRAC.
Definition: mptrac.c:6377
double scan_ctl(const char *filename, int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
Scans a control file or command-line arguments for a specified variable.
Definition: mptrac.c:12434
void mptrac_read_clim(const ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
Definition: mptrac.c:6663
void mptrac_alloc(ctl_t **ctl, cache_t **cache, clim_t **clim, met_t **met0, met_t **met1, atm_t **atm, depo_t **depo, dd_t **dd)
Allocates and initializes memory resources for MPTRAC.
Definition: mptrac.c:6294
int mptrac_read_met(const char *filename, const ctl_t *ctl, const clim_t *clim, met_t *met, dd_t *dd)
Reads meteorological data from a file, supporting multiple formats and MPI broadcasting.
Definition: mptrac.c:7742
void mptrac_read_ctl(const char *filename, int argc, char *argv[], ctl_t *ctl)
Reads control parameters from a configuration file and populates the given structure.
Definition: mptrac.c:6723
void get_tropo(const int met_tropo, ctl_t *ctl, const clim_t *clim, met_t *met, const double *lons, const int nx, const double *lats, const int ny, double *pt, double *zt, double *tt, double *qt, double *o3t, double *ps, double *zs)
Calculate tropopause data.
Definition: mptrac.c:2712
MPTRAC library declarations.
#define NC(cmd)
Execute a NetCDF command and check for errors.
Definition: mptrac.h:1508
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: mptrac.h:2406
#define EY
Maximum number of latitudes for meteo data.
Definition: mptrac.h:554
#define USAGE
Print usage information on -h or --help.
Definition: mptrac.h:2213
#define EX
Maximum number of longitudes for meteo data.
Definition: mptrac.h:549
#define LOG(level,...)
Print a log message with a specified logging level.
Definition: mptrac.h:2336
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
Definition: mptrac.h:1537
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
Definition: mptrac.h:1621
Climatological data.
Definition: mptrac.h:3785
Control parameters.
Definition: mptrac.h:2494
int met_tropo
Tropopause definition (0=none, 1=clim, 2=cold point, 3=WMO_1st, 4=WMO_2nd, 5=dynamical).
Definition: mptrac.h:2988
Domain decomposition data structure.
Definition: mptrac.h:4021
Meteo data structure.
Definition: mptrac.h:3844
int nx
Number of longitudes.
Definition: mptrac.h:3853
int ny
Number of latitudes.
Definition: mptrac.h:3856
double lon[EX]
Longitudes [deg].
Definition: mptrac.h:3865
double time
Time [s].
Definition: mptrac.h:3847
double lat[EY]
Latitudes [deg].
Definition: mptrac.h:3868
int main(int argc, char *argv[])
Definition: tropo.c:39
void usage(void)
Print command-line help.
Definition: tropo.c:277