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.");
63 (int)
scan_ctl(argv[1], argc, argv,
"SELECT_STRIDE", -1,
"1", NULL);
65 (int)
scan_ctl(argv[1], argc, argv,
"SELECT_IDX0", -1,
"-999", NULL);
67 (int)
scan_ctl(argv[1], argc, argv,
"SELECT_IDX1", -1,
"-999", NULL);
69 (int)
scan_ctl(argv[1], argc, argv,
"SELECT_IP0", -1,
"-999", NULL);
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);
75 P(
scan_ctl(argv[1], argc, argv,
"SELECT_Z0", -1,
"0", NULL));
77 P(
scan_ctl(argv[1], argc, argv,
"SELECT_Z1", -1,
"0", NULL));
79 scan_ctl(argv[1], argc, argv,
"SELECT_THETA0", -1,
"0", NULL);
81 scan_ctl(argv[1], argc, argv,
"SELECT_THETA1", -1,
"0", NULL);
83 scan_ctl(argv[1], argc, argv,
"SELECT_LON0", -1,
"0", NULL);
85 scan_ctl(argv[1], argc, argv,
"SELECT_LON1", -1,
"0", NULL);
87 scan_ctl(argv[1], argc, argv,
"SELECT_LAT0", -1,
"0", NULL);
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);
93 scan_ctl(argv[1], argc, argv,
"SELECT_RLON", -1,
"0", NULL);
95 scan_ctl(argv[1], argc, argv,
"SELECT_RLAT", -1,
"0", NULL);
102 for (
int f = 3; f < argc; f++) {
111 ip0 =
MIN(ip0, atm->
np - 1);
114 ip1 =
MIN(ip1, atm->
np - 1);
119 for (
int ip = ip0; ip <= ip1; ip += stride) {
122 if (ctl.
qnt_idx >= 0 && idx0 >= 0 && idx1 >= 0)
128 if ((t1 > t0 && (atm->
time[ip] < t0 || atm->
time[ip] > t1))
129 || (t1 < t0 && (atm->
time[ip] < t0 && atm->
time[ip] > t1)))
134 if ((p0 > p1 && (atm->
p[ip] > p0 || atm->
p[ip] < p1))
135 || (p0 < p1 && (atm->
p[ip] > p0 && atm->
p[ip] < p1)))
139 if (theta0 != theta1) {
143 else if (ctl.
qnt_t >= 0)
147 (
"Filtering requires temperature or potential temperature data!");
148 if ((theta1 > theta0 && (theta < theta0 || theta > theta1))
149 || (theta1 < theta0 && (theta < theta0 && theta > theta1)))
155 if ((lon1 > lon0 && (atm->
lon[ip] < lon0 || atm->
lon[ip] > lon1))
156 || (lon1 < lon0 && (atm->
lon[ip] < lon0 && atm->
lon[ip] > lon1)))
161 if ((lat1 > lat0 && (atm->
lat[ip] < lat0 || atm->
lat[ip] > lat1))
162 || (lat1 < lat0 && (atm->
lat[ip] < lat0 && atm->
lat[ip] > lat1)))
168 double r =
DIST(x0, x1);
169 if ((r1 > r0 && (r < r0 || r > r1))
170 || (r1 < r0 && (r < r0 && r > r1)))
176 atm2->
p[atm2->
np] = atm->
p[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!");
202 printf(
"\nMPTRAC atm_select tool.\n\n");
203 printf(
"Extract subsets of air parcels from atmospheric data files.\n");
206 printf(
" atm_select <ctl> <atm_select> <atm1> [<atm2> ...]\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");
int main(int argc, char *argv[])
void usage(void)
Print command-line help.
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.
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.
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.
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.
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
MPTRAC library declarations.
#define MIN(a, b)
Macro to determine the minimum of two values.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define USAGE
Print usage information on -h or --help.
#define P(z)
Compute pressure at given altitude.
#define THETA(p, t)
Compute potential temperature.
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
#define NP
Maximum number of atmospheric data points.
#define DIST(a, b)
Calculate the distance between two points in Cartesian coordinates.
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].
int qnt_theta
Quantity array index for potential temperature.
int qnt_t
Quantity array index for temperature.
int qnt_idx
Quantity array index for air parcel IDs.
int nq
Number of quantities.