48 {
49
51
52 static FILE *out;
53
54 static char varname[
LEN];
55
56 static double time0, lons[
EX], lats[
EY], zm[
EY], zs[
EY], pm[
EY],
58
59 static float help[
EX *
EY], tropo_z0[
EX][
EY], tropo_p0[
EX][
EY],
61
62 static int ncid, varid, varid_z, varid_p, varid_t, varid_q, varid_o3, h2o,
63 o3, n[
EY], nt[
EY], init, ntime, nlon, nlat, ilon, ilat;
64
65 static size_t count[10], start[10];
66
67
69
70
71 if (argc < 5)
72 ERRMSG(
"Missing or invalid command-line arguments.\n\n"
73 "Usage: tropo_zm <ctl> <zm.tab> <var> <tropo.nc>\n\n"
74 "Use -h for full help.");
75
76
78
79
80 for (int iarg = 4; iarg < argc; iarg++) {
81
82
83 LOG(1,
"Read tropopause data: %s", argv[iarg]);
84 if (nc_open(argv[iarg], NC_NOWRITE, &ncid) != NC_NOERR)
85 ERRMSG(
"Cannot open file!");
86
87
91
92
95
96
97 sprintf(varname, "%s_z", argv[3]);
98 NC(nc_inq_varid(ncid, varname, &varid_z));
99 sprintf(varname, "%s_p", argv[3]);
100 NC(nc_inq_varid(ncid, varname, &varid_p));
101 sprintf(varname, "%s_t", argv[3]);
102 NC(nc_inq_varid(ncid, varname, &varid_t));
103 sprintf(varname, "%s_q", argv[3]);
104 h2o = (nc_inq_varid(ncid, varname, &varid_q) == NC_NOERR);
105 sprintf(varname, "%s_o3", argv[3]);
106 o3 = (nc_inq_varid(ncid, varname, &varid_o3) == NC_NOERR);
107
108
109 count[0] = 1;
110 count[1] = (size_t) nlat;
111 count[2] = (size_t) nlon;
112
113
114 for (int it = 0; it < ntime; it++) {
115
116
117 if (!init) {
118 init = 1;
120 }
121
122
123 start[0] = (size_t) it;
124 NC(nc_get_vara_float(ncid, varid_z, start, count, help));
125 for (ilon = 0; ilon < nlon; ilon++)
126 for (ilat = 0; ilat < nlat; ilat++)
127 tropo_z0[ilon][ilat] = help[ilat * nlon + ilon];
128 NC(nc_get_vara_float(ncid, varid_p, start, count, help));
129 for (ilon = 0; ilon < nlon; ilon++)
130 for (ilat = 0; ilat < nlat; ilat++)
131 tropo_p0[ilon][ilat] = help[ilat * nlon + ilon];
132 NC(nc_get_vara_float(ncid, varid_t, start, count, help));
133 for (ilon = 0; ilon < nlon; ilon++)
134 for (ilat = 0; ilat < nlat; ilat++)
135 tropo_t0[ilon][ilat] = help[ilat * nlon + ilon];
136 if (h2o) {
137 NC(nc_get_vara_float(ncid, varid_q, start, count, help));
138 for (ilon = 0; ilon < nlon; ilon++)
139 for (ilat = 0; ilat < nlat; ilat++)
140 tropo_q0[ilon][ilat] = help[ilat * nlon + ilon];
141 } else
142 for (ilon = 0; ilon < nlon; ilon++)
143 for (ilat = 0; ilat < nlat; ilat++)
144 tropo_q0[ilon][ilat] = NAN;
145 if (o3) {
146 NC(nc_get_vara_float(ncid, varid_o3, start, count, help));
147 for (ilon = 0; ilon < nlon; ilon++)
148 for (ilat = 0; ilat < nlat; ilat++)
149 tropo_o30[ilon][ilat] = help[ilat * nlon + ilon];
150 } else
151 for (ilon = 0; ilon < nlon; ilon++)
152 for (ilat = 0; ilat < nlat; ilat++)
153 tropo_o30[ilon][ilat] = NAN;
154
155
156 for (ilat = 0; ilat < nlat; ilat++)
157 for (ilon = 0; ilon < nlon; ilon++) {
158 nt[ilat]++;
159 if (isfinite(tropo_z0[ilon][ilat])
160 && isfinite(tropo_p0[ilon][ilat])
161 && isfinite(tropo_t0[ilon][ilat])
162 && (!h2o || isfinite(tropo_q0[ilon][ilat]))
163 && (!o3 || isfinite(tropo_o30[ilon][ilat]))) {
164 zm[ilat] += tropo_z0[ilon][ilat];
165 zs[ilat] +=
SQR(tropo_z0[ilon][ilat]);
166 pm[ilat] += tropo_p0[ilon][ilat];
167 ps[ilat] +=
SQR(tropo_p0[ilon][ilat]);
168 tm[ilat] += tropo_t0[ilon][ilat];
169 ts[ilat] +=
SQR(tropo_t0[ilon][ilat]);
170 qm[ilat] += tropo_q0[ilon][ilat];
171 qs[ilat] +=
SQR(tropo_q0[ilon][ilat]);
172 o3m[ilat] += tropo_o30[ilon][ilat];
173 o3s[ilat] +=
SQR(tropo_o30[ilon][ilat]);
174 n[ilat]++;
175 }
176 }
177 }
178
179
181 }
182
183
184 for (ilat = 0; ilat < nlat; ilat++)
185 if (n[ilat] > 0) {
186 zm[ilat] /= n[ilat];
187 pm[ilat] /= n[ilat];
188 tm[ilat] /= n[ilat];
189 qm[ilat] /= n[ilat];
190 o3m[ilat] /= n[ilat];
191 double aux = zs[ilat] / n[ilat] -
SQR(zm[ilat]);
192 zs[ilat] = aux > 0 ? sqrt(aux) : 0.0;
193 aux = ps[ilat] / n[ilat] -
SQR(pm[ilat]);
194 ps[ilat] = aux > 0 ? sqrt(aux) : 0.0;
195 aux = ts[ilat] / n[ilat] -
SQR(tm[ilat]);
196 ts[ilat] = aux > 0 ? sqrt(aux) : 0.0;
197 aux = qs[ilat] / n[ilat] -
SQR(qm[ilat]);
198 qs[ilat] = aux > 0 ? sqrt(aux) : 0.0;
199 aux = o3s[ilat] / n[ilat] -
SQR(o3m[ilat]);
200 o3s[ilat] = aux > 0 ? sqrt(aux) : 0.0;
201 }
202
203
204 LOG(1,
"Write tropopause zonal mean data: %s", argv[2]);
205 if (!(out = fopen(argv[2], "w")))
206 ERRMSG(
"Cannot create file!");
207
208
209 fprintf(out,
210 "# $1 = time [s]\n"
211 "# $2 = latitude [deg]\n"
212 "# $3 = tropopause height (mean) [km]\n"
213 "# $4 = tropopause pressure (mean) [hPa]\n"
214 "# $5 = tropopause temperature (mean) [K]\n"
215 "# $6 = tropopause water vapor (mean) [ppv]\n"
216 "# $7 = tropopause ozone (mean) [ppv]\n"
217 "# $8 = tropopause height (sigma) [km]\n"
218 "# $9 = tropopause pressure (sigma) [hPa]\n"
219 "# $10 = tropopause temperature (sigma) [K]\n"
220 "# $11 = tropopause water vapor (sigma) [ppv]\n"
221 "# $12 = tropopause ozone (sigma) [ppv]\n"
222 "# $13 = number of data points\n"
223 "# $14 = occurrence frequency [%%]\n\n");
224
225
226 for (ilat = 0; ilat < nlat; ilat++)
227 fprintf(out, "%.2f %g %g %g %g %g %g %g %g %g %g %g %d %g\n",
228 time0, lats[ilat], zm[ilat], pm[ilat], tm[ilat], qm[ilat],
229 o3m[ilat], zs[ilat], ps[ilat], ts[ilat], qs[ilat], o3s[ilat],
230 n[ilat], 100. * n[ilat] / nt[ilat]);
231
232
233 fclose(out);
234
235 return EXIT_SUCCESS;
236}
double time_from_filename(const char *filename, const int offset)
Extracts and converts a timestamp from a filename to Julian seconds.
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 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.