MPTRAC
Functions
atm_stat.c File Reference

Calculate air parcel statistics. More...

#include "mptrac.h"

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Detailed Description

Calculate air parcel statistics.

Definition in file atm_stat.c.

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 27 of file atm_stat.c.

29 {
30
31 ctl_t ctl;
32
33 atm_t *atm, *atm_filt;
34
35 FILE *out;
36
37 double latm, lonm, t, t0 = NAN, qm[NQ], *work, zm, *zs;
38
39 int init = 0;
40
41 /* Allocate... */
42 ALLOC(atm, atm_t, 1);
43 ALLOC(atm_filt, atm_t, 1);
44 ALLOC(work, double,
45 NP);
46 ALLOC(zs, double,
47 NP);
48
49 /* Check arguments... */
50 if (argc < 4)
51 ERRMSG("Give parameters: <ctl> <stat.tab> <param> <atm1> [<atm2> ...]");
52
53 /* Read control parameters... */
54 read_ctl(argv[1], argc, argv, &ctl);
55 const int ens =
56 (int) scan_ctl(argv[1], argc, argv, "STAT_ENS", -1, "-999", NULL);
57 const double p0 =
58 P(scan_ctl(argv[1], argc, argv, "STAT_Z0", -1, "-1000", NULL));
59 const double p1 =
60 P(scan_ctl(argv[1], argc, argv, "STAT_Z1", -1, "1000", NULL));
61 const double lat0 =
62 scan_ctl(argv[1], argc, argv, "STAT_LAT0", -1, "-1000", NULL);
63 const double lat1 =
64 scan_ctl(argv[1], argc, argv, "STAT_LAT1", -1, "1000", NULL);
65 const double lon0 =
66 scan_ctl(argv[1], argc, argv, "STAT_LON0", -1, "-1000", NULL);
67 const double lon1 =
68 scan_ctl(argv[1], argc, argv, "STAT_LON1", -1, "1000", NULL);
69
70 /* Write info... */
71 LOG(1, "Write air parcel statistics: %s", argv[2]);
72
73 /* Create output file... */
74 if (!(out = fopen(argv[2], "w")))
75 ERRMSG("Cannot create file!");
76
77 /* Write header... */
78 fprintf(out,
79 "# $1 = time [s]\n"
80 "# $2 = time difference [s]\n"
81 "# $3 = altitude (%s) [km]\n"
82 "# $4 = longitude (%s) [deg]\n"
83 "# $5 = latitude (%s) [deg]\n", argv[3], argv[3], argv[3]);
84 for (int iq = 0; iq < ctl.nq; iq++)
85 fprintf(out, "# $%d = %s (%s) [%s]\n", iq + 6,
86 ctl.qnt_name[iq], argv[3], ctl.qnt_unit[iq]);
87 fprintf(out, "# $%d = number of particles\n\n", ctl.nq + 6);
88
89 /* Loop over files... */
90 for (int f = 4; f < argc; f++) {
91
92 /* Read atmopheric data... */
93 if (!read_atm(argv[f], &ctl, atm))
94 continue;
95
96 /* Get time from filename... */
97 t = time_from_filename(argv[f], ctl.atm_type < 2 ? 20 : 19);
98
99 /* Save initial time... */
100 if (!init) {
101 init = 1;
102 t0 = t;
103 }
104
105 /* Filter data... */
106 atm_filt->np = 0;
107 for (int ip = 0; ip < atm->np; ip++) {
108
109 /* Check time... */
110 if (!isfinite(atm->time[ip]))
111 continue;
112
113 /* Check ensemble index... */
114 if (ctl.qnt_ens > 0 && atm->q[ctl.qnt_ens][ip] != ens)
115 continue;
116
117 /* Check spatial range... */
118 if (atm->p[ip] > p0 || atm->p[ip] < p1
119 || atm->lon[ip] < lon0 || atm->lon[ip] > lon1
120 || atm->lat[ip] < lat0 || atm->lat[ip] > lat1)
121 continue;
122
123 /* Save data... */
124 atm_filt->time[atm_filt->np] = atm->time[ip];
125 atm_filt->p[atm_filt->np] = atm->p[ip];
126 atm_filt->lon[atm_filt->np] = atm->lon[ip];
127 atm_filt->lat[atm_filt->np] = atm->lat[ip];
128 for (int iq = 0; iq < ctl.nq; iq++)
129 atm_filt->q[iq][atm_filt->np] = atm->q[iq][ip];
130 atm_filt->np++;
131 }
132
133 /* Get heights... */
134 for (int ip = 0; ip < atm_filt->np; ip++)
135 zs[ip] = Z(atm_filt->p[ip]);
136
137 /* Get statistics... */
138 if (strcasecmp(argv[3], "mean") == 0) {
139 zm = gsl_stats_mean(zs, 1, (size_t) atm_filt->np);
140 lonm = gsl_stats_mean(atm_filt->lon, 1, (size_t) atm_filt->np);
141 latm = gsl_stats_mean(atm_filt->lat, 1, (size_t) atm_filt->np);
142 for (int iq = 0; iq < ctl.nq; iq++)
143 qm[iq] = gsl_stats_mean(atm_filt->q[iq], 1, (size_t) atm_filt->np);
144 } else if (strcasecmp(argv[3], "stddev") == 0) {
145 zm = gsl_stats_sd(zs, 1, (size_t) atm_filt->np);
146 lonm = gsl_stats_sd(atm_filt->lon, 1, (size_t) atm_filt->np);
147 latm = gsl_stats_sd(atm_filt->lat, 1, (size_t) atm_filt->np);
148 for (int iq = 0; iq < ctl.nq; iq++)
149 qm[iq] = gsl_stats_sd(atm_filt->q[iq], 1, (size_t) atm_filt->np);
150 } else if (strcasecmp(argv[3], "min") == 0) {
151 zm = gsl_stats_min(zs, 1, (size_t) atm_filt->np);
152 lonm = gsl_stats_min(atm_filt->lon, 1, (size_t) atm_filt->np);
153 latm = gsl_stats_min(atm_filt->lat, 1, (size_t) atm_filt->np);
154 for (int iq = 0; iq < ctl.nq; iq++)
155 qm[iq] = gsl_stats_min(atm_filt->q[iq], 1, (size_t) atm_filt->np);
156 } else if (strcasecmp(argv[3], "max") == 0) {
157 zm = gsl_stats_max(zs, 1, (size_t) atm_filt->np);
158 lonm = gsl_stats_max(atm_filt->lon, 1, (size_t) atm_filt->np);
159 latm = gsl_stats_max(atm_filt->lat, 1, (size_t) atm_filt->np);
160 for (int iq = 0; iq < ctl.nq; iq++)
161 qm[iq] = gsl_stats_max(atm_filt->q[iq], 1, (size_t) atm_filt->np);
162 } else if (strcasecmp(argv[3], "skew") == 0) {
163 zm = gsl_stats_skew(zs, 1, (size_t) atm_filt->np);
164 lonm = gsl_stats_skew(atm_filt->lon, 1, (size_t) atm_filt->np);
165 latm = gsl_stats_skew(atm_filt->lat, 1, (size_t) atm_filt->np);
166 for (int iq = 0; iq < ctl.nq; iq++)
167 qm[iq] = gsl_stats_skew(atm_filt->q[iq], 1, (size_t) atm_filt->np);
168 } else if (strcasecmp(argv[3], "kurt") == 0) {
169 zm = gsl_stats_kurtosis(zs, 1, (size_t) atm_filt->np);
170 lonm = gsl_stats_kurtosis(atm_filt->lon, 1, (size_t) atm_filt->np);
171 latm = gsl_stats_kurtosis(atm_filt->lat, 1, (size_t) atm_filt->np);
172 for (int iq = 0; iq < ctl.nq; iq++)
173 qm[iq] =
174 gsl_stats_kurtosis(atm_filt->q[iq], 1, (size_t) atm_filt->np);
175 } else if (strcasecmp(argv[3], "median") == 0) {
176 zm = gsl_stats_median(zs, 1, (size_t) atm_filt->np);
177 lonm = gsl_stats_median(atm_filt->lon, 1, (size_t) atm_filt->np);
178 latm = gsl_stats_median(atm_filt->lat, 1, (size_t) atm_filt->np);
179 for (int iq = 0; iq < ctl.nq; iq++)
180 qm[iq] = gsl_stats_median(atm_filt->q[iq], 1, (size_t) atm_filt->np);
181 } else if (strcasecmp(argv[3], "absdev") == 0) {
182 zm = gsl_stats_absdev(zs, 1, (size_t) atm_filt->np);
183 lonm = gsl_stats_absdev(atm_filt->lon, 1, (size_t) atm_filt->np);
184 latm = gsl_stats_absdev(atm_filt->lat, 1, (size_t) atm_filt->np);
185 for (int iq = 0; iq < ctl.nq; iq++)
186 qm[iq] = gsl_stats_absdev(atm_filt->q[iq], 1, (size_t) atm_filt->np);
187 } else if (strcasecmp(argv[3], "mad") == 0) {
188 zm = gsl_stats_mad0(zs, 1, (size_t) atm_filt->np, work);
189 lonm = gsl_stats_mad0(atm_filt->lon, 1, (size_t) atm_filt->np, work);
190 latm = gsl_stats_mad0(atm_filt->lat, 1, (size_t) atm_filt->np, work);
191 for (int iq = 0; iq < ctl.nq; iq++)
192 qm[iq] =
193 gsl_stats_mad0(atm_filt->q[iq], 1, (size_t) atm_filt->np, work);
194 } else
195 ERRMSG("Unknown parameter!");
196
197 /* Write data... */
198 fprintf(out, "%.2f %.2f %g %g %g", t, t - t0, zm, lonm, latm);
199 for (int iq = 0; iq < ctl.nq; iq++) {
200 fprintf(out, " ");
201 fprintf(out, ctl.qnt_format[iq], qm[iq]);
202 }
203 fprintf(out, " %d\n", atm_filt->np);
204 }
205
206 /* Close file... */
207 fclose(out);
208
209 /* Free... */
210 free(atm);
211 free(atm_filt);
212 free(work);
213 free(zs);
214
215 return EXIT_SUCCESS;
216}
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:8503
double time_from_filename(const char *filename, const int offset)
Extracts and converts a timestamp from a filename to Julian seconds.
Definition: mptrac.c:8816
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.
Definition: mptrac.c:5156
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.
Definition: mptrac.c:4566
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: mptrac.h:1916
#define Z(p)
Convert pressure to altitude.
Definition: mptrac.h:1741
#define P(z)
Compute pressure at given altitude.
Definition: mptrac.h:1304
#define NQ
Maximum number of quantities per data point.
Definition: mptrac.h:251
#define ALLOC(ptr, type, n)
Allocate memory for a pointer with error handling.
Definition: mptrac.h:349
#define NP
Maximum number of atmospheric data points.
Definition: mptrac.h:246
#define LOG(level,...)
Print a log message with a specified logging level.
Definition: mptrac.h:1846
Air parcel data.
Definition: mptrac.h:3147
double time[NP]
Time [s].
Definition: mptrac.h:3153
double lat[NP]
Latitude [deg].
Definition: mptrac.h:3162
double lon[NP]
Longitude [deg].
Definition: mptrac.h:3159
int np
Number of air parcels.
Definition: mptrac.h:3150
double q[NQ][NP]
Quantity data (for various, user-defined attributes).
Definition: mptrac.h:3165
double p[NP]
Pressure [hPa].
Definition: mptrac.h:3156
Control parameters.
Definition: mptrac.h:2170
char qnt_format[NQ][LEN]
Quantity output format.
Definition: mptrac.h:2189
int atm_type
Type of atmospheric data files (0=ASCII, 1=binary, 2=netCDF, 3=CLaMS_traj, 4=CLaMS_pos).
Definition: mptrac.h:2932
char qnt_unit[NQ][LEN]
Quantity units.
Definition: mptrac.h:2186
char qnt_name[NQ][LEN]
Quantity names.
Definition: mptrac.h:2180
int qnt_ens
Quantity array index for ensemble IDs.
Definition: mptrac.h:2195
int nq
Number of quantities.
Definition: mptrac.h:2177
Here is the call graph for this function: