27#include "jurassic_unified_library.h"
48 const obs_t * obs_test,
49 const obs_t * obs_ref,
67 ERRMSG(
"Give parameters: <ctl> <obs> <atm> <rad>");
84 jur_unified_init(argc, argv);
85 jur_unified_formod_multiple_packages(&atm, &obs, 1, NULL);
92 char dirlist[
LEN], obsref[
LEN], task[
LEN];
98 scan_ctl(argc, argv,
"TASK", -1,
"-", task);
101 scan_ctl(argc, argv,
"DIRLIST", -1,
"-", dirlist);
104 scan_ctl(argc, argv,
"OBSREF", -1,
"-", obsref);
107 if (dirlist[0] ==
'-')
108 call_formod(&ctl, tbl, NULL, argv[2], argv[3], argv[4], task, obsref);
115 if (!(in = fopen(dirlist,
"r")))
116 ERRMSG(
"Cannot open directory list!");
120 while (fscanf(in,
"%4999s", wrkdir) != EOF) {
123 LOG(1,
"\nWorking directory: %s", wrkdir);
126 call_formod(&ctl, tbl, wrkdir, argv[2], argv[3], argv[4], task, obsref);
151 const char *obsref) {
153 static atm_t atm, atm2;
154 static obs_t obs, obs2;
157 read_atm(wrkdir, atmfile, ctl, &atm);
160 read_obs(wrkdir, obsfile, ctl, &obs);
163 if (task[0] ==
'p' || task[0] ==
'P') {
166 for (
int ir = 0; ir < obs.
nr; ir++) {
170 for (
int ip = 0; ip < atm.
np; ip++)
173 atm2.
z[atm2.
np] = atm.
z[ip];
176 atm2.
p[atm2.
np] = atm.
p[ip];
177 atm2.
t[atm2.
np] = atm.
t[ip];
178 for (
int ig = 0; ig < ctl->
ng; ig++)
179 atm2.
q[ig][atm2.
np] = atm.
q[ig][ip];
180 for (
int iw = 0; iw < ctl->
nw; iw++)
181 atm2.
k[iw][atm2.
np] = atm.
k[iw][ip];
188 obs2.
vpz[0] = obs.
vpz[ir];
199 formod(ctl, tbl, &atm2, &obs2);
202 for (
int id = 0;
id < ctl->
nd;
id++) {
203 obs.
rad[id][ir] = obs2.
rad[id][0];
204 obs.
tau[id][ir] = obs2.
tau[id][0];
217 formod(ctl, tbl, &atm, &obs);
223 if (obsref[0] !=
'-') {
226 read_obs(wrkdir, obsref, ctl, &obs2);
229 double mre[
ND], sdre[
ND], minre[
ND], maxre[
ND];
233 for (
int id = 0;
id < ctl->
nd;
id++)
235 (
"EVAL: nu= %.4f cm^-1 | MRE= %g %% | SDRE= %g %% | MinRE= %g %% | MaxRE= %g %%\n",
236 ctl->
nu[
id], mre[
id], sdre[
id], minre[
id], maxre[
id]);
240 if (task[0] ==
'c' || task[0] ==
'C') {
251 for (
int ig = 0; ig < ctl->
ng; ig++) {
257 for (
int iw = 0; iw < ctl->
nw; iw++)
258 for (
int ip = 0; ip < atm2.
np; ip++)
262 for (
int ig2 = 0; ig2 < ctl->
ng; ig2++)
264 for (
int ip = 0; ip < atm2.
np; ip++)
268 formod(ctl, tbl, &atm2, &obs);
271 sprintf(filename,
"%s.%s", radfile, ctl->
emitter[ig]);
279 for (
int ig = 0; ig < ctl->
ng; ig++)
280 for (
int ip = 0; ip < atm2.
np; ip++)
284 formod(ctl, tbl, &atm2, &obs);
287 sprintf(filename,
"%s.EXTINCT", radfile);
292 if (task[0] ==
't' || task[0] ==
'T') {
295 double t_min, t_max, t_mean = 0, t_sd = 0;
300 gsl_rng *rng = gsl_rng_alloc(gsl_rng_default);
307 double dtemp = 40. * (gsl_rng_uniform(rng) - 0.5);
308 double dpress = 1. - 0.1 * gsl_rng_uniform(rng);
310 for (
int ig = 0; ig < ctl->
ng; ig++)
311 dq[ig] = 0.8 + 0.4 * gsl_rng_uniform(rng);
312 for (
int ip = 0; ip < atm2.
np; ip++) {
314 atm2.
p[ip] *= dpress;
315 for (
int ig = 0; ig < ctl->
ng; ig++)
316 atm2.
q[ig][ip] *= dq[ig];
320 double t0 = omp_get_wtime();
321 formod(ctl, tbl, &atm2, &obs);
322 double dt = omp_get_wtime() - t0;
327 if (n == 0 || dt < t_min)
329 if (n == 0 || dt > t_max)
333 }
while (t_mean < 10.0);
336 t_mean /= (double) n;
337 t_sd = sqrt(t_sd / (
double) n -
POW2(t_mean));
338 printf(
"RUNTIME: mean= %g s | stddev= %g s | min= %g s | max= %g s\n",
339 t_mean, t_sd, t_min, t_max);
346 if (task[0] ==
's' || task[0] ==
'S') {
351 formod(ctl, tbl, &atm, &obs);
355 for (
double dz = 0.01; dz <= 2; dz *= 1.1)
356 for (
double ds = 0.1; ds <= 50; ds *= 1.1) {
363 double t0 = omp_get_wtime();
364 formod(ctl, tbl, &atm, &obs);
365 double dt = omp_get_wtime() - t0;
368 double mre[
ND], sdre[
ND], minre[
ND], maxre[
ND];
372 for (
int id = 0;
id < ctl->
nd;
id++)
374 (
"STEPSIZE: ds= %.4f km | dz= %g km | t= %g s | nu= %.4f cm^-1"
375 " | MRE= %g %% | SDRE= %g %% | MinRE= %g %% | MaxRE= %g %%\n",
376 ds, dz, dt, ctl->
nu[
id], mre[
id], sdre[
id], minre[
id],
387 const obs_t *obs_test,
388 const obs_t *obs_ref,
395 for (
int id = 0;
id < ctl->
nd;
id++) {
397 double sum = 0, sum2 = 0;
403 for (
int ir = 0; ir < obs_test->
nr; ir++) {
406 if (obs_ref->
rad[
id][ir] == 0)
410 double err = 100.0 * (obs_test->
rad[id][ir] - obs_ref->
rad[id][ir])
411 / obs_ref->
rad[
id][ir];
425 sdre[id] = sqrt(sum2 / n - mre[
id] * mre[
id]);
void read_ctl(int argc, char *argv[], ctl_t *ctl)
Read model control parameters from command-line and configuration input.
void read_atm(const char *dirname, const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric profile data from an ASCII file.
void copy_obs(const ctl_t *ctl, obs_t *obs_dest, const obs_t *obs_src, const int init)
Copy or initialize observation geometry and radiance data.
void read_obs(const char *dirname, const char *filename, const ctl_t *ctl, obs_t *obs)
Read observation geometry and radiance data from an ASCII file.
void write_obs(const char *dirname, const char *filename, const ctl_t *ctl, const obs_t *obs)
Write observation geometry and radiance data to a text file.
double scan_ctl(int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
Scan control file or command-line arguments for a configuration variable.
void formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
Execute the selected forward model.
tbl_t * read_tbl(const ctl_t *ctl)
Read all emissivity lookup tables for all gases and frequencies.
void copy_atm(const ctl_t *ctl, atm_t *atm_dest, const atm_t *atm_src, const int init)
Copy or initialize atmospheric profile data.
JURASSIC library declarations.
#define LEN
Maximum length of ASCII data lines.
#define POW2(x)
Compute the square of a value.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define ND
Maximum number of radiance channels.
#define NG
Maximum number of emitters.
#define LOG(level,...)
Print a log message with a specified logging level.
Atmospheric profile data.
double time[NP]
Time (seconds since 2000-01-01T00:00Z).
double k[NW][NP]
Extinction [km^-1].
double lat[NP]
Latitude [deg].
double lon[NP]
Longitude [deg].
double t[NP]
Temperature [K].
int np
Number of data points.
double z[NP]
Altitude [km].
double q[NG][NP]
Volume mixing ratio [ppv].
double p[NP]
Pressure [hPa].
int nw
Number of spectral windows.
double nu[ND]
Centroid wavenumber of each channel [cm^-1].
int ctm_co2
Compute CO2 continuum (0=no, 1=yes).
int ctm_n2
Compute N2 continuum (0=no, 1=yes).
int ctm_h2o
Compute H2O continuum (0=no, 1=yes).
int ng
Number of emitters.
int nd
Number of radiance channels.
int ctm_o2
Compute O2 continuum (0=no, 1=yes).
char emitter[NG][LEN]
Name of each emitter.
double rayds
Maximum step length for raytracing [km].
double raydz
Vertical step length for raytracing [km].
Observation geometry and radiance data.
double tau[ND][NR]
Transmittance of ray path.
double rad[ND][NR]
Radiance [W/(m^2 sr cm^-1)].
double vpz[NR]
View point altitude [km].
double vplat[NR]
View point latitude [deg].
double obslon[NR]
Observer longitude [deg].
double obslat[NR]
Observer latitude [deg].
double obsz[NR]
Observer altitude [km].
double vplon[NR]
View point longitude [deg].
double time[NR]
Time (seconds since 2000-01-01T00:00Z).
int nr
Number of ray paths.
Emissivity look-up tables.