48 {
49
51
52 static FILE *out;
53
54 static char varname[
LEN];
55
56 static double lons[
EX], lats[
EY], *zm, *zs, *pm, *ps, *tm, *ts, *qm, *qs,
57 *o3m, *o3s;
58
59 static float *tropo_z0, *tropo_p0, *tropo_t0, *tropo_q0, *tropo_o30;
60
61 static int ncid, varid, varid_z, varid_p, varid_t, varid_q, varid_o3, h2o,
62 o3, *n, *nt, ntime, nlon, nlat;
63
64 static size_t count[10], start[10];
65
66
87
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,
98
103
104
106
107
108 if (argc < 5)
109 ERRMSG(
"Missing or invalid command-line arguments.\n\n"
110 "Usage: tropo_clim <ctl> <clim.tab> <var> <tropo.nc> [<tropo2.nc> ...]\n\n"
111 "Use -h for full help.");
112
113
115
116
117 for (int iarg = 4; iarg < argc; iarg++) {
118
119
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!");
123
124
128
129
132
133
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);
144
145
146 count[0] = 1;
147 count[1] = (size_t) nlat;
148 count[2] = (size_t) nlon;
149
150
151 for (int it = 0; it < ntime; it++) {
152
153
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));
158 if (h2o) {
159 NC(nc_get_vara_float(ncid, varid_q, start, count, tropo_q0));
160 } else
161 for (int i = 0; i < nlon * nlat; i++)
162 tropo_q0[i] = NAN;
163 if (o3) {
164 NC(nc_get_vara_float(ncid, varid_o3, start, count, tropo_o30));
165 } else
166 for (int i = 0; i < nlon * nlat; i++)
167 tropo_o30[i] = NAN;
168
169
170 for (int i = 0; i < nlon * nlat; i++) {
171 nt[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]);
187 n[i]++;
188 }
189 }
190 }
191
192
194 }
195
196
197 for (int i = 0; i < nlon * nlat; i++)
198 if (n[i] > 0) {
199 zm[i] /= n[i];
200 pm[i] /= n[i];
201 tm[i] /= n[i];
202 qm[i] /= n[i];
203 o3m[i] /= n[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;
214 }
215
216
217 LOG(1,
"Write tropopause climatological data: %s", argv[2]);
218 if (!(out = fopen(argv[2], "w")))
219 ERRMSG(
"Cannot create file!");
220
221
222 fprintf(out,
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");
237
238
239 for (int ilat = 0; ilat < nlat; ilat++) {
240 fprintf(out, "\n");
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]);
250 }
251
252
253 fclose(out);
254
255
256 free(zm);
257 free(zs);
258 free(pm);
259 free(ps);
260 free(tm);
261 free(ts);
262 free(qm);
263 free(qs);
264 free(o3m);
265 free(o3s);
266
267 free(tropo_z0);
268 free(tropo_p0);
269 free(tropo_t0);
270 free(tropo_q0);
271 free(tropo_o30);
272
273 free(n);
274 free(nt);
275
276 return EXIT_SUCCESS;
277}
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.
#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.
#define NT
Maximum number of time steps.