54 static char varname[
LEN];
56 static double lons[
EX], lats[
EY], *zm, *zs, *pm, *ps, *tm, *ts, *qm, *qs,
59 static float *tropo_z0, *tropo_p0, *tropo_t0, *tropo_q0, *tropo_o30;
61 static int ncid, varid, varid_z, varid_p, varid_t, varid_q, varid_o3, h2o,
62 o3, *n, *nt, ntime, nlon, nlat;
64 static size_t count[10], start[10];
88 ALLOC(tropo_z0,
float,
90 ALLOC(tropo_p0,
float,
92 ALLOC(tropo_t0,
float,
94 ALLOC(tropo_q0,
float,
96 ALLOC(tropo_o30,
float,
109 ERRMSG(
"Missing or invalid command-line arguments.\n\n"
110 "Usage: tropo_clim <ctl> <clim.tab> <var> <tropo.nc> [<tropo2.nc> ...] [KEY VALUE ...]\n\n"
111 "Use -h for full help.");
117 for (
int iarg = 4; iarg < argc; iarg++) {
120 LOG(1,
"Read tropopause data: %s", argv[iarg]);
121 if (nc_open(argv[iarg], NC_NOWRITE, &ncid) != NC_NOERR)
122 ERRMSG(
"Cannot open file!");
134 sprintf(varname,
"%s_z", argv[3]);
135 NC(nc_inq_varid(ncid, varname, &varid_z));
136 sprintf(varname,
"%s_p", argv[3]);
137 NC(nc_inq_varid(ncid, varname, &varid_p));
138 sprintf(varname,
"%s_t", argv[3]);
139 NC(nc_inq_varid(ncid, varname, &varid_t));
140 sprintf(varname,
"%s_q", argv[3]);
141 h2o = (nc_inq_varid(ncid, varname, &varid_q) == NC_NOERR);
142 sprintf(varname,
"%s_o3", argv[3]);
143 o3 = (nc_inq_varid(ncid, varname, &varid_o3) == NC_NOERR);
147 count[1] = (size_t) nlat;
148 count[2] = (size_t) nlon;
151 for (
int it = 0; it < ntime; it++) {
154 start[0] = (size_t) it;
155 NC(nc_get_vara_float(ncid, varid_z, start, count, tropo_z0));
156 NC(nc_get_vara_float(ncid, varid_p, start, count, tropo_p0));
157 NC(nc_get_vara_float(ncid, varid_t, start, count, tropo_t0));
159 NC(nc_get_vara_float(ncid, varid_q, start, count, tropo_q0));
161 for (
int i = 0; i < nlon * nlat; i++)
164 NC(nc_get_vara_float(ncid, varid_o3, start, count, tropo_o30));
166 for (
int i = 0; i < nlon * nlat; i++)
170 for (
int i = 0; i < nlon * nlat; i++) {
172 if (isfinite(tropo_z0[i])
173 && isfinite(tropo_p0[i])
174 && isfinite(tropo_t0[i])
175 && (!h2o || isfinite(tropo_q0[i]))
176 && (!o3 || isfinite(tropo_o30[i]))) {
177 zm[i] += tropo_z0[i];
178 zs[i] +=
SQR(tropo_z0[i]);
179 pm[i] += tropo_p0[i];
180 ps[i] +=
SQR(tropo_p0[i]);
181 tm[i] += tropo_t0[i];
182 ts[i] +=
SQR(tropo_t0[i]);
183 qm[i] += tropo_q0[i];
184 qs[i] +=
SQR(tropo_q0[i]);
185 o3m[i] += tropo_o30[i];
186 o3s[i] +=
SQR(tropo_o30[i]);
197 for (
int i = 0; i < nlon * nlat; i++)
204 double aux = zs[i] / n[i] -
SQR(zm[i]);
205 zs[i] = aux > 0 ? sqrt(aux) : 0.0;
206 aux = ps[i] / n[i] -
SQR(pm[i]);
207 ps[i] = aux > 0 ? sqrt(aux) : 0.0;
208 aux = ts[i] / n[i] -
SQR(tm[i]);
209 ts[i] = aux > 0 ? sqrt(aux) : 0.0;
210 aux = qs[i] / n[i] -
SQR(qm[i]);
211 qs[i] = aux > 0 ? sqrt(aux) : 0.0;
212 aux = o3s[i] / n[i] -
SQR(o3m[i]);
213 o3s[i] = aux > 0 ? sqrt(aux) : 0.0;
217 LOG(1,
"Write tropopause climatological data: %s", argv[2]);
218 if (!(out = fopen(argv[2],
"w")))
219 ERRMSG(
"Cannot create file!");
223 "# $1 = longitude [deg]\n"
224 "# $2 = latitude [deg]\n"
225 "# $3 = tropopause height (mean) [km]\n"
226 "# $4 = tropopause pressure (mean) [hPa]\n"
227 "# $5 = tropopause temperature (mean) [K]\n"
228 "# $6 = tropopause water vapor (mean) [ppv]\n"
229 "# $7 = tropopause ozone (mean) [ppv]\n"
230 "# $8 = tropopause height (sigma) [km]\n"
231 "# $9 = tropopause pressure (sigma) [hPa]\n"
232 "# $10 = tropopause temperature (sigma) [K]\n"
233 "# $11 = tropopause water vapor (sigma) [ppv]\n"
234 "# $12 = tropopause ozone (sigma) [ppv]\n"
235 "# $13 = number of data points\n"
236 "# $14 = occurrence frequency [%%]\n");
239 for (
int ilat = 0; ilat < nlat; ilat++) {
241 for (
int ilon = 0; ilon < nlon; ilon++)
242 fprintf(out,
"%g %g %g %g %g %g %g %g %g %g %g %g %d %g\n",
243 lons[ilon], lats[ilat], zm[ilat * nlon + ilon],
244 pm[ilat * nlon + ilon], tm[ilat * nlon + ilon],
245 qm[ilat * nlon + ilon], o3m[ilat * nlon + ilon],
246 zs[ilat * nlon + ilon], ps[ilat * nlon + ilon],
247 ts[ilat * nlon + ilon], qs[ilat * nlon + ilon],
248 o3s[ilat * nlon + ilon], n[ilat * nlon + ilon],
249 100. * n[ilat * nlon + ilon] / nt[ilat * nlon + ilon]);
285 printf(
"\nMPTRAC tropo_clim tool.\n\n");
286 printf(
"Calculate tropopause climatology statistics.\n");
290 (
" tropo_clim <ctl> <clim.tab> <var> <tropo.nc> [<tropo2.nc> ...] [KEY VALUE ...]\n");
292 printf(
"Arguments:\n");
293 printf(
" <ctl> Control file.\n");
294 printf(
" <clim.tab> Output table.\n");
296 (
" <var> Tropopause variable prefix, such as clp, dyn, wmo_1st,\n");
297 printf(
" or wmo_2nd.\n");
298 printf(
" <tropo*> Tropopause netCDF input files.\n");
299 printf(
" [KEY VALUE] Optional control parameters.\n");
300 printf(
"\nFurther information:\n");
301 printf(
" Manual: https://slcs-jsc.github.io/mptrac/\n");
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.
MPTRAC library declarations.
#define LEN
Maximum length of ASCII data lines.
#define NC(cmd)
Execute a NetCDF command and check for errors.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define EY
Maximum number of latitudes for meteo data.
#define USAGE
Print usage information on -h or --help.
#define EX
Maximum number of longitudes for meteo data.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define SQR(x)
Compute the square of a value.
#define LOG(level,...)
Print a log message with a specified logging level.
#define NC_GET_DOUBLE(varname, ptr, force)
Retrieve a double-precision variable from a NetCDF file.
#define NC_INQ_DIM(dimname, ptr, min, max, check)
Inquire the length of a dimension in a NetCDF file.
int main(int argc, char *argv[])
#define NT
Maximum number of time steps.
void usage(void)
Print command-line help.