GPS Code Collection
tropo.c
Go to the documentation of this file.
1/*
2 This file is part of the GPS Code Collection.
3
4 the GPS Code Collections is free software: you can redistribute it
5 and/or modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation, either version 3 of
7 the License, or (at your option) any later version.
8
9 The GPS Code Collection is distributed in the hope that it will be
10 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with the GPS Code Collection. If not, see
16 <http://www.gnu.org/licenses/>.
17
18 Copyright (C) 2019-2025 Forschungszentrum Juelich GmbH
19*/
20
26#include "libgps.h"
27
28/* ------------------------------------------------------------
29 Main...
30 ------------------------------------------------------------ */
31
32int main(
33 int argc,
34 char *argv[]) {
35
36 gps_t *gps;
37
38 double clp_tlon[NDS], clp_tlat[NDS], wmo_1st_tlon[NDS], wmo_1st_tlat[NDS],
39 wmo_2nd_tlon[NDS], wmo_2nd_tlat[NDS];
40
41 float clp_th[NDS], clp_tp[NDS], clp_tq[NDS], clp_tt[NDS], wmo_1st_th[NDS],
42 wmo_1st_tp[NDS], wmo_1st_tq[NDS], wmo_1st_tt[NDS], wmo_2nd_th[NDS],
43 wmo_2nd_tp[NDS], wmo_2nd_tq[NDS], wmo_2nd_tt[NDS];
44
45 /* Allocate... */
46 ALLOC(gps, gps_t, 1);
47
48 /* Check arguments... */
49 if (argc < 4)
50 ERRMSG("Give parameters: <ctl> <out.nc> <gps1.nc> [<gps2.nc> ...]");
51
52 /* Get control parameters... */
53 const double prof_zmax_min =
54 scan_ctl(argc, argv, "PROF_ZMAX_MIN", -1, "35", NULL);
55 const double prof_zmin_max =
56 scan_ctl(argc, argv, "PROF_ZMIN_MAX", -1, "5", NULL);
57
58 /* Read individual GPS-RO data files... */
59 for (int iarg = 3; iarg < argc; iarg++) {
60 FILE *in;
61 if (!(in = fopen(argv[iarg], "r")))
62 continue;
63 else {
64 fclose(in);
65 read_gps_prof(argv[iarg], gps, prof_zmin_max, prof_zmax_min);
66 }
67 }
68
69 /* Check number of profiles... */
70 if (gps->nds <= 0)
71 ERRMSG("No profiles found!");
72
73 /* ------------------------------------------------------------
74 Get tropopause data...
75 ------------------------------------------------------------ */
76
77 /* Cold point... */
78 tropopause_spline(gps, 2);
79 for (int ids = 0; ids < gps->nds; ids++) {
80 clp_tlon[ids] = gps->tlon[ids];
81 clp_tlat[ids] = gps->tlat[ids];
82 clp_tp[ids] = (float) gps->tp[ids];
83 clp_th[ids] = (float) gps->th[ids];
84 clp_tt[ids] = (float) gps->tt[ids];
85 clp_tq[ids] = (float) gps->tq[ids];
86 }
87
88 /* WMO 1st tropopause... */
89 tropopause_spline(gps, 3);
90 for (int ids = 0; ids < gps->nds; ids++) {
91 wmo_1st_tlon[ids] = gps->tlon[ids];
92 wmo_1st_tlat[ids] = gps->tlat[ids];
93 wmo_1st_tp[ids] = (float) gps->tp[ids];
94 wmo_1st_th[ids] = (float) gps->th[ids];
95 wmo_1st_tt[ids] = (float) gps->tt[ids];
96 wmo_1st_tq[ids] = (float) gps->tq[ids];
97 }
98
99 /* WMO 2nd tropopause... */
100 tropopause_spline(gps, 4);
101 for (int ids = 0; ids < gps->nds; ids++) {
102 wmo_2nd_tlon[ids] = gps->tlon[ids];
103 wmo_2nd_tlat[ids] = gps->tlat[ids];
104 wmo_2nd_tp[ids] = (float) gps->tp[ids];
105 wmo_2nd_th[ids] = (float) gps->th[ids];
106 wmo_2nd_tt[ids] = (float) gps->tt[ids];
107 wmo_2nd_tq[ids] = (float) gps->tq[ids];
108 }
109
110 /* ------------------------------------------------------------
111 Write netCDF files...
112 ------------------------------------------------------------ */
113
114 /* Create netCDF file... */
115 int ncid, varid, dimid[10];
116 printf("Write tropopause file: %s\n", argv[2]);
117 NC(nc_create(argv[2], NC_CLOBBER, &ncid));
118
119 /* Set dimensions... */
120 NC(nc_def_dim(ncid, "NDS", (size_t) gps->nds, &dimid[0]));
121
122 /* Add variables... */
123 add_var(ncid, "time", "s", "time (seconds since 2000-01-01T00:00Z)",
124 NC_DOUBLE, dimid, &varid, 1);
125
126 add_var(ncid, "clp_lat", "degrees_north", "cold point latitude", NC_DOUBLE,
127 dimid, &varid, 1);
128 add_var(ncid, "clp_lon", "degrees_east", "cold point longitude", NC_DOUBLE,
129 dimid, &varid, 1);
130 add_var(ncid, "clp_z", "km", "cold point height", NC_FLOAT, dimid, &varid,
131 1);
132 add_var(ncid, "clp_p", "hPa", "cold point pressure", NC_FLOAT, dimid,
133 &varid, 1);
134 add_var(ncid, "clp_t", "K", "cold point temperature", NC_FLOAT, dimid,
135 &varid, 1);
136 add_var(ncid, "clp_q", "ppv", "cold point water vapor", NC_FLOAT, dimid,
137 &varid, 1);
138
139 add_var(ncid, "wmo_1st_lat", "degrees_north", "WMO 1st tropopause latitude",
140 NC_DOUBLE, dimid, &varid, 1);
141 add_var(ncid, "wmo_1st_lon", "degrees_east", "WMO 1st tropopause longitude",
142 NC_DOUBLE, dimid, &varid, 1);
143 add_var(ncid, "wmo_1st_z", "km", "WMO 1st tropopause height", NC_FLOAT,
144 dimid, &varid, 1);
145 add_var(ncid, "wmo_1st_p", "hPa", "WMO 1st tropopause pressure", NC_FLOAT,
146 dimid, &varid, 1);
147 add_var(ncid, "wmo_1st_t", "K", "WMO 1st tropopause temperature", NC_FLOAT,
148 dimid, &varid, 1);
149 add_var(ncid, "wmo_1st_q", "ppv", "WMO 1st tropopause water vapor",
150 NC_FLOAT, dimid, &varid, 1);
151
152 add_var(ncid, "wmo_2nd_lat", "degrees_north", "WMO 2nd tropopause latitude",
153 NC_DOUBLE, dimid, &varid, 1);
154 add_var(ncid, "wmo_2nd_lon", "degrees_east", "WMO 2nd tropopause longitude",
155 NC_DOUBLE, dimid, &varid, 1);
156 add_var(ncid, "wmo_2nd_z", "km", "WMO 2nd tropopause height", NC_FLOAT,
157 dimid, &varid, 1);
158 add_var(ncid, "wmo_2nd_p", "hPa", "WMO 2nd tropopause pressure", NC_FLOAT,
159 dimid, &varid, 1);
160 add_var(ncid, "wmo_2nd_t", "K", "WMO 2nd tropopause temperature", NC_FLOAT,
161 dimid, &varid, 1);
162 add_var(ncid, "wmo_2nd_q", "ppv", "WMO 2nd tropopause water vapor",
163 NC_FLOAT, dimid, &varid, 1);
164
165 /* Leave define mode... */
166 NC(nc_enddef(ncid));
167
168 /* Write data... */
169 NC(nc_inq_varid(ncid, "time", &varid));
170 NC(nc_put_var_double(ncid, varid, gps->time));
171
172 NC(nc_inq_varid(ncid, "clp_lat", &varid));
173 NC(nc_put_var_double(ncid, varid, clp_tlat));
174 NC(nc_inq_varid(ncid, "clp_lon", &varid));
175 NC(nc_put_var_double(ncid, varid, clp_tlon));
176 NC(nc_inq_varid(ncid, "clp_z", &varid));
177 NC(nc_put_var_float(ncid, varid, clp_th));
178 NC(nc_inq_varid(ncid, "clp_p", &varid));
179 NC(nc_put_var_float(ncid, varid, clp_tp));
180 NC(nc_inq_varid(ncid, "clp_t", &varid));
181 NC(nc_put_var_float(ncid, varid, clp_tt));
182 NC(nc_inq_varid(ncid, "clp_q", &varid));
183 NC(nc_put_var_float(ncid, varid, clp_tq));
184
185 NC(nc_inq_varid(ncid, "wmo_1st_lat", &varid));
186 NC(nc_put_var_double(ncid, varid, wmo_1st_tlat));
187 NC(nc_inq_varid(ncid, "wmo_1st_lon", &varid));
188 NC(nc_put_var_double(ncid, varid, wmo_1st_tlon));
189 NC(nc_inq_varid(ncid, "wmo_1st_z", &varid));
190 NC(nc_put_var_float(ncid, varid, wmo_1st_th));
191 NC(nc_inq_varid(ncid, "wmo_1st_p", &varid));
192 NC(nc_put_var_float(ncid, varid, wmo_1st_tp));
193 NC(nc_inq_varid(ncid, "wmo_1st_t", &varid));
194 NC(nc_put_var_float(ncid, varid, wmo_1st_tt));
195 NC(nc_inq_varid(ncid, "wmo_1st_q", &varid));
196 NC(nc_put_var_float(ncid, varid, wmo_1st_tq));
197
198 NC(nc_inq_varid(ncid, "wmo_2nd_lat", &varid));
199 NC(nc_put_var_double(ncid, varid, wmo_2nd_tlat));
200 NC(nc_inq_varid(ncid, "wmo_2nd_lon", &varid));
201 NC(nc_put_var_double(ncid, varid, wmo_2nd_tlon));
202 NC(nc_inq_varid(ncid, "wmo_2nd_z", &varid));
203 NC(nc_put_var_float(ncid, varid, wmo_2nd_th));
204 NC(nc_inq_varid(ncid, "wmo_2nd_p", &varid));
205 NC(nc_put_var_float(ncid, varid, wmo_2nd_tp));
206 NC(nc_inq_varid(ncid, "wmo_2nd_t", &varid));
207 NC(nc_put_var_float(ncid, varid, wmo_2nd_tt));
208 NC(nc_inq_varid(ncid, "wmo_2nd_q", &varid));
209 NC(nc_put_var_float(ncid, varid, wmo_2nd_tq));
210
211 /* Close file... */
212 NC(nc_close(ncid));
213
214 /* Free... */
215 free(gps);
216
217 return EXIT_SUCCESS;
218}
void read_gps_prof(char *filename, gps_t *gps, double prof_zmin_max, double prof_zmax_min)
Read GPS-RO profile.
Definition: libgps.c:528
void add_var(int ncid, const char *varname, const char *unit, const char *longname, int type, int dimid[], int *varid, int ndims)
Add variable to netCDF file.
Definition: libgps.c:30
void tropopause_spline(gps_t *gps, int met_tropo)
Find tropopause height using cubic spline interpolation.
Definition: libgps.c:942
GPS Code Collection library declarations.
#define NC(cmd)
Execute netCDF library command and check result.
Definition: libgps.h:134
#define NDS
Maximum number of GPS-RO profiles.
Definition: libgps.h:100
GPS-RO profile data.
Definition: libgps.h:153
double time[NDS]
Time (seconds since 2000-01-01T00:00Z).
Definition: libgps.h:162
double tlon[NDS]
Tropopause longitude [deg].
Definition: libgps.h:198
double tt[NDS]
Tropopause temperature [K].
Definition: libgps.h:192
double tp[NDS]
Tropopause pressure [hPa].
Definition: libgps.h:189
int nds
Number of profiles.
Definition: libgps.h:156
double th[NDS]
Tropopause height [km].
Definition: libgps.h:186
double tlat[NDS]
Tropopause latitude [deg].
Definition: libgps.h:201
double tq[NDS]
Tropopause water vapor [ppmv].
Definition: libgps.h:195
int main(int argc, char *argv[])
Definition: tropo.c:32