40 {
41
43
45
46 static FILE *out;
47
48 static char varname[
LEN];
49
50 static double times[
NT], lons[
EX], lats[
EY], time0, time1, z0, z0sig, p0,
51 p0sig, t0, t0sig, q0, q0sig, o30, o30sig;
52
53 static float help[
EX *
EY], tropo_z0[
EX][
EY], tropo_z1[
EX][
EY],
56
57 static int it_old =
58 -999, ncid, varid, varid_z, varid_p, varid_t, varid_q, varid_o3, h2o, o3,
59 ntime, nlon, nlat, ilon, ilat;
60
61 static size_t count[10], start[10];
62
63
65
66
67 if (argc < 5)
68 ERRMSG(
"Give parameters: <ctl> <sample.tab> <tropo.nc> <var> <atm_in>");
69
70
72 int method =
73 (int)
scan_ctl(argv[1], argc, argv,
"TROPO_SAMPLE_METHOD", -1,
"1", NULL);
74
75
77 ERRMSG(
"Cannot open file!");
78
79
80 LOG(1,
"Read tropopause data: %s", argv[3]);
81 if (nc_open(argv[3], NC_NOWRITE, &ncid) != NC_NOERR)
82 ERRMSG(
"Cannot open file!");
83
84
88
89
93
94
95 sprintf(varname, "%s_z", argv[4]);
96 NC(nc_inq_varid(ncid, varname, &varid_z));
97 sprintf(varname, "%s_p", argv[4]);
98 NC(nc_inq_varid(ncid, varname, &varid_p));
99 sprintf(varname, "%s_t", argv[4]);
100 NC(nc_inq_varid(ncid, varname, &varid_t));
101 sprintf(varname, "%s_q", argv[4]);
102 h2o = (nc_inq_varid(ncid, varname, &varid_q) == NC_NOERR);
103 sprintf(varname, "%s_o3", argv[4]);
104 o3 = (nc_inq_varid(ncid, varname, &varid_o3) == NC_NOERR);
105
106
107 count[0] = 1;
108 count[1] = (size_t) nlat;
109 count[2] = (size_t) nlon;
110
111
112 LOG(1,
"Write tropopause sample data: %s", argv[2]);
113 if (!(out = fopen(argv[2], "w")))
114 ERRMSG(
"Cannot create file!");
115
116
117 fprintf(out,
118 "# $1 = time [s]\n"
119 "# $2 = altitude [km]\n"
120 "# $3 = longitude [deg]\n" "# $4 = latitude [deg]\n");
121 for (
int iq = 0; iq < ctl.
nq; iq++)
122 fprintf(out,
"# $%i = %s [%s]\n", iq + 5, ctl.
qnt_name[iq],
124 fprintf(out,
"# $%d = tropopause height (mean) [km]\n", 5 + ctl.
nq);
125 fprintf(out,
"# $%d = tropopause pressure (mean) [hPa]\n", 6 + ctl.
nq);
126 fprintf(out,
"# $%d = tropopause temperature (mean) [K]\n", 7 + ctl.
nq);
127 fprintf(out,
"# $%d = tropopause water vapor (mean) [ppv]\n", 8 + ctl.
nq);
128 fprintf(out,
"# $%d = tropopause ozone (mean) [ppv]\n", 9 + ctl.
nq);
129 fprintf(out,
"# $%d = tropopause height (sigma) [km]\n", 10 + ctl.
nq);
130 fprintf(out,
"# $%d = tropopause pressure (sigma) [hPa]\n", 11 + ctl.
nq);
131 fprintf(out,
"# $%d = tropopause temperature (sigma) [K]\n", 12 + ctl.
nq);
132 fprintf(out,
"# $%d = tropopause water vapor (sigma) [ppv]\n", 13 + ctl.
nq);
133 fprintf(out,
"# $%d = tropopause ozone (sigma) [ppv]\n\n", 14 + ctl.
nq);
134
135
136 for (
int ip = 0; ip < atm->
np; ip++) {
137
138
139 if (ip > 0 && atm->
time[ip] < atm->
time[ip - 1])
140 ERRMSG(
"Time must be ascending!");
141
142
143 if (atm->
time[ip] < times[0] || atm->
time[ip] > times[ntime - 1])
144 continue;
145
146
148 if (it != it_old) {
149
150 time0 = times[it];
151 start[0] = (size_t) it;
152 NC(nc_get_vara_float(ncid, varid_z, start, count, help));
153 for (ilon = 0; ilon < nlon; ilon++)
154 for (ilat = 0; ilat < nlat; ilat++)
155 tropo_z0[ilon][ilat] = help[ilat * nlon + ilon];
156 NC(nc_get_vara_float(ncid, varid_p, start, count, help));
157 for (ilon = 0; ilon < nlon; ilon++)
158 for (ilat = 0; ilat < nlat; ilat++)
159 tropo_p0[ilon][ilat] = help[ilat * nlon + ilon];
160 NC(nc_get_vara_float(ncid, varid_t, start, count, help));
161 for (ilon = 0; ilon < nlon; ilon++)
162 for (ilat = 0; ilat < nlat; ilat++)
163 tropo_t0[ilon][ilat] = help[ilat * nlon + ilon];
164 if (h2o) {
165 NC(nc_get_vara_float(ncid, varid_q, start, count, help));
166 for (ilon = 0; ilon < nlon; ilon++)
167 for (ilat = 0; ilat < nlat; ilat++)
168 tropo_q0[ilon][ilat] = help[ilat * nlon + ilon];
169 } else
170 for (ilon = 0; ilon < nlon; ilon++)
171 for (ilat = 0; ilat < nlat; ilat++)
172 tropo_q0[ilon][ilat] = NAN;
173 if (o3) {
174 NC(nc_get_vara_float(ncid, varid_o3, start, count, help));
175 for (ilon = 0; ilon < nlon; ilon++)
176 for (ilat = 0; ilat < nlat; ilat++)
177 tropo_o30[ilon][ilat] = help[ilat * nlon + ilon];
178 } else
179 for (ilon = 0; ilon < nlon; ilon++)
180 for (ilat = 0; ilat < nlat; ilat++)
181 tropo_o30[ilon][ilat] = NAN;
182
183 time1 = times[it + 1];
184 start[0] = (size_t) it + 1;
185 NC(nc_get_vara_float(ncid, varid_z, start, count, help));
186 for (ilon = 0; ilon < nlon; ilon++)
187 for (ilat = 0; ilat < nlat; ilat++)
188 tropo_z1[ilon][ilat] = help[ilat * nlon + ilon];
189 NC(nc_get_vara_float(ncid, varid_p, start, count, help));
190 for (ilon = 0; ilon < nlon; ilon++)
191 for (ilat = 0; ilat < nlat; ilat++)
192 tropo_p1[ilon][ilat] = help[ilat * nlon + ilon];
193 NC(nc_get_vara_float(ncid, varid_t, start, count, help));
194 for (ilon = 0; ilon < nlon; ilon++)
195 for (ilat = 0; ilat < nlat; ilat++)
196 tropo_t1[ilon][ilat] = help[ilat * nlon + ilon];
197 if (h2o) {
198 NC(nc_get_vara_float(ncid, varid_q, start, count, help));
199 for (ilon = 0; ilon < nlon; ilon++)
200 for (ilat = 0; ilat < nlat; ilat++)
201 tropo_q1[ilon][ilat] = help[ilat * nlon + ilon];
202 } else
203 for (ilon = 0; ilon < nlon; ilon++)
204 for (ilat = 0; ilat < nlat; ilat++)
205 tropo_q1[ilon][ilat] = NAN;
206 if (o3) {
207 NC(nc_get_vara_float(ncid, varid_o3, start, count, help));
208 for (ilon = 0; ilon < nlon; ilon++)
209 for (ilat = 0; ilat < nlat; ilat++)
210 tropo_o31[ilon][ilat] = help[ilat * nlon + ilon];
211 } else
212 for (ilon = 0; ilon < nlon; ilon++)
213 for (ilat = 0; ilat < nlat; ilat++)
214 tropo_o31[ilon][ilat] = NAN;
215 }
216 it_old = it;
217
218
220 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
221 atm->
lat[ip], method, &z0, &z0sig);
223 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
224 atm->
lat[ip], method, &p0, &p0sig);
226 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
227 atm->
lat[ip], method, &t0, &t0sig);
229 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
230 atm->
lat[ip], method, &q0, &q0sig);
232 lons, lats, nlon, nlat, atm->
time[ip], atm->
lon[ip],
233 atm->
lat[ip], method, &o30, &o30sig);
234
235
236 fprintf(out,
"%.2f %g %g %g", atm->
time[ip],
Z(atm->
p[ip]),
237 atm->
lon[ip], atm->
lat[ip]);
238 for (
int iq = 0; iq < ctl.
nq; iq++) {
239 fprintf(out, " ");
241 }
242 fprintf(out, " %g %g %g %g %g %g %g %g %g %g\n",
243 z0, p0, t0, q0, o30, z0sig, p0sig, t0sig, q0sig, o30sig);
244 }
245
246
247 fclose(out);
249
250
251 free(atm);
252
253 return EXIT_SUCCESS;
254}
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).
void read_ctl(const char *filename, int argc, char *argv[], ctl_t *ctl)
Reads control parameters from a configuration file and populates the given structure.
int 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.
#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 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 NC_INQ_DIM(dimname, ptr, min, max)
Inquire the length of a dimension in a NetCDF file.
#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.
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.
#define NT
Maximum number of time steps.