MPTRAC
atm_select.c
Go to the documentation of this file.
1/*
2 This file is part of MPTRAC.
3
4 MPTRAC is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 MPTRAC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with MPTRAC. If not, see <http://www.gnu.org/licenses/>.
16
17 Copyright (C) 2013-2026 Forschungszentrum Juelich GmbH
18*/
19
25#include "mptrac.h"
26
27/* ------------------------------------------------------------
28 Functions...
29 ------------------------------------------------------------ */
30
32void usage(
33 void);
34
35/* ------------------------------------------------------------
36 Main...
37 ------------------------------------------------------------ */
38
39int main(
40 int argc,
41 char *argv[]) {
42
43 ctl_t ctl;
44
45 atm_t *atm, *atm2;
46
47 /* Allocate... */
48 ALLOC(atm, atm_t, 1);
49 ALLOC(atm2, atm_t, 1);
50
51 /* Print usage information... */
52 USAGE;
53
54 /* Check arguments... */
55 if (argc < 4)
56 ERRMSG("Missing or invalid command-line arguments.\n\n"
57 "Usage: atm_select <ctl> <atm_select> <atm1> [<atm2> ...]\n\n"
58 "Use -h for full help.");
59
60 /* Read control parameters... */
61 mptrac_read_ctl(argv[1], argc, argv, &ctl);
62 const int stride =
63 (int) scan_ctl(argv[1], argc, argv, "SELECT_STRIDE", -1, "1", NULL);
64 const int idx0 =
65 (int) scan_ctl(argv[1], argc, argv, "SELECT_IDX0", -1, "-999", NULL);
66 const int idx1 =
67 (int) scan_ctl(argv[1], argc, argv, "SELECT_IDX1", -1, "-999", NULL);
68 int ip0 =
69 (int) scan_ctl(argv[1], argc, argv, "SELECT_IP0", -1, "-999", NULL);
70 int ip1 =
71 (int) scan_ctl(argv[1], argc, argv, "SELECT_IP1", -1, "-999", NULL);
72 const double t0 = scan_ctl(argv[1], argc, argv, "SELECT_T0", -1, "0", NULL);
73 const double t1 = scan_ctl(argv[1], argc, argv, "SELECT_T1", -1, "0", NULL);
74 const double p0 =
75 P(scan_ctl(argv[1], argc, argv, "SELECT_Z0", -1, "0", NULL));
76 const double p1 =
77 P(scan_ctl(argv[1], argc, argv, "SELECT_Z1", -1, "0", NULL));
78 const double theta0 =
79 scan_ctl(argv[1], argc, argv, "SELECT_THETA0", -1, "0", NULL);
80 const double theta1 =
81 scan_ctl(argv[1], argc, argv, "SELECT_THETA1", -1, "0", NULL);
82 const double lon0 =
83 scan_ctl(argv[1], argc, argv, "SELECT_LON0", -1, "0", NULL);
84 const double lon1 =
85 scan_ctl(argv[1], argc, argv, "SELECT_LON1", -1, "0", NULL);
86 const double lat0 =
87 scan_ctl(argv[1], argc, argv, "SELECT_LAT0", -1, "0", NULL);
88 const double lat1 =
89 scan_ctl(argv[1], argc, argv, "SELECT_LAT1", -1, "0", NULL);
90 const double r0 = scan_ctl(argv[1], argc, argv, "SELECT_R0", -1, "0", NULL);
91 const double r1 = scan_ctl(argv[1], argc, argv, "SELECT_R1", -1, "0", NULL);
92 const double rlon =
93 scan_ctl(argv[1], argc, argv, "SELECT_RLON", -1, "0", NULL);
94 const double rlat =
95 scan_ctl(argv[1], argc, argv, "SELECT_RLAT", -1, "0", NULL);
96
97 /* Get Cartesian coordinates... */
98 double x0[3], x1[3];
99 geo2cart(0, rlon, rlat, x0);
100
101 /* Loop over files... */
102 for (int f = 3; f < argc; f++) {
103
104 /* Read atmopheric data... */
105 if (!mptrac_read_atm(argv[f], &ctl, atm))
106 continue;
107
108 /* Adjust range of air parcels... */
109 if (ip0 < 0)
110 ip0 = 0;
111 ip0 = MIN(ip0, atm->np - 1);
112 if (ip1 < 0)
113 ip1 = atm->np - 1;
114 ip1 = MIN(ip1, atm->np - 1);
115 if (ip1 < ip0)
116 ip1 = ip0;
117
118 /* Loop over air parcels... */
119 for (int ip = ip0; ip <= ip1; ip += stride) {
120
121 /* Check air parcel index... */
122 if (ctl.qnt_idx >= 0 && idx0 >= 0 && idx1 >= 0)
123 if (atm->q[ctl.qnt_idx][ip] < idx0 || atm->q[ctl.qnt_idx][ip] > idx1)
124 continue;
125
126 /* Check time... */
127 if (t0 != t1)
128 if ((t1 > t0 && (atm->time[ip] < t0 || atm->time[ip] > t1))
129 || (t1 < t0 && (atm->time[ip] < t0 && atm->time[ip] > t1)))
130 continue;
131
132 /* Check vertical distance... */
133 if (p0 != p1)
134 if ((p0 > p1 && (atm->p[ip] > p0 || atm->p[ip] < p1))
135 || (p0 < p1 && (atm->p[ip] > p0 && atm->p[ip] < p1)))
136 continue;
137
138 /* Check potential temperature... */
139 if (theta0 != theta1) {
140 double theta;
141 if (ctl.qnt_theta >= 0)
142 theta = atm->q[ctl.qnt_theta][ip];
143 else if (ctl.qnt_t >= 0)
144 theta = THETA(atm->p[ip], atm->q[ctl.qnt_t][ip]);
145 else
146 ERRMSG
147 ("Filtering requires temperature or potential temperature data!");
148 if ((theta1 > theta0 && (theta < theta0 || theta > theta1))
149 || (theta1 < theta0 && (theta < theta0 && theta > theta1)))
150 continue;
151 }
152
153 /* Check longitude... */
154 if (lon0 != lon1)
155 if ((lon1 > lon0 && (atm->lon[ip] < lon0 || atm->lon[ip] > lon1))
156 || (lon1 < lon0 && (atm->lon[ip] < lon0 && atm->lon[ip] > lon1)))
157 continue;
158
159 /* Check latitude... */
160 if (lat0 != lat1)
161 if ((lat1 > lat0 && (atm->lat[ip] < lat0 || atm->lat[ip] > lat1))
162 || (lat1 < lat0 && (atm->lat[ip] < lat0 && atm->lat[ip] > lat1)))
163 continue;
164
165 /* Check horizontal distace... */
166 if (r0 != r1) {
167 geo2cart(0, atm->lon[ip], atm->lat[ip], x1);
168 double r = DIST(x0, x1);
169 if ((r1 > r0 && (r < r0 || r > r1))
170 || (r1 < r0 && (r < r0 && r > r1)))
171 continue;
172 }
173
174 /* Copy data... */
175 atm2->time[atm2->np] = atm->time[ip];
176 atm2->p[atm2->np] = atm->p[ip];
177 atm2->lon[atm2->np] = atm->lon[ip];
178 atm2->lat[atm2->np] = atm->lat[ip];
179 for (int iq = 0; iq < ctl.nq; iq++)
180 atm2->q[iq][atm2->np] = atm->q[iq][ip];
181 if ((++atm2->np) > NP)
182 ERRMSG("Too many air parcels!");
183 }
184 }
185
186 /* Close file... */
187 mptrac_write_atm(argv[2], &ctl, atm2, 0);
188
189 /* Free... */
190 free(atm);
191 free(atm2);
192
193 return EXIT_SUCCESS;
194}
195
196/*****************************************************************************/
197
199void usage(
200 void) {
201
202 printf("\nMPTRAC atm_select tool.\n\n");
203 printf("Extract subsets of air parcels from atmospheric data files.\n");
204 printf("\n");
205 printf("Usage:\n");
206 printf(" atm_select <ctl> <atm_select> <atm1> [<atm2> ...]\n");
207 printf("\n");
208 printf("Arguments:\n");
209 printf(" <ctl> Control file.\n");
210 printf(" <atm_select> Atmospheric output file for selected parcels.\n");
211 printf(" <atm*> Atmospheric input files.\n");
212 printf("\nFurther information:\n");
213 printf(" Manual: https://slcs-jsc.github.io/mptrac/\n");
214}
int main(int argc, char *argv[])
Definition: atm_select.c:39
void usage(void)
Print command-line help.
Definition: atm_select.c:199
void mptrac_write_atm(const char *filename, const ctl_t *ctl, const atm_t *atm, const double t)
Writes air parcel data to a file in various formats.
Definition: mptrac.c:6526
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.
Definition: mptrac.c:10745
int mptrac_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.
Definition: mptrac.c:5117
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.
Definition: mptrac.c:5248
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
Definition: mptrac.c:1674
MPTRAC library declarations.
#define MIN(a, b)
Macro to determine the minimum of two values.
Definition: mptrac.h:1175
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: mptrac.h:2102
#define USAGE
Print usage information on -h or --help.
Definition: mptrac.h:1909
#define P(z)
Compute pressure at given altitude.
Definition: mptrac.h:1480
#define THETA(p, t)
Compute potential temperature.
Definition: mptrac.h:1820
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
Definition: mptrac.h:453
#define NP
Maximum number of atmospheric data points.
Definition: mptrac.h:355
#define DIST(a, b)
Calculate the distance between two points in Cartesian coordinates.
Definition: mptrac.h:704
Air parcel data.
Definition: mptrac.h:3241
double time[NP]
Time [s].
Definition: mptrac.h:3247
double lat[NP]
Latitude [deg].
Definition: mptrac.h:3256
double lon[NP]
Longitude [deg].
Definition: mptrac.h:3253
int np
Number of air parcels.
Definition: mptrac.h:3244
double q[NQ][NP]
Quantity data (for various, user-defined attributes).
Definition: mptrac.h:3259
double p[NP]
Pressure [hPa].
Definition: mptrac.h:3250
Control parameters.
Definition: mptrac.h:2190
int qnt_theta
Quantity array index for potential temperature.
Definition: mptrac.h:2401
int qnt_t
Quantity array index for temperature.
Definition: mptrac.h:2284
int qnt_idx
Quantity array index for air parcel IDs.
Definition: mptrac.h:2212
int nq
Number of quantities.
Definition: mptrac.h:2197