56 static char varname[
LEN];
58 static double times[
NT], lons[
EX], lats[
EY], time0, time1, z0, z0sig, p0,
59 p0sig, t0, t0sig, q0, q0sig, o30, o30sig;
61 static float help[
EX *
EY], tropo_z0[
EX][
EY], tropo_z1[
EX][
EY],
66 -999, ncid, varid, varid_z, varid_p, varid_t, varid_q, varid_o3, h2o, o3,
67 ntime, nlon, nlat, ilon, ilat;
69 static size_t count[10], start[10];
79 ERRMSG(
"Missing or invalid command-line arguments.\n\n"
80 "Usage: tropo_sample <ctl> <sample.tab> <tropo.nc> <var> <atm_in>\n\n"
81 "Use -h for full help.");
86 (int)
scan_ctl(argv[1], argc, argv,
"TROPO_SAMPLE_METHOD", -1,
"1", NULL);
90 ERRMSG(
"Cannot open file!");
93 LOG(1,
"Read tropopause data: %s", argv[3]);
94 if (nc_open(argv[3], NC_NOWRITE, &ncid) != NC_NOERR)
95 ERRMSG(
"Cannot open file!");
108 sprintf(varname,
"%s_z", argv[4]);
109 NC(nc_inq_varid(ncid, varname, &varid_z));
110 sprintf(varname,
"%s_p", argv[4]);
111 NC(nc_inq_varid(ncid, varname, &varid_p));
112 sprintf(varname,
"%s_t", argv[4]);
113 NC(nc_inq_varid(ncid, varname, &varid_t));
114 sprintf(varname,
"%s_q", argv[4]);
115 h2o = (nc_inq_varid(ncid, varname, &varid_q) == NC_NOERR);
116 sprintf(varname,
"%s_o3", argv[4]);
117 o3 = (nc_inq_varid(ncid, varname, &varid_o3) == NC_NOERR);
121 count[1] = (size_t) nlat;
122 count[2] = (size_t) nlon;
125 LOG(1,
"Write tropopause sample data: %s", argv[2]);
126 if (!(out = fopen(argv[2],
"w")))
127 ERRMSG(
"Cannot create file!");
132 "# $2 = altitude [km]\n"
133 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
134 for (
int iq = 0; iq < ctl.
nq; iq++)
135 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl.
qnt_name[iq],
137 fprintf(out,
"# $%d = tropopause height (mean) [km]\n", 5 + ctl.
nq);
138 fprintf(out,
"# $%d = tropopause pressure (mean) [hPa]\n", 6 + ctl.
nq);
139 fprintf(out,
"# $%d = tropopause temperature (mean) [K]\n", 7 + ctl.
nq);
140 fprintf(out,
"# $%d = tropopause water vapor (mean) [ppv]\n", 8 + ctl.
nq);
141 fprintf(out,
"# $%d = tropopause ozone (mean) [ppv]\n", 9 + ctl.
nq);
142 fprintf(out,
"# $%d = tropopause height (sigma) [km]\n", 10 + ctl.
nq);
143 fprintf(out,
"# $%d = tropopause pressure (sigma) [hPa]\n", 11 + ctl.
nq);
144 fprintf(out,
"# $%d = tropopause temperature (sigma) [K]\n", 12 + ctl.
nq);
145 fprintf(out,
"# $%d = tropopause water vapor (sigma) [ppv]\n", 13 + ctl.
nq);
146 fprintf(out,
"# $%d = tropopause ozone (sigma) [ppv]\n\n", 14 + ctl.
nq);
149 for (
int ip = 0; ip < atm->
np; ip++) {
152 if (ip > 0 && atm->
time[ip] < atm->
time[ip - 1])
153 ERRMSG(
"Time must be ascending!");
156 if (atm->
time[ip] < times[0] || atm->
time[ip] > times[ntime - 1])
164 start[0] = (size_t) it;
165 NC(nc_get_vara_float(ncid, varid_z, start, count, help));
166 for (ilon = 0; ilon < nlon; ilon++)
167 for (ilat = 0; ilat < nlat; ilat++)
168 tropo_z0[ilon][ilat] = help[ilat * nlon + ilon];
169 NC(nc_get_vara_float(ncid, varid_p, start, count, help));
170 for (ilon = 0; ilon < nlon; ilon++)
171 for (ilat = 0; ilat < nlat; ilat++)
172 tropo_p0[ilon][ilat] = help[ilat * nlon + ilon];
173 NC(nc_get_vara_float(ncid, varid_t, start, count, help));
174 for (ilon = 0; ilon < nlon; ilon++)
175 for (ilat = 0; ilat < nlat; ilat++)
176 tropo_t0[ilon][ilat] = help[ilat * nlon + ilon];
178 NC(nc_get_vara_float(ncid, varid_q, start, count, help));
179 for (ilon = 0; ilon < nlon; ilon++)
180 for (ilat = 0; ilat < nlat; ilat++)
181 tropo_q0[ilon][ilat] = help[ilat * nlon + ilon];
183 for (ilon = 0; ilon < nlon; ilon++)
184 for (ilat = 0; ilat < nlat; ilat++)
185 tropo_q0[ilon][ilat] = NAN;
187 NC(nc_get_vara_float(ncid, varid_o3, start, count, help));
188 for (ilon = 0; ilon < nlon; ilon++)
189 for (ilat = 0; ilat < nlat; ilat++)
190 tropo_o30[ilon][ilat] = help[ilat * nlon + ilon];
192 for (ilon = 0; ilon < nlon; ilon++)
193 for (ilat = 0; ilat < nlat; ilat++)
194 tropo_o30[ilon][ilat] = NAN;
196 time1 = times[it + 1];
197 start[0] = (size_t) it + 1;
198 NC(nc_get_vara_float(ncid, varid_z, start, count, help));
199 for (ilon = 0; ilon < nlon; ilon++)
200 for (ilat = 0; ilat < nlat; ilat++)
201 tropo_z1[ilon][ilat] = help[ilat * nlon + ilon];
202 NC(nc_get_vara_float(ncid, varid_p, start, count, help));
203 for (ilon = 0; ilon < nlon; ilon++)
204 for (ilat = 0; ilat < nlat; ilat++)
205 tropo_p1[ilon][ilat] = help[ilat * nlon + ilon];
206 NC(nc_get_vara_float(ncid, varid_t, start, count, help));
207 for (ilon = 0; ilon < nlon; ilon++)
208 for (ilat = 0; ilat < nlat; ilat++)
209 tropo_t1[ilon][ilat] = help[ilat * nlon + ilon];
211 NC(nc_get_vara_float(ncid, varid_q, start, count, help));
212 for (ilon = 0; ilon < nlon; ilon++)
213 for (ilat = 0; ilat < nlat; ilat++)
214 tropo_q1[ilon][ilat] = help[ilat * nlon + ilon];
216 for (ilon = 0; ilon < nlon; ilon++)
217 for (ilat = 0; ilat < nlat; ilat++)
218 tropo_q1[ilon][ilat] = NAN;
220 NC(nc_get_vara_float(ncid, varid_o3, start, count, help));
221 for (ilon = 0; ilon < nlon; ilon++)
222 for (ilat = 0; ilat < nlat; ilat++)
223 tropo_o31[ilon][ilat] = help[ilat * nlon + ilon];
225 for (ilon = 0; ilon < nlon; ilon++)
226 for (ilat = 0; ilat < nlat; ilat++)
227 tropo_o31[ilon][ilat] = NAN;
233 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
234 atm->
lat[ip], method, &z0, &z0sig);
236 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
237 atm->
lat[ip], method, &p0, &p0sig);
239 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
240 atm->
lat[ip], method, &t0, &t0sig);
242 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
243 atm->
lat[ip], method, &q0, &q0sig);
245 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
246 atm->
lat[ip], method, &o30, &o30sig);
249 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
250 atm->
lon[ip], atm->
lat[ip]);
251 for (
int iq = 0; iq < ctl.
nq; iq++) {
255 fprintf(out,
" %g %g %g %g %g %g %g %g %g %g\n",
256 z0, p0, t0, q0, o30, z0sig, p0sig, t0sig, q0sig, o30sig);
275 printf(
"\nMPTRAC tropo_sample tool.\n\n");
276 printf(
"Sample tropopause data at atmospheric particle locations.\n");
279 printf(
" tropo_sample <ctl> <sample.tab> <tropo.nc> <var> <atm_in>\n");
281 printf(
"Arguments:\n");
282 printf(
" <ctl> Control file.\n");
283 printf(
" <sample.tab> Output table.\n");
284 printf(
" <tropo.nc> Tropopause netCDF input file.\n");
286 (
" <var> Tropopause variable prefix, such as clp, dyn, wmo_1st,\n");
287 printf(
" or wmo_2nd.\n");
288 printf(
" <atm_in> Atmospheric input file with sample locations.\n");
289 printf(
"\nFurther information:\n");
290 printf(
" Manual: https://slcs-jsc.github.io/mptrac/\n");
int locate_irr(const double *xx, const int n, const double x)
Locate the index of the interval containing a given value in a sorted array.
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.
void intpol_tropo_3d(const double time0, float array0[EX][EY], const double time1, float array1[EX][EY], const double lons[EX], const double lats[EY], const int nlon, const int nlat, const double time, const double lon, const double lat, const int method, double *var, double *sigma)
Interpolates tropopause data in 3D (latitude, longitude, and time).
int mptrac_read_atm(const char *filename, const ctl_t *ctl, atm_t *atm)
Reads air parcel data from a specified file into the given atmospheric structure.
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 Z(p)
Convert pressure to altitude.
#define EX
Maximum number of longitudes for meteo data.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#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.
double lat[NP]
Latitude [deg].
double lon[NP]
Longitude [deg].
int np
Number of air parcels.
double q[NQ][NP]
Quantity data (for various, user-defined attributes).
double p[NP]
Pressure [hPa].
char qnt_format[NQ][LEN]
Quantity output format.
char qnt_unit[NQ][LEN]
Quantity units.
char qnt_name[NQ][LEN]
Quantity names.
int nq
Number of quantities.
int main(int argc, char *argv[])
#define NT
Maximum number of time steps.
void usage(void)
Print command-line help.