29 {
30
32
34
36
39
40 static int init, nx, ny, nt, ncid, varid, dims[3];
41
42 static size_t count[10], start[10];
43
44
47
48
49 if (argc < 4)
50 ERRMSG(
"Give parameters: <ctl> <tropo.nc> <met0> [ <met1> ... ]");
51
52
54 double lon0 =
scan_ctl(argv[1], argc, argv,
"TROPO_LON0", -1,
"-180", NULL);
55 double lon1 =
scan_ctl(argv[1], argc, argv,
"TROPO_LON1", -1,
"180", NULL);
56 double dlon =
scan_ctl(argv[1], argc, argv,
"TROPO_DLON", -1,
"-999", NULL);
57 double lat0 =
scan_ctl(argv[1], argc, argv,
"TROPO_LAT0", -1,
"-90", NULL);
58 double lat1 =
scan_ctl(argv[1], argc, argv,
"TROPO_LAT1", -1,
"90", NULL);
59 double dlat =
scan_ctl(argv[1], argc, argv,
"TROPO_DLAT", -1,
"-999", NULL);
60 int h2o = (int)
scan_ctl(argv[1], argc, argv,
"TROPO_H2O", -1,
"1", NULL);
61 int o3 = (int)
scan_ctl(argv[1], argc, argv,
"TROPO_O3", -1,
"1", NULL);
62
63
65
66
67 for (int i = 3; i < argc; i++) {
68
69
71
72
73 if (!
read_met(argv[i], &ctl, clim, met))
74 continue;
75
76
77 if (!init) {
78 init = 1;
79
80
81 if (dlon <= 0)
82 dlon = fabs(met->
lon[1] - met->
lon[0]);
83 if (dlat <= 0)
84 dlat = fabs(met->
lat[1] - met->
lat[0]);
85 if (lon0 < -360 && lon1 > 360) {
86 lon0 = gsl_stats_min(met->
lon, 1, (
size_t) met->
nx);
87 lon1 = gsl_stats_max(met->
lon, 1, (
size_t) met->
nx);
88 }
89 nx = ny = 0;
90 for (lon = lon0; lon <= lon1; lon += dlon) {
91 lons[nx] = lon;
93 ERRMSG(
"Too many longitudes!");
94 }
95 if (lat0 < -90 && lat1 > 90) {
96 lat0 = gsl_stats_min(met->
lat, 1, (
size_t) met->
ny);
97 lat1 = gsl_stats_max(met->
lat, 1, (
size_t) met->
ny);
98 }
99 for (lat = lat0; lat <= lat1; lat += dlat) {
100 lats[ny] = lat;
102 ERRMSG(
"Too many latitudes!");
103 }
104
105
106 LOG(1,
"Write tropopause data file: %s", argv[2]);
107 NC(nc_create(argv[2], NC_CLOBBER, &ncid));
108
109
110 NC(nc_def_dim(ncid,
"time", (
size_t) NC_UNLIMITED, &dims[0]));
111 NC(nc_def_dim(ncid,
"lat", (
size_t) ny, &dims[1]));
112 NC(nc_def_dim(ncid,
"lon", (
size_t) nx, &dims[2]));
113
114
115 NC_DEF_VAR(
"time", NC_DOUBLE, 1, &dims[0],
"time",
116 "seconds since 2000-01-01 00:00:00 UTC");
117 NC_DEF_VAR(
"lat", NC_DOUBLE, 1, &dims[1],
"latitude",
"degrees_north");
118 NC_DEF_VAR(
"lon", NC_DOUBLE, 1, &dims[2],
"longitude",
"degrees_east");
119
120 NC_DEF_VAR(
"clp_z", NC_FLOAT, 3, &dims[0],
"cold point height",
"km");
121 NC_DEF_VAR(
"clp_p", NC_FLOAT, 3, &dims[0],
"cold point pressure",
122 "hPa");
123 NC_DEF_VAR(
"clp_t", NC_FLOAT, 3, &dims[0],
"cold point temperature",
124 "K");
125 if (h2o)
126 NC_DEF_VAR(
"clp_q", NC_FLOAT, 3, &dims[0],
"cold point water vapor",
127 "ppv");
128 if (o3)
129 NC_DEF_VAR(
"clp_o3", NC_FLOAT, 3, &dims[0],
"cold point ozone",
130 "ppv");
131
133 "dynamical tropopause height", "km");
135 "dynamical tropopause pressure", "hPa");
137 "dynamical tropopause temperature", "K");
138 if (h2o)
140 "dynamical tropopause water vapor", "ppv");
141 if (o3)
143 "dynamical tropopause ozone", "ppv");
144
145 NC_DEF_VAR(
"wmo_1st_z", NC_FLOAT, 3, &dims[0],
146 "WMO 1st tropopause height", "km");
147 NC_DEF_VAR(
"wmo_1st_p", NC_FLOAT, 3, &dims[0],
148 "WMO 1st tropopause pressure", "hPa");
149 NC_DEF_VAR(
"wmo_1st_t", NC_FLOAT, 3, &dims[0],
150 "WMO 1st tropopause temperature", "K");
151 if (h2o)
152 NC_DEF_VAR(
"wmo_1st_q", NC_FLOAT, 3, &dims[0],
153 "WMO 1st tropopause water vapor", "ppv");
154 if (o3)
155 NC_DEF_VAR(
"wmo_1st_o3", NC_FLOAT, 3, &dims[0],
156 "WMO 1st tropopause ozone", "ppv");
157
158 NC_DEF_VAR(
"wmo_2nd_z", NC_FLOAT, 3, &dims[0],
159 "WMO 2nd tropopause height", "km");
160 NC_DEF_VAR(
"wmo_2nd_p", NC_FLOAT, 3, &dims[0],
161 "WMO 2nd tropopause pressure", "hPa");
162 NC_DEF_VAR(
"wmo_2nd_t", NC_FLOAT, 3, &dims[0],
163 "WMO 2nd tropopause temperature", "K");
164 if (h2o)
165 NC_DEF_VAR(
"wmo_2nd_q", NC_FLOAT, 3, &dims[0],
166 "WMO 2nd tropopause water vapor", "ppv");
167 if (o3)
168 NC_DEF_VAR(
"wmo_2nd_o3", NC_FLOAT, 3, &dims[0],
169 "WMO 2nd tropopause ozone", "ppv");
170
171 NC_DEF_VAR(
"ps", NC_FLOAT, 3, &dims[0],
"surface pressure",
"hPa");
172 NC_DEF_VAR(
"zs", NC_FLOAT, 3, &dims[0],
"surface height",
"km");
173
174
176
177
180 }
181
182
183 start[0] = (size_t) nt;
184 count[0] = 1;
185 start[1] = 0;
186 count[1] = (size_t) ny;
187 start[2] = 0;
188 count[2] = (size_t) nx;
190
191
192 get_tropo(2, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
193 zs);
197 if (h2o)
199 if (o3)
201
202
203 get_tropo(5, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
204 zs);
208 if (h2o)
210 if (o3)
212
213
214 get_tropo(3, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
215 zs);
219 if (h2o)
221 if (o3)
223
224
225 get_tropo(4, &ctl, clim, met, lons, nx, lats, ny, pt, zt, tt, qt, o3t, ps,
226 zs);
230 if (h2o)
232 if (o3)
234
235
238
239
240 nt++;
241 }
242
243
245
246
247 free(clim);
248 free(met);
249
250 return EXIT_SUCCESS;
251}
void read_clim(ctl_t *ctl, clim_t *clim)
Reads various climatological data and populates the given climatology structure.
void get_tropo(int met_tropo, ctl_t *ctl, clim_t *clim, met_t *met, double *lons, int nx, double *lats, int ny, double *pt, double *zt, double *tt, double *qt, double *o3t, double *ps, double *zs)
Calculate tropopause data.
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_met(const char *filename, ctl_t *ctl, clim_t *clim, met_t *met)
Reads meteorological data from a file and populates the provided structures.
double scan_ctl(const char *filename, int argc, char *argv[], const char *varname, int arridx, const char *defvalue, char *value)
Scans a control file or command-line arguments for a specified variable.
#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 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_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units)
Define a NetCDF variable with attributes.
int met_tropo
Tropopause definition (0=none, 1=clim, 2=cold point, 3=WMO_1st, 4=WMO_2nd, 5=dynamical).
int nx
Number of longitudes.
int ny
Number of latitudes.
double lon[EX]
Longitude [deg].
double lat[EY]
Latitude [deg].