JURASSIC
Functions
jurassic.c File Reference

JURASSIC library definitions. More...

#include "jurassic.h"

Go to the source code of this file.

Functions

void analyze_avk (const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const int *iqa, const int *ipa, const gsl_matrix *avk)
 Analyze averaging kernel (AVK) matrix for retrieval diagnostics. More...
 
void analyze_avk_quantity (const gsl_matrix *avk, const int iq, const int *ipa, const size_t *n0, const size_t *n1, double *cont, double *res)
 Analyze averaging kernel submatrix for a specific retrieved quantity. More...
 
size_t atm2x (const ctl_t *ctl, const atm_t *atm, gsl_vector *x, int *iqa, int *ipa)
 Convert atmospheric data to state vector elements. More...
 
void atm2x_help (const double value, const int value_iqa, const int value_ip, gsl_vector *x, int *iqa, int *ipa, size_t *n)
 Append a single atmospheric value to the state vector. More...
 
void cart2geo (const double *x, double *z, double *lon, double *lat)
 Converts Cartesian coordinates to geographic coordinates. More...
 
void climatology (const ctl_t *ctl, atm_t *atm)
 Initializes atmospheric climatology profiles. More...
 
double cos_sza (const double sec, const double lon, const double lat)
 Calculates the cosine of the solar zenith angle. More...
 
double cost_function (const gsl_vector *dx, const gsl_vector *dy, const gsl_matrix *s_a_inv, const gsl_vector *sig_eps_inv)
 Compute the normalized quadratic cost function for optimal estimation. More...
 
double ctmco2 (const double nu, const double p, const double t, const double u)
 Compute carbon dioxide continuum (optical depth). More...
 
double ctmh2o (const double nu, const double p, const double t, const double q, const double u)
 Compute water vapor continuum (optical depth). More...
 
double ctmn2 (const double nu, const double p, const double t)
 Compute N₂ collision-induced absorption coefficient. More...
 
double ctmo2 (const double nu, const double p, const double t)
 Compute O₂ collision-induced absorption coefficient. More...
 
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. More...
 
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. More...
 
void day2doy (int year, int mon, int day, int *doy)
 Convert a calendar date to day-of-year. More...
 
void doy2day (int year, int doy, int *mon, int *day)
 Convert a day-of-year value to a calendar date. More...
 
int find_emitter (const ctl_t *ctl, const char *emitter)
 Find gas species index by name. More...
 
void formod (const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
 Execute the selected forward model. More...
 
void formod_continua (const ctl_t *ctl, const los_t *los, const int ip, double *beta)
 Compute total extinction including gaseous continua. More...
 
void formod_fov (const ctl_t *ctl, obs_t *obs)
 Apply field-of-view (FOV) convolution to modeled radiances. More...
 
void formod_pencil (const ctl_t *ctl, const tbl_t *tbl, const atm_t *atm, obs_t *obs, const int ir)
 Compute line-of-sight radiances using the pencil-beam forward model. More...
 
void formod_rfm (const ctl_t *ctl, const tbl_t *tbl, const atm_t *atm, obs_t *obs)
 Forward-model radiance and transmittance with the Reference Forward Model (RFM). More...
 
void formod_srcfunc (const ctl_t *ctl, const tbl_t *tbl, const double t, double *src)
 Interpolate the source function (Planck radiance) at a given temperature. More...
 
void geo2cart (const double z, const double lon, const double lat, double *x)
 Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates. More...
 
void hydrostatic (const ctl_t *ctl, atm_t *atm)
 Adjust pressure profile using the hydrostatic equation. More...
 
void idx2name (const ctl_t *ctl, const int idx, char *quantity)
 Convert a quantity index to a descriptive name string. More...
 
void init_srcfunc (const ctl_t *ctl, tbl_t *tbl)
 Initialize source function lookup tables from emissivity data. More...
 
void intpol_atm (const ctl_t *ctl, const atm_t *atm, const double z, double *p, double *t, double *q, double *k)
 Interpolate atmospheric state variables at a given altitude. More...
 
void intpol_tbl_cga (const ctl_t *ctl, const tbl_t *tbl, const los_t *los, const int ip, double tau_path[ND][NG], double tau_seg[ND])
 Interpolate emissivities and transmittances using the Curtis–Godson approximation (CGA). More...
 
void intpol_tbl_ega (const ctl_t *ctl, const tbl_t *tbl, const los_t *los, const int ip, double tau_path[ND][NG], double tau_seg[ND])
 Interpolate emissivities and transmittances using the Emissivity Growth Approximation (EGA). More...
 
double intpol_tbl_eps (const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double logu)
 Interpolate gas emissivity as a function of column amount. More...
 
double intpol_tbl_u (const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double logeps)
 Interpolate column amount as a function of emissivity. More...
 
void jsec2time (const double jsec, int *year, int *mon, int *day, int *hour, int *min, int *sec, double *remain)
 Converts Julian seconds to calendar date and time components. More...
 
void kernel (const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs, gsl_matrix *k)
 Compute the Jacobian (kernel) matrix by finite differences. More...
 
int locate_irr (const double *xx, const int n, const double x)
 Locate index for interpolation on an irregular grid. More...
 
int locate_reg (const double *xx, const int n, const double x)
 Locate index for interpolation on a regular (uniform) grid. More...
 
int locate_tbl (const float *xx, const int n, const double x)
 Locate index for interpolation within emissivity table grids. More...
 
void matrix_invert (gsl_matrix *a)
 Invert a square matrix, optimized for diagonal or symmetric positive-definite matrices. More...
 
void matrix_product (const gsl_matrix *a, const gsl_vector *b, const int transpose, gsl_matrix *c)
 Compute structured matrix products of the form \(A^T B A\) or \(A B A^T\). More...
 
size_t obs2y (const ctl_t *ctl, const obs_t *obs, gsl_vector *y, int *ida, int *ira)
 Convert observation radiances into a measurement vector. More...
 
void optimal_estimation (ret_t *ret, ctl_t *ctl, tbl_t *tbl, obs_t *obs_meas, obs_t *obs_i, atm_t *atm_apr, atm_t *atm_i, double *chisq)
 Perform optimal estimation retrieval using Levenberg–Marquardt minimization. More...
 
void raytrace (const ctl_t *ctl, const atm_t *atm, obs_t *obs, los_t *los, const int ir)
 Perform line-of-sight (LOS) ray tracing through the atmosphere. More...
 
void read_atm (const char *dirname, const char *filename, const ctl_t *ctl, atm_t *atm)
 Read atmospheric input data from a file. More...
 
void read_atm_asc (const char *filename, const ctl_t *ctl, atm_t *atm)
 Read atmospheric data in ASCII format. More...
 
void read_atm_bin (const char *filename, const ctl_t *ctl, atm_t *atm)
 Read atmospheric data in binary format. More...
 
void read_atm_nc (const char *filename, const ctl_t *ctl, atm_t *atm, int profile)
 Read one atmospheric profile from a netCDF file. More...
 
void read_ctl (int argc, char *argv[], ctl_t *ctl)
 Read model control parameters from command-line and configuration input. More...
 
void read_matrix (const char *dirname, const char *filename, gsl_matrix *matrix)
 Read a numerical matrix from an ASCII file. More...
 
void read_obs (const char *dirname, const char *filename, const ctl_t *ctl, obs_t *obs)
 Read observation data from an input file. More...
 
void read_obs_asc (const char *filename, const ctl_t *ctl, obs_t *obs)
 Read ASCII-formatted observation data from a file. More...
 
void read_obs_bin (const char *filename, const ctl_t *ctl, obs_t *obs)
 Read binary-formatted observation data from a file. More...
 
void read_obs_nc (const char *filename, const ctl_t *ctl, obs_t *obs, const int profile)
 Read one observation profile from a NetCDF file. More...
 
double read_obs_rfm (const char *basename, const double z, const double *nu, const double *f, const int n)
 Read and spectrally convolve an RFM output spectrum. More...
 
void read_ret (int argc, char *argv[], const ctl_t *ctl, ret_t *ret)
 Read retrieval configuration and error parameters. More...
 
void read_rfm_spec (const char *filename, double *nu, double *rad, int *npts)
 Read a Reference Forward Model (RFM) ASCII spectrum. More...
 
void read_shape (const char *filename, double *x, double *y, int *n)
 Read a two-column shape function from an ASCII file. More...
 
tbl_tread_tbl (const ctl_t *ctl)
 Read emissivity lookup tables from disk. More...
 
void read_tbl_asc (const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
 Read a single ASCII emissivity lookup table. More...
 
void read_tbl_bin (const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
 Read a single compact binary emissivity lookup table. More...
 
void read_tbl_nc_channel (const ctl_t *ctl, tbl_t *tbl, int id, int ig, int ncid)
 Read one packed emissivity lookup table from an open NetCDF file. More...
 
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. More...
 
void set_cov_apr (const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const int *iqa, const int *ipa, gsl_matrix *s_a)
 Construct the a priori covariance matrix \(\mathbf{S_a}\) for retrieval parameters. More...
 
void set_cov_meas (const ret_t *ret, const ctl_t *ctl, const obs_t *obs, gsl_vector *sig_noise, gsl_vector *sig_formod, gsl_vector *sig_eps_inv)
 Construct measurement error standard deviations and their inverse. More...
 
void tangent_point (const los_t *los, double *tpz, double *tplon, double *tplat)
 Determine the tangent point along a line of sight (LOS). More...
 
void tbl_free (const ctl_t *ctl, tbl_t *tbl)
 Free lookup table and all internally allocated memory. More...
 
void tbl_pack (const tbl_t *tbl, int id, int ig, uint8_t *buf, size_t *bytes_used)
 Pack a lookup table into a contiguous binary buffer. More...
 
size_t tbl_packed_size (const tbl_t *tbl, int id, int ig)
 Compute required buffer size (in bytes) for tbl_pack(). More...
 
size_t tbl_unpack (tbl_t *tbl, int id, int ig, const uint8_t *buf)
 Unpack a lookup table from a contiguous binary buffer. More...
 
void time2jsec (const int year, const int mon, const int day, const int hour, const int min, const int sec, const double remain, double *jsec)
 Converts time components to seconds since January 1, 2000, 12:00:00 UTC. More...
 
void timer (const char *name, const char *file, const char *func, int line, int mode)
 Simple wall-clock timer for runtime diagnostics. More...
 
void write_atm (const char *dirname, const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric data to a file. More...
 
void write_atm_asc (const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric data to an ASCII file. More...
 
void write_atm_bin (const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric data to a binary file. More...
 
void write_atm_nc (const char *filename, const ctl_t *ctl, const atm_t *atm, int profile)
 Write one atmospheric profile to a netCDF file. More...
 
void write_atm_rfm (const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric profile in RFM-compatible format. More...
 
void write_matrix (const char *dirname, const char *filename, const ctl_t *ctl, const gsl_matrix *matrix, const atm_t *atm, const obs_t *obs, const char *rowspace, const char *colspace, const char *sort)
 Write a fully annotated matrix (e.g., Jacobian or gain matrix) to file. More...
 
void write_obs (const char *dirname, const char *filename, const ctl_t *ctl, const obs_t *obs)
 Write observation data to an output file in ASCII or binary format. More...
 
void write_obs_asc (const char *filename, const ctl_t *ctl, const obs_t *obs)
 Write observation data to an ASCII text file. More...
 
void write_obs_bin (const char *filename, const ctl_t *ctl, const obs_t *obs)
 Write observation data in binary format to a file. More...
 
void write_obs_nc (const char *filename, const ctl_t *ctl, const obs_t *obs, const int profile)
 Write one observation profile to a NetCDF file. More...
 
void write_shape (const char *filename, const double *x, const double *y, const int n)
 Write tabulated shape function data to a text file. More...
 
void write_stddev (const char *quantity, const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const gsl_matrix *s)
 Write retrieval standard deviation profiles to disk. More...
 
void write_tbl (const ctl_t *ctl, const tbl_t *tbl)
 Write emissivity lookup tables to disk. More...
 
void write_tbl_asc (const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
 Write one emissivity lookup table in human-readable ASCII format. More...
 
void write_tbl_bin (const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
 Write one emissivity lookup table in compact binary format. More...
 
void write_tbl_nc (const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
 Write one packed lookup table to a NetCDF file. More...
 
void x2atm (const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
 Map retrieval state vector back to atmospheric structure. More...
 
void x2atm_help (double *value, const gsl_vector *x, size_t *n)
 Helper function to extract a single value from the retrieval state vector. More...
 
void y2obs (const ctl_t *ctl, const gsl_vector *y, obs_t *obs)
 Copy elements from the measurement vector y into the observation structure. More...
 

Detailed Description

JURASSIC library definitions.

Definition in file jurassic.c.

Function Documentation

◆ analyze_avk()

void analyze_avk ( const ret_t ret,
const ctl_t ctl,
const atm_t atm,
const int *  iqa,
const int *  ipa,
const gsl_matrix *  avk 
)

Analyze averaging kernel (AVK) matrix for retrieval diagnostics.

Decomposes and evaluates the averaging kernel matrix \(\mathbf{A}\) to quantify the retrieval sensitivity and vertical resolution for each retrieved quantity (pressure, temperature, trace gases, extinction, etc.). The results are written to diagnostic atmospheric files for visualization.

Parameters
[in]retRetrieval control and configuration structure (ret_t).
[in]ctlGlobal control structure (ctl_t) defining retrieval setup and quantities.
[in]atmRetrieved atmospheric state structure (atm_t).
[in]iqaArray mapping state vector indices to physical quantities (e.g., IDXP, IDXT, IDXQ(...)).
[in]ipaArray mapping state vector indices to atmospheric grid points.
[in]avkAveraging kernel matrix \(\mathbf{A}\) (gsl_matrix, n×n).

The averaging kernel matrix \(\mathbf{A}\) describes the sensitivity of the retrieved state \(\hat{x}\) to the true state \(x\):

\[ \hat{x} - x_a = \mathbf{A} (x - x_a) \]

where \(x_a\) is the a priori state.
This function separates and evaluates:

  • Contribution profiles: diagonal dominance or total response (sensitivity).
  • Resolution profiles: width or spread of the averaging kernels.

Internally, this function:

  1. Identifies submatrices of \(\mathbf{A}\) corresponding to each physical quantity (pressure, temperature, VMRs, extinction, clouds, surface).
  2. Calls analyze_avk_quantity() for each retrieved parameter type to compute quantitative measures of contribution and resolution.
  3. Writes the results as atmospheric profiles:
    • atm_cont.tab — contribution functions (sensitivity).
    • atm_res.tab — resolution functions (vertical response width).
See also
analyze_avk_quantity, write_atm, set_cov_apr, set_cov_meas
Note
  • Submatrices are identified by matching the quantity index iqa[i] to the quantity constants (e.g., IDXT, IDXQ(ig), etc.).
  • Cloud and surface quantities are treated as scalar elements.
  • Output files are written to the retrieval working directory (ret->dir).
Warning
  • The averaging kernel must be fully computed and dimensionally consistent with the state vector before calling this function.
  • File writing will overwrite existing diagnostics in ret->dir.
Author
Lars Hoffmann

Definition at line 29 of file jurassic.c.

35 {
36
37 /* Allocate... */
38 atm_t *atm_cont, *atm_res;
39 ALLOC(atm_cont, atm_t, 1);
40 ALLOC(atm_res, atm_t, 1);
41
42 /* Get sizes... */
43 const size_t n = avk->size1;
44
45 /* Find sub-matrices for different quantities... */
46 size_t n0[NQ], n1[NQ];
47 for (int iq = 0; iq < NQ; iq++) {
48 n0[iq] = N;
49 for (size_t i = 0; i < n; i++) {
50 if (iqa[i] == iq && n0[iq] == N)
51 n0[iq] = i;
52 if (iqa[i] == iq)
53 n1[iq] = i - n0[iq] + 1;
54 }
55 }
56
57 /* Initialize... */
58 copy_atm(ctl, atm_cont, atm, 1);
59 copy_atm(ctl, atm_res, atm, 1);
60
61 /* Analyze quantities... */
62 analyze_avk_quantity(avk, IDXP, ipa, n0, n1, atm_cont->p, atm_res->p);
63 analyze_avk_quantity(avk, IDXT, ipa, n0, n1, atm_cont->t, atm_res->t);
64 for (int ig = 0; ig < ctl->ng; ig++)
65 analyze_avk_quantity(avk, IDXQ(ig), ipa, n0, n1,
66 atm_cont->q[ig], atm_res->q[ig]);
67 for (int iw = 0; iw < ctl->nw; iw++)
68 analyze_avk_quantity(avk, IDXK(iw), ipa, n0, n1,
69 atm_cont->k[iw], atm_res->k[iw]);
70 analyze_avk_quantity(avk, IDXCLZ, ipa, n0, n1, &atm_cont->clz,
71 &atm_res->clz);
72 analyze_avk_quantity(avk, IDXCLDZ, ipa, n0, n1, &atm_cont->cldz,
73 &atm_res->cldz);
74 for (int icl = 0; icl < ctl->ncl; icl++)
75 analyze_avk_quantity(avk, IDXCLK(icl), ipa, n0, n1,
76 &atm_cont->clk[icl], &atm_res->clk[icl]);
77 analyze_avk_quantity(avk, IDXSFT, ipa, n0, n1, &atm_cont->sft,
78 &atm_res->sft);
79 for (int isf = 0; isf < ctl->nsf; isf++)
80 analyze_avk_quantity(avk, IDXSFEPS(isf), ipa, n0, n1,
81 &atm_cont->sfeps[isf], &atm_res->sfeps[isf]);
82
83 /* Write results to disk... */
84 write_atm(ret->dir, "atm_cont.tab", ctl, atm_cont);
85 write_atm(ret->dir, "atm_res.tab", ctl, atm_res);
86
87 /* Free... */
88 free(atm_cont);
89 free(atm_res);
90}
void write_atm(const char *dirname, const char *filename, const ctl_t *ctl, const atm_t *atm)
Write atmospheric data to a file.
Definition: jurassic.c:6951
void analyze_avk_quantity(const gsl_matrix *avk, const int iq, const int *ipa, const size_t *n0, const size_t *n1, double *cont, double *res)
Analyze averaging kernel submatrix for a specific retrieved quantity.
Definition: jurassic.c:94
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.
Definition: jurassic.c:3264
#define N
Maximum size of state vector.
Definition: jurassic.h:278
#define IDXCLZ
Index for cloud layer height.
Definition: jurassic.h:343
#define IDXCLDZ
Index for cloud layer depth.
Definition: jurassic.h:346
#define IDXK(iw)
Indices for extinction.
Definition: jurassic.h:340
#define NQ
Maximum number of quantities.
Definition: jurassic.h:283
#define IDXSFT
Index for surface layer temperature.
Definition: jurassic.h:352
#define IDXSFEPS(isf)
Indices for surface layer emissivity.
Definition: jurassic.h:355
#define IDXCLK(icl)
Indices for cloud layer extinction.
Definition: jurassic.h:349
#define IDXP
Index for pressure.
Definition: jurassic.h:331
#define ALLOC(ptr, type, n)
Allocate memory for an array.
Definition: jurassic.h:378
#define IDXQ(ig)
Indices for volume mixing ratios.
Definition: jurassic.h:337
#define IDXT
Index for temperature.
Definition: jurassic.h:334
Atmospheric profile data.
Definition: jurassic.h:1243
double sfeps[NSF]
Surface emissivity.
Definition: jurassic.h:1285
double k[NW][NP]
Extinction [km^-1].
Definition: jurassic.h:1270
double t[NP]
Temperature [K].
Definition: jurassic.h:1264
double clz
Cloud layer height [km].
Definition: jurassic.h:1273
double cldz
Cloud layer depth [km].
Definition: jurassic.h:1276
double sft
Surface temperature [K].
Definition: jurassic.h:1282
double clk[NCL]
Cloud layer extinction [km^-1].
Definition: jurassic.h:1279
double q[NG][NP]
Volume mixing ratio [ppv].
Definition: jurassic.h:1267
double p[NP]
Pressure [hPa].
Definition: jurassic.h:1261
int nw
Number of spectral windows.
Definition: jurassic.h:1323
int ng
Number of emitters.
Definition: jurassic.h:1299
int ncl
Number of cloud layer spectral grid points.
Definition: jurassic.h:1329
int nsf
Number of surface layer spectral grid points.
Definition: jurassic.h:1335
char dir[LEN]
Working directory.
Definition: jurassic.h:1577
Here is the call graph for this function:

◆ analyze_avk_quantity()

void analyze_avk_quantity ( const gsl_matrix *  avk,
const int  iq,
const int *  ipa,
const size_t *  n0,
const size_t *  n1,
double *  cont,
double *  res 
)

Analyze averaging kernel submatrix for a specific retrieved quantity.

Computes the contribution (sensitivity) and resolution (information density) profiles for a given physical quantity from its corresponding submatrix of the full averaging kernel matrix \(\mathbf{A}\).

Parameters
[in]avkAveraging kernel matrix \(\mathbf{A}\) (gsl_matrix, n×n), describing the sensitivity of the retrieved state to the true state.
[in]iqQuantity index identifier (e.g., IDXP, IDXT, IDXQ(ig), IDXK(iw), IDXCLZ, etc.).
[in]ipaArray mapping state vector indices to atmospheric grid indices.
[in]n0Array of starting indices for each quantity sub-block in the state vector.
[in]n1Array of lengths (number of elements) for each quantity sub-block.
[out]contArray of contribution values, representing the total sensitivity or response of the retrieval at each grid point.
[out]resArray of resolution measures, representing the vertical information density or averaging kernel width at each grid point.

For a given quantity \(q\), the function extracts its corresponding block \(\mathbf{A}_q\) from the full averaging kernel matrix and computes:

  • Contribution function

    \[ \text{cont}_i = \sum_j A_{ij}^{(q)} \]

    giving the total response of retrieved element \(i\) to perturbations in all true elements \(j\) of the same quantity.
  • Resolution (information density)

    \[ \text{res}_i = \frac{1}{A_{ii}^{(q)}} \]

    approximating the degree of vertical resolution or smoothing at level \(i\).

The results are stored in the provided arrays cont[] and res[], indexed according to the atmospheric profile index via ipa[].

See also
analyze_avk, write_atm, set_cov_apr
Note
  • Only elements associated with the specified quantity index (iq) are processed.
  • The function assumes the averaging kernel matrix is square and symmetric.
  • The contribution and resolution arrays must be preallocated to at least the number of atmospheric grid points (atm->np).
Warning
  • If the diagonal element A_ii is zero or near-zero, the corresponding resolution value may be undefined or numerically unstable.
  • Input indices n0[iq] and n1[iq] must have been computed by analyze_avk().
Author
Lars Hoffmann

Definition at line 94 of file jurassic.c.

101 {
102
103 /* Loop over state vector elements... */
104 if (n0[iq] < N)
105 for (size_t i = 0; i < n1[iq]; i++) {
106
107 /* Get area of averaging kernel... */
108 for (size_t j = 0; j < n1[iq]; j++)
109 cont[ipa[n0[iq] + i]] += gsl_matrix_get(avk, n0[iq] + i, n0[iq] + j);
110
111 /* Get information density... */
112 res[ipa[n0[iq] + i]] = 1 / gsl_matrix_get(avk, n0[iq] + i, n0[iq] + i);
113 }
114}

◆ atm2x()

size_t atm2x ( const ctl_t ctl,
const atm_t atm,
gsl_vector *  x,
int *  iqa,
int *  ipa 
)

Convert atmospheric data to state vector elements.

Extracts selected quantities from an atmospheric profile (atm_t) according to retrieval settings in ctl_t, and appends them to the state vector x. For each included quantity, the function also stores its quantity index (iqa) and profile index (ipa).

The function respects retrieval altitude limits defined in ctl (e.g., retp_zmin/zmax, rett_zmin/zmax, etc.) and includes only variables flagged for retrieval (e.g., ret_clz, ret_sft, etc.).

Parameters
[in]ctlControl settings defining retrieval configuration and limits.
[in]atmAtmospheric profile data to extract from.
[out]xGSL vector to store state-vector elements.
[out]iqaQuantity index array corresponding to elements in x.
[out]ipaProfile index array corresponding to elements in x.
Returns
Number of elements written to the state vector.
Note
Internally calls atm2x_help() to append individual values.
See also
atm_t, ctl_t, atm2x_help
Author
Lars Hoffmann

Definition at line 118 of file jurassic.c.

123 {
124
125 size_t n = 0;
126
127 /* Add pressure... */
128 for (int ip = 0; ip < atm->np; ip++)
129 if (atm->z[ip] >= ctl->retp_zmin && atm->z[ip] <= ctl->retp_zmax)
130 atm2x_help(atm->p[ip], IDXP, ip, x, iqa, ipa, &n);
131
132 /* Add temperature... */
133 for (int ip = 0; ip < atm->np; ip++)
134 if (atm->z[ip] >= ctl->rett_zmin && atm->z[ip] <= ctl->rett_zmax)
135 atm2x_help(atm->t[ip], IDXT, ip, x, iqa, ipa, &n);
136
137 /* Add volume mixing ratios... */
138 for (int ig = 0; ig < ctl->ng; ig++)
139 for (int ip = 0; ip < atm->np; ip++)
140 if (atm->z[ip] >= ctl->retq_zmin[ig]
141 && atm->z[ip] <= ctl->retq_zmax[ig])
142 atm2x_help(atm->q[ig][ip], IDXQ(ig), ip, x, iqa, ipa, &n);
143
144 /* Add extinction... */
145 for (int iw = 0; iw < ctl->nw; iw++)
146 for (int ip = 0; ip < atm->np; ip++)
147 if (atm->z[ip] >= ctl->retk_zmin[iw]
148 && atm->z[ip] <= ctl->retk_zmax[iw])
149 atm2x_help(atm->k[iw][ip], IDXK(iw), ip, x, iqa, ipa, &n);
150
151 /* Add cloud variables... */
152 if (ctl->ret_clz)
153 atm2x_help(atm->clz, IDXCLZ, 0, x, iqa, ipa, &n);
154 if (ctl->ret_cldz)
155 atm2x_help(atm->cldz, IDXCLDZ, 0, x, iqa, ipa, &n);
156 if (ctl->ret_clk)
157 for (int icl = 0; icl < ctl->ncl; icl++)
158 atm2x_help(atm->clk[icl], IDXCLK(icl), 0, x, iqa, ipa, &n);
159
160 /* Add surface variables... */
161 if (ctl->ret_sft)
162 atm2x_help(atm->sft, IDXSFT, 0, x, iqa, ipa, &n);
163 if (ctl->ret_sfeps)
164 for (int isf = 0; isf < ctl->nsf; isf++)
165 atm2x_help(atm->sfeps[isf], IDXSFEPS(isf), 0, x, iqa, ipa, &n);
166
167 return n;
168}
void atm2x_help(const double value, const int value_iqa, const int value_ip, gsl_vector *x, int *iqa, int *ipa, size_t *n)
Append a single atmospheric value to the state vector.
Definition: jurassic.c:172
int np
Number of data points.
Definition: jurassic.h:1246
double z[NP]
Altitude [km].
Definition: jurassic.h:1252
double retp_zmin
Minimum altitude for pressure retrieval [km].
Definition: jurassic.h:1395
double retk_zmax[NW]
Maximum altitude for extinction retrieval [km].
Definition: jurassic.h:1416
double rett_zmax
Maximum altitude for temperature retrieval [km].
Definition: jurassic.h:1404
int ret_sfeps
Retrieve surface layer emissivity (0=no, 1=yes).
Definition: jurassic.h:1431
int ret_sft
Retrieve surface layer temperature (0=no, 1=yes).
Definition: jurassic.h:1428
int ret_clz
Retrieve cloud layer height (0=no, 1=yes).
Definition: jurassic.h:1419
double retq_zmax[NG]
Maximum altitude for volume mixing ratio retrieval [km].
Definition: jurassic.h:1410
double retq_zmin[NG]
Minimum altitude for volume mixing ratio retrieval [km].
Definition: jurassic.h:1407
double rett_zmin
Minimum altitude for temperature retrieval [km].
Definition: jurassic.h:1401
double retk_zmin[NW]
Minimum altitude for extinction retrieval [km].
Definition: jurassic.h:1413
int ret_clk
Retrieve cloud layer extinction (0=no, 1=yes).
Definition: jurassic.h:1425
int ret_cldz
Retrieve cloud layer depth (0=no, 1=yes).
Definition: jurassic.h:1422
double retp_zmax
Maximum altitude for pressure retrieval [km].
Definition: jurassic.h:1398
Here is the call graph for this function:

◆ atm2x_help()

void atm2x_help ( const double  value,
const int  value_iqa,
const int  value_ip,
gsl_vector *  x,
int *  iqa,
int *  ipa,
size_t *  n 
)

Append a single atmospheric value to the state vector.

Helper routine for atm2x(). Inserts one scalar value and its corresponding quantity and profile indices into the state vector and tracking arrays, then increments the element counter.

Parameters
[in]valueValue to add to the state vector.
[in]value_iqaQuantity index (e.g., IDXP, IDXT, etc.).
[in]value_ipProfile index within the atmospheric profile.
[out]xGSL vector containing state-vector elements (may be NULL).
[out]iqaQuantity index array corresponding to x (may be NULL).
[out]ipaProfile index array corresponding to x (may be NULL).
[in,out]nCurrent number of elements in the state vector; incremented on return.
Note
This function performs no range checking and assumes valid array bounds.
See also
atm2x
Author
Lars Hoffmann

Definition at line 172 of file jurassic.c.

179 {
180
181 /* Add element to state vector... */
182 if (x != NULL)
183 gsl_vector_set(x, *n, value);
184 if (iqa != NULL)
185 iqa[*n] = value_iqa;
186 if (ipa != NULL)
187 ipa[*n] = value_ip;
188 (*n)++;
189}

◆ cart2geo()

void cart2geo ( const double *  x,
double *  z,
double *  lon,
double *  lat 
)

Converts Cartesian coordinates to geographic coordinates.

This function converts a point from Cartesian coordinates (x, y, z) to geographic coordinates (longitude, latitude, and altitude). It uses the spherical Earth approximation for the conversion.

Parameters
xPointer to an array containing the Cartesian coordinates (x, y, z) in kilometers.
zPointer to a double where the computed altitude (above the reference ellipsoid) will be stored, in kilometers.
lonPointer to a double where the computed longitude (in degrees) will be stored.
latPointer to a double where the computed latitude (in degrees) will be stored.
Author
Lars Hoffmann

Definition at line 193 of file jurassic.c.

197 {
198
199 const double radius = NORM(x);
200
201 *lat = RAD2DEG(asin(x[2] / radius));
202 *lon = RAD2DEG(atan2(x[1], x[0]));
203 *z = radius - RE;
204}
#define RE
Mean radius of Earth [km].
Definition: jurassic.h:189
#define NORM(a)
Compute the norm (magnitude) of a 3D vector.
Definition: jurassic.h:916
#define RAD2DEG(rad)
Convert radians to degrees.
Definition: jurassic.h:990

◆ climatology()

void climatology ( const ctl_t ctl,
atm_t atm 
)

Initializes atmospheric climatology profiles.

This function populates the atmospheric state (atm) with standard climatological profiles of pressure, temperature, and trace gas concentrations (e.g., H2O, CH4, CO, O3, etc.) as a function of altitude. The profiles are based on reference climatological datasets and are used for atmospheric modeling and radiative transfer calculations.

Parameters
[in]ctlControl parameters structure.
[out]atmAtmospheric state structure to be populated with climatological data.
Author
Lars Hoffmann

Definition at line 208 of file jurassic.c.

210 {
211
212 static const double z[121] = {
213 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
214 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
215 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
216 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
217 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
218 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
219 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120
220 };
221
222 static const double pre[121] = {
223 1017, 901.083, 796.45, 702.227, 617.614, 541.644, 473.437, 412.288,
224 357.603, 308.96, 265.994, 228.348, 195.619, 167.351, 143.039, 122.198,
225 104.369, 89.141, 76.1528, 65.0804, 55.641, 47.591, 40.7233, 34.8637,
226 29.8633, 25.5956, 21.9534, 18.8445, 16.1909, 13.9258, 11.9913,
227 10.34, 8.92988, 7.72454, 6.6924, 5.80701, 5.04654, 4.39238, 3.82902,
228 3.34337, 2.92413, 2.56128, 2.2464, 1.97258, 1.73384, 1.52519, 1.34242,
229 1.18197, 1.04086, 0.916546, 0.806832, 0.709875, 0.624101, 0.548176,
230 0.480974, 0.421507, 0.368904, 0.322408, 0.281386, 0.245249, 0.213465,
231 0.185549, 0.161072, 0.139644, 0.120913, 0.104568, 0.0903249, 0.0779269,
232 0.0671493, 0.0577962, 0.0496902, 0.0426736, 0.0366093, 0.0313743,
233 0.0268598, 0.0229699, 0.0196206, 0.0167399, 0.0142646, 0.0121397,
234 0.0103181, 0.00875775, 0.00742226, 0.00628076, 0.00530519, 0.00447183,
235 0.00376124, 0.00315632, 0.00264248, 0.00220738, 0.00184003, 0.00153095,
236 0.00127204, 0.00105608, 0.000876652, 0.00072798, 0.00060492,
237 0.000503201, 0.000419226, 0.000349896, 0.000292659, 0.000245421,
238 0.000206394, 0.000174125, 0.000147441, 0.000125333, 0.000106985,
239 9.173e-05, 7.90172e-05, 6.84172e-05, 5.95574e-05, 5.21183e-05,
240 4.58348e-05, 4.05127e-05, 3.59987e-05, 3.21583e-05, 2.88718e-05,
241 2.60322e-05, 2.35687e-05, 2.14263e-05, 1.95489e-05
242 };
243
244 static const double tem[121] = {
245 285.14, 279.34, 273.91, 268.3, 263.24, 256.55, 250.2, 242.82, 236.17,
246 229.87, 225.04, 221.19, 218.85, 217.19, 216.2, 215.68, 215.42, 215.55,
247 215.92, 216.4, 216.93, 217.45, 218, 218.68, 219.39, 220.25, 221.3,
248 222.41, 223.88, 225.42, 227.2, 229.52, 231.89, 234.51, 236.85, 239.42,
249 241.94, 244.57, 247.36, 250.32, 253.34, 255.82, 258.27, 260.39,
250 262.03, 263.45, 264.2, 264.78, 264.67, 264.38, 263.24, 262.03, 260.02,
251 258.09, 255.63, 253.28, 250.43, 247.81, 245.26, 242.77, 240.38,
252 237.94, 235.79, 233.53, 231.5, 229.53, 227.6, 225.62, 223.77, 222.06,
253 220.33, 218.69, 217.18, 215.64, 214.13, 212.52, 210.86, 209.25,
254 207.49, 205.81, 204.11, 202.22, 200.32, 198.39, 195.92, 193.46,
255 190.94, 188.31, 185.82, 183.57, 181.43, 179.74, 178.64, 178.1, 178.25,
256 178.7, 179.41, 180.67, 182.31, 184.18, 186.6, 189.53, 192.66, 196.54,
257 201.13, 205.93, 211.73, 217.86, 225, 233.53, 242.57, 252.14, 261.48,
258 272.97, 285.26, 299.12, 312.2, 324.17, 338.34, 352.56, 365.28
259 };
260
261 static const double c2h2[121] = {
262 1.352e-09, 2.83e-10, 1.269e-10, 6.926e-11, 4.346e-11, 2.909e-11,
263 2.014e-11, 1.363e-11, 8.71e-12, 5.237e-12, 2.718e-12, 1.375e-12,
264 5.786e-13, 2.16e-13, 7.317e-14, 2.551e-14, 1.055e-14, 4.758e-15,
265 2.056e-15, 7.703e-16, 2.82e-16, 1.035e-16, 4.382e-17, 1.946e-17,
266 9.638e-18, 5.2e-18, 2.811e-18, 1.494e-18, 7.925e-19, 4.213e-19,
267 1.998e-19, 8.78e-20, 3.877e-20, 1.728e-20, 7.743e-21, 3.536e-21,
268 1.623e-21, 7.508e-22, 3.508e-22, 1.65e-22, 7.837e-23, 3.733e-23,
269 1.808e-23, 8.77e-24, 4.285e-24, 2.095e-24, 1.032e-24, 5.082e-25,
270 2.506e-25, 1.236e-25, 6.088e-26, 2.996e-26, 1.465e-26, 0, 0, 0,
271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
274 };
275
276 static const double c2h6[121] = {
277 2.667e-09, 2.02e-09, 1.658e-09, 1.404e-09, 1.234e-09, 1.109e-09,
278 1.012e-09, 9.262e-10, 8.472e-10, 7.71e-10, 6.932e-10, 6.216e-10,
279 5.503e-10, 4.87e-10, 4.342e-10, 3.861e-10, 3.347e-10, 2.772e-10,
280 2.209e-10, 1.672e-10, 1.197e-10, 8.536e-11, 5.783e-11, 3.846e-11,
281 2.495e-11, 1.592e-11, 1.017e-11, 6.327e-12, 3.895e-12, 2.403e-12,
282 1.416e-12, 8.101e-13, 4.649e-13, 2.686e-13, 1.557e-13, 9.14e-14,
283 5.386e-14, 3.19e-14, 1.903e-14, 1.14e-14, 6.875e-15, 4.154e-15,
284 2.538e-15, 1.553e-15, 9.548e-16, 5.872e-16, 3.63e-16, 2.244e-16,
285 1.388e-16, 8.587e-17, 5.308e-17, 3.279e-17, 2.017e-17, 1.238e-17,
286 7.542e-18, 4.585e-18, 2.776e-18, 1.671e-18, 9.985e-19, 5.937e-19,
287 3.518e-19, 2.07e-19, 1.215e-19, 7.06e-20, 4.097e-20, 2.37e-20,
288 1.363e-20, 7.802e-21, 4.441e-21, 2.523e-21, 1.424e-21, 8.015e-22,
289 4.497e-22, 2.505e-22, 1.391e-22, 7.691e-23, 4.238e-23, 2.331e-23,
290 1.274e-23, 6.929e-24, 3.752e-24, 2.02e-24, 1.083e-24, 5.774e-25,
291 3.041e-25, 1.593e-25, 8.308e-26, 4.299e-26, 2.195e-26, 1.112e-26,
292 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
293 0, 0, 0, 0, 0, 0, 0, 0, 0
294 };
295
296 static const double ccl4[121] = {
297 1.075e-10, 1.075e-10, 1.075e-10, 1.075e-10, 1.075e-10, 1.075e-10,
298 1.075e-10, 1.075e-10, 1.075e-10, 1.06e-10, 1.024e-10, 9.69e-11,
299 8.93e-11, 8.078e-11, 7.213e-11, 6.307e-11, 5.383e-11, 4.49e-11,
300 3.609e-11, 2.705e-11, 1.935e-11, 1.385e-11, 8.35e-12, 5.485e-12,
301 3.853e-12, 2.22e-12, 5.875e-13, 3.445e-13, 1.015e-13, 6.075e-14,
302 4.383e-14, 2.692e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
303 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
304 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
305 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
306 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
307 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
308 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
309 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
310 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
311 1e-14, 1e-14, 1e-14
312 };
313
314 static const double ch3oh[121] = {
315 5.01099e-10, 5.01099e-10, 5.01099e-10, 5.01099e-10, 5.01099e-10,
316 5.01099e-10, 5.50999e-10, 5.7313e-10, 5.75638e-10, 5.4086e-10,
317 4.77601e-10, 4.12907e-10, 3.6274e-10, 3.26448e-10, 2.9706e-10,
318 2.27698e-10, 1.96999e-10, 1.66212e-10, 1.17941e-10, 1.19844e-10,
319 1.11211e-10, 1.02714e-10, 9.86138e-11, 9.45133e-11, 9.04127e-11,
320 8.05243e-11, 6.3678e-11, 4.68317e-11, 4.00618e-11, 3.95786e-11,
321 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
322 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
323 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
324 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
325 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
326 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
327 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
328 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
329 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
330 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
331 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
332 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
333 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
334 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
335 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
336 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
337 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
338 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
339 3.95786e-11
340 };
341
342 static const double ch4[121] = {
343 1.864e-06, 1.835e-06, 1.819e-06, 1.805e-06, 1.796e-06, 1.788e-06,
344 1.782e-06, 1.776e-06, 1.769e-06, 1.761e-06, 1.749e-06, 1.734e-06,
345 1.716e-06, 1.692e-06, 1.654e-06, 1.61e-06, 1.567e-06, 1.502e-06,
346 1.433e-06, 1.371e-06, 1.323e-06, 1.277e-06, 1.232e-06, 1.188e-06,
347 1.147e-06, 1.108e-06, 1.07e-06, 1.027e-06, 9.854e-07, 9.416e-07,
348 8.933e-07, 8.478e-07, 7.988e-07, 7.515e-07, 7.07e-07, 6.64e-07,
349 6.239e-07, 5.864e-07, 5.512e-07, 5.184e-07, 4.87e-07, 4.571e-07,
350 4.296e-07, 4.04e-07, 3.802e-07, 3.578e-07, 3.383e-07, 3.203e-07,
351 3.032e-07, 2.889e-07, 2.76e-07, 2.635e-07, 2.519e-07, 2.409e-07,
352 2.302e-07, 2.219e-07, 2.144e-07, 2.071e-07, 1.999e-07, 1.93e-07,
353 1.862e-07, 1.795e-07, 1.731e-07, 1.668e-07, 1.607e-07, 1.548e-07,
354 1.49e-07, 1.434e-07, 1.38e-07, 1.328e-07, 1.277e-07, 1.227e-07,
355 1.18e-07, 1.134e-07, 1.089e-07, 1.046e-07, 1.004e-07, 9.635e-08,
356 9.245e-08, 8.867e-08, 8.502e-08, 8.15e-08, 7.809e-08, 7.48e-08,
357 7.159e-08, 6.849e-08, 6.55e-08, 6.262e-08, 5.98e-08, 5.708e-08,
358 5.448e-08, 5.194e-08, 4.951e-08, 4.72e-08, 4.5e-08, 4.291e-08,
359 4.093e-08, 3.905e-08, 3.729e-08, 3.563e-08, 3.408e-08, 3.265e-08,
360 3.128e-08, 2.996e-08, 2.87e-08, 2.76e-08, 2.657e-08, 2.558e-08,
361 2.467e-08, 2.385e-08, 2.307e-08, 2.234e-08, 2.168e-08, 2.108e-08,
362 2.05e-08, 1.998e-08, 1.947e-08, 1.902e-08, 1.86e-08, 1.819e-08,
363 1.782e-08
364 };
365
366 static const double clo[121] = {
367 7.419e-15, 1.061e-14, 1.518e-14, 2.195e-14, 3.175e-14, 4.666e-14,
368 6.872e-14, 1.03e-13, 1.553e-13, 2.375e-13, 3.664e-13, 5.684e-13,
369 8.915e-13, 1.402e-12, 2.269e-12, 4.125e-12, 7.501e-12, 1.257e-11,
370 2.048e-11, 3.338e-11, 5.44e-11, 8.846e-11, 1.008e-10, 1.082e-10,
371 1.157e-10, 1.232e-10, 1.312e-10, 1.539e-10, 1.822e-10, 2.118e-10,
372 2.387e-10, 2.687e-10, 2.875e-10, 3.031e-10, 3.23e-10, 3.648e-10,
373 4.117e-10, 4.477e-10, 4.633e-10, 4.794e-10, 4.95e-10, 5.104e-10,
374 5.259e-10, 5.062e-10, 4.742e-10, 4.443e-10, 4.051e-10, 3.659e-10,
375 3.305e-10, 2.911e-10, 2.54e-10, 2.215e-10, 1.927e-10, 1.675e-10,
376 1.452e-10, 1.259e-10, 1.09e-10, 9.416e-11, 8.119e-11, 6.991e-11,
377 6.015e-11, 5.163e-11, 4.43e-11, 3.789e-11, 3.24e-11, 2.769e-11,
378 2.361e-11, 2.011e-11, 1.71e-11, 1.453e-11, 1.233e-11, 1.045e-11,
379 8.851e-12, 7.48e-12, 6.316e-12, 5.326e-12, 4.487e-12, 3.778e-12,
380 3.176e-12, 2.665e-12, 2.234e-12, 1.87e-12, 1.563e-12, 1.304e-12,
381 1.085e-12, 9.007e-13, 7.468e-13, 6.179e-13, 5.092e-13, 4.188e-13,
382 3.442e-13, 2.816e-13, 2.304e-13, 1.885e-13, 1.542e-13, 1.263e-13,
383 1.035e-13, 8.5e-14, 7.004e-14, 5.783e-14, 4.795e-14, 4.007e-14,
384 3.345e-14, 2.792e-14, 2.33e-14, 1.978e-14, 1.686e-14, 1.438e-14,
385 1.234e-14, 1.07e-14, 9.312e-15, 8.131e-15, 7.164e-15, 6.367e-15,
386 5.67e-15, 5.088e-15, 4.565e-15, 4.138e-15, 3.769e-15, 3.432e-15,
387 3.148e-15
388 };
389
390 static const double clono2[121] = {
391 1.011e-13, 1.515e-13, 2.272e-13, 3.446e-13, 5.231e-13, 8.085e-13,
392 1.253e-12, 1.979e-12, 3.149e-12, 5.092e-12, 8.312e-12, 1.366e-11,
393 2.272e-11, 3.791e-11, 6.209e-11, 9.101e-11, 1.334e-10, 1.951e-10,
394 2.853e-10, 3.94e-10, 4.771e-10, 5.771e-10, 6.675e-10, 7.665e-10,
395 8.504e-10, 8.924e-10, 9.363e-10, 8.923e-10, 8.411e-10, 7.646e-10,
396 6.525e-10, 5.576e-10, 4.398e-10, 3.403e-10, 2.612e-10, 1.915e-10,
397 1.407e-10, 1.028e-10, 7.455e-11, 5.42e-11, 3.708e-11, 2.438e-11,
398 1.618e-11, 1.075e-11, 7.17e-12, 4.784e-12, 3.205e-12, 2.147e-12,
399 1.44e-12, 9.654e-13, 6.469e-13, 4.332e-13, 2.891e-13, 1.926e-13,
400 1.274e-13, 8.422e-14, 5.547e-14, 3.636e-14, 2.368e-14, 1.536e-14,
401 9.937e-15, 6.39e-15, 4.101e-15, 2.61e-15, 1.659e-15, 1.052e-15,
402 6.638e-16, 4.172e-16, 2.61e-16, 1.63e-16, 1.013e-16, 6.275e-17,
403 3.879e-17, 2.383e-17, 1.461e-17, 8.918e-18, 5.43e-18, 3.301e-18,
404 1.997e-18, 1.203e-18, 7.216e-19, 4.311e-19, 2.564e-19, 1.519e-19,
405 8.911e-20, 5.203e-20, 3.026e-20, 1.748e-20, 9.99e-21, 5.673e-21,
406 3.215e-21, 1.799e-21, 1.006e-21, 5.628e-22, 3.146e-22, 1.766e-22,
407 9.94e-23, 5.614e-23, 3.206e-23, 1.841e-23, 1.071e-23, 6.366e-24,
408 3.776e-24, 2.238e-24, 1.326e-24, 8.253e-25, 5.201e-25, 3.279e-25,
409 2.108e-25, 1.395e-25, 9.326e-26, 6.299e-26, 4.365e-26, 3.104e-26,
410 2.219e-26, 1.621e-26, 1.185e-26, 8.92e-27, 6.804e-27, 5.191e-27,
411 4.041e-27
412 };
413
414 static const double co[121] = {
415 1.907e-07, 1.553e-07, 1.362e-07, 1.216e-07, 1.114e-07, 1.036e-07,
416 9.737e-08, 9.152e-08, 8.559e-08, 7.966e-08, 7.277e-08, 6.615e-08,
417 5.884e-08, 5.22e-08, 4.699e-08, 4.284e-08, 3.776e-08, 3.274e-08,
418 2.845e-08, 2.479e-08, 2.246e-08, 2.054e-08, 1.991e-08, 1.951e-08,
419 1.94e-08, 2.009e-08, 2.1e-08, 2.201e-08, 2.322e-08, 2.45e-08,
420 2.602e-08, 2.73e-08, 2.867e-08, 2.998e-08, 3.135e-08, 3.255e-08,
421 3.352e-08, 3.426e-08, 3.484e-08, 3.53e-08, 3.593e-08, 3.671e-08,
422 3.759e-08, 3.945e-08, 4.192e-08, 4.49e-08, 5.03e-08, 5.703e-08,
423 6.538e-08, 7.878e-08, 9.644e-08, 1.196e-07, 1.498e-07, 1.904e-07,
424 2.422e-07, 3.055e-07, 3.804e-07, 4.747e-07, 5.899e-07, 7.272e-07,
425 8.91e-07, 1.071e-06, 1.296e-06, 1.546e-06, 1.823e-06, 2.135e-06,
426 2.44e-06, 2.714e-06, 2.967e-06, 3.189e-06, 3.391e-06, 3.58e-06,
427 3.773e-06, 4.022e-06, 4.346e-06, 4.749e-06, 5.199e-06, 5.668e-06,
428 6.157e-06, 6.688e-06, 7.254e-06, 7.867e-06, 8.539e-06, 9.26e-06,
429 1.009e-05, 1.119e-05, 1.228e-05, 1.365e-05, 1.506e-05, 1.641e-05,
430 1.784e-05, 1.952e-05, 2.132e-05, 2.323e-05, 2.531e-05, 2.754e-05,
431 3.047e-05, 3.459e-05, 3.922e-05, 4.439e-05, 4.825e-05, 5.077e-05,
432 5.34e-05, 5.618e-05, 5.909e-05, 6.207e-05, 6.519e-05, 6.845e-05,
433 6.819e-05, 6.726e-05, 6.622e-05, 6.512e-05, 6.671e-05, 6.862e-05,
434 7.048e-05, 7.264e-05, 7.3e-05, 7.3e-05, 7.3e-05, 7.3e-05, 7.3e-05
435 };
436
437 static const double cof2[121] = {
438 7.5e-14, 1.055e-13, 1.485e-13, 2.111e-13, 3.001e-13, 4.333e-13,
439 6.269e-13, 9.221e-13, 1.364e-12, 2.046e-12, 3.093e-12, 4.703e-12,
440 7.225e-12, 1.113e-11, 1.66e-11, 2.088e-11, 2.626e-11, 3.433e-11,
441 4.549e-11, 5.886e-11, 7.21e-11, 8.824e-11, 1.015e-10, 1.155e-10,
442 1.288e-10, 1.388e-10, 1.497e-10, 1.554e-10, 1.606e-10, 1.639e-10,
443 1.64e-10, 1.64e-10, 1.596e-10, 1.542e-10, 1.482e-10, 1.382e-10,
444 1.289e-10, 1.198e-10, 1.109e-10, 1.026e-10, 9.484e-11, 8.75e-11,
445 8.086e-11, 7.49e-11, 6.948e-11, 6.446e-11, 5.961e-11, 5.505e-11,
446 5.085e-11, 4.586e-11, 4.1e-11, 3.665e-11, 3.235e-11, 2.842e-11,
447 2.491e-11, 2.11e-11, 1.769e-11, 1.479e-11, 1.197e-11, 9.631e-12,
448 7.74e-12, 6.201e-12, 4.963e-12, 3.956e-12, 3.151e-12, 2.507e-12,
449 1.99e-12, 1.576e-12, 1.245e-12, 9.83e-13, 7.742e-13, 6.088e-13,
450 4.782e-13, 3.745e-13, 2.929e-13, 2.286e-13, 1.782e-13, 1.388e-13,
451 1.079e-13, 8.362e-14, 6.471e-14, 4.996e-14, 3.85e-14, 2.96e-14,
452 2.265e-14, 1.729e-14, 1.317e-14, 9.998e-15, 7.549e-15, 5.683e-15,
453 4.273e-15, 3.193e-15, 2.385e-15, 1.782e-15, 1.331e-15, 9.957e-16,
454 7.461e-16, 5.601e-16, 4.228e-16, 3.201e-16, 2.438e-16, 1.878e-16,
455 1.445e-16, 1.111e-16, 8.544e-17, 6.734e-17, 5.341e-17, 4.237e-17,
456 3.394e-17, 2.759e-17, 2.254e-17, 1.851e-17, 1.54e-17, 1.297e-17,
457 1.096e-17, 9.365e-18, 8e-18, 6.938e-18, 6.056e-18, 5.287e-18,
458 4.662e-18
459 };
460
461 static const double f11[121] = {
462 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10,
463 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.635e-10, 2.536e-10,
464 2.44e-10, 2.348e-10, 2.258e-10, 2.153e-10, 2.046e-10, 1.929e-10,
465 1.782e-10, 1.648e-10, 1.463e-10, 1.291e-10, 1.1e-10, 8.874e-11,
466 7.165e-11, 5.201e-11, 3.744e-11, 2.577e-11, 1.64e-11, 1.048e-11,
467 5.993e-12, 3.345e-12, 1.839e-12, 9.264e-13, 4.688e-13, 2.329e-13,
468 1.129e-13, 5.505e-14, 2.825e-14, 1.492e-14, 7.997e-15, 5.384e-15,
469 3.988e-15, 2.955e-15, 2.196e-15, 1.632e-15, 1.214e-15, 9.025e-16,
470 6.708e-16, 4.984e-16, 3.693e-16, 2.733e-16, 2.013e-16, 1.481e-16,
471 1.087e-16, 7.945e-17, 5.782e-17, 4.195e-17, 3.038e-17, 2.19e-17,
472 1.577e-17, 1.128e-17, 8.063e-18, 5.753e-18, 4.09e-18, 2.899e-18,
473 2.048e-18, 1.444e-18, 1.015e-18, 7.12e-19, 4.985e-19, 3.474e-19,
474 2.417e-19, 1.677e-19, 1.161e-19, 8.029e-20, 5.533e-20, 3.799e-20,
475 2.602e-20, 1.776e-20, 1.209e-20, 8.202e-21, 5.522e-21, 3.707e-21,
476 2.48e-21, 1.652e-21, 1.091e-21, 7.174e-22, 4.709e-22, 3.063e-22,
477 1.991e-22, 1.294e-22, 8.412e-23, 5.483e-23, 3.581e-23, 2.345e-23,
478 1.548e-23, 1.027e-23, 6.869e-24, 4.673e-24, 3.173e-24, 2.153e-24,
479 1.461e-24, 1.028e-24, 7.302e-25, 5.188e-25, 3.739e-25, 2.753e-25,
480 2.043e-25, 1.528e-25, 1.164e-25, 9.041e-26, 7.051e-26, 5.587e-26,
481 4.428e-26, 3.588e-26, 2.936e-26, 2.402e-26, 1.995e-26
482 };
483
484 static const double f113[121] = {
485 1.9e-11, 1.9e-11, 1.899e-11, 1.899e-11, 1.898e-11, 1.898e-11,
486 1.897e-11, 1.896e-11, 1.895e-11, 1.894e-11, 1.893e-11, 1.89e-11,
487 1.887e-11, 1.871e-11, 1.854e-11, 1.803e-11, 1.751e-11, 1.664e-11,
488 1.576e-11, 1.466e-11, 1.356e-11, 1.236e-11, 1.116e-11, 9.931e-12,
489 8.702e-12, 7.515e-12, 6.4238e-12, 5.3326e-12, 4.3652e-12, 3.5216e-12,
490 2.678e-12, 2.1532e-12, 1.6284e-12, 1.2202e-12, 9.286e-13, 6.37e-13,
491 4.95e-13, 3.53e-13, 2.5004e-13, 1.8612e-13, 1.222e-13, 9.704e-14,
492 7.188e-14, 5.3338e-14, 4.1414e-14, 2.949e-14, 2.3722e-14, 1.7954e-14,
493 1.37794e-14, 1.11982e-14, 8.617e-15, 7.6036e-15, 6.5902e-15,
494 5.5768e-15, 4.5634e-15, 3.55e-15, 3.1008e-15, 2.6516e-15, 2.2024e-15,
495 1.7532e-15, 1.304e-15, 1.1354e-15, 9.668e-16, 7.982e-16, 6.296e-16,
496 4.61e-16, 3.9734e-16, 3.3368e-16, 2.7002e-16, 2.0636e-16, 1.427e-16,
497 1.22804e-16, 1.02908e-16, 8.3012e-17, 6.3116e-17, 4.322e-17,
498 3.6838e-17, 3.0456e-17, 2.4074e-17, 1.7692e-17, 1.131e-17,
499 9.6202e-18, 7.9304e-18, 6.2406e-18, 4.5508e-18, 2.861e-18,
500 2.40476e-18, 1.94852e-18, 1.49228e-18, 1.03604e-18, 5.798e-19,
501 4.8502e-19, 3.9024e-19, 2.9546e-19, 2.0068e-19, 1.059e-19,
502 8.7084e-20, 6.8268e-20, 4.9452e-20, 3.0636e-20, 1.182e-20,
503 9.64344e-21, 7.46688e-21, 5.29032e-21, 3.11376e-21, 9.372e-22,
504 7.5685e-22, 5.765e-22, 3.9615e-22, 2.158e-22, 3.545e-23,
505 2.86046e-23, 2.17592e-23, 1.49138e-23, 8.0684e-24, 1.223e-24,
506 9.92358e-25, 7.61716e-25, 5.31074e-25, 3.00432e-25, 6.979e-26
507 };
508
509 static const double f114[121] = {
510 1.2e-11, 1.2e-11, 1.2e-11, 1.2e-11, 1.199e-11, 1.199e-11,
511 1.199e-11, 1.199e-11, 1.198e-11, 1.198e-11, 1.198e-11, 1.197e-11,
512 1.196e-11, 1.191e-11, 1.185e-11, 1.167e-11, 1.149e-11, 1.12e-11,
513 1.09e-11, 1.053e-11, 1.015e-11, 9.731e-12, 9.311e-12, 8.865e-12,
514 8.419e-12, 7.949e-12, 7.4774e-12, 7.0058e-12, 6.54e-12, 6.08e-12,
515 5.62e-12, 5.1908e-12, 4.7616e-12, 4.3622e-12, 3.9926e-12, 3.623e-12,
516 3.3274e-12, 3.0318e-12, 2.7702e-12, 2.5426e-12, 2.315e-12, 2.1514e-12,
517 1.9878e-12, 1.8448e-12, 1.7224e-12, 1.6e-12, 1.51e-12, 1.42e-12,
518 1.3462e-12, 1.2886e-12, 1.231e-12, 1.1922e-12, 1.1534e-12, 1.1146e-12,
519 1.0758e-12, 1.037e-12, 1.0025e-12, 9.68e-13, 9.335e-13, 8.99e-13,
520 8.645e-13, 8.344e-13, 8.043e-13, 7.742e-13, 7.441e-13, 7.14e-13,
521 6.8718e-13, 6.6036e-13, 6.3354e-13, 6.0672e-13, 5.799e-13, 5.5612e-13,
522 5.3234e-13, 5.0856e-13, 4.8478e-13, 4.61e-13, 4.394e-13, 4.178e-13,
523 3.962e-13, 3.746e-13, 3.53e-13, 3.3288e-13, 3.1276e-13, 2.9264e-13,
524 2.7252e-13, 2.524e-13, 2.3368e-13, 2.1496e-13, 1.9624e-13, 1.7752e-13,
525 1.588e-13, 1.4221e-13, 1.2562e-13, 1.0903e-13, 9.244e-14, 7.585e-14,
526 6.4942e-14, 5.4034e-14, 4.3126e-14, 3.2218e-14, 2.131e-14, 1.76694e-14,
527 1.40288e-14, 1.03882e-14, 6.7476e-15, 3.107e-15, 2.52738e-15,
528 1.94776e-15, 1.36814e-15, 7.8852e-16, 2.089e-16, 1.69288e-16,
529 1.29676e-16, 9.0064e-17, 5.0452e-17, 1.084e-17, 8.85136e-18,
530 6.86272e-18, 4.87408e-18, 2.88544e-18, 8.968e-19
531 };
532
533 static const double f12[121] = {
534 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10,
535 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.429e-10, 5.291e-10,
536 5.155e-10, 5.022e-10, 4.893e-10, 4.772e-10, 4.655e-10, 4.497e-10,
537 4.249e-10, 4.015e-10, 3.632e-10, 3.261e-10, 2.858e-10, 2.408e-10,
538 2.03e-10, 1.685e-10, 1.4e-10, 1.163e-10, 9.65e-11, 8.02e-11, 6.705e-11,
539 5.624e-11, 4.764e-11, 4.249e-11, 3.792e-11, 3.315e-11, 2.819e-11,
540 2.4e-11, 1.999e-11, 1.64e-11, 1.352e-11, 1.14e-11, 9.714e-12,
541 8.28e-12, 7.176e-12, 6.251e-12, 5.446e-12, 4.72e-12, 4.081e-12,
542 3.528e-12, 3.08e-12, 2.699e-12, 2.359e-12, 2.111e-12, 1.901e-12,
543 1.709e-12, 1.534e-12, 1.376e-12, 1.233e-12, 1.103e-12, 9.869e-13,
544 8.808e-13, 7.859e-13, 7.008e-13, 6.241e-13, 5.553e-13, 4.935e-13,
545 4.383e-13, 3.889e-13, 3.447e-13, 3.054e-13, 2.702e-13, 2.389e-13,
546 2.11e-13, 1.862e-13, 1.643e-13, 1.448e-13, 1.274e-13, 1.121e-13,
547 9.844e-14, 8.638e-14, 7.572e-14, 6.62e-14, 5.782e-14, 5.045e-14,
548 4.394e-14, 3.817e-14, 3.311e-14, 2.87e-14, 2.48e-14, 2.142e-14,
549 1.851e-14, 1.599e-14, 1.383e-14, 1.196e-14, 1.036e-14, 9e-15,
550 7.828e-15, 6.829e-15, 5.992e-15, 5.254e-15, 4.606e-15, 4.037e-15,
551 3.583e-15, 3.19e-15, 2.841e-15, 2.542e-15, 2.291e-15, 2.07e-15,
552 1.875e-15, 1.71e-15, 1.57e-15, 1.442e-15, 1.333e-15, 1.232e-15,
553 1.147e-15, 1.071e-15, 1.001e-15, 9.396e-16
554 };
555
556 static const double f14[121] = {
557 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11,
558 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 8.91e-11, 8.73e-11, 8.46e-11,
559 8.19e-11, 7.92e-11, 7.74e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
560 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
561 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
562 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
563 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
564 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
565 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
566 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
567 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
568 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
569 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
570 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
571 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
572 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
573 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11
574 };
575
576 static const double f22[121] = {
577 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10,
578 1.4e-10, 1.4e-10, 1.4e-10, 1.372e-10, 1.317e-10, 1.235e-10, 1.153e-10,
579 1.075e-10, 1.002e-10, 9.332e-11, 8.738e-11, 8.194e-11, 7.7e-11,
580 7.165e-11, 6.753e-11, 6.341e-11, 5.971e-11, 5.6e-11, 5.229e-11,
581 4.859e-11, 4.488e-11, 4.118e-11, 3.83e-11, 3.568e-11, 3.308e-11,
582 3.047e-11, 2.82e-11, 2.594e-11, 2.409e-11, 2.237e-11, 2.065e-11,
583 1.894e-11, 1.771e-11, 1.647e-11, 1.532e-11, 1.416e-11, 1.332e-11,
584 1.246e-11, 1.161e-11, 1.087e-11, 1.017e-11, 9.471e-12, 8.853e-12,
585 8.235e-12, 7.741e-12, 7.247e-12, 6.836e-12, 6.506e-12, 6.176e-12,
586 5.913e-12, 5.65e-12, 5.419e-12, 5.221e-12, 5.024e-12, 4.859e-12,
587 4.694e-12, 4.546e-12, 4.414e-12, 4.282e-12, 4.15e-12, 4.019e-12,
588 3.903e-12, 3.805e-12, 3.706e-12, 3.607e-12, 3.508e-12, 3.41e-12,
589 3.31e-12, 3.212e-12, 3.129e-12, 3.047e-12, 2.964e-12, 2.882e-12,
590 2.8e-12, 2.734e-12, 2.668e-12, 2.602e-12, 2.537e-12, 2.471e-12,
591 2.421e-12, 2.372e-12, 2.322e-12, 2.273e-12, 2.224e-12, 2.182e-12,
592 2.141e-12, 2.1e-12, 2.059e-12, 2.018e-12, 1.977e-12, 1.935e-12,
593 1.894e-12, 1.853e-12, 1.812e-12, 1.77e-12, 1.73e-12, 1.688e-12,
594 1.647e-12, 1.606e-12, 1.565e-12, 1.524e-12, 1.483e-12, 1.441e-12,
595 1.4e-12, 1.359e-12, 1.317e-12, 1.276e-12, 1.235e-12, 1.194e-12,
596 1.153e-12, 1.112e-12, 1.071e-12, 1.029e-12, 9.883e-13
597 };
598
599 static const double h2co[121] = {
600 8.71857e-11, 8.71857e-11, 8.71857e-11, 8.71857e-11, 8.71857e-11,
601 8.71857e-11, 7.72315e-11, 6.85464e-11, 6.0758e-11, 5.32087e-11,
602 4.5719e-11, 3.79458e-11, 3.07607e-11, 2.46025e-11, 1.94038e-11,
603 1.40882e-11, 1.0623e-11, 8.35457e-12, 6.87427e-12, 7.09071e-12,
604 8.96183e-12, 1.09012e-11, 1.50545e-11, 1.92077e-11, 2.3361e-11,
605 2.7054e-11, 3.01936e-11, 3.33333e-11, 3.69281e-11, 4.08069e-11,
606 4.57318e-11, 5.1348e-11, 5.69642e-11, 6.33173e-11, 6.98984e-11,
607 7.63144e-11, 8.22774e-11, 8.82405e-11, 9.3746e-11, 9.92074e-11,
608 1.04669e-10, 1.10055e-10, 1.15293e-10, 1.20531e-10, 1.26293e-10,
609 1.32585e-10, 1.35966e-10, 1.36242e-10, 1.36519e-10, 1.61155e-10,
610 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
611 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
612 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
613 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
614 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
615 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
616 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
617 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
618 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
619 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
620 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
621 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
622 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
623 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
624 1.99157e-10
625 };
626
627 static const double h2o[121] = {
628 0.01166, 0.008269, 0.005742, 0.003845, 0.00277, 0.001897, 0.001272,
629 0.000827, 0.000539, 0.0003469, 0.0001579, 3.134e-05, 1.341e-05,
630 6.764e-06, 4.498e-06, 3.703e-06, 3.724e-06, 3.899e-06, 4.002e-06,
631 4.122e-06, 4.277e-06, 4.438e-06, 4.558e-06, 4.673e-06, 4.763e-06,
632 4.809e-06, 4.856e-06, 4.936e-06, 5.021e-06, 5.114e-06, 5.222e-06,
633 5.331e-06, 5.414e-06, 5.488e-06, 5.563e-06, 5.633e-06, 5.704e-06,
634 5.767e-06, 5.819e-06, 5.872e-06, 5.914e-06, 5.949e-06, 5.984e-06,
635 6.015e-06, 6.044e-06, 6.073e-06, 6.104e-06, 6.136e-06, 6.167e-06,
636 6.189e-06, 6.208e-06, 6.226e-06, 6.212e-06, 6.185e-06, 6.158e-06,
637 6.114e-06, 6.066e-06, 6.018e-06, 5.877e-06, 5.728e-06, 5.582e-06,
638 5.437e-06, 5.296e-06, 5.156e-06, 5.02e-06, 4.886e-06, 4.754e-06,
639 4.625e-06, 4.498e-06, 4.374e-06, 4.242e-06, 4.096e-06, 3.955e-06,
640 3.817e-06, 3.683e-06, 3.491e-06, 3.204e-06, 2.94e-06, 2.696e-06,
641 2.47e-06, 2.252e-06, 2.019e-06, 1.808e-06, 1.618e-06, 1.445e-06,
642 1.285e-06, 1.105e-06, 9.489e-07, 8.121e-07, 6.938e-07, 5.924e-07,
643 5.04e-07, 4.288e-07, 3.648e-07, 3.103e-07, 2.642e-07, 2.252e-07,
644 1.921e-07, 1.643e-07, 1.408e-07, 1.211e-07, 1.048e-07, 9.063e-08,
645 7.835e-08, 6.774e-08, 5.936e-08, 5.221e-08, 4.592e-08, 4.061e-08,
646 3.62e-08, 3.236e-08, 2.902e-08, 2.62e-08, 2.383e-08, 2.171e-08,
647 1.989e-08, 1.823e-08, 1.684e-08, 1.562e-08, 1.449e-08, 1.351e-08
648 };
649
650 static const double h2o2[121] = {
651 1.779e-10, 7.938e-10, 8.953e-10, 8.032e-10, 6.564e-10, 5.159e-10,
652 4.003e-10, 3.026e-10, 2.222e-10, 1.58e-10, 1.044e-10, 6.605e-11,
653 3.413e-11, 1.453e-11, 1.062e-11, 1.009e-11, 9.597e-12, 1.175e-11,
654 1.572e-11, 2.091e-11, 2.746e-11, 3.603e-11, 4.791e-11, 6.387e-11,
655 8.239e-11, 1.007e-10, 1.23e-10, 1.363e-10, 1.489e-10, 1.585e-10,
656 1.608e-10, 1.632e-10, 1.576e-10, 1.502e-10, 1.423e-10, 1.302e-10,
657 1.192e-10, 1.085e-10, 9.795e-11, 8.854e-11, 8.057e-11, 7.36e-11,
658 6.736e-11, 6.362e-11, 6.087e-11, 5.825e-11, 5.623e-11, 5.443e-11,
659 5.27e-11, 5.098e-11, 4.931e-11, 4.769e-11, 4.611e-11, 4.458e-11,
660 4.308e-11, 4.102e-11, 3.887e-11, 3.682e-11, 3.521e-11, 3.369e-11,
661 3.224e-11, 3.082e-11, 2.946e-11, 2.814e-11, 2.687e-11, 2.566e-11,
662 2.449e-11, 2.336e-11, 2.227e-11, 2.123e-11, 2.023e-11, 1.927e-11,
663 1.835e-11, 1.746e-11, 1.661e-11, 1.58e-11, 1.502e-11, 1.428e-11,
664 1.357e-11, 1.289e-11, 1.224e-11, 1.161e-11, 1.102e-11, 1.045e-11,
665 9.895e-12, 9.369e-12, 8.866e-12, 8.386e-12, 7.922e-12, 7.479e-12,
666 7.06e-12, 6.656e-12, 6.274e-12, 5.914e-12, 5.575e-12, 5.257e-12,
667 4.959e-12, 4.679e-12, 4.42e-12, 4.178e-12, 3.954e-12, 3.75e-12,
668 3.557e-12, 3.372e-12, 3.198e-12, 3.047e-12, 2.908e-12, 2.775e-12,
669 2.653e-12, 2.544e-12, 2.442e-12, 2.346e-12, 2.26e-12, 2.183e-12,
670 2.11e-12, 2.044e-12, 1.98e-12, 1.924e-12, 1.871e-12, 1.821e-12,
671 1.775e-12
672 };
673
674 static const double hcl[121] = {
675 3.70385e-11, 3.70385e-11, 3.70385e-11, 3.70385e-11, 3.70385e-11,
676 3.70385e-11, 2.21247e-11, 1.88117e-11, 2.36957e-11, 3.72192e-11,
677 5.79399e-11, 8.04158e-11, 1.01779e-10, 1.2301e-10, 1.53924e-10,
678 1.93737e-10, 2.5561e-10, 3.84228e-10, 6.18248e-10, 6.31222e-10,
679 7.84907e-10, 9.36932e-10, 1.03508e-09, 1.13323e-09, 1.23138e-09,
680 1.31985e-09, 1.39669e-09, 1.47352e-09, 1.56375e-09, 1.66234e-09,
681 1.78086e-09, 1.91256e-09, 2.04425e-09, 2.16629e-09, 2.28535e-09,
682 2.39439e-09, 2.47597e-09, 2.55755e-09, 2.60873e-09, 2.65696e-09,
683 2.70519e-09, 2.75658e-09, 2.81422e-09, 2.87187e-09, 2.94013e-09,
684 3.01911e-09, 3.09497e-09, 3.16749e-09, 3.24001e-09, 3.30525e-09,
685 3.3665e-09, 3.42424e-09, 3.4619e-09, 3.49956e-09, 3.52273e-09,
686 3.54214e-09, 3.56154e-09, 3.57918e-09, 3.59049e-09, 3.6018e-09,
687 3.6132e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
688 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
689 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
690 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
691 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
692 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
693 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
694 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
695 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
696 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
697 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
698 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
699 3.62476e-09
700 };
701
702 static const double hcn[121] = {
703 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10,
704 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.498e-10, 5.495e-10, 5.493e-10,
705 5.49e-10, 5.488e-10, 4.717e-10, 3.946e-10, 3.174e-10, 2.4e-10,
706 1.626e-10, 1.619e-10, 1.612e-10, 1.602e-10, 1.593e-10, 1.582e-10,
707 1.572e-10, 1.56e-10, 1.549e-10, 1.539e-10, 1.53e-10, 1.519e-10,
708 1.506e-10, 1.487e-10, 1.467e-10, 1.449e-10, 1.43e-10, 1.413e-10,
709 1.397e-10, 1.382e-10, 1.368e-10, 1.354e-10, 1.337e-10, 1.315e-10,
710 1.292e-10, 1.267e-10, 1.241e-10, 1.215e-10, 1.19e-10, 1.165e-10,
711 1.141e-10, 1.118e-10, 1.096e-10, 1.072e-10, 1.047e-10, 1.021e-10,
712 9.968e-11, 9.739e-11, 9.539e-11, 9.339e-11, 9.135e-11, 8.898e-11,
713 8.664e-11, 8.439e-11, 8.249e-11, 8.075e-11, 7.904e-11, 7.735e-11,
714 7.565e-11, 7.399e-11, 7.245e-11, 7.109e-11, 6.982e-11, 6.863e-11,
715 6.755e-11, 6.657e-11, 6.587e-11, 6.527e-11, 6.476e-11, 6.428e-11,
716 6.382e-11, 6.343e-11, 6.307e-11, 6.272e-11, 6.238e-11, 6.205e-11,
717 6.17e-11, 6.137e-11, 6.102e-11, 6.072e-11, 6.046e-11, 6.03e-11,
718 6.018e-11, 6.01e-11, 6.001e-11, 5.992e-11, 5.984e-11, 5.975e-11,
719 5.967e-11, 5.958e-11, 5.95e-11, 5.941e-11, 5.933e-11, 5.925e-11,
720 5.916e-11, 5.908e-11, 5.899e-11, 5.891e-11, 5.883e-11, 5.874e-11,
721 5.866e-11, 5.858e-11, 5.85e-11, 5.841e-11, 5.833e-11, 5.825e-11,
722 5.817e-11, 5.808e-11, 5.8e-11, 5.792e-11, 5.784e-11
723 };
724
725 static const double hf[121] = {
726 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11,
727 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11,
728 2.64279e-11, 2.64279e-11, 2.64279e-11, 3.86691e-11, 5.22002e-11,
729 6.92471e-11, 9.13979e-11, 1.37918e-10, 2.24918e-10, 2.29824e-10,
730 2.94241e-10, 3.58363e-10, 4.12881e-10, 4.67399e-10, 5.21917e-10,
731 5.74229e-10, 6.23889e-10, 6.73549e-10, 7.24119e-10, 7.75256e-10,
732 8.319e-10, 8.92185e-10, 9.52469e-10, 1.01325e-09, 1.07419e-09,
733 1.13565e-09, 1.19856e-09, 1.26146e-09, 1.31439e-09, 1.36635e-09,
734 1.41831e-09, 1.46549e-09, 1.50321e-09, 1.54093e-09, 1.57986e-09,
735 1.62e-09, 1.66286e-09, 1.70863e-09, 1.75439e-09, 1.79827e-09,
736 1.84111e-09, 1.88125e-09, 1.90603e-09, 1.93081e-09, 1.9413e-09,
737 1.94807e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
738 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
739 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
740 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
741 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
742 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
743 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
744 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
745 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
746 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
747 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
748 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
749 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
750 1.95485e-09
751 };
752
753 static const double hno3[121] = {
754 1.809e-10, 7.234e-10, 5.899e-10, 4.342e-10, 3.277e-10, 2.661e-10,
755 2.35e-10, 2.267e-10, 2.389e-10, 2.651e-10, 3.255e-10, 4.099e-10,
756 5.42e-10, 6.978e-10, 8.807e-10, 1.112e-09, 1.405e-09, 2.04e-09,
757 3.111e-09, 4.5e-09, 5.762e-09, 7.37e-09, 7.852e-09, 8.109e-09,
758 8.067e-09, 7.554e-09, 7.076e-09, 6.268e-09, 5.524e-09, 4.749e-09,
759 3.909e-09, 3.223e-09, 2.517e-09, 1.942e-09, 1.493e-09, 1.122e-09,
760 8.449e-10, 6.361e-10, 4.787e-10, 3.611e-10, 2.804e-10, 2.215e-10,
761 1.758e-10, 1.441e-10, 1.197e-10, 9.953e-11, 8.505e-11, 7.334e-11,
762 6.325e-11, 5.625e-11, 5.058e-11, 4.548e-11, 4.122e-11, 3.748e-11,
763 3.402e-11, 3.088e-11, 2.8e-11, 2.536e-11, 2.293e-11, 2.072e-11,
764 1.871e-11, 1.687e-11, 1.52e-11, 1.368e-11, 1.23e-11, 1.105e-11,
765 9.922e-12, 8.898e-12, 7.972e-12, 7.139e-12, 6.385e-12, 5.708e-12,
766 5.099e-12, 4.549e-12, 4.056e-12, 3.613e-12, 3.216e-12, 2.862e-12,
767 2.544e-12, 2.259e-12, 2.004e-12, 1.776e-12, 1.572e-12, 1.391e-12,
768 1.227e-12, 1.082e-12, 9.528e-13, 8.379e-13, 7.349e-13, 6.436e-13,
769 5.634e-13, 4.917e-13, 4.291e-13, 3.745e-13, 3.267e-13, 2.854e-13,
770 2.494e-13, 2.181e-13, 1.913e-13, 1.68e-13, 1.479e-13, 1.31e-13,
771 1.159e-13, 1.025e-13, 9.067e-14, 8.113e-14, 7.281e-14, 6.535e-14,
772 5.892e-14, 5.348e-14, 4.867e-14, 4.439e-14, 4.073e-14, 3.76e-14,
773 3.476e-14, 3.229e-14, 3e-14, 2.807e-14, 2.635e-14, 2.473e-14,
774 2.332e-14
775 };
776
777 static const double hno4[121] = {
778 6.118e-12, 3.594e-12, 2.807e-12, 3.04e-12, 4.458e-12, 7.986e-12,
779 1.509e-11, 2.661e-11, 3.738e-11, 4.652e-11, 4.429e-11, 3.992e-11,
780 3.347e-11, 3.005e-11, 3.173e-11, 4.055e-11, 5.812e-11, 8.489e-11,
781 1.19e-10, 1.482e-10, 1.766e-10, 2.103e-10, 2.35e-10, 2.598e-10,
782 2.801e-10, 2.899e-10, 3e-10, 2.817e-10, 2.617e-10, 2.332e-10,
783 1.933e-10, 1.605e-10, 1.232e-10, 9.285e-11, 6.941e-11, 4.951e-11,
784 3.539e-11, 2.402e-11, 1.522e-11, 9.676e-12, 6.056e-12, 3.745e-12,
785 2.34e-12, 1.463e-12, 9.186e-13, 5.769e-13, 3.322e-13, 1.853e-13,
786 1.035e-13, 7.173e-14, 5.382e-14, 4.036e-14, 3.401e-14, 2.997e-14,
787 2.635e-14, 2.316e-14, 2.034e-14, 1.783e-14, 1.56e-14, 1.363e-14,
788 1.19e-14, 1.037e-14, 9.032e-15, 7.846e-15, 6.813e-15, 5.912e-15,
789 5.121e-15, 4.431e-15, 3.829e-15, 3.306e-15, 2.851e-15, 2.456e-15,
790 2.114e-15, 1.816e-15, 1.559e-15, 1.337e-15, 1.146e-15, 9.811e-16,
791 8.389e-16, 7.162e-16, 6.109e-16, 5.203e-16, 4.425e-16, 3.76e-16,
792 3.184e-16, 2.692e-16, 2.274e-16, 1.917e-16, 1.61e-16, 1.35e-16,
793 1.131e-16, 9.437e-17, 7.874e-17, 6.57e-17, 5.481e-17, 4.579e-17,
794 3.828e-17, 3.204e-17, 2.691e-17, 2.264e-17, 1.912e-17, 1.626e-17,
795 1.382e-17, 1.174e-17, 9.972e-18, 8.603e-18, 7.45e-18, 6.453e-18,
796 5.623e-18, 4.944e-18, 4.361e-18, 3.859e-18, 3.443e-18, 3.096e-18,
797 2.788e-18, 2.528e-18, 2.293e-18, 2.099e-18, 1.929e-18, 1.773e-18,
798 1.64e-18
799 };
800
801 static const double hocl[121] = {
802 1.056e-12, 1.194e-12, 1.35e-12, 1.531e-12, 1.737e-12, 1.982e-12,
803 2.263e-12, 2.599e-12, 2.991e-12, 3.459e-12, 4.012e-12, 4.662e-12,
804 5.438e-12, 6.35e-12, 7.425e-12, 8.686e-12, 1.016e-11, 1.188e-11,
805 1.389e-11, 1.659e-11, 2.087e-11, 2.621e-11, 3.265e-11, 4.064e-11,
806 4.859e-11, 5.441e-11, 6.09e-11, 6.373e-11, 6.611e-11, 6.94e-11,
807 7.44e-11, 7.97e-11, 8.775e-11, 9.722e-11, 1.064e-10, 1.089e-10,
808 1.114e-10, 1.106e-10, 1.053e-10, 1.004e-10, 9.006e-11, 7.778e-11,
809 6.739e-11, 5.636e-11, 4.655e-11, 3.845e-11, 3.042e-11, 2.368e-11,
810 1.845e-11, 1.442e-11, 1.127e-11, 8.814e-12, 6.544e-12, 4.763e-12,
811 3.449e-12, 2.612e-12, 1.999e-12, 1.526e-12, 1.16e-12, 8.793e-13,
812 6.655e-13, 5.017e-13, 3.778e-13, 2.829e-13, 2.117e-13, 1.582e-13,
813 1.178e-13, 8.755e-14, 6.486e-14, 4.799e-14, 3.54e-14, 2.606e-14,
814 1.916e-14, 1.403e-14, 1.026e-14, 7.48e-15, 5.446e-15, 3.961e-15,
815 2.872e-15, 2.076e-15, 1.498e-15, 1.077e-15, 7.726e-16, 5.528e-16,
816 3.929e-16, 2.785e-16, 1.969e-16, 1.386e-16, 9.69e-17, 6.747e-17,
817 4.692e-17, 3.236e-17, 2.232e-17, 1.539e-17, 1.061e-17, 7.332e-18,
818 5.076e-18, 3.522e-18, 2.461e-18, 1.726e-18, 1.22e-18, 8.75e-19,
819 6.264e-19, 4.482e-19, 3.207e-19, 2.368e-19, 1.762e-19, 1.312e-19,
820 9.891e-20, 7.595e-20, 5.87e-20, 4.567e-20, 3.612e-20, 2.904e-20,
821 2.343e-20, 1.917e-20, 1.568e-20, 1.308e-20, 1.1e-20, 9.25e-21,
822 7.881e-21
823 };
824
825 static const double n2o[121] = {
826 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07,
827 3.17e-07, 3.17e-07, 3.17e-07, 3.124e-07, 3.077e-07, 3.03e-07,
828 2.984e-07, 2.938e-07, 2.892e-07, 2.847e-07, 2.779e-07, 2.705e-07,
829 2.631e-07, 2.557e-07, 2.484e-07, 2.345e-07, 2.201e-07, 2.01e-07,
830 1.754e-07, 1.532e-07, 1.329e-07, 1.154e-07, 1.003e-07, 8.735e-08,
831 7.617e-08, 6.512e-08, 5.547e-08, 4.709e-08, 3.915e-08, 3.259e-08,
832 2.738e-08, 2.327e-08, 1.98e-08, 1.711e-08, 1.493e-08, 1.306e-08,
833 1.165e-08, 1.049e-08, 9.439e-09, 8.375e-09, 7.391e-09, 6.525e-09,
834 5.759e-09, 5.083e-09, 4.485e-09, 3.953e-09, 3.601e-09, 3.27e-09,
835 2.975e-09, 2.757e-09, 2.556e-09, 2.37e-09, 2.195e-09, 2.032e-09,
836 1.912e-09, 1.79e-09, 1.679e-09, 1.572e-09, 1.482e-09, 1.402e-09,
837 1.326e-09, 1.254e-09, 1.187e-09, 1.127e-09, 1.071e-09, 1.02e-09,
838 9.673e-10, 9.193e-10, 8.752e-10, 8.379e-10, 8.017e-10, 7.66e-10,
839 7.319e-10, 7.004e-10, 6.721e-10, 6.459e-10, 6.199e-10, 5.942e-10,
840 5.703e-10, 5.488e-10, 5.283e-10, 5.082e-10, 4.877e-10, 4.696e-10,
841 4.52e-10, 4.355e-10, 4.198e-10, 4.039e-10, 3.888e-10, 3.754e-10,
842 3.624e-10, 3.499e-10, 3.381e-10, 3.267e-10, 3.163e-10, 3.058e-10,
843 2.959e-10, 2.864e-10, 2.77e-10, 2.686e-10, 2.604e-10, 2.534e-10,
844 2.462e-10, 2.386e-10, 2.318e-10, 2.247e-10, 2.189e-10, 2.133e-10,
845 2.071e-10, 2.014e-10, 1.955e-10, 1.908e-10, 1.86e-10, 1.817e-10
846 };
847
848 static const double n2o5[121] = {
849 1.231e-11, 3.035e-12, 1.702e-12, 9.877e-13, 8.081e-13, 9.039e-13,
850 1.169e-12, 1.474e-12, 1.651e-12, 1.795e-12, 1.998e-12, 2.543e-12,
851 4.398e-12, 7.698e-12, 1.28e-11, 2.131e-11, 3.548e-11, 5.894e-11,
852 7.645e-11, 1.089e-10, 1.391e-10, 1.886e-10, 2.386e-10, 2.986e-10,
853 3.487e-10, 3.994e-10, 4.5e-10, 4.6e-10, 4.591e-10, 4.1e-10, 3.488e-10,
854 2.846e-10, 2.287e-10, 1.696e-10, 1.011e-10, 6.428e-11, 4.324e-11,
855 2.225e-11, 6.214e-12, 3.608e-12, 8.793e-13, 4.491e-13, 1.04e-13,
856 6.1e-14, 3.436e-14, 6.671e-15, 1.171e-15, 5.848e-16, 1.212e-16,
857 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
858 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
859 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
860 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
861 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
862 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
863 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
864 1e-16, 1e-16
865 };
866
867 static const double nh3[121] = {
868 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10,
869 1e-10, 1e-10, 1e-10, 1e-10, 9.444e-11, 8.488e-11, 7.241e-11, 5.785e-11,
870 4.178e-11, 3.018e-11, 2.18e-11, 1.574e-11, 1.137e-11, 8.211e-12,
871 5.973e-12, 4.327e-12, 3.118e-12, 2.234e-12, 1.573e-12, 1.04e-12,
872 6.762e-13, 4.202e-13, 2.406e-13, 1.335e-13, 6.938e-14, 3.105e-14,
873 1.609e-14, 1.033e-14, 6.432e-15, 4.031e-15, 2.555e-15, 1.656e-15,
874 1.115e-15, 7.904e-16, 5.63e-16, 4.048e-16, 2.876e-16, 2.004e-16,
875 1.356e-16, 9.237e-17, 6.235e-17, 4.223e-17, 3.009e-17, 2.328e-17,
876 2.002e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
877 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
878 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
879 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
880 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
881 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
882 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
883 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
884 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
885 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
886 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
887 1.914e-17
888 };
889
890 static const double no[121] = {
891 2.586e-10, 4.143e-11, 1.566e-11, 9.591e-12, 8.088e-12, 8.462e-12,
892 1.013e-11, 1.328e-11, 1.855e-11, 2.678e-11, 3.926e-11, 5.464e-11,
893 7.012e-11, 8.912e-11, 1.127e-10, 1.347e-10, 1.498e-10, 1.544e-10,
894 1.602e-10, 1.824e-10, 2.078e-10, 2.366e-10, 2.691e-10, 5.141e-10,
895 8.259e-10, 1.254e-09, 1.849e-09, 2.473e-09, 3.294e-09, 4.16e-09,
896 5.095e-09, 6.11e-09, 6.93e-09, 7.888e-09, 8.903e-09, 9.713e-09,
897 1.052e-08, 1.115e-08, 1.173e-08, 1.21e-08, 1.228e-08, 1.239e-08,
898 1.231e-08, 1.213e-08, 1.192e-08, 1.138e-08, 1.085e-08, 1.008e-08,
899 9.224e-09, 8.389e-09, 7.262e-09, 6.278e-09, 5.335e-09, 4.388e-09,
900 3.589e-09, 2.761e-09, 2.129e-09, 1.633e-09, 1.243e-09, 9.681e-10,
901 8.355e-10, 7.665e-10, 7.442e-10, 8.584e-10, 9.732e-10, 1.063e-09,
902 1.163e-09, 1.286e-09, 1.472e-09, 1.707e-09, 2.032e-09, 2.474e-09,
903 2.977e-09, 3.506e-09, 4.102e-09, 5.013e-09, 6.493e-09, 8.414e-09,
904 1.077e-08, 1.367e-08, 1.777e-08, 2.625e-08, 3.926e-08, 5.545e-08,
905 7.195e-08, 9.464e-08, 1.404e-07, 2.183e-07, 3.329e-07, 4.535e-07,
906 6.158e-07, 8.187e-07, 1.075e-06, 1.422e-06, 1.979e-06, 2.71e-06,
907 3.58e-06, 4.573e-06, 5.951e-06, 7.999e-06, 1.072e-05, 1.372e-05,
908 1.697e-05, 2.112e-05, 2.643e-05, 3.288e-05, 3.994e-05, 4.794e-05,
909 5.606e-05, 6.383e-05, 7.286e-05, 8.156e-05, 8.883e-05, 9.469e-05,
910 9.848e-05, 0.0001023, 0.0001066, 0.0001115, 0.0001145, 0.0001142,
911 0.0001133
912 };
913
914 static const double no2[121] = {
915 3.036e-09, 2.945e-10, 9.982e-11, 5.069e-11, 3.485e-11, 2.982e-11,
916 2.947e-11, 3.164e-11, 3.714e-11, 4.586e-11, 6.164e-11, 8.041e-11,
917 9.982e-11, 1.283e-10, 1.73e-10, 2.56e-10, 3.909e-10, 5.959e-10,
918 9.081e-10, 1.384e-09, 1.788e-09, 2.189e-09, 2.686e-09, 3.091e-09,
919 3.49e-09, 3.796e-09, 4.2e-09, 5.103e-09, 6.005e-09, 6.3e-09, 6.706e-09,
920 7.07e-09, 7.434e-09, 7.663e-09, 7.788e-09, 7.8e-09, 7.597e-09,
921 7.482e-09, 7.227e-09, 6.403e-09, 5.585e-09, 4.606e-09, 3.703e-09,
922 2.984e-09, 2.183e-09, 1.48e-09, 8.441e-10, 5.994e-10, 3.799e-10,
923 2.751e-10, 1.927e-10, 1.507e-10, 1.102e-10, 6.971e-11, 5.839e-11,
924 3.904e-11, 3.087e-11, 2.176e-11, 1.464e-11, 1.209e-11, 8.497e-12,
925 6.477e-12, 4.371e-12, 2.914e-12, 2.424e-12, 1.753e-12, 1.35e-12,
926 9.417e-13, 6.622e-13, 5.148e-13, 3.841e-13, 3.446e-13, 3.01e-13,
927 2.551e-13, 2.151e-13, 1.829e-13, 1.64e-13, 1.475e-13, 1.352e-13,
928 1.155e-13, 9.963e-14, 9.771e-14, 9.577e-14, 9.384e-14, 9.186e-14,
929 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14,
930 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14,
931 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14,
932 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14
933 };
934
935 static const double o3[121] = {
936 2.218e-08, 3.394e-08, 3.869e-08, 4.219e-08, 4.501e-08, 4.778e-08,
937 5.067e-08, 5.402e-08, 5.872e-08, 6.521e-08, 7.709e-08, 9.461e-08,
938 1.269e-07, 1.853e-07, 2.723e-07, 3.964e-07, 5.773e-07, 8.2e-07,
939 1.155e-06, 1.59e-06, 2.076e-06, 2.706e-06, 3.249e-06, 3.848e-06,
940 4.459e-06, 4.986e-06, 5.573e-06, 5.958e-06, 6.328e-06, 6.661e-06,
941 6.9e-06, 7.146e-06, 7.276e-06, 7.374e-06, 7.447e-06, 7.383e-06,
942 7.321e-06, 7.161e-06, 6.879e-06, 6.611e-06, 6.216e-06, 5.765e-06,
943 5.355e-06, 4.905e-06, 4.471e-06, 4.075e-06, 3.728e-06, 3.413e-06,
944 3.125e-06, 2.856e-06, 2.607e-06, 2.379e-06, 2.17e-06, 1.978e-06,
945 1.8e-06, 1.646e-06, 1.506e-06, 1.376e-06, 1.233e-06, 1.102e-06,
946 9.839e-07, 8.771e-07, 7.814e-07, 6.947e-07, 6.102e-07, 5.228e-07,
947 4.509e-07, 3.922e-07, 3.501e-07, 3.183e-07, 2.909e-07, 2.686e-07,
948 2.476e-07, 2.284e-07, 2.109e-07, 2.003e-07, 2.013e-07, 2.022e-07,
949 2.032e-07, 2.042e-07, 2.097e-07, 2.361e-07, 2.656e-07, 2.989e-07,
950 3.37e-07, 3.826e-07, 4.489e-07, 5.26e-07, 6.189e-07, 7.312e-07,
951 8.496e-07, 8.444e-07, 8.392e-07, 8.339e-07, 8.286e-07, 8.234e-07,
952 8.181e-07, 8.129e-07, 8.077e-07, 8.026e-07, 6.918e-07, 5.176e-07,
953 3.865e-07, 2.885e-07, 2.156e-07, 1.619e-07, 1.219e-07, 9.161e-08,
954 6.972e-08, 5.399e-08, 3.498e-08, 2.111e-08, 1.322e-08, 8.482e-09,
955 5.527e-09, 3.423e-09, 2.071e-09, 1.314e-09, 8.529e-10, 5.503e-10,
956 3.665e-10
957 };
958
959 static const double ocs[121] = {
960 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 5.997e-10,
961 5.989e-10, 5.881e-10, 5.765e-10, 5.433e-10, 5.074e-10, 4.567e-10,
962 4.067e-10, 3.601e-10, 3.093e-10, 2.619e-10, 2.232e-10, 1.805e-10,
963 1.46e-10, 1.187e-10, 8.03e-11, 5.435e-11, 3.686e-11, 2.217e-11,
964 1.341e-11, 8.756e-12, 4.511e-12, 2.37e-12, 1.264e-12, 8.28e-13,
965 5.263e-13, 3.209e-13, 1.717e-13, 9.068e-14, 4.709e-14, 2.389e-14,
966 1.236e-14, 1.127e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
967 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
968 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
969 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
970 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
971 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
972 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
973 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
974 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
975 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
976 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
977 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
978 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
979 1.091e-14, 1.091e-14, 1.091e-14
980 };
981
982 static const double sf6[121] = {
983 4.103e-12, 4.103e-12, 4.103e-12, 4.103e-12, 4.103e-12, 4.103e-12,
984 4.103e-12, 4.103e-12, 4.103e-12, 4.087e-12, 4.064e-12, 4.023e-12,
985 3.988e-12, 3.941e-12, 3.884e-12, 3.755e-12, 3.622e-12, 3.484e-12,
986 3.32e-12, 3.144e-12, 2.978e-12, 2.811e-12, 2.653e-12, 2.489e-12,
987 2.332e-12, 2.199e-12, 2.089e-12, 2.013e-12, 1.953e-12, 1.898e-12,
988 1.859e-12, 1.826e-12, 1.798e-12, 1.776e-12, 1.757e-12, 1.742e-12,
989 1.728e-12, 1.717e-12, 1.707e-12, 1.698e-12, 1.691e-12, 1.685e-12,
990 1.679e-12, 1.675e-12, 1.671e-12, 1.668e-12, 1.665e-12, 1.663e-12,
991 1.661e-12, 1.659e-12, 1.658e-12, 1.657e-12, 1.656e-12, 1.655e-12,
992 1.654e-12, 1.653e-12, 1.653e-12, 1.652e-12, 1.652e-12, 1.652e-12,
993 1.651e-12, 1.651e-12, 1.651e-12, 1.651e-12, 1.651e-12, 1.651e-12,
994 1.651e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
995 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
996 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
997 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
998 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
999 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1000 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1001 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12
1002 };
1003
1004 static const double so2[121] = {
1005 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10,
1006 1e-10, 1e-10, 9.867e-11, 9.537e-11, 9e-11, 8.404e-11, 7.799e-11,
1007 7.205e-11, 6.616e-11, 6.036e-11, 5.475e-11, 5.007e-11, 4.638e-11,
1008 4.346e-11, 4.055e-11, 3.763e-11, 3.471e-11, 3.186e-11, 2.905e-11,
1009 2.631e-11, 2.358e-11, 2.415e-11, 2.949e-11, 3.952e-11, 5.155e-11,
1010 6.76e-11, 8.741e-11, 1.099e-10, 1.278e-10, 1.414e-10, 1.512e-10,
1011 1.607e-10, 1.699e-10, 1.774e-10, 1.832e-10, 1.871e-10, 1.907e-10,
1012 1.943e-10, 1.974e-10, 1.993e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1013 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1014 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1015 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1016 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1017 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1018 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1019 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10
1020 };
1021
1022 const double *q[NG] = { NULL };
1023
1024 /* Identify variable... */
1025 for (int ig = 0; ig < ctl->ng; ig++) {
1026 q[ig] = NULL;
1027 if (strcasecmp(ctl->emitter[ig], "C2H2") == 0)
1028 q[ig] = c2h2;
1029 if (strcasecmp(ctl->emitter[ig], "C2H6") == 0)
1030 q[ig] = c2h6;
1031 if (strcasecmp(ctl->emitter[ig], "CCl4") == 0)
1032 q[ig] = ccl4;
1033 if (strcasecmp(ctl->emitter[ig], "CH3OH") == 0)
1034 q[ig] = ch3oh;
1035 if (strcasecmp(ctl->emitter[ig], "CH4") == 0)
1036 q[ig] = ch4;
1037 if (strcasecmp(ctl->emitter[ig], "ClO") == 0)
1038 q[ig] = clo;
1039 if (strcasecmp(ctl->emitter[ig], "ClONO2") == 0)
1040 q[ig] = clono2;
1041 if (strcasecmp(ctl->emitter[ig], "CO") == 0)
1042 q[ig] = co;
1043 if (strcasecmp(ctl->emitter[ig], "COF2") == 0)
1044 q[ig] = cof2;
1045 if (strcasecmp(ctl->emitter[ig], "F11") == 0)
1046 q[ig] = f11;
1047 if (strcasecmp(ctl->emitter[ig], "F113") == 0)
1048 q[ig] = f113;
1049 if (strcasecmp(ctl->emitter[ig], "F114") == 0)
1050 q[ig] = f114;
1051 if (strcasecmp(ctl->emitter[ig], "F12") == 0)
1052 q[ig] = f12;
1053 if (strcasecmp(ctl->emitter[ig], "F14") == 0)
1054 q[ig] = f14;
1055 if (strcasecmp(ctl->emitter[ig], "F22") == 0)
1056 q[ig] = f22;
1057 if (strcasecmp(ctl->emitter[ig], "H2CO") == 0)
1058 q[ig] = h2co;
1059 if (strcasecmp(ctl->emitter[ig], "H2O") == 0)
1060 q[ig] = h2o;
1061 if (strcasecmp(ctl->emitter[ig], "H2O2") == 0)
1062 q[ig] = h2o2;
1063 if (strcasecmp(ctl->emitter[ig], "HCl") == 0)
1064 q[ig] = hcl;
1065 if (strcasecmp(ctl->emitter[ig], "HCN") == 0)
1066 q[ig] = hcn;
1067 if (strcasecmp(ctl->emitter[ig], "HF") == 0)
1068 q[ig] = hf;
1069 if (strcasecmp(ctl->emitter[ig], "HNO3") == 0)
1070 q[ig] = hno3;
1071 if (strcasecmp(ctl->emitter[ig], "HNO4") == 0)
1072 q[ig] = hno4;
1073 if (strcasecmp(ctl->emitter[ig], "HOCl") == 0)
1074 q[ig] = hocl;
1075 if (strcasecmp(ctl->emitter[ig], "N2O") == 0)
1076 q[ig] = n2o;
1077 if (strcasecmp(ctl->emitter[ig], "N2O5") == 0)
1078 q[ig] = n2o5;
1079 if (strcasecmp(ctl->emitter[ig], "NH3") == 0)
1080 q[ig] = nh3;
1081 if (strcasecmp(ctl->emitter[ig], "NO") == 0)
1082 q[ig] = no;
1083 if (strcasecmp(ctl->emitter[ig], "NO2") == 0)
1084 q[ig] = no2;
1085 if (strcasecmp(ctl->emitter[ig], "O3") == 0)
1086 q[ig] = o3;
1087 if (strcasecmp(ctl->emitter[ig], "OCS") == 0)
1088 q[ig] = ocs;
1089 if (strcasecmp(ctl->emitter[ig], "SF6") == 0)
1090 q[ig] = sf6;
1091 if (strcasecmp(ctl->emitter[ig], "SO2") == 0)
1092 q[ig] = so2;
1093 }
1094
1095 /* Loop over atmospheric data points... */
1096 for (int ip = 0; ip < atm->np; ip++) {
1097
1098 /* Get altitude index... */
1099 const int iz = locate_reg(z, 121, atm->z[ip]);
1100
1101 /* Interpolate pressure... */
1102 atm->p[ip] = LOGY(z[iz], pre[iz], z[iz + 1], pre[iz + 1], atm->z[ip]);
1103
1104 /* Interpolate temperature... */
1105 atm->t[ip] = LIN(z[iz], tem[iz], z[iz + 1], tem[iz + 1], atm->z[ip]);
1106
1107 /* Interpolate trace gases... */
1108 for (int ig = 0; ig < ctl->ng; ig++)
1109 if (q[ig] != NULL)
1110 atm->q[ig][ip] =
1111 LIN(z[iz], q[ig][iz], z[iz + 1], q[ig][iz + 1], atm->z[ip]);
1112 else
1113 atm->q[ig][ip] = 0;
1114
1115 /* Set CO2... */
1116 if (ctl->ig_co2 >= 0)
1117 atm->q[ctl->ig_co2][ip] =
1118 371.789948e-6 + 2.026214e-6 * (atm->time[ip] - 63158400.) / 31557600.;
1119
1120 /* Set N2... */
1121 if (ctl->ig_n2 >= 0)
1122 atm->q[ctl->ig_n2][ip] = N2;
1123
1124 /* Set O2... */
1125 if (ctl->ig_o2 >= 0)
1126 atm->q[ctl->ig_o2][ip] = O2;
1127
1128 /* Set extinction to zero... */
1129 for (int iw = 0; iw < ctl->nw; iw++)
1130 atm->k[iw][ip] = 0;
1131
1132 /* Set cloud layer... */
1133 atm->clz = atm->cldz = 0;
1134 for (int icl = 0; icl < ctl->ncl; icl++)
1135 atm->clk[icl] = 0;
1136
1137 /* Set surface... */
1138 atm->sft = 0;
1139 for (int isf = 0; isf < ctl->nsf; isf++)
1140 atm->sfeps[isf] = 1;
1141 }
1142}
int locate_reg(const double *xx, const int n, const double x)
Locate index for interpolation on a regular (uniform) grid.
Definition: jurassic.c:4505
#define O2
Oxygen concentration.
Definition: jurassic.h:179
#define LOGY(x0, y0, x1, y1, x)
Compute logarithmic interpolation in y.
Definition: jurassic.h:587
#define NG
Maximum number of emitters.
Definition: jurassic.h:243
#define N2
Nitrogen concentration.
Definition: jurassic.h:174
#define LIN(x0, y0, x1, y1, x)
Compute linear interpolation.
Definition: jurassic.h:566
double time[NP]
Time (seconds since 2000-01-01T00:00Z).
Definition: jurassic.h:1249
int ig_co2
Emitter index of CO2.
Definition: jurassic.h:1305
int ig_o2
Emitter index of O2.
Definition: jurassic.h:1314
int ig_n2
Emitter index of N2.
Definition: jurassic.h:1311
char emitter[NG][LEN]
Name of each emitter.
Definition: jurassic.h:1302
Here is the call graph for this function:

◆ cos_sza()

double cos_sza ( const double  sec,
const double  lon,
const double  lat 
)

Calculates the cosine of the solar zenith angle.

This function computes the cosine of the solar zenith angle (SZA), which describes the angle between the local zenith (straight up) and the line connecting the observer to the center of the Sun. The cosine of the SZA is often used directly in radiative transfer and photochemical calculations to avoid unnecessary use of trigonometric inverse functions.

Parameters
secSeconds elapsed since 2000-01-01T12:00Z.
lonObserver's longitude in degrees.
latObserver's latitude in degrees.
Returns
The cosine of the solar zenith angle (dimensionless, range [-1, 1]).

The cosine of the solar zenith angle is computed based on the observer's position (longitude and latitude) and the specified time in seconds elapsed since 2000-01-01T12:00Z.

Note
The input longitude and latitude must be specified in degrees.
See also
acos() — can be used to convert the returned value to the solar zenith angle in radians if needed.
Author
Lars Hoffmann

Definition at line 1146 of file jurassic.c.

1149 {
1150
1151 /* Number of days and fraction with respect to 2000-01-01T12:00Z... */
1152 const double D = sec / 86400 - 0.5;
1153
1154 /* Geocentric apparent ecliptic longitude [rad]... */
1155 const double g = DEG2RAD(357.529 + 0.98560028 * D);
1156 const double q = 280.459 + 0.98564736 * D;
1157 const double L = DEG2RAD(q + 1.915 * sin(g) + 0.020 * sin(2 * g));
1158
1159 /* Mean obliquity of the ecliptic [rad]... */
1160 const double e = DEG2RAD(23.439 - 0.00000036 * D);
1161
1162 /* Declination [rad]... */
1163 const double sindec = sin(e) * sin(L);
1164
1165 /* Right ascension [rad]... */
1166 const double ra = atan2(cos(e) * sin(L), cos(L));
1167
1168 /* Greenwich Mean Sidereal Time [h]... */
1169 const double GMST = 18.697374558 + 24.06570982441908 * D;
1170
1171 /* Local Sidereal Time [h]... */
1172 const double LST = GMST + lon / 15;
1173
1174 /* Hour angle [rad]... */
1175 const double h = LST / 12 * M_PI - ra;
1176
1177 /* Convert latitude... */
1178 const double lat_help = DEG2RAD(lat);
1179
1180 /* Return cosine of solar zenith angle... */
1181 return sin(lat_help) * sindec + cos(lat_help)
1182 * sqrt(1 - POW2(sindec)) * cos(h);
1183}
#define POW2(x)
Compute the square of a value.
Definition: jurassic.h:961
#define DEG2RAD(deg)
Convert degrees to radians.
Definition: jurassic.h:447

◆ cost_function()

double cost_function ( const gsl_vector *  dx,
const gsl_vector *  dy,
const gsl_matrix *  s_a_inv,
const gsl_vector *  sig_eps_inv 
)

Compute the normalized quadratic cost function for optimal estimation.

Evaluates the cost function

\[ J = \frac{1}{m} \left[ (\mathbf{y} - \mathbf{y_a})^T \mathbf{S_\epsilon^{-1}} (\mathbf{y} - \mathbf{y_a}) + (\mathbf{x} - \mathbf{x_a})^T \mathbf{S_a^{-1}} (\mathbf{x} - \mathbf{x_a}) \right] \]

where \(\mathbf{dx} = \mathbf{x} - \mathbf{x_a}\) and \(\mathbf{dy} = \mathbf{y} - \mathbf{y_a}\) represent the deviations from a priori state and measurement vectors, respectively.

Parameters
[in]dxState deviation vector (x - x_a).
[in]dyMeasurement deviation vector (y - y_a).
[in]s_a_invInverse of the a priori covariance matrix ( \(\mathbf{S_a^{-1}}\)).
[in]sig_eps_invVector of inverse measurement uncertainties ( \(\mathbf{S_\epsilon^{-1/2}}\) diagonal elements).
Returns
Normalized cost function value (dimensionless).
  • Implements the standard Optimal Estimation Method (Rodgers, 2000) cost function.
  • The first term ( \(\chi^2_m\)) measures the weighted measurement residuals: \(\chi^2_m = \sum_i (dy_i / \sigma_{\epsilon,i})^2\).
  • The second term ( \(\chi^2_a\)) measures the deviation from the a priori state: \(\chi^2_a = dx^T \mathbf{S_a^{-1}} dx\).
  • The result is normalized by the number of measurements \(m\) for scale consistency.
See also
retrieval, s_a_inv, sig_eps_inv
Note
  • Assumes diagonal measurement error covariance (independent measurements).
  • The covariance matrices must be positive-definite and properly dimensioned.
  • The function does not modify the input vectors.
Author
Lars Hoffmann

Definition at line 1187 of file jurassic.c.

1191 {
1192
1193 double chisq_a, chisq_m = 0;
1194
1195 /* Get sizes... */
1196 const size_t m = dy->size;
1197 const size_t n = dx->size;
1198
1199 /* Allocate... */
1200 gsl_vector *x_aux = gsl_vector_alloc(n);
1201
1202 /* Determine normalized cost function...
1203 (chi^2 = 1/m * [dy^T * S_eps^{-1} * dy + dx^T * S_a^{-1} * dx]) */
1204 for (size_t i = 0; i < m; i++)
1205 chisq_m += POW2(gsl_vector_get(dy, i) * gsl_vector_get(sig_eps_inv, i));
1206 gsl_blas_dgemv(CblasNoTrans, 1.0, s_a_inv, dx, 0.0, x_aux);
1207 gsl_blas_ddot(dx, x_aux, &chisq_a);
1208
1209 /* Free... */
1210 gsl_vector_free(x_aux);
1211
1212 /* Return cost function value... */
1213 return (chisq_m + chisq_a) / (double) m;
1214}

◆ ctmco2()

double ctmco2 ( const double  nu,
const double  p,
const double  t,
const double  u 
)

Compute carbon dioxide continuum (optical depth).

Author
Lars Hoffmann

Definition at line 1218 of file jurassic.c.

1222 {
1223
1224 static const double co2296[2001] =
1225 { 9.3388e-5, 9.7711e-5, 1.0224e-4, 1.0697e-4,
1226 1.1193e-4, 1.1712e-4, 1.2255e-4, 1.2824e-4, 1.3419e-4, 1.4043e-4,
1227 1.4695e-4, 1.5378e-4, 1.6094e-4, 1.6842e-4, 1.7626e-4, 1.8447e-4,
1228 1.9307e-4, 2.0207e-4, 2.1149e-4, 2.2136e-4, 2.3169e-4, 2.4251e-4,
1229 2.5384e-4, 2.657e-4, 2.7813e-4, 2.9114e-4, 3.0477e-4, 3.1904e-4,
1230 3.3399e-4, 3.4965e-4, 3.6604e-4, 3.8322e-4, 4.0121e-4, 4.2006e-4,
1231 4.398e-4, 4.6047e-4, 4.8214e-4, 5.0483e-4, 5.286e-4, 5.535e-4,
1232 5.7959e-4, 6.0693e-4, 6.3557e-4, 6.6558e-4, 6.9702e-4, 7.2996e-4,
1233 7.6449e-4, 8.0066e-4, 8.3856e-4, 8.7829e-4, 9.1991e-4, 9.6354e-4,
1234 .0010093, .0010572, .0011074, .00116, .0012152, .001273,
1235 .0013336, .0013972, .0014638, .0015336, .0016068, .0016835,
1236 .001764, .0018483, .0019367, .0020295, .0021267, .0022286,
1237 .0023355, .0024476, .0025652, .0026885, .0028178, .0029534,
1238 .0030956, .0032448, .0034012, .0035654, .0037375, .0039181,
1239 .0041076, .0043063, .0045148, .0047336, .0049632, .005204,
1240 .0054567, .0057219, .0060002, .0062923, .0065988, .0069204,
1241 .007258, .0076123, .0079842, .0083746, .0087844, .0092146,
1242 .0096663, .01014, .010638, .011161, .01171, .012286, .012891,
1243 .013527, .014194, .014895, .015631, .016404, .017217, .01807,
1244 .018966, .019908, .020897, .021936, .023028, .024176, .025382,
1245 .026649, .027981, .02938, .030851, .032397, .034023, .035732,
1246 .037528, .039416, .041402, .04349, .045685, .047994, .050422,
1247 .052975, .055661, .058486, .061458, .064584, .067873, .071334,
1248 .074975, .078807, .082839, .087082, .091549, .096249, .1012,
1249 .10641, .11189, .11767, .12375, .13015, .13689, .14399, .15147,
1250 .15935, .16765, .17639, .18561, .19531, .20554, .21632, .22769,
1251 .23967, .25229, .2656, .27964, .29443, .31004, .3265, .34386,
1252 .36218, .3815, .40188, .42339, .44609, .47004, .49533, .52202,
1253 .5502, .57995, .61137, .64455, .6796, .71663, .75574, .79707,
1254 .84075, .88691, .9357, .98728, 1.0418, 1.0995, 1.1605, 1.225,
1255 1.2932, 1.3654, 1.4418, 1.5227, 1.6083, 1.6989, 1.7948, 1.8964,
1256 2.004, 2.118, 2.2388, 2.3668, 2.5025, 2.6463, 2.7988, 2.9606,
1257 3.1321, 3.314, 3.5071, 3.712, 3.9296, 4.1605, 4.4058, 4.6663,
1258 4.9431, 5.2374, 5.5501, 5.8818, 6.2353, 6.6114, 7.0115, 7.4372,
1259 7.8905, 8.3731, 8.8871, 9.4349, 10.019, 10.641, 11.305, 12.013,
1260 12.769, 13.576, 14.437, 15.358, 16.342, 17.39, 18.513, 19.716,
1261 21.003, 22.379, 23.854, 25.436, 27.126, 28.942, 30.89, 32.973,
1262 35.219, 37.634, 40.224, 43.021, 46.037, 49.29, 52.803, 56.447,
1263 60.418, 64.792, 69.526, 74.637, 80.182, 86.193, 92.713, 99.786,
1264 107.47, 115.84, 124.94, 134.86, 145.69, 157.49, 170.3, 184.39,
1265 199.83, 216.4, 234.55, 254.72, 276.82, 299.85, 326.16, 354.99,
1266 386.51, 416.68, 449.89, 490.12, 534.35, 578.25, 632.26, 692.61,
1267 756.43, 834.75, 924.11, 1016.9, 996.96, 1102.7, 1219.2, 1351.9,
1268 1494.3, 1654.1, 1826.5, 2027.9, 2249., 2453.8, 2714.4, 2999.4,
1269 3209.5, 3509., 3840.4, 3907.5, 4190.7, 4533.5, 4648.3, 5059.1,
1270 5561.6, 6191.4, 6820.8, 7905.9, 9362.2, 2431.3, 2211.3, 2046.8,
1271 2023.8, 1985.9, 1905.9, 1491.1, 1369.8, 1262.2, 1200.7, 887.74,
1272 820.25, 885.23, 887.21, 816.73, 1126.9, 1216.2, 1272.4, 1579.5,
1273 1634.2, 1656.3, 1657.9, 1789.5, 1670.8, 1509.5, 8474.6, 7489.2,
1274 6793.6, 6117., 5574.1, 5141.2, 5084.6, 4745.1, 4413.2, 4102.8,
1275 4024.7, 3715., 3398.6, 3100.8, 2900.4, 2629.2, 2374., 2144.7,
1276 1955.8, 1760.8, 1591.2, 1435.2, 1296.2, 1174., 1065.1, 967.76,
1277 999.48, 897.45, 809.23, 732.77, 670.26, 611.93, 560.11, 518.77,
1278 476.84, 438.8, 408.48, 380.21, 349.24, 322.71, 296.65, 272.85,
1279 251.96, 232.04, 213.88, 197.69, 182.41, 168.41, 155.79, 144.05,
1280 133.31, 123.48, 114.5, 106.21, 98.591, 91.612, 85.156, 79.204,
1281 73.719, 68.666, 63.975, 59.637, 56.35, 52.545, 49.042, 45.788,
1282 42.78, 39.992, 37.441, 35.037, 32.8, 30.744, 28.801, 26.986,
1283 25.297, 23.731, 22.258, 20.883, 19.603, 18.403, 17.295, 16.249,
1284 15.271, 14.356, 13.501, 12.701, 11.954, 11.254, 10.6, 9.9864,
1285 9.4118, 8.8745, 8.3714, 7.8997, 7.4578, 7.0446, 6.6573, 6.2949,
1286 5.9577, 5.6395, 5.3419, 5.063, 4.8037, 4.5608, 4.3452, 4.1364,
1287 3.9413, 3.7394, 3.562, 3.3932, 3.2325, 3.0789, 2.9318, 2.7898,
1288 2.6537, 2.5225, 2.3958, 2.2305, 2.1215, 2.0245, 1.9427, 1.8795,
1289 1.8336, 1.7604, 1.7016, 1.6419, 1.5282, 1.4611, 1.3443, 1.27,
1290 1.1675, 1.0824, 1.0534, .99833, .95854, .92981, .90887, .89346,
1291 .88113, .87068, .86102, .85096, .88262, .86151, .83565, .80518,
1292 .77045, .73736, .74744, .74954, .75773, .82267, .83493, .89402,
1293 .89725, .93426, .95564, .94045, .94174, .93404, .92035, .90456,
1294 .88621, .86673, .78117, .7515, .72056, .68822, .65658, .62764,
1295 .55984, .55598, .57407, .60963, .63763, .66198, .61132, .60972,
1296 .52496, .50649, .41872, .3964, .32422, .27276, .24048, .23772,
1297 .2286, .22711, .23999, .32038, .34371, .36621, .38561, .39953,
1298 .40636, .44913, .42716, .3919, .35477, .33935, .3351, .39746,
1299 .40993, .49398, .49956, .56157, .54742, .57295, .57386, .55417,
1300 .50745, .471, .43446, .39102, .34993, .31269, .27888, .24912,
1301 .22291, .19994, .17972, .16197, .14633, .13252, .12029, .10942,
1302 .099745, .091118, .083404, .076494, .070292, .064716, .059697,
1303 .055173, .051093, .047411, .044089, .041092, .038392, .035965,
1304 .033789, .031846, .030122, .028607, .02729, .026169, .025209,
1305 .024405, .023766, .023288, .022925, .022716, .022681, .022685,
1306 .022768, .023133, .023325, .023486, .024004, .024126, .024083,
1307 .023785, .024023, .023029, .021649, .021108, .019454, .017809,
1308 .017292, .016635, .017037, .018068, .018977, .018756, .017847,
1309 .016557, .016142, .014459, .012869, .012381, .010875, .0098701,
1310 .009285, .0091698, .0091701, .0096145, .010553, .01106, .012613,
1311 .014362, .015017, .016507, .017741, .01768, .017784, .0171,
1312 .016357, .016172, .017257, .018978, .020935, .021741, .023567,
1313 .025183, .025589, .026732, .027648, .028278, .028215, .02856,
1314 .029015, .029062, .028851, .028497, .027825, .027801, .026523,
1315 .02487, .022967, .022168, .020194, .018605, .017903, .018439,
1316 .019697, .020311, .020855, .020057, .018608, .016738, .015963,
1317 .013844, .011801, .011134, .0097573, .0086007, .0086226,
1318 .0083721, .0090978, .0097616, .0098426, .011317, .012853, .01447,
1319 .014657, .015771, .016351, .016079, .014829, .013431, .013185,
1320 .013207, .01448, .016176, .017971, .018265, .019526, .020455,
1321 .019797, .019802, .0194, .018176, .017505, .016197, .015339,
1322 .014401, .013213, .012203, .011186, .010236, .0093288, .0084854,
1323 .0076837, .0069375, .0062614, .0056628, .0051153, .0046015,
1324 .0041501, .003752, .0033996, .0030865, .0028077, .0025586,
1325 .0023355, .0021353, .0019553, .0017931, .0016466, .0015141,
1326 .0013941, .0012852, .0011862, .0010962, .0010142, 9.3935e-4,
1327 8.71e-4, 8.0851e-4, 7.5132e-4, 6.9894e-4, 6.5093e-4, 6.0689e-4,
1328 5.6647e-4, 5.2935e-4, 4.9525e-4, 4.6391e-4, 4.3509e-4, 4.086e-4,
1329 3.8424e-4, 3.6185e-4, 3.4126e-4, 3.2235e-4, 3.0498e-4, 2.8904e-4,
1330 2.7444e-4, 2.6106e-4, 2.4883e-4, 2.3766e-4, 2.275e-4, 2.1827e-4,
1331 2.0992e-4, 2.0239e-4, 1.9563e-4, 1.896e-4, 1.8427e-4, 1.796e-4,
1332 1.7555e-4, 1.7209e-4, 1.692e-4, 1.6687e-4, 1.6505e-4, 1.6375e-4,
1333 1.6294e-4, 1.6261e-4, 1.6274e-4, 1.6334e-4, 1.6438e-4, 1.6587e-4,
1334 1.678e-4, 1.7017e-4, 1.7297e-4, 1.762e-4, 1.7988e-4, 1.8399e-4,
1335 1.8855e-4, 1.9355e-4, 1.9902e-4, 2.0494e-4, 2.1134e-4, 2.1823e-4,
1336 2.2561e-4, 2.335e-4, 2.4192e-4, 2.5088e-4, 2.604e-4, 2.705e-4,
1337 2.8119e-4, 2.9251e-4, 3.0447e-4, 3.171e-4, 3.3042e-4, 3.4447e-4,
1338 3.5927e-4, 3.7486e-4, 3.9127e-4, 4.0854e-4, 4.267e-4, 4.4579e-4,
1339 4.6586e-4, 4.8696e-4, 5.0912e-4, 5.324e-4, 5.5685e-4, 5.8253e-4,
1340 6.0949e-4, 6.378e-4, 6.6753e-4, 6.9873e-4, 7.3149e-4, 7.6588e-4,
1341 8.0198e-4, 8.3987e-4, 8.7964e-4, 9.2139e-4, 9.6522e-4, .0010112,
1342 .0010595, .0011102, .0011634, .0012193, .001278, .0013396,
1343 .0014043, .0014722, .0015436, .0016185, .0016972, .0017799,
1344 .0018668, .001958, .0020539, .0021547, .0022606, .0023719,
1345 .002489, .002612, .0027414, .0028775, .0030206, .0031712,
1346 .0033295, .0034962, .0036716, .0038563, .0040506, .0042553,
1347 .0044709, .004698, .0049373, .0051894, .0054552, .0057354,
1348 .006031, .0063427, .0066717, .0070188, .0073854, .0077726,
1349 .0081816, .0086138, .0090709, .0095543, .010066, .010607,
1350 .011181, .011789, .012433, .013116, .013842, .014613, .015432,
1351 .016304, .017233, .018224, .019281, .020394, .021574, .022836,
1352 .024181, .025594, .027088, .028707, .030401, .032245, .034219,
1353 .036262, .038539, .040987, .043578, .04641, .04949, .052726,
1354 .056326, .0602, .064093, .068521, .073278, .077734, .083064,
1355 .088731, .093885, .1003, .1072, .11365, .12187, .13078, .13989,
1356 .15095, .16299, .17634, .19116, .20628, .22419, .24386, .26587,
1357 .28811, .31399, .34321, .36606, .39675, .42742, .44243, .47197,
1358 .49993, .49027, .51147, .52803, .48931, .49729, .5026, .43854,
1359 .441, .44766, .43414, .46151, .50029, .55247, .43855, .32115,
1360 .32607, .3431, .36119, .38029, .41179, .43996, .47144, .51853,
1361 .55362, .59122, .66338, .69877, .74001, .82923, .86907, .90361,
1362 1.0025, 1.031, 1.0559, 1.104, 1.1178, 1.1341, 1.1547, 1.351,
1363 1.4772, 1.4812, 1.4907, 1.512, 1.5442, 1.5853, 1.6358, 1.6963,
1364 1.7674, 1.8474, 1.9353, 2.0335, 2.143, 2.2592, 2.3853, 2.5217,
1365 2.6686, 2.8273, 2.9998, 3.183, 3.3868, 3.6109, 3.8564, 4.1159,
1366 4.4079, 4.7278, 5.0497, 5.3695, 5.758, 6.0834, 6.4976, 6.9312,
1367 7.38, 7.5746, 7.9833, 8.3791, 8.3956, 8.7501, 9.1067, 9.072,
1368 9.4649, 9.9112, 10.402, 10.829, 11.605, 12.54, 12.713, 10.443,
1369 10.825, 11.375, 11.955, 12.623, 13.326, 14.101, 15.041, 15.547,
1370 16.461, 17.439, 18.716, 19.84, 21.036, 22.642, 23.901, 25.244,
1371 27.03, 28.411, 29.871, 31.403, 33.147, 34.744, 36.456, 39.239,
1372 43.605, 45.162, 47.004, 49.093, 51.391, 53.946, 56.673, 59.629,
1373 63.167, 66.576, 70.254, 74.222, 78.477, 83.034, 87.914, 93.18,
1374 98.77, 104.74, 111.15, 117.95, 125.23, 133.01, 141.33, 150.21,
1375 159.71, 169.89, 180.93, 192.54, 204.99, 218.34, 232.65, 248.,
1376 264.47, 282.14, 301.13, 321.53, 343.48, 367.08, 392.5, 419.88,
1377 449.4, 481.26, 515.64, 552.79, 592.99, 636.48, 683.61, 734.65,
1378 789.99, 850.02, 915.14, 985.81, 1062.5, 1147.1, 1237.8, 1336.4,
1379 1443.2, 1558.9, 1684.2, 1819.2, 1965.2, 2122.6, 2291.7, 2470.8,
1380 2665.7, 2874.9, 3099.4, 3337.9, 3541., 3813.3, 4111.9, 4439.3,
1381 4798.9, 5196., 5639.2, 6087.5, 6657.7, 7306.7, 8040.7, 8845.5,
1382 9702.2, 10670., 11739., 12842., 14141., 15498., 17068., 18729.,
1383 20557., 22559., 25248., 27664., 30207., 32915., 35611., 38081.,
1384 40715., 43191., 41651., 42750., 43785., 44353., 44366., 44189.,
1385 43618., 42862., 41878., 35133., 35215., 36383., 39420., 44055.,
1386 44155., 45850., 46853., 39197., 38274., 29942., 28553., 21792.,
1387 21228., 17106., 14955., 18181., 19557., 21427., 23728., 26301.,
1388 28584., 30775., 32536., 33867., 40089., 39204., 37329., 34452.,
1389 31373., 33921., 34800., 36043., 44415., 45162., 52181., 50895.,
1390 54140., 50840., 50468., 48302., 44915., 40910., 36754., 32755.,
1391 29093., 25860., 22962., 20448., 18247., 16326., 14645., 13165.,
1392 11861., 10708., 9686.9, 8779.7, 7971.9, 7250.8, 6605.7, 6027.2,
1393 5507.3, 5039.1, 4616.6, 4234.8, 3889., 3575.4, 3290.5, 3031.3,
1394 2795.2, 2579.9, 2383.1, 2203.3, 2038.6, 1887.6, 1749.1, 1621.9,
1395 1505., 1397.4, 1298.3, 1207., 1122.8, 1045., 973.1, 906.64,
1396 845.16, 788.22, 735.48, 686.57, 641.21, 599.1, 559.99, 523.64,
1397 489.85, 458.42, 429.16, 401.92, 376.54, 352.88, 330.82, 310.24,
1398 291.03, 273.09, 256.34, 240.69, 226.05, 212.37, 199.57, 187.59,
1399 176.37, 165.87, 156.03, 146.82, 138.17, 130.07, 122.47, 115.34,
1400 108.65, 102.37, 96.473, 90.934, 85.73, 80.84, 76.243, 71.922,
1401 67.858, 64.034, 60.438, 57.052, 53.866, 50.866, 48.04, 45.379,
1402 42.872, 40.51, 38.285, 36.188, 34.211, 32.347, 30.588, 28.929,
1403 27.362, 25.884, 24.489, 23.171, 21.929, 20.755, 19.646, 18.599,
1404 17.61, 16.677, 15.795, 14.961, 14.174, 13.43, 12.725, 12.06,
1405 11.431, 10.834, 10.27, 9.7361, 9.2302, 8.7518, 8.2997, 7.8724,
1406 7.4674, 7.0848, 6.7226, 6.3794, 6.054, 5.745, 5.4525, 5.1752,
1407 4.9121, 4.6625, 4.4259, 4.2015, 3.9888, 3.7872, 3.5961, 3.4149,
1408 3.2431, 3.0802, 2.9257, 2.7792, 2.6402, 2.5084, 2.3834, 2.2648,
1409 2.1522, 2.0455, 1.9441, 1.848, 1.7567, 1.6701, 1.5878, 1.5097,
1410 1.4356, 1.3651, 1.2981, 1.2345, 1.174, 1.1167, 1.062, 1.0101,
1411 .96087, .91414, .86986, .82781, .78777, .74971, .71339, .67882,
1412 .64604, .61473, .58507, .55676, .52987, .5044, .48014, .45715,
1413 .43527, .41453, .3948, .37609, .35831, .34142, .32524, .30995,
1414 .29536, .28142, .26807, .25527, .24311, .23166, .22077, .21053,
1415 .20081, .19143, .18261, .17407, .16603, .15833, .15089, .14385,
1416 .13707, .13065, .12449, .11865, .11306, .10774, .10266, .097818,
1417 .093203, .088815, .084641, .080671, .076892, .073296, .069873,
1418 .066613, .06351, .060555, .05774, .055058, .052504, .050071,
1419 .047752, .045543, .043438, .041432, .039521, .037699, .035962,
1420 .034307, .032729, .031225, .029791, .028423, .02712, .025877,
1421 .024692, .023563, .022485, .021458, .020478, .019543, .018652,
1422 .017802, .016992, .016219, .015481, .014778, .014107, .013467,
1423 .012856, .012274, .011718, .011188, .010682, .0102, .0097393,
1424 .0093001, .008881, .0084812, .0080997, .0077358, .0073885,
1425 .0070571, .0067409, .0064393, .0061514, .0058768, .0056147,
1426 .0053647, .0051262, .0048987, .0046816, .0044745, .0042769,
1427 .0040884, .0039088, .0037373, .0035739, .003418, .0032693,
1428 .0031277, .0029926, .0028639, .0027413, .0026245, .0025133,
1429 .0024074, .0023066, .0022108, .0021196, .002033, .0019507,
1430 .0018726, .0017985, .0017282, .0016617, .0015988, .0015394,
1431 .0014834, .0014306, .0013811, .0013346, .0012911, .0012506,
1432 .0012131, .0011784, .0011465, .0011175, .0010912, .0010678,
1433 .0010472, .0010295, .0010147, .001003, 9.9428e-4, 9.8883e-4,
1434 9.8673e-4, 9.8821e-4, 9.9343e-4, .0010027, .0010164, .0010348,
1435 .0010586, .0010882, .0011245, .0011685, .0012145, .0012666,
1436 .0013095, .0013688, .0014048, .0014663, .0015309, .0015499,
1437 .0016144, .0016312, .001705, .0017892, .0018499, .0019715,
1438 .0021102, .0022442, .0024284, .0025893, .0027703, .0029445,
1439 .0031193, .003346, .0034552, .0036906, .0037584, .0040084,
1440 .0041934, .0044587, .0047093, .0049759, .0053421, .0055134,
1441 .0059048, .0058663, .0061036, .0063259, .0059657, .0060653,
1442 .0060972, .0055539, .0055653, .0055772, .005331, .0054953,
1443 .0055919, .0058684, .006183, .0066675, .0069808, .0075142,
1444 .0078536, .0084282, .0089454, .0094625, .0093703, .0095857,
1445 .0099283, .010063, .010521, .0097778, .0098175, .010379, .010447,
1446 .0105, .010617, .010706, .01078, .011177, .011212, .011304,
1447 .011446, .011603, .011816, .012165, .012545, .013069, .013539,
1448 .01411, .014776, .016103, .017016, .017994, .018978, .01998,
1449 .021799, .022745, .023681, .024627, .025562, .026992, .027958,
1450 .029013, .030154, .031402, .03228, .033651, .035272, .037088,
1451 .039021, .041213, .043597, .045977, .04877, .051809, .054943,
1452 .058064, .061528, .06537, .069309, .071928, .075752, .079589,
1453 .083352, .084096, .087497, .090817, .091198, .094966, .099045,
1454 .10429, .10867, .11518, .12269, .13126, .14087, .15161, .16388,
1455 .16423, .1759, .18721, .19994, .21275, .22513, .23041, .24231,
1456 .25299, .25396, .26396, .27696, .27929, .2908, .30595, .31433,
1457 .3282, .3429, .35944, .37467, .39277, .41245, .43326, .45649,
1458 .48152, .51897, .54686, .57877, .61263, .64962, .68983, .73945,
1459 .78619, .83537, .89622, .95002, 1.0067, 1.0742, 1.1355, 1.2007,
1460 1.2738, 1.347, 1.4254, 1.5094, 1.6009, 1.6976, 1.8019, 1.9148,
1461 2.0357, 2.166, 2.3066, 2.4579, 2.6208, 2.7966, 2.986, 3.188,
1462 3.4081, 3.6456, 3.9, 4.1747, 4.4712, 4.7931, 5.1359, 5.5097,
1463 5.9117, 6.3435, 6.8003, 7.3001, 7.8385, 8.3945, 9.011, 9.6869,
1464 10.392, 11.18, 12.036, 12.938, 13.944, 14.881, 16.029, 17.255,
1465 18.574, 19.945, 21.38, 22.9, 24.477, 26.128, 27.87, 29.037,
1466 30.988, 33.145, 35.506, 37.76, 40.885, 44.487, 48.505, 52.911,
1467 57.56, 61.964, 67.217, 72.26, 78.343, 85.08, 91.867, 99.435,
1468 107.68, 116.97, 127.12, 138.32, 150.26, 163.04, 174.81, 189.26,
1469 205.61, 224.68, 240.98, 261.88, 285.1, 307.58, 334.35, 363.53,
1470 394.68, 427.85, 458.85, 489.25, 472.87, 486.93, 496.27, 501.52,
1471 501.57, 497.14, 488.09, 476.32, 393.76, 388.51, 393.42, 414.45,
1472 455.12, 514.62, 520.38, 547.42, 562.6, 487.47, 480.83, 391.06,
1473 376.92, 303.7, 295.91, 256.03, 236.73, 280.38, 310.71, 335.53,
1474 367.88, 401.94, 435.52, 469.13, 497.94, 588.82, 597.94, 597.2,
1475 588.28, 571.2, 555.75, 603.56, 638.15, 680.75, 801.72, 848.01,
1476 962.15, 990.06, 1068.1, 1076.2, 1115.3, 1134.2, 1136.6, 1119.1,
1477 1108.9, 1090.6, 1068.7, 1041.9, 1005.4, 967.98, 927.08, 780.1,
1478 751.41, 733.12, 742.65, 785.56, 855.16, 852.45, 878.1, 784.59,
1479 777.81, 765.13, 622.93, 498.09, 474.89, 386.9, 378.48, 336.17,
1480 322.04, 329.57, 350.5, 383.38, 420.02, 462.39, 499.71, 531.98,
1481 654.99, 653.43, 639.99, 605.16, 554.16, 504.42, 540.64, 552.33,
1482 679.46, 699.51, 713.91, 832.17, 919.91, 884.96, 907.57, 846.56,
1483 818.56, 768.93, 706.71, 642.17, 575.95, 515.38, 459.07, 409.02,
1484 364.61, 325.46, 291.1, 260.89, 234.39, 211.01, 190.38, 172.11,
1485 155.91, 141.49, 128.63, 117.13, 106.84, 97.584, 89.262, 81.756,
1486 74.975, 68.842, 63.28, 58.232, 53.641, 49.46, 45.649, 42.168,
1487 38.991, 36.078, 33.409, 30.96, 28.71, 26.642, 24.737, 22.985,
1488 21.37, 19.882, 18.512, 17.242, 16.073, 14.987, 13.984, 13.05,
1489 12.186, 11.384, 10.637, 9.9436, 9.2988, 8.6991, 8.141, 7.6215,
1490 7.1378, 6.6872, 6.2671, 5.8754, 5.51, 5.1691, 4.851, 4.5539,
1491 4.2764, 4.0169, 3.7742, 3.5472, 3.3348, 3.1359, 2.9495, 2.7749,
1492 2.6113, 2.4578, 2.3139, 2.1789, 2.0523, 1.9334, 1.8219, 1.7171,
1493 1.6188, 1.5263, 1.4395, 1.3579, 1.2812, 1.209, 1.1411, 1.0773,
1494 1.0171, .96048, .90713, .85684, .80959, .76495, .72282, .68309,
1495 .64563, .61035, .57707, .54573, .51622, .48834, .46199, .43709,
1496 .41359, .39129, .37034, .35064, .33198, .31442, .29784, .28218,
1497 .26732, .25337, .24017, .22774, .21601, .20479, .19426
1498 };
1499
1500 static const double co2260[2001] =
1501 { 5.7971e-5, 6.0733e-5, 6.3628e-5, 6.6662e-5,
1502 6.9843e-5, 7.3176e-5, 7.6671e-5, 8.0334e-5, 8.4175e-5, 8.8201e-5,
1503 9.2421e-5, 9.6846e-5, 1.0149e-4, 1.0635e-4, 1.1145e-4, 1.1679e-4,
1504 1.224e-4, 1.2828e-4, 1.3444e-4, 1.409e-4, 1.4768e-4, 1.5479e-4,
1505 1.6224e-4, 1.7006e-4, 1.7826e-4, 1.8685e-4, 1.9587e-4, 2.0532e-4,
1506 2.1524e-4, 2.2565e-4, 2.3656e-4, 2.48e-4, 2.6001e-4, 2.7261e-4,
1507 2.8582e-4, 2.9968e-4, 3.1422e-4, 3.2948e-4, 3.4548e-4, 3.6228e-4,
1508 3.799e-4, 3.9838e-4, 4.1778e-4, 4.3814e-4, 4.595e-4, 4.8191e-4,
1509 5.0543e-4, 5.3012e-4, 5.5603e-4, 5.8321e-4, 6.1175e-4, 6.417e-4,
1510 6.7314e-4, 7.0614e-4, 7.4078e-4, 7.7714e-4, 8.1531e-4, 8.5538e-4,
1511 8.9745e-4, 9.4162e-4, 9.8798e-4, .0010367, .0010878, .0011415,
1512 .0011978, .001257, .0013191, .0013844, .001453, .0015249,
1513 .0016006, .00168, .0017634, .001851, .001943, .0020397, .0021412,
1514 .0022479, .00236, .0024778, .0026015, .0027316, .0028682,
1515 .0030117, .0031626, .0033211, .0034877, .0036628, .0038469,
1516 .0040403, .0042436, .0044574, .004682, .0049182, .0051665,
1517 .0054276, .0057021, .0059907, .0062942, .0066133, .0069489,
1518 .0073018, .0076729, .0080632, .0084738, .0089056, .0093599,
1519 .0098377, .01034, .010869, .011426, .012011, .012627, .013276,
1520 .013958, .014676, .015431, .016226, .017063, .017944, .018872,
1521 .019848, .020876, .021958, .023098, .024298, .025561, .026892,
1522 .028293, .029769, .031323, .032961, .034686, .036503, .038418,
1523 .040435, .042561, .044801, .047161, .049649, .052271, .055035,
1524 .057948, .061019, .064256, .06767, .07127, .075066, .079069,
1525 .083291, .087744, .092441, .097396, .10262, .10814, .11396,
1526 .1201, .12658, .13342, .14064, .14826, .1563, .1648, .17376,
1527 .18323, .19324, .2038, .21496, .22674, .23919, .25234, .26624,
1528 .28093, .29646, .31287, .33021, .34855, .36794, .38844, .41012,
1529 .43305, .45731, .48297, .51011, .53884, .56924, .60141, .63547,
1530 .67152, .70969, .75012, .79292, .83826, .8863, .93718, .99111,
1531 1.0482, 1.1088, 1.173, 1.2411, 1.3133, 1.3898, 1.471, 1.5571,
1532 1.6485, 1.7455, 1.8485, 1.9577, 2.0737, 2.197, 2.3278, 2.4668,
1533 2.6145, 2.7715, 2.9383, 3.1156, 3.3042, 3.5047, 3.7181, 3.9451,
1534 4.1866, 4.4437, 4.7174, 5.0089, 5.3192, 5.65, 6.0025, 6.3782,
1535 6.7787, 7.206, 7.6617, 8.1479, 8.6669, 9.221, 9.8128, 10.445,
1536 11.12, 11.843, 12.615, 13.441, 14.325, 15.271, 16.283, 17.367,
1537 18.529, 19.776, 21.111, 22.544, 24.082, 25.731, 27.504, 29.409,
1538 31.452, 33.654, 36.024, 38.573, 41.323, 44.29, 47.492, 50.951,
1539 54.608, 58.588, 62.929, 67.629, 72.712, 78.226, 84.207, 90.699,
1540 97.749, 105.42, 113.77, 122.86, 132.78, 143.61, 155.44, 168.33,
1541 182.48, 198.01, 214.87, 233.39, 253.86, 276.34, 300.3, 327.28,
1542 356.89, 389.48, 422.29, 458.99, 501.39, 548.13, 595.62, 652.74,
1543 716.54, 784.57, 866.78, 960.59, 1062.8, 1072.5, 1189.5, 1319.4,
1544 1467.6, 1630.2, 1813.7, 2016.9, 2253., 2515.3, 2773.5, 3092.8,
1545 3444.4, 3720.4, 4104.3, 4527.5, 4645.9, 5021.7, 5462.2, 5597.,
1546 6110.6, 6732.5, 7513.8, 8270.6, 9640.6, 11487., 2796.1, 2680.1,
1547 2441.6, 2404.2, 2334.8, 2215.2, 1642.5, 1477.9, 1328.1, 1223.5,
1548 843.34, 766.96, 831.65, 834.84, 774.85, 1156.3, 1275.6, 1366.1,
1549 1795.6, 1885., 1936.5, 1953.4, 2154.4, 2002.7, 1789.8, 10381.,
1550 9040., 8216.5, 7384.7, 6721.9, 6187.7, 6143.8, 5703.9, 5276.6,
1551 4873.1, 4736., 4325.3, 3927., 3554.1, 3286.1, 2950.1, 2642.4,
1552 2368.7, 2138.9, 1914., 1719.6, 1543.9, 1388.6, 1252.1, 1132.2,
1553 1024.1, 1025.4, 920.58, 829.59, 750.54, 685.01, 624.25, 570.14,
1554 525.81, 481.85, 441.95, 408.71, 377.23, 345.86, 318.51, 292.26,
1555 268.34, 247.04, 227.14, 209.02, 192.69, 177.59, 163.78, 151.26,
1556 139.73, 129.19, 119.53, 110.7, 102.57, 95.109, 88.264, 81.948,
1557 76.13, 70.768, 65.827, 61.251, 57.022, 53.495, 49.824, 46.443,
1558 43.307, 40.405, 37.716, 35.241, 32.923, 30.77, 28.78, 26.915,
1559 25.177, 23.56, 22.059, 20.654, 19.345, 18.126, 16.988, 15.93,
1560 14.939, 14.014, 13.149, 12.343, 11.589, 10.884, 10.225, 9.6093,
1561 9.0327, 8.4934, 7.9889, 7.5166, 7.0744, 6.6604, 6.2727, 5.9098,
1562 5.5701, 5.2529, 4.955, 4.676, 4.4148, 4.171, 3.9426, 3.7332,
1563 3.5347, 3.3493, 3.1677, 3.0025, 2.8466, 2.6994, 2.5601, 2.4277,
1564 2.3016, 2.1814, 2.0664, 1.9564, 1.8279, 1.7311, 1.6427, 1.5645,
1565 1.4982, 1.443, 1.374, 1.3146, 1.2562, 1.17, 1.1105, 1.0272,
1566 .96863, .89718, .83654, .80226, .75908, .72431, .69573, .67174,
1567 .65126, .63315, .61693, .60182, .58715, .59554, .57649, .55526,
1568 .53177, .50622, .48176, .4813, .47642, .47492, .50273, .50293,
1569 .52687, .52239, .53419, .53814, .52626, .52211, .51492, .50622,
1570 .49746, .48841, .4792, .43534, .41999, .40349, .38586, .36799,
1571 .35108, .31089, .30803, .3171, .33599, .35041, .36149, .32924,
1572 .32462, .27309, .25961, .20922, .19504, .15683, .13098, .11588,
1573 .11478, .11204, .11363, .12135, .16423, .17785, .19094, .20236,
1574 .21084, .2154, .24108, .22848, .20871, .18797, .17963, .17834,
1575 .21552, .22284, .26945, .27052, .30108, .28977, .29772, .29224,
1576 .27658, .24956, .22777, .20654, .18392, .16338, .1452, .12916,
1577 .1152, .10304, .092437, .083163, .075031, .067878, .061564,
1578 .055976, .051018, .046609, .042679, .03917, .036032, .033223,
1579 .030706, .02845, .026428, .024617, .022998, .021554, .02027,
1580 .019136, .018141, .017278, .016541, .015926, .015432, .015058,
1581 .014807, .014666, .014635, .014728, .014947, .01527, .015728,
1582 .016345, .017026, .017798, .018839, .019752, .020636, .021886,
1583 .022695, .02327, .023478, .024292, .023544, .022222, .021932,
1584 .020052, .018143, .017722, .017031, .017782, .01938, .020734,
1585 .020476, .019255, .017477, .016878, .014617, .012489, .011765,
1586 .0099077, .0086446, .0079446, .0078644, .0079763, .008671,
1587 .01001, .0108, .012933, .015349, .016341, .018484, .020254,
1588 .020254, .020478, .019591, .018595, .018385, .019913, .022254,
1589 .024847, .025809, .028053, .029924, .030212, .031367, .03222,
1590 .032739, .032537, .03286, .033344, .033507, .033499, .033339,
1591 .032809, .033041, .031723, .029837, .027511, .026603, .024032,
1592 .021914, .020948, .021701, .023425, .024259, .024987, .023818,
1593 .021768, .019223, .018144, .015282, .012604, .01163, .0097907,
1594 .008336, .0082473, .0079582, .0088077, .009779, .010129, .012145,
1595 .014378, .016761, .01726, .018997, .019998, .019809, .01819,
1596 .016358, .016099, .01617, .017939, .020223, .022521, .02277,
1597 .024279, .025247, .024222, .023989, .023224, .021493, .020362,
1598 .018596, .017309, .015975, .014466, .013171, .011921, .01078,
1599 .0097229, .0087612, .0078729, .0070682, .0063494, .0057156,
1600 .0051459, .0046273, .0041712, .0037686, .0034119, .003095,
1601 .0028126, .0025603, .0023342, .0021314, .0019489, .0017845,
1602 .001636, .0015017, .00138, .0012697, .0011694, .0010782,
1603 9.9507e-4, 9.1931e-4, 8.5013e-4, 7.869e-4, 7.2907e-4, 6.7611e-4,
1604 6.2758e-4, 5.8308e-4, 5.4223e-4, 5.0473e-4, 4.7027e-4, 4.3859e-4,
1605 4.0946e-4, 3.8265e-4, 3.5798e-4, 3.3526e-4, 3.1436e-4, 2.9511e-4,
1606 2.7739e-4, 2.6109e-4, 2.4609e-4, 2.3229e-4, 2.1961e-4, 2.0797e-4,
1607 1.9729e-4, 1.875e-4, 1.7855e-4, 1.7038e-4, 1.6294e-4, 1.5619e-4,
1608 1.5007e-4, 1.4456e-4, 1.3961e-4, 1.3521e-4, 1.3131e-4, 1.2789e-4,
1609 1.2494e-4, 1.2242e-4, 1.2032e-4, 1.1863e-4, 1.1733e-4, 1.1641e-4,
1610 1.1585e-4, 1.1565e-4, 1.158e-4, 1.1629e-4, 1.1712e-4, 1.1827e-4,
1611 1.1976e-4, 1.2158e-4, 1.2373e-4, 1.262e-4, 1.2901e-4, 1.3214e-4,
1612 1.3562e-4, 1.3944e-4, 1.4361e-4, 1.4814e-4, 1.5303e-4, 1.5829e-4,
1613 1.6394e-4, 1.6999e-4, 1.7644e-4, 1.8332e-4, 1.9063e-4, 1.984e-4,
1614 2.0663e-4, 2.1536e-4, 2.246e-4, 2.3436e-4, 2.4468e-4, 2.5558e-4,
1615 2.6708e-4, 2.7921e-4, 2.92e-4, 3.0548e-4, 3.1968e-4, 3.3464e-4,
1616 3.5039e-4, 3.6698e-4, 3.8443e-4, 4.0281e-4, 4.2214e-4, 4.4248e-4,
1617 4.6389e-4, 4.864e-4, 5.1009e-4, 5.3501e-4, 5.6123e-4, 5.888e-4,
1618 6.1781e-4, 6.4833e-4, 6.8043e-4, 7.142e-4, 7.4973e-4, 7.8711e-4,
1619 8.2644e-4, 8.6783e-4, 9.1137e-4, 9.5721e-4, .0010054, .0010562,
1620 .0011096, .0011659, .0012251, .0012875, .0013532, .0014224,
1621 .0014953, .001572, .0016529, .0017381, .0018279, .0019226,
1622 .0020224, .0021277, .0022386, .0023557, .0024792, .0026095,
1623 .002747, .0028921, .0030453, .0032071, .003378, .0035586,
1624 .0037494, .003951, .0041642, .0043897, .0046282, .0048805,
1625 .0051476, .0054304, .00573, .0060473, .0063837, .0067404,
1626 .0071188, .0075203, .0079466, .0083994, .0088806, .0093922,
1627 .0099366, .010516, .011134, .011792, .012494, .013244, .014046,
1628 .014898, .015808, .016781, .017822, .018929, .020108, .02138,
1629 .022729, .02419, .02576, .027412, .029233, .031198, .033301,
1630 .035594, .038092, .040767, .04372, .046918, .050246, .053974,
1631 .058009, .061976, .066586, .071537, .076209, .081856, .087998,
1632 .093821, .10113, .10913, .11731, .12724, .13821, .15025, .1639,
1633 .17807, .19472, .21356, .23496, .25758, .28387, .31389, .34104,
1634 .37469, .40989, .43309, .46845, .5042, .5023, .52981, .55275,
1635 .51075, .51976, .52457, .44779, .44721, .4503, .4243, .45244,
1636 .49491, .55399, .39021, .24802, .2501, .2618, .27475, .28879,
1637 .31317, .33643, .36257, .4018, .43275, .46525, .53333, .56599,
1638 .60557, .70142, .74194, .77736, .88567, .91182, .93294, .98407,
1639 .98772, .99176, .9995, 1.2405, 1.3602, 1.338, 1.3255, 1.3267,
1640 1.3404, 1.3634, 1.3967, 1.4407, 1.4961, 1.5603, 1.6328, 1.7153,
1641 1.8094, 1.9091, 2.018, 2.1367, 2.264, 2.4035, 2.5562, 2.7179,
1642 2.9017, 3.1052, 3.3304, 3.5731, 3.8488, 4.1553, 4.4769, 4.7818,
1643 5.1711, 5.5204, 5.9516, 6.4097, 6.8899, 7.1118, 7.5469, 7.9735,
1644 7.9511, 8.3014, 8.6418, 8.4757, 8.8256, 9.2294, 9.6923, 10.033,
1645 10.842, 11.851, 11.78, 8.8435, 9.1381, 9.5956, 10.076, 10.629,
1646 11.22, 11.883, 12.69, 13.163, 13.974, 14.846, 16.027, 17.053,
1647 18.148, 19.715, 20.907, 22.163, 23.956, 25.235, 26.566, 27.94,
1648 29.576, 30.956, 32.432, 35.337, 39.911, 41.128, 42.625, 44.386,
1649 46.369, 48.619, 51.031, 53.674, 56.825, 59.921, 63.286, 66.929,
1650 70.859, 75.081, 79.618, 84.513, 89.739, 95.335, 101.35, 107.76,
1651 114.63, 121.98, 129.87, 138.3, 147.34, 157.04, 167.56, 178.67,
1652 190.61, 203.43, 217.19, 231.99, 247.88, 264.98, 283.37, 303.17,
1653 324.49, 347.47, 372.25, 398.98, 427.85, 459.06, 492.8, 529.31,
1654 568.89, 611.79, 658.35, 708.91, 763.87, 823.65, 888.72, 959.58,
1655 1036.8, 1121.8, 1213.9, 1314.3, 1423.8, 1543., 1672.8, 1813.4,
1656 1966.1, 2131.4, 2309.5, 2499.3, 2705., 2925.7, 3161.6, 3411.3,
1657 3611.5, 3889.2, 4191.1, 4519.3, 4877.9, 5272.9, 5712.9, 6142.7,
1658 6719.6, 7385., 8145., 8977.7, 9831.9, 10827., 11934., 13063.,
1659 14434., 15878., 17591., 19435., 21510., 23835., 26835., 29740.,
1660 32878., 36305., 39830., 43273., 46931., 50499., 49586., 51598.,
1661 53429., 54619., 55081., 55102., 54485., 53487., 52042., 42689.,
1662 42607., 44020., 47994., 54169., 53916., 55808., 56642., 46049.,
1663 44243., 32929., 30658., 21963., 20835., 15962., 13679., 17652.,
1664 19680., 22388., 25625., 29184., 32520., 35720., 38414., 40523.,
1665 49228., 48173., 45678., 41768., 37600., 41313., 42654., 44465.,
1666 55736., 56630., 65409., 63308., 66572., 61845., 60379., 56777.,
1667 51920., 46601., 41367., 36529., 32219., 28470., 25192., 22362.,
1668 19907., 17772., 15907., 14273., 12835., 11567., 10445., 9450.2,
1669 8565.1, 7776., 7070.8, 6439.2, 5872.3, 5362.4, 4903., 4488.3,
1670 4113.4, 3773.8, 3465.8, 3186.1, 2931.7, 2700.1, 2488.8, 2296.,
1671 2119.8, 1958.6, 1810.9, 1675.6, 1551.4, 1437.3, 1332.4, 1236.,
1672 1147.2, 1065.3, 989.86, 920.22, 855.91, 796.48, 741.53, 690.69,
1673 643.62, 600.02, 559.6, 522.13, 487.35, 455.06, 425.08, 397.21,
1674 371.3, 347.2, 324.78, 303.9, 284.46, 266.34, 249.45, 233.7,
1675 219.01, 205.3, 192.5, 180.55, 169.38, 158.95, 149.2, 140.07,
1676 131.54, 123.56, 116.09, 109.09, 102.54, 96.405, 90.655, 85.266,
1677 80.213, 75.475, 71.031, 66.861, 62.948, 59.275, 55.827, 52.587,
1678 49.544, 46.686, 43.998, 41.473, 39.099, 36.867, 34.768, 32.795,
1679 30.939, 29.192, 27.546, 25.998, 24.539, 23.164, 21.869, 20.65,
1680 19.501, 18.419, 17.399, 16.438, 15.532, 14.678, 13.874, 13.115,
1681 12.4, 11.726, 11.088, 10.488, 9.921, 9.3846, 8.8784, 8.3996,
1682 7.9469, 7.5197, 7.1174, 6.738, 6.379, 6.0409, 5.7213, 5.419,
1683 5.1327, 4.8611, 4.6046, 4.3617, 4.1316, 3.9138, 3.7077, 3.5125,
1684 3.3281, 3.1536, 2.9885, 2.8323, 2.6846, 2.5447, 2.4124, 2.2871,
1685 2.1686, 2.0564, 1.9501, 1.8495, 1.7543, 1.6641, 1.5787, 1.4978,
1686 1.4212, 1.3486, 1.2799, 1.2147, 1.1529, 1.0943, 1.0388, .98602,
1687 .93596, .8886, .84352, .80078, .76029, .722, .68585, .65161,
1688 .61901, .58808, .55854, .53044, .5039, .47853, .45459, .43173,
1689 .41008, .38965, .37021, .35186, .33444, .31797, .30234, .28758,
1690 .2736, .26036, .24764, .2357, .22431, .21342, .20295, .19288,
1691 .18334, .17444, .166, .15815, .15072, .14348, .13674, .13015,
1692 .12399, .11807, .11231, .10689, .10164, .096696, .091955,
1693 .087476, .083183, .079113, .075229, .071536, .068026, .064698,
1694 .06154, .058544, .055699, .052997, .050431, .047993, .045676,
1695 .043475, .041382, .039392, .037501, .035702, .033991, .032364,
1696 .030817, .029345, .027945, .026613, .025345, .024139, .022991,
1697 .021899, .02086, .019871, .018929, .018033, .01718, .016368,
1698 .015595, .014859, .014158, .013491, .012856, .012251, .011675,
1699 .011126, .010604, .010107, .0096331, .009182, .0087523, .0083431,
1700 .0079533, .0075821, .0072284, .0068915, .0065706, .0062649,
1701 .0059737, .0056963, .005432, .0051802, .0049404, .0047118,
1702 .0044941, .0042867, .0040891, .0039009, .0037216, .0035507,
1703 .003388, .0032329, .0030852, .0029445, .0028105, .0026829,
1704 .0025613, .0024455, .0023353, .0022303, .0021304, .0020353,
1705 .0019448, .0018587, .0017767, .0016988, .0016247, .0015543,
1706 .0014874, .0014238, .0013635, .0013062, .0012519, .0012005,
1707 .0011517, .0011057, .0010621, .001021, 9.8233e-4, 9.4589e-4,
1708 9.1167e-4, 8.7961e-4, 8.4964e-4, 8.2173e-4, 7.9582e-4, 7.7189e-4,
1709 7.499e-4, 7.2983e-4, 7.1167e-4, 6.9542e-4, 6.8108e-4, 6.6866e-4,
1710 6.5819e-4, 6.4971e-4, 6.4328e-4, 6.3895e-4, 6.3681e-4, 6.3697e-4,
1711 6.3956e-4, 6.4472e-4, 6.5266e-4, 6.6359e-4, 6.778e-4, 6.9563e-4,
1712 7.1749e-4, 7.4392e-4, 7.7556e-4, 8.1028e-4, 8.4994e-4, 8.8709e-4,
1713 9.3413e-4, 9.6953e-4, .0010202, .0010738, .0010976, .0011507,
1714 .0011686, .0012264, .001291, .0013346, .0014246, .0015293,
1715 .0016359, .0017824, .0019255, .0020854, .002247, .0024148,
1716 .0026199, .0027523, .0029704, .0030702, .0033047, .0035013,
1717 .0037576, .0040275, .0043089, .0046927, .0049307, .0053486,
1718 .0053809, .0056699, .0059325, .0055488, .005634, .0056392,
1719 .004946, .0048855, .0048208, .0044386, .0045498, .0046377,
1720 .0048939, .0052396, .0057324, .0060859, .0066906, .0071148,
1721 .0077224, .0082687, .008769, .0084471, .008572, .0087729,
1722 .008775, .0090742, .0080704, .0080288, .0085747, .0086087,
1723 .0086408, .0088752, .0089381, .0089757, .0093532, .0092824,
1724 .0092566, .0092645, .0092735, .009342, .0095806, .0097991,
1725 .010213, .010611, .011129, .011756, .013237, .01412, .015034,
1726 .015936, .01682, .018597, .019315, .019995, .020658, .021289,
1727 .022363, .022996, .023716, .024512, .025434, .026067, .027118,
1728 .028396, .029865, .031442, .033253, .03525, .037296, .039701,
1729 .042356, .045154, .048059, .051294, .054893, .058636, .061407,
1730 .065172, .068974, .072676, .073379, .076547, .079556, .079134,
1731 .082308, .085739, .090192, .09359, .099599, .10669, .11496,
1732 .1244, .13512, .14752, .14494, .15647, .1668, .17863, .19029,
1733 .20124, .20254, .21179, .21982, .21625, .22364, .23405, .23382,
1734 .2434, .25708, .26406, .27621, .28909, .30395, .31717, .33271,
1735 .3496, .36765, .38774, .40949, .446, .46985, .49846, .5287, .562,
1736 .59841, .64598, .68834, .7327, .78978, .8373, .88708, .94744,
1737 1.0006, 1.0574, 1.1215, 1.1856, 1.2546, 1.3292, 1.4107, 1.4974,
1738 1.5913, 1.6931, 1.8028, 1.9212, 2.0492, 2.1874, 2.3365, 2.4978,
1739 2.6718, 2.8588, 3.062, 3.2818, 3.5188, 3.7752, 4.0527, 4.3542,
1740 4.6782, 5.0312, 5.4123, 5.8246, 6.2639, 6.7435, 7.2636, 7.8064,
1741 8.4091, 9.0696, 9.7677, 10.548, 11.4, 12.309, 13.324, 14.284,
1742 15.445, 16.687, 18.019, 19.403, 20.847, 22.366, 23.925, 25.537,
1743 27.213, 28.069, 29.864, 31.829, 33.988, 35.856, 38.829, 42.321,
1744 46.319, 50.606, 55.126, 59.126, 64.162, 68.708, 74.615, 81.176,
1745 87.739, 95.494, 103.83, 113.38, 123.99, 135.8, 148.7, 162.58,
1746 176.32, 192.6, 211.47, 232.7, 252.64, 277.41, 305.38, 333.44,
1747 366.42, 402.66, 442.14, 484.53, 526.42, 568.15, 558.78, 582.6,
1748 600.98, 613.94, 619.44, 618.24, 609.84, 595.96, 484.86, 475.59,
1749 478.49, 501.56, 552.19, 628.44, 630.39, 658.92, 671.96, 562.7,
1750 545.88, 423.43, 400.14, 306.59, 294.13, 246.8, 226.51, 278.21,
1751 314.39, 347.22, 389.13, 433.16, 477.48, 521.67, 560.54, 683.6,
1752 696.37, 695.91, 683.1, 658.24, 634.89, 698.85, 742.87, 796.66,
1753 954.49, 1009.5, 1150.5, 1179.1, 1267.9, 1272.4, 1312.7, 1330.4,
1754 1331.6, 1315.8, 1308.3, 1293.3, 1274.6, 1249.5, 1213.2, 1172.1,
1755 1124.4, 930.33, 893.36, 871.27, 883.54, 940.76, 1036., 1025.6,
1756 1053.1, 914.51, 894.15, 865.03, 670.63, 508.41, 475.15, 370.85,
1757 361.06, 319.38, 312.75, 331.87, 367.13, 415., 467.94, 525.49,
1758 578.41, 624.66, 794.82, 796.97, 780.29, 736.49, 670.18, 603.75,
1759 659.67, 679.8, 857.12, 884.05, 900.65, 1046.1, 1141.9, 1083.,
1760 1089.2, 1e3, 947.08, 872.31, 787.91, 704.75, 624.93, 553.68,
1761 489.91, 434.21, 385.64, 343.3, 306.42, 274.18, 245.94, 221.11,
1762 199.23, 179.88, 162.73, 147.48, 133.88, 121.73, 110.86, 101.1,
1763 92.323, 84.417, 77.281, 70.831, 64.991, 59.694, 54.884, 50.509,
1764 46.526, 42.893, 39.58, 36.549, 33.776, 31.236, 28.907, 26.77,
1765 24.805, 23., 21.339, 19.81, 18.404, 17.105, 15.909, 14.801,
1766 13.778, 12.83, 11.954, 11.142, 10.389, 9.691, 9.0434, 8.4423,
1767 7.8842, 7.3657, 6.8838, 6.4357, 6.0189, 5.6308, 5.2696, 4.9332,
1768 4.6198, 4.3277, 4.0553, 3.8012, 3.5639, 3.3424, 3.1355, 2.9422,
1769 2.7614, 2.5924, 2.4343, 2.2864, 2.148, 2.0184, 1.8971, 1.7835,
1770 1.677, 1.5773, 1.4838, 1.3961, 1.3139, 1.2369, 1.1645, 1.0966,
1771 1.0329, .97309, .91686, .86406, .81439, .76767, .72381, .68252,
1772 .64359, .60695, .57247, .54008, .50957, .48092, .45401, .42862,
1773 .40465, .38202, .36072, .34052, .3216, .30386, .28711, .27135,
1774 .25651, .24252, .2293, .21689, .20517, .19416, .18381, .17396,
1775 .16469
1776 };
1777
1778 static const double co2230[2001] =
1779 { 2.743e-5, 2.8815e-5, 3.027e-5, 3.1798e-5,
1780 3.3405e-5, 3.5094e-5, 3.6869e-5, 3.8734e-5, 4.0694e-5, 4.2754e-5,
1781 4.492e-5, 4.7196e-5, 4.9588e-5, 5.2103e-5, 5.4747e-5, 5.7525e-5,
1782 6.0446e-5, 6.3516e-5, 6.6744e-5, 7.0137e-5, 7.3704e-5, 7.7455e-5,
1783 8.1397e-5, 8.5543e-5, 8.9901e-5, 9.4484e-5, 9.9302e-5, 1.0437e-4,
1784 1.097e-4, 1.153e-4, 1.2119e-4, 1.2738e-4, 1.3389e-4, 1.4074e-4,
1785 1.4795e-4, 1.5552e-4, 1.6349e-4, 1.7187e-4, 1.8068e-4, 1.8995e-4,
1786 1.997e-4, 2.0996e-4, 2.2075e-4, 2.321e-4, 2.4403e-4, 2.5659e-4,
1787 2.698e-4, 2.837e-4, 2.9832e-4, 3.137e-4, 3.2988e-4, 3.4691e-4,
1788 3.6483e-4, 3.8368e-4, 4.0351e-4, 4.2439e-4, 4.4635e-4, 4.6947e-4,
1789 4.9379e-4, 5.1939e-4, 5.4633e-4, 5.7468e-4, 6.0452e-4, 6.3593e-4,
1790 6.69e-4, 7.038e-4, 7.4043e-4, 7.79e-4, 8.1959e-4, 8.6233e-4,
1791 9.0732e-4, 9.5469e-4, .0010046, .0010571, .0011124, .0011706,
1792 .0012319, .0012964, .0013644, .001436, .0015114, .0015908,
1793 .0016745, .0017625, .0018553, .0019531, .002056, .0021645,
1794 .0022788, .0023992, .002526, .0026596, .0028004, .0029488,
1795 .0031052, .0032699, .0034436, .0036265, .0038194, .0040227,
1796 .0042369, .0044628, .0047008, .0049518, .0052164, .0054953,
1797 .0057894, .0060995, .0064265, .0067713, .007135, .0075184,
1798 .0079228, .0083494, .0087993, .0092738, .0097745, .010303,
1799 .01086, .011448, .012068, .012722, .013413, .014142, .014911,
1800 .015723, .01658, .017484, .018439, .019447, .020511, .021635,
1801 .022821, .024074, .025397, .026794, .02827, .029829, .031475,
1802 .033215, .035052, .036994, .039045, .041213, .043504, .045926,
1803 .048485, .05119, .05405, .057074, .060271, .063651, .067225,
1804 .071006, .075004, .079233, .083708, .088441, .093449, .098749,
1805 .10436, .11029, .11657, .12322, .13026, .13772, .14561, .15397,
1806 .16282, .1722, .18214, .19266, .20381, .21563, .22816, .24143,
1807 .2555, .27043, .28625, .30303, .32082, .3397, .35972, .38097,
1808 .40352, .42746, .45286, .47983, .50847, .53888, .57119, .6055,
1809 .64196, .6807, .72187, .76564, .81217, .86165, .91427, .97025,
1810 1.0298, 1.0932, 1.1606, 1.2324, 1.3088, 1.3902, 1.477, 1.5693,
1811 1.6678, 1.7727, 1.8845, 2.0038, 2.131, 2.2666, 2.4114, 2.5659,
1812 2.7309, 2.907, 3.0951, 3.2961, 3.5109, 3.7405, 3.986, 4.2485,
1813 4.5293, 4.8299, 5.1516, 5.4961, 5.8651, 6.2605, 6.6842, 7.1385,
1814 7.6256, 8.1481, 8.7089, 9.3109, 9.9573, 10.652, 11.398, 12.2,
1815 13.063, 13.992, 14.99, 16.064, 17.222, 18.469, 19.813, 21.263,
1816 22.828, 24.516, 26.34, 28.31, 30.437, 32.738, 35.226, 37.914,
1817 40.824, 43.974, 47.377, 51.061, 55.011, 59.299, 63.961, 69.013,
1818 74.492, 80.444, 86.919, 93.836, 101.23, 109.25, 117.98, 127.47,
1819 137.81, 149.07, 161.35, 174.75, 189.42, 205.49, 223.02, 242.26,
1820 263.45, 286.75, 311.94, 340.01, 370.86, 404.92, 440.44, 480.27,
1821 525.17, 574.71, 626.22, 686.8, 754.38, 827.07, 913.38, 1011.7,
1822 1121.5, 1161.6, 1289.5, 1432.2, 1595.4, 1777., 1983.3, 2216.1,
1823 2485.7, 2788.3, 3101.5, 3481., 3902.1, 4257.1, 4740., 5272.8,
1824 5457.9, 5946.2, 6505.3, 6668.4, 7302.4, 8061.6, 9015.8, 9908.3,
1825 11613., 13956., 3249.6, 3243., 2901.5, 2841.3, 2729.6, 2558.2,
1826 1797.8, 1583.2, 1386., 1233.5, 787.74, 701.46, 761.66, 767.21,
1827 722.83, 1180.6, 1332.1, 1461.6, 2032.9, 2166., 2255.9, 2294.7,
1828 2587.2, 2396.5, 2122.4, 12553., 10784., 9832.5, 8827.3, 8029.1,
1829 7377.9, 7347.1, 6783.8, 6239.1, 5721.1, 5503., 4975.1, 4477.8,
1830 4021.3, 3676.8, 3275.3, 2914.9, 2597.4, 2328.2, 2075.4, 1857.6,
1831 1663.6, 1493.3, 1343.8, 1213.3, 1095.6, 1066.5, 958.91, 865.15,
1832 783.31, 714.35, 650.77, 593.98, 546.2, 499.9, 457.87, 421.75,
1833 387.61, 355.25, 326.62, 299.7, 275.21, 253.17, 232.83, 214.31,
1834 197.5, 182.08, 167.98, 155.12, 143.32, 132.5, 122.58, 113.48,
1835 105.11, 97.415, 90.182, 83.463, 77.281, 71.587, 66.341, 61.493,
1836 57.014, 53.062, 49.21, 45.663, 42.38, 39.348, 36.547, 33.967,
1837 31.573, 29.357, 27.314, 25.415, 23.658, 22.03, 20.524, 19.125,
1838 17.829, 16.627, 15.511, 14.476, 13.514, 12.618, 11.786, 11.013,
1839 10.294, 9.6246, 9.0018, 8.4218, 7.8816, 7.3783, 6.9092, 6.4719,
1840 6.0641, 5.6838, 5.3289, 4.998, 4.6893, 4.4014, 4.1325, 3.8813,
1841 3.6469, 3.4283, 3.2241, 3.035, 2.8576, 2.6922, 2.5348, 2.3896,
1842 2.2535, 2.1258, 2.0059, 1.8929, 1.7862, 1.6854, 1.5898, 1.4992,
1843 1.4017, 1.3218, 1.2479, 1.1809, 1.1215, 1.0693, 1.0116, .96016,
1844 .9105, .84859, .80105, .74381, .69982, .65127, .60899, .57843,
1845 .54592, .51792, .49336, .47155, .45201, .43426, .41807, .40303,
1846 .38876, .3863, .37098, .35492, .33801, .32032, .30341, .29874,
1847 .29193, .28689, .29584, .29155, .29826, .29195, .29287, .2904,
1848 .28199, .27709, .27162, .26622, .26133, .25676, .25235, .23137,
1849 .22365, .21519, .20597, .19636, .18699, .16485, .16262, .16643,
1850 .17542, .18198, .18631, .16759, .16338, .13505, .1267, .10053,
1851 .092554, .074093, .062159, .055523, .054849, .05401, .05528,
1852 .058982, .07952, .08647, .093244, .099285, .10393, .10661,
1853 .12072, .11417, .10396, .093265, .089137, .088909, .10902,
1854 .11277, .13625, .13565, .14907, .14167, .1428, .13744, .12768,
1855 .11382, .10244, .091686, .08109, .071739, .063616, .056579,
1856 .050504, .045251, .040689, .036715, .033237, .030181, .027488,
1857 .025107, .022998, .021125, .01946, .017979, .016661, .015489,
1858 .014448, .013526, .012712, .011998, .011375, .010839, .010384,
1859 .010007, .0097053, .0094783, .0093257, .0092489, .0092504,
1860 .0093346, .0095077, .0097676, .01012, .01058, .011157, .011844,
1861 .012672, .013665, .014766, .015999, .017509, .018972, .020444,
1862 .022311, .023742, .0249, .025599, .026981, .026462, .025143,
1863 .025066, .022814, .020458, .020026, .019142, .020189, .022371,
1864 .024163, .023728, .02199, .019506, .018591, .015576, .012784,
1865 .011744, .0094777, .0079148, .0070652, .006986, .0071758,
1866 .008086, .0098025, .01087, .013609, .016764, .018137, .021061,
1867 .023498, .023576, .023965, .022828, .021519, .021283, .023364,
1868 .026457, .029782, .030856, .033486, .035515, .035543, .036558,
1869 .037198, .037472, .037045, .037284, .03777, .038085, .038366,
1870 .038526, .038282, .038915, .037697, .035667, .032941, .031959,
1871 .028692, .025918, .024596, .025592, .027873, .028935, .02984,
1872 .028148, .025305, .021912, .020454, .016732, .013357, .01205,
1873 .009731, .0079881, .0077704, .0074387, .0083895, .0096776,
1874 .010326, .01293, .015955, .019247, .020145, .02267, .024231,
1875 .024184, .022131, .019784, .01955, .01971, .022119, .025116,
1876 .027978, .028107, .029808, .030701, .029164, .028551, .027286,
1877 .024946, .023259, .020982, .019221, .017471, .015643, .014074,
1878 .01261, .011301, .010116, .0090582, .0081036, .0072542, .0065034,
1879 .0058436, .0052571, .0047321, .0042697, .0038607, .0034977,
1880 .0031747, .0028864, .0026284, .002397, .002189, .0020017,
1881 .0018326, .0016798, .0015414, .0014159, .0013019, .0011983,
1882 .0011039, .0010177, 9.391e-4, 8.6717e-4, 8.0131e-4, 7.4093e-4,
1883 6.8553e-4, 6.3464e-4, 5.8787e-4, 5.4487e-4, 5.0533e-4, 4.69e-4,
1884 4.3556e-4, 4.0474e-4, 3.7629e-4, 3.5e-4, 3.2569e-4, 3.032e-4,
1885 2.8239e-4, 2.6314e-4, 2.4535e-4, 2.2891e-4, 2.1374e-4, 1.9975e-4,
1886 1.8685e-4, 1.7498e-4, 1.6406e-4, 1.5401e-4, 1.4479e-4, 1.3633e-4,
1887 1.2858e-4, 1.2148e-4, 1.1499e-4, 1.0907e-4, 1.0369e-4, 9.8791e-5,
1888 9.4359e-5, 9.0359e-5, 8.6766e-5, 8.3555e-5, 8.0703e-5, 7.8192e-5,
1889 7.6003e-5, 7.4119e-5, 7.2528e-5, 7.1216e-5, 7.0171e-5, 6.9385e-5,
1890 6.8848e-5, 6.8554e-5, 6.8496e-5, 6.8669e-5, 6.9069e-5, 6.9694e-5,
1891 7.054e-5, 7.1608e-5, 7.2896e-5, 7.4406e-5, 7.6139e-5, 7.8097e-5,
1892 8.0283e-5, 8.2702e-5, 8.5357e-5, 8.8255e-5, 9.1402e-5, 9.4806e-5,
1893 9.8473e-5, 1.0241e-4, 1.0664e-4, 1.1115e-4, 1.1598e-4, 1.2112e-4,
1894 1.2659e-4, 1.3241e-4, 1.3859e-4, 1.4515e-4, 1.521e-4, 1.5947e-4,
1895 1.6728e-4, 1.7555e-4, 1.8429e-4, 1.9355e-4, 2.0334e-4, 2.1369e-4,
1896 2.2463e-4, 2.3619e-4, 2.4841e-4, 2.6132e-4, 2.7497e-4, 2.8938e-4,
1897 3.0462e-4, 3.2071e-4, 3.3771e-4, 3.5567e-4, 3.7465e-4, 3.947e-4,
1898 4.1588e-4, 4.3828e-4, 4.6194e-4, 4.8695e-4, 5.1338e-4, 5.4133e-4,
1899 5.7087e-4, 6.0211e-4, 6.3515e-4, 6.701e-4, 7.0706e-4, 7.4617e-4,
1900 7.8756e-4, 8.3136e-4, 8.7772e-4, 9.2681e-4, 9.788e-4, .0010339,
1901 .0010922, .001154, .0012195, .0012889, .0013626, .0014407,
1902 .0015235, .0016114, .0017048, .0018038, .001909, .0020207,
1903 .0021395, .0022657, .0023998, .0025426, .0026944, .002856,
1904 .0030281, .0032114, .0034068, .003615, .0038371, .004074,
1905 .004327, .0045971, .0048857, .0051942, .0055239, .0058766,
1906 .0062538, .0066573, .0070891, .007551, .0080455, .0085747,
1907 .0091412, .0097481, .010397, .011092, .011837, .012638, .013495,
1908 .014415, .01541, .016475, .017621, .018857, .020175, .02162,
1909 .023185, .024876, .02672, .028732, .030916, .033319, .035939,
1910 .038736, .041847, .04524, .048715, .052678, .056977, .061203,
1911 .066184, .07164, .076952, .083477, .090674, .098049, .10697,
1912 .1169, .1277, .14011, .15323, .1684, .18601, .20626, .22831,
1913 .25417, .28407, .31405, .34957, .38823, .41923, .46026, .50409,
1914 .51227, .54805, .57976, .53818, .55056, .557, .46741, .46403,
1915 .4636, .42265, .45166, .49852, .56663, .34306, .17779, .17697,
1916 .18346, .19129, .20014, .21778, .23604, .25649, .28676, .31238,
1917 .33856, .39998, .4288, .46568, .56654, .60786, .64473, .76466,
1918 .7897, .80778, .86443, .85736, .84798, .84157, 1.1385, 1.2446,
1919 1.1923, 1.1552, 1.1338, 1.1266, 1.1292, 1.1431, 1.1683, 1.2059,
1920 1.2521, 1.3069, 1.3712, 1.4471, 1.5275, 1.6165, 1.7145, 1.8189,
1921 1.9359, 2.065, 2.2007, 2.3591, 2.5362, 2.7346, 2.9515, 3.2021,
1922 3.4851, 3.7935, 4.0694, 4.4463, 4.807, 5.2443, 5.7178, 6.2231,
1923 6.4796, 6.9461, 7.4099, 7.3652, 7.7182, 8.048, 7.7373, 8.0363,
1924 8.3855, 8.8044, 9.0257, 9.8574, 10.948, 10.563, 6.8979, 7.0744,
1925 7.4121, 7.7663, 8.1768, 8.6243, 9.1437, 9.7847, 10.182, 10.849,
1926 11.572, 12.602, 13.482, 14.431, 15.907, 16.983, 18.11, 19.884,
1927 21.02, 22.18, 23.355, 24.848, 25.954, 27.13, 30.186, 34.893,
1928 35.682, 36.755, 38.111, 39.703, 41.58, 43.606, 45.868, 48.573,
1929 51.298, 54.291, 57.559, 61.116, 64.964, 69.124, 73.628, 78.471,
1930 83.683, 89.307, 95.341, 101.84, 108.83, 116.36, 124.46, 133.18,
1931 142.57, 152.79, 163.69, 175.43, 188.11, 201.79, 216.55, 232.51,
1932 249.74, 268.38, 288.54, 310.35, 333.97, 359.55, 387.26, 417.3,
1933 449.88, 485.2, 523.54, 565.14, 610.28, 659.31, 712.56, 770.43,
1934 833.36, 901.82, 976.36, 1057.6, 1146.8, 1243.8, 1350., 1466.3,
1935 1593.6, 1732.7, 1884.1, 2049.1, 2228.2, 2421.9, 2629.4, 2853.7,
1936 3094.4, 3351.1, 3622.3, 3829.8, 4123.1, 4438.3, 4777.2, 5144.1,
1937 5545.4, 5990.5, 6404.5, 6996.8, 7687.6, 8482.9, 9349.4, 10203.,
1938 11223., 12358., 13493., 14916., 16416., 18236., 20222., 22501.,
1939 25102., 28358., 31707., 35404., 39538., 43911., 48391., 53193.,
1940 58028., 58082., 61276., 64193., 66294., 67480., 67921., 67423.,
1941 66254., 64341., 51737., 51420., 53072., 58145., 66195., 65358.,
1942 67377., 67869., 53509., 50553., 35737., 32425., 21704., 19974.,
1943 14457., 12142., 16798., 19489., 23049., 27270., 31910., 36457.,
1944 40877., 44748., 47876., 59793., 58626., 55454., 50337., 44893.,
1945 50228., 52216., 54747., 69541., 70455., 81014., 77694., 80533.,
1946 73953., 70927., 65539., 59002., 52281., 45953., 40292., 35360.,
1947 31124., 27478., 24346., 21647., 19308., 17271., 15491., 13927.,
1948 12550., 11331., 10250., 9288.8, 8431.4, 7664.9, 6978.3, 6361.8,
1949 5807.4, 5307.7, 4856.8, 4449., 4079.8, 3744.9, 3440.8, 3164.2,
1950 2912.3, 2682.7, 2473., 2281.4, 2106., 1945.3, 1797.9, 1662.5,
1951 1538.1, 1423.6, 1318.1, 1221., 1131.5, 1049., 972.99, 902.87,
1952 838.01, 777.95, 722.2, 670.44, 622.35, 577.68, 536.21, 497.76,
1953 462.12, 429.13, 398.61, 370.39, 344.29, 320.16, 297.85, 277.2,
1954 258.08, 240.38, 223.97, 208.77, 194.66, 181.58, 169.43, 158.15,
1955 147.67, 137.92, 128.86, 120.44, 112.6, 105.3, 98.499, 92.166,
1956 86.264, 80.763, 75.632, 70.846, 66.381, 62.213, 58.321, 54.685,
1957 51.288, 48.114, 45.145, 42.368, 39.772, 37.341, 35.065, 32.937,
1958 30.943, 29.077, 27.33, 25.693, 24.158, 22.717, 21.367, 20.099,
1959 18.909, 17.792, 16.744, 15.761, 14.838, 13.971, 13.157, 12.393,
1960 11.676, 11.003, 10.369, 9.775, 9.2165, 8.6902, 8.1963, 7.7314,
1961 7.2923, 6.8794, 6.4898, 6.122, 5.7764, 5.4525, 5.1484, 4.8611,
1962 4.5918, 4.3379, 4.0982, 3.8716, 3.6567, 3.4545, 3.2634, 3.0828,
1963 2.9122, 2.7512, 2.5993, 2.4561, 2.3211, 2.1938, 2.0737, 1.9603,
1964 1.8534, 1.7525, 1.6572, 1.5673, 1.4824, 1.4022, 1.3265, 1.2551,
1965 1.1876, 1.1239, 1.0637, 1.0069, .9532, .90248, .85454, .80921,
1966 .76631, .72569, .6872, .65072, .61635, .5836, .55261, .52336,
1967 .49581, .46998, .44559, .42236, .40036, .37929, .35924, .34043,
1968 .32238, .30547, .28931, .27405, .25975, .24616, .23341, .22133,
1969 .20997, .19924, .18917, .17967, .17075, .16211, .15411, .14646,
1970 .13912, .13201, .12509, .11857, .11261, .10698, .10186, .097039,
1971 .092236, .087844, .083443, .07938, .075452, .071564, .067931,
1972 .064389, .061078, .057901, .054921, .052061, .049364, .046789,
1973 .04435, .042044, .039866, .037808, .035863, .034023, .032282,
1974 .030634, .029073, .027595, .026194, .024866, .023608, .022415,
1975 .021283, .02021, .019193, .018228, .017312, .016443, .015619,
1976 .014837, .014094, .01339, .012721, .012086, .011483, .010911,
1977 .010368, .009852, .0093623, .0088972, .0084556, .0080362,
1978 .0076379, .0072596, .0069003, .006559, .0062349, .0059269,
1979 .0056344, .0053565, .0050925, .0048417, .0046034, .004377,
1980 .0041618, .0039575, .0037633, .0035788, .0034034, .0032368,
1981 .0030785, .002928, .0027851, .0026492, .0025201, .0023975,
1982 .0022809, .0021701, .0020649, .0019649, .0018699, .0017796,
1983 .0016938, .0016122, .0015348, .0014612, .0013913, .001325,
1984 .0012619, .0012021, .0011452, .0010913, .0010401, 9.9149e-4,
1985 9.454e-4, 9.0169e-4, 8.6024e-4, 8.2097e-4, 7.8377e-4, 7.4854e-4,
1986 7.1522e-4, 6.8371e-4, 6.5393e-4, 6.2582e-4, 5.9932e-4, 5.7435e-4,
1987 5.5087e-4, 5.2882e-4, 5.0814e-4, 4.8881e-4, 4.7076e-4, 4.5398e-4,
1988 4.3843e-4, 4.2407e-4, 4.109e-4, 3.9888e-4, 3.88e-4, 3.7826e-4,
1989 3.6963e-4, 3.6213e-4, 3.5575e-4, 3.505e-4, 3.464e-4, 3.4346e-4,
1990 3.4173e-4, 3.4125e-4, 3.4206e-4, 3.4424e-4, 3.4787e-4, 3.5303e-4,
1991 3.5986e-4, 3.6847e-4, 3.7903e-4, 3.9174e-4, 4.0681e-4, 4.2455e-4,
1992 4.4527e-4, 4.6942e-4, 4.9637e-4, 5.2698e-4, 5.5808e-4, 5.9514e-4,
1993 6.2757e-4, 6.689e-4, 7.1298e-4, 7.3955e-4, 7.8403e-4, 8.0449e-4,
1994 8.5131e-4, 9.0256e-4, 9.3692e-4, .0010051, .0010846, .0011678,
1995 .001282, .0014016, .0015355, .0016764, .0018272, .0020055,
1996 .0021455, .0023421, .0024615, .0026786, .0028787, .0031259,
1997 .0034046, .0036985, .0040917, .0043902, .0048349, .0049531,
1998 .0052989, .0056148, .0052452, .0053357, .005333, .0045069,
1999 .0043851, .004253, .003738, .0038084, .0039013, .0041505,
2000 .0045372, .0050569, .0054507, .0061267, .0066122, .0072449,
2001 .0078012, .0082651, .0076538, .0076573, .0076806, .0075227,
2002 .0076269, .0063758, .006254, .0067749, .0067909, .0068231,
2003 .0072143, .0072762, .0072954, .007679, .0075107, .0073658,
2004 .0072441, .0071074, .0070378, .007176, .0072472, .0075844,
2005 .0079291, .008412, .0090165, .010688, .011535, .012375, .013166,
2006 .013895, .015567, .016011, .016392, .016737, .017043, .017731,
2007 .018031, .018419, .018877, .019474, .019868, .020604, .021538,
2008 .022653, .023869, .025288, .026879, .028547, .030524, .03274,
2009 .035132, .03769, .040567, .043793, .047188, .049962, .053542,
2010 .057205, .060776, .061489, .064419, .067124, .065945, .068487,
2011 .071209, .074783, .077039, .082444, .08902, .09692, .10617,
2012 .11687, .12952, .12362, .13498, .14412, .15492, .16519, .1744,
2013 .17096, .17714, .18208, .17363, .17813, .18564, .18295, .19045,
2014 .20252, .20815, .21844, .22929, .24229, .25321, .26588, .2797,
2015 .29465, .31136, .32961, .36529, .38486, .41027, .43694, .4667,
2016 .49943, .54542, .58348, .62303, .67633, .71755, .76054, .81371,
2017 .85934, .90841, .96438, 1.0207, 1.0821, 1.1491, 1.2226, 1.3018,
2018 1.388, 1.4818, 1.5835, 1.6939, 1.8137, 1.9435, 2.0843, 2.237,
2019 2.4026, 2.5818, 2.7767, 2.9885, 3.2182, 3.4679, 3.7391, 4.0349,
2020 4.3554, 4.7053, 5.0849, 5.4986, 5.9436, 6.4294, 6.9598, 7.5203,
2021 8.143, 8.8253, 9.5568, 10.371, 11.267, 12.233, 13.31, 14.357,
2022 15.598, 16.93, 18.358, 19.849, 21.408, 23.04, 24.706, 26.409,
2023 28.153, 28.795, 30.549, 32.43, 34.49, 36.027, 38.955, 42.465,
2024 46.565, 50.875, 55.378, 59.002, 63.882, 67.949, 73.693, 80.095,
2025 86.403, 94.264, 102.65, 112.37, 123.3, 135.54, 149.14, 163.83,
2026 179.17, 196.89, 217.91, 240.94, 264.13, 292.39, 324.83, 358.21,
2027 397.16, 440.5, 488.6, 541.04, 595.3, 650.43, 652.03, 688.74,
2028 719.47, 743.54, 757.68, 762.35, 756.43, 741.42, 595.43, 580.97,
2029 580.83, 605.68, 667.88, 764.49, 759.93, 789.12, 798.17, 645.66,
2030 615.65, 455.05, 421.09, 306.45, 289.14, 235.7, 215.52, 274.57,
2031 316.53, 357.73, 409.89, 465.06, 521.84, 579.02, 630.64, 794.46,
2032 813., 813.56, 796.25, 761.57, 727.97, 812.14, 866.75, 932.5,
2033 1132.8, 1194.8, 1362.2, 1387.2, 1482.3, 1479.7, 1517.9, 1533.1,
2034 1534.2, 1523.3, 1522.5, 1515.5, 1505.2, 1486.5, 1454., 1412.,
2035 1358.8, 1107.8, 1060.9, 1033.5, 1048.2, 1122.4, 1248.9, 1227.1,
2036 1255.4, 1058.9, 1020.7, 970.59, 715.24, 512.56, 468.47, 349.3,
2037 338.26, 299.22, 301.26, 332.38, 382.08, 445.49, 515.87, 590.85,
2038 662.3, 726.05, 955.59, 964.11, 945.17, 891.48, 807.11, 720.9,
2039 803.36, 834.46, 1073.9, 1107.1, 1123.6, 1296., 1393.7, 1303.1,
2040 1284.3, 1161.8, 1078.8, 976.13, 868.72, 767.4, 674.72, 593.73,
2041 523.12, 462.24, 409.75, 364.34, 325., 290.73, 260.76, 234.46,
2042 211.28, 190.78, 172.61, 156.44, 142.01, 129.12, 117.57, 107.2,
2043 97.877, 89.47, 81.882, 75.021, 68.807, 63.171, 58.052, 53.396,
2044 49.155, 45.288, 41.759, 38.531, 35.576, 32.868, 30.384, 28.102,
2045 26.003, 24.071, 22.293, 20.655, 19.147, 17.756, 16.476, 15.292,
2046 14.198, 13.183, 12.241, 11.367, 10.554, 9.7989, 9.0978, 8.4475,
2047 7.845, 7.2868, 6.7704, 6.2927, 5.8508, 5.4421, 5.064, 4.714,
2048 4.3902, 4.0902, 3.8121, 3.5543, 3.315, 3.093, 2.8869, 2.6953,
2049 2.5172, 2.3517, 2.1977, 2.0544, 1.9211, 1.7969, 1.6812, 1.5735,
2050 1.4731, 1.3794, 1.2921, 1.2107, 1.1346, 1.0637, .99744, .93554,
2051 .87771, .82368, .77313, .72587, .6816, .64014, .60134, .565,
2052 .53086, .49883, .46881, .44074, .4144, .38979, .36679, .34513,
2053 .32474, .30552, .28751, .27045, .25458, .23976, .22584, .21278,
2054 .20051, .18899, .17815, .16801, .15846, .14954, .14117, .13328,
2055 .12584
2056 };
2057
2058 /* Get CO2 continuum absorption... */
2059 const double xw = nu / 2 + 1;
2060 if (xw >= 1 && xw < 2001) {
2061 const int iw = (int) xw;
2062 const double dw = xw - iw;
2063 const double ew = 1 - dw;
2064 const double cw296 = ew * co2296[iw - 1] + dw * co2296[iw];
2065 const double cw260 = ew * co2260[iw - 1] + dw * co2260[iw];
2066 const double cw230 = ew * co2230[iw - 1] + dw * co2230[iw];
2067 const double dt230 = t - 230;
2068 const double dt260 = t - 260;
2069 const double dt296 = t - 296;
2070 const double ctw =
2071 dt260 * 5.050505e-4 * dt296 * cw230 -
2072 dt230 * 9.259259e-4 * dt296 * cw260 +
2073 dt230 * 4.208754e-4 * dt260 * cw296;
2074 return u / NA / 1000 * p / P0 * ctw;
2075 } else
2076 return 0;
2077}
#define P0
Standard pressure [hPa].
Definition: jurassic.h:184
#define NA
Avogadro's number.
Definition: jurassic.h:169

◆ ctmh2o()

double ctmh2o ( const double  nu,
const double  p,
const double  t,
const double  q,
const double  u 
)

Compute water vapor continuum (optical depth).

Author
Lars Hoffmann

Definition at line 2081 of file jurassic.c.

2086 {
2087
2088 static const double h2o296[2001] =
2089 { .17, .1695, .172, .168, .1687, .1624, .1606,
2090 .1508, .1447, .1344, .1214, .1133, .1009, .09217, .08297, .06989,
2091 .06513, .05469, .05056, .04417, .03779, .03484, .02994, .0272,
2092 .02325, .02063, .01818, .01592, .01405, .01251, .0108, .009647,
2093 .008424, .007519, .006555, .00588, .005136, .004511, .003989,
2094 .003509, .003114, .00274, .002446, .002144, .001895, .001676,
2095 .001486, .001312, .001164, .001031, 9.129e-4, 8.106e-4, 7.213e-4,
2096 6.4e-4, 5.687e-4, 5.063e-4, 4.511e-4, 4.029e-4, 3.596e-4,
2097 3.22e-4, 2.889e-4, 2.597e-4, 2.337e-4, 2.108e-4, 1.907e-4,
2098 1.728e-4, 1.57e-4, 1.43e-4, 1.305e-4, 1.195e-4, 1.097e-4,
2099 1.009e-4, 9.307e-5, 8.604e-5, 7.971e-5, 7.407e-5, 6.896e-5,
2100 6.433e-5, 6.013e-5, 5.631e-5, 5.283e-5, 4.963e-5, 4.669e-5,
2101 4.398e-5, 4.148e-5, 3.917e-5, 3.702e-5, 3.502e-5, 3.316e-5,
2102 3.142e-5, 2.978e-5, 2.825e-5, 2.681e-5, 2.546e-5, 2.419e-5,
2103 2.299e-5, 2.186e-5, 2.079e-5, 1.979e-5, 1.884e-5, 1.795e-5,
2104 1.711e-5, 1.633e-5, 1.559e-5, 1.49e-5, 1.426e-5, 1.367e-5,
2105 1.312e-5, 1.263e-5, 1.218e-5, 1.178e-5, 1.143e-5, 1.112e-5,
2106 1.088e-5, 1.07e-5, 1.057e-5, 1.05e-5, 1.051e-5, 1.059e-5,
2107 1.076e-5, 1.1e-5, 1.133e-5, 1.18e-5, 1.237e-5, 1.308e-5,
2108 1.393e-5, 1.483e-5, 1.614e-5, 1.758e-5, 1.93e-5, 2.123e-5,
2109 2.346e-5, 2.647e-5, 2.93e-5, 3.279e-5, 3.745e-5, 4.152e-5,
2110 4.813e-5, 5.477e-5, 6.203e-5, 7.331e-5, 8.056e-5, 9.882e-5,
2111 1.05e-4, 1.21e-4, 1.341e-4, 1.572e-4, 1.698e-4, 1.968e-4,
2112 2.175e-4, 2.431e-4, 2.735e-4, 2.867e-4, 3.19e-4, 3.371e-4,
2113 3.554e-4, 3.726e-4, 3.837e-4, 3.878e-4, 3.864e-4, 3.858e-4,
2114 3.841e-4, 3.852e-4, 3.815e-4, 3.762e-4, 3.618e-4, 3.579e-4,
2115 3.45e-4, 3.202e-4, 3.018e-4, 2.785e-4, 2.602e-4, 2.416e-4,
2116 2.097e-4, 1.939e-4, 1.689e-4, 1.498e-4, 1.308e-4, 1.17e-4,
2117 1.011e-4, 9.237e-5, 7.909e-5, 7.006e-5, 6.112e-5, 5.401e-5,
2118 4.914e-5, 4.266e-5, 3.963e-5, 3.316e-5, 3.037e-5, 2.598e-5,
2119 2.294e-5, 2.066e-5, 1.813e-5, 1.583e-5, 1.423e-5, 1.247e-5,
2120 1.116e-5, 9.76e-6, 8.596e-6, 7.72e-6, 6.825e-6, 6.108e-6,
2121 5.366e-6, 4.733e-6, 4.229e-6, 3.731e-6, 3.346e-6, 2.972e-6,
2122 2.628e-6, 2.356e-6, 2.102e-6, 1.878e-6, 1.678e-6, 1.507e-6,
2123 1.348e-6, 1.21e-6, 1.089e-6, 9.806e-7, 8.857e-7, 8.004e-7,
2124 7.261e-7, 6.599e-7, 6.005e-7, 5.479e-7, 5.011e-7, 4.595e-7,
2125 4.219e-7, 3.885e-7, 3.583e-7, 3.314e-7, 3.071e-7, 2.852e-7,
2126 2.654e-7, 2.474e-7, 2.311e-7, 2.162e-7, 2.026e-7, 1.902e-7,
2127 1.788e-7, 1.683e-7, 1.587e-7, 1.497e-7, 1.415e-7, 1.338e-7,
2128 1.266e-7, 1.2e-7, 1.138e-7, 1.08e-7, 1.027e-7, 9.764e-8,
2129 9.296e-8, 8.862e-8, 8.458e-8, 8.087e-8, 7.744e-8, 7.429e-8,
2130 7.145e-8, 6.893e-8, 6.664e-8, 6.468e-8, 6.322e-8, 6.162e-8,
2131 6.07e-8, 5.992e-8, 5.913e-8, 5.841e-8, 5.796e-8, 5.757e-8,
2132 5.746e-8, 5.731e-8, 5.679e-8, 5.577e-8, 5.671e-8, 5.656e-8,
2133 5.594e-8, 5.593e-8, 5.602e-8, 5.62e-8, 5.693e-8, 5.725e-8,
2134 5.858e-8, 6.037e-8, 6.249e-8, 6.535e-8, 6.899e-8, 7.356e-8,
2135 7.918e-8, 8.618e-8, 9.385e-8, 1.039e-7, 1.158e-7, 1.29e-7,
2136 1.437e-7, 1.65e-7, 1.871e-7, 2.121e-7, 2.427e-7, 2.773e-7,
2137 3.247e-7, 3.677e-7, 4.037e-7, 4.776e-7, 5.101e-7, 6.214e-7,
2138 6.936e-7, 7.581e-7, 8.486e-7, 9.355e-7, 9.942e-7, 1.063e-6,
2139 1.123e-6, 1.191e-6, 1.215e-6, 1.247e-6, 1.26e-6, 1.271e-6,
2140 1.284e-6, 1.317e-6, 1.323e-6, 1.349e-6, 1.353e-6, 1.362e-6,
2141 1.344e-6, 1.329e-6, 1.336e-6, 1.327e-6, 1.325e-6, 1.359e-6,
2142 1.374e-6, 1.415e-6, 1.462e-6, 1.526e-6, 1.619e-6, 1.735e-6,
2143 1.863e-6, 2.034e-6, 2.265e-6, 2.482e-6, 2.756e-6, 3.103e-6,
2144 3.466e-6, 3.832e-6, 4.378e-6, 4.913e-6, 5.651e-6, 6.311e-6,
2145 7.169e-6, 8.057e-6, 9.253e-6, 1.047e-5, 1.212e-5, 1.36e-5,
2146 1.569e-5, 1.776e-5, 2.02e-5, 2.281e-5, 2.683e-5, 2.994e-5,
2147 3.488e-5, 3.896e-5, 4.499e-5, 5.175e-5, 6.035e-5, 6.34e-5,
2148 7.281e-5, 7.923e-5, 8.348e-5, 9.631e-5, 1.044e-4, 1.102e-4,
2149 1.176e-4, 1.244e-4, 1.283e-4, 1.326e-4, 1.4e-4, 1.395e-4,
2150 1.387e-4, 1.363e-4, 1.314e-4, 1.241e-4, 1.228e-4, 1.148e-4,
2151 1.086e-4, 1.018e-4, 8.89e-5, 8.316e-5, 7.292e-5, 6.452e-5,
2152 5.625e-5, 5.045e-5, 4.38e-5, 3.762e-5, 3.29e-5, 2.836e-5,
2153 2.485e-5, 2.168e-5, 1.895e-5, 1.659e-5, 1.453e-5, 1.282e-5,
2154 1.132e-5, 1.001e-5, 8.836e-6, 7.804e-6, 6.922e-6, 6.116e-6,
2155 5.429e-6, 4.824e-6, 4.278e-6, 3.788e-6, 3.371e-6, 2.985e-6,
2156 2.649e-6, 2.357e-6, 2.09e-6, 1.858e-6, 1.647e-6, 1.462e-6,
2157 1.299e-6, 1.155e-6, 1.028e-6, 9.142e-7, 8.132e-7, 7.246e-7,
2158 6.451e-7, 5.764e-7, 5.151e-7, 4.603e-7, 4.121e-7, 3.694e-7,
2159 3.318e-7, 2.985e-7, 2.69e-7, 2.428e-7, 2.197e-7, 1.992e-7,
2160 1.81e-7, 1.649e-7, 1.506e-7, 1.378e-7, 1.265e-7, 1.163e-7,
2161 1.073e-7, 9.918e-8, 9.191e-8, 8.538e-8, 7.949e-8, 7.419e-8,
2162 6.94e-8, 6.508e-8, 6.114e-8, 5.761e-8, 5.437e-8, 5.146e-8,
2163 4.89e-8, 4.636e-8, 4.406e-8, 4.201e-8, 4.015e-8, 3.84e-8,
2164 3.661e-8, 3.51e-8, 3.377e-8, 3.242e-8, 3.13e-8, 3.015e-8,
2165 2.918e-8, 2.83e-8, 2.758e-8, 2.707e-8, 2.656e-8, 2.619e-8,
2166 2.609e-8, 2.615e-8, 2.63e-8, 2.675e-8, 2.745e-8, 2.842e-8,
2167 2.966e-8, 3.125e-8, 3.318e-8, 3.565e-8, 3.85e-8, 4.191e-8,
2168 4.59e-8, 5.059e-8, 5.607e-8, 6.239e-8, 6.958e-8, 7.796e-8,
2169 8.773e-8, 9.88e-8, 1.114e-7, 1.258e-7, 1.422e-7, 1.61e-7,
2170 1.822e-7, 2.06e-7, 2.337e-7, 2.645e-7, 2.996e-7, 3.393e-7,
2171 3.843e-7, 4.363e-7, 4.935e-7, 5.607e-7, 6.363e-7, 7.242e-7,
2172 8.23e-7, 9.411e-7, 1.071e-6, 1.232e-6, 1.402e-6, 1.6e-6, 1.82e-6,
2173 2.128e-6, 2.386e-6, 2.781e-6, 3.242e-6, 3.653e-6, 4.323e-6,
2174 4.747e-6, 5.321e-6, 5.919e-6, 6.681e-6, 7.101e-6, 7.983e-6,
2175 8.342e-6, 8.741e-6, 9.431e-6, 9.952e-6, 1.026e-5, 1.055e-5,
2176 1.095e-5, 1.095e-5, 1.087e-5, 1.056e-5, 1.026e-5, 9.715e-6,
2177 9.252e-6, 8.452e-6, 7.958e-6, 7.268e-6, 6.295e-6, 6.003e-6, 5e-6,
2178 4.591e-6, 3.983e-6, 3.479e-6, 3.058e-6, 2.667e-6, 2.293e-6,
2179 1.995e-6, 1.747e-6, 1.517e-6, 1.335e-6, 1.165e-6, 1.028e-6,
2180 9.007e-7, 7.956e-7, 7.015e-7, 6.192e-7, 5.491e-7, 4.859e-7,
2181 4.297e-7, 3.799e-7, 3.38e-7, 3.002e-7, 2.659e-7, 2.366e-7,
2182 2.103e-7, 1.861e-7, 1.655e-7, 1.469e-7, 1.309e-7, 1.162e-7,
2183 1.032e-7, 9.198e-8, 8.181e-8, 7.294e-8, 6.516e-8, 5.787e-8,
2184 5.163e-8, 4.612e-8, 4.119e-8, 3.695e-8, 3.308e-8, 2.976e-8,
2185 2.67e-8, 2.407e-8, 2.171e-8, 1.965e-8, 1.78e-8, 1.617e-8,
2186 1.47e-8, 1.341e-8, 1.227e-8, 1.125e-8, 1.033e-8, 9.524e-9,
2187 8.797e-9, 8.162e-9, 7.565e-9, 7.04e-9, 6.56e-9, 6.129e-9,
2188 5.733e-9, 5.376e-9, 5.043e-9, 4.75e-9, 4.466e-9, 4.211e-9,
2189 3.977e-9, 3.759e-9, 3.558e-9, 3.373e-9, 3.201e-9, 3.043e-9,
2190 2.895e-9, 2.76e-9, 2.635e-9, 2.518e-9, 2.411e-9, 2.314e-9,
2191 2.23e-9, 2.151e-9, 2.087e-9, 2.035e-9, 1.988e-9, 1.946e-9,
2192 1.927e-9, 1.916e-9, 1.916e-9, 1.933e-9, 1.966e-9, 2.018e-9,
2193 2.09e-9, 2.182e-9, 2.299e-9, 2.442e-9, 2.623e-9, 2.832e-9,
2194 3.079e-9, 3.368e-9, 3.714e-9, 4.104e-9, 4.567e-9, 5.091e-9,
2195 5.701e-9, 6.398e-9, 7.194e-9, 8.127e-9, 9.141e-9, 1.035e-8,
2196 1.177e-8, 1.338e-8, 1.508e-8, 1.711e-8, 1.955e-8, 2.216e-8,
2197 2.534e-8, 2.871e-8, 3.291e-8, 3.711e-8, 4.285e-8, 4.868e-8,
2198 5.509e-8, 6.276e-8, 7.262e-8, 8.252e-8, 9.4e-8, 1.064e-7,
2199 1.247e-7, 1.411e-7, 1.626e-7, 1.827e-7, 2.044e-7, 2.284e-7,
2200 2.452e-7, 2.854e-7, 3.026e-7, 3.278e-7, 3.474e-7, 3.693e-7,
2201 3.93e-7, 4.104e-7, 4.22e-7, 4.439e-7, 4.545e-7, 4.778e-7,
2202 4.812e-7, 5.018e-7, 4.899e-7, 5.075e-7, 5.073e-7, 5.171e-7,
2203 5.131e-7, 5.25e-7, 5.617e-7, 5.846e-7, 6.239e-7, 6.696e-7,
2204 7.398e-7, 8.073e-7, 9.15e-7, 1.009e-6, 1.116e-6, 1.264e-6,
2205 1.439e-6, 1.644e-6, 1.856e-6, 2.147e-6, 2.317e-6, 2.713e-6,
2206 2.882e-6, 2.99e-6, 3.489e-6, 3.581e-6, 4.033e-6, 4.26e-6,
2207 4.543e-6, 4.84e-6, 4.826e-6, 5.013e-6, 5.252e-6, 5.277e-6,
2208 5.306e-6, 5.236e-6, 5.123e-6, 5.171e-6, 4.843e-6, 4.615e-6,
2209 4.385e-6, 3.97e-6, 3.693e-6, 3.231e-6, 2.915e-6, 2.495e-6,
2210 2.144e-6, 1.91e-6, 1.639e-6, 1.417e-6, 1.226e-6, 1.065e-6,
2211 9.29e-7, 8.142e-7, 7.161e-7, 6.318e-7, 5.581e-7, 4.943e-7,
2212 4.376e-7, 3.884e-7, 3.449e-7, 3.06e-7, 2.712e-7, 2.412e-7,
2213 2.139e-7, 1.903e-7, 1.689e-7, 1.499e-7, 1.331e-7, 1.183e-7,
2214 1.05e-7, 9.362e-8, 8.306e-8, 7.403e-8, 6.578e-8, 5.853e-8,
2215 5.216e-8, 4.632e-8, 4.127e-8, 3.678e-8, 3.279e-8, 2.923e-8,
2216 2.612e-8, 2.339e-8, 2.094e-8, 1.877e-8, 1.686e-8, 1.516e-8,
2217 1.366e-8, 1.234e-8, 1.114e-8, 1.012e-8, 9.182e-9, 8.362e-9,
2218 7.634e-9, 6.981e-9, 6.406e-9, 5.888e-9, 5.428e-9, 5.021e-9,
2219 4.65e-9, 4.326e-9, 4.033e-9, 3.77e-9, 3.536e-9, 3.327e-9,
2220 3.141e-9, 2.974e-9, 2.825e-9, 2.697e-9, 2.584e-9, 2.488e-9,
2221 2.406e-9, 2.34e-9, 2.292e-9, 2.259e-9, 2.244e-9, 2.243e-9,
2222 2.272e-9, 2.31e-9, 2.378e-9, 2.454e-9, 2.618e-9, 2.672e-9,
2223 2.831e-9, 3.05e-9, 3.225e-9, 3.425e-9, 3.677e-9, 3.968e-9,
2224 4.221e-9, 4.639e-9, 4.96e-9, 5.359e-9, 5.649e-9, 6.23e-9,
2225 6.716e-9, 7.218e-9, 7.746e-9, 7.988e-9, 8.627e-9, 8.999e-9,
2226 9.442e-9, 9.82e-9, 1.015e-8, 1.06e-8, 1.079e-8, 1.109e-8,
2227 1.137e-8, 1.186e-8, 1.18e-8, 1.187e-8, 1.194e-8, 1.192e-8,
2228 1.224e-8, 1.245e-8, 1.246e-8, 1.318e-8, 1.377e-8, 1.471e-8,
2229 1.582e-8, 1.713e-8, 1.853e-8, 2.063e-8, 2.27e-8, 2.567e-8,
2230 2.891e-8, 3.264e-8, 3.744e-8, 4.286e-8, 4.915e-8, 5.623e-8,
2231 6.336e-8, 7.293e-8, 8.309e-8, 9.319e-8, 1.091e-7, 1.243e-7,
2232 1.348e-7, 1.449e-7, 1.62e-7, 1.846e-7, 1.937e-7, 2.04e-7,
2233 2.179e-7, 2.298e-7, 2.433e-7, 2.439e-7, 2.464e-7, 2.611e-7,
2234 2.617e-7, 2.582e-7, 2.453e-7, 2.401e-7, 2.349e-7, 2.203e-7,
2235 2.066e-7, 1.939e-7, 1.78e-7, 1.558e-7, 1.391e-7, 1.203e-7,
2236 1.048e-7, 9.464e-8, 8.306e-8, 7.239e-8, 6.317e-8, 5.52e-8,
2237 4.847e-8, 4.282e-8, 3.796e-8, 3.377e-8, 2.996e-8, 2.678e-8,
2238 2.4e-8, 2.134e-8, 1.904e-8, 1.705e-8, 1.523e-8, 1.35e-8,
2239 1.204e-8, 1.07e-8, 9.408e-9, 8.476e-9, 7.47e-9, 6.679e-9,
2240 5.929e-9, 5.267e-9, 4.711e-9, 4.172e-9, 3.761e-9, 3.288e-9,
2241 2.929e-9, 2.609e-9, 2.315e-9, 2.042e-9, 1.844e-9, 1.64e-9,
2242 1.47e-9, 1.31e-9, 1.176e-9, 1.049e-9, 9.377e-10, 8.462e-10,
2243 7.616e-10, 6.854e-10, 6.191e-10, 5.596e-10, 5.078e-10, 4.611e-10,
2244 4.197e-10, 3.83e-10, 3.505e-10, 3.215e-10, 2.956e-10, 2.726e-10,
2245 2.521e-10, 2.338e-10, 2.173e-10, 2.026e-10, 1.895e-10, 1.777e-10,
2246 1.672e-10, 1.579e-10, 1.496e-10, 1.423e-10, 1.358e-10, 1.302e-10,
2247 1.254e-10, 1.216e-10, 1.187e-10, 1.163e-10, 1.147e-10, 1.145e-10,
2248 1.15e-10, 1.17e-10, 1.192e-10, 1.25e-10, 1.298e-10, 1.345e-10,
2249 1.405e-10, 1.538e-10, 1.648e-10, 1.721e-10, 1.872e-10, 1.968e-10,
2250 2.089e-10, 2.172e-10, 2.317e-10, 2.389e-10, 2.503e-10, 2.585e-10,
2251 2.686e-10, 2.8e-10, 2.895e-10, 3.019e-10, 3.037e-10, 3.076e-10,
2252 3.146e-10, 3.198e-10, 3.332e-10, 3.397e-10, 3.54e-10, 3.667e-10,
2253 3.895e-10, 4.071e-10, 4.565e-10, 4.983e-10, 5.439e-10, 5.968e-10,
2254 6.676e-10, 7.456e-10, 8.405e-10, 9.478e-10, 1.064e-9, 1.218e-9,
2255 1.386e-9, 1.581e-9, 1.787e-9, 2.032e-9, 2.347e-9, 2.677e-9,
2256 3.008e-9, 3.544e-9, 4.056e-9, 4.687e-9, 5.331e-9, 6.227e-9,
2257 6.854e-9, 8.139e-9, 8.945e-9, 9.865e-9, 1.125e-8, 1.178e-8,
2258 1.364e-8, 1.436e-8, 1.54e-8, 1.672e-8, 1.793e-8, 1.906e-8,
2259 2.036e-8, 2.144e-8, 2.292e-8, 2.371e-8, 2.493e-8, 2.606e-8,
2260 2.706e-8, 2.866e-8, 3.036e-8, 3.136e-8, 3.405e-8, 3.665e-8,
2261 3.837e-8, 4.229e-8, 4.748e-8, 5.32e-8, 5.763e-8, 6.677e-8,
2262 7.216e-8, 7.716e-8, 8.958e-8, 9.419e-8, 1.036e-7, 1.108e-7,
2263 1.189e-7, 1.246e-7, 1.348e-7, 1.31e-7, 1.361e-7, 1.364e-7,
2264 1.363e-7, 1.343e-7, 1.293e-7, 1.254e-7, 1.235e-7, 1.158e-7,
2265 1.107e-7, 9.961e-8, 9.011e-8, 7.91e-8, 6.916e-8, 6.338e-8,
2266 5.564e-8, 4.827e-8, 4.198e-8, 3.695e-8, 3.276e-8, 2.929e-8,
2267 2.633e-8, 2.391e-8, 2.192e-8, 2.021e-8, 1.89e-8, 1.772e-8,
2268 1.667e-8, 1.603e-8, 1.547e-8, 1.537e-8, 1.492e-8, 1.515e-8,
2269 1.479e-8, 1.45e-8, 1.513e-8, 1.495e-8, 1.529e-8, 1.565e-8,
2270 1.564e-8, 1.553e-8, 1.569e-8, 1.584e-8, 1.57e-8, 1.538e-8,
2271 1.513e-8, 1.472e-8, 1.425e-8, 1.349e-8, 1.328e-8, 1.249e-8,
2272 1.17e-8, 1.077e-8, 9.514e-9, 8.614e-9, 7.46e-9, 6.621e-9,
2273 5.775e-9, 5.006e-9, 4.308e-9, 3.747e-9, 3.24e-9, 2.84e-9,
2274 2.481e-9, 2.184e-9, 1.923e-9, 1.71e-9, 1.504e-9, 1.334e-9,
2275 1.187e-9, 1.053e-9, 9.367e-10, 8.306e-10, 7.419e-10, 6.63e-10,
2276 5.918e-10, 5.277e-10, 4.717e-10, 4.222e-10, 3.783e-10, 3.39e-10,
2277 3.036e-10, 2.729e-10, 2.455e-10, 2.211e-10, 1.995e-10, 1.804e-10,
2278 1.635e-10, 1.485e-10, 1.355e-10, 1.24e-10, 1.139e-10, 1.051e-10,
2279 9.757e-11, 9.114e-11, 8.577e-11, 8.139e-11, 7.792e-11, 7.52e-11,
2280 7.39e-11, 7.311e-11, 7.277e-11, 7.482e-11, 7.698e-11, 8.162e-11,
2281 8.517e-11, 8.968e-11, 9.905e-11, 1.075e-10, 1.187e-10, 1.291e-10,
2282 1.426e-10, 1.573e-10, 1.734e-10, 1.905e-10, 2.097e-10, 2.28e-10,
2283 2.473e-10, 2.718e-10, 2.922e-10, 3.128e-10, 3.361e-10, 3.641e-10,
2284 3.91e-10, 4.196e-10, 4.501e-10, 4.932e-10, 5.258e-10, 5.755e-10,
2285 6.253e-10, 6.664e-10, 7.344e-10, 7.985e-10, 8.877e-10, 1.005e-9,
2286 1.118e-9, 1.251e-9, 1.428e-9, 1.61e-9, 1.888e-9, 2.077e-9,
2287 2.331e-9, 2.751e-9, 3.061e-9, 3.522e-9, 3.805e-9, 4.181e-9,
2288 4.575e-9, 5.167e-9, 5.634e-9, 6.007e-9, 6.501e-9, 6.829e-9,
2289 7.211e-9, 7.262e-9, 7.696e-9, 7.832e-9, 7.799e-9, 7.651e-9,
2290 7.304e-9, 7.15e-9, 6.977e-9, 6.603e-9, 6.209e-9, 5.69e-9,
2291 5.432e-9, 4.764e-9, 4.189e-9, 3.64e-9, 3.203e-9, 2.848e-9,
2292 2.51e-9, 2.194e-9, 1.946e-9, 1.75e-9, 1.567e-9, 1.426e-9,
2293 1.302e-9, 1.197e-9, 1.109e-9, 1.035e-9, 9.719e-10, 9.207e-10,
2294 8.957e-10, 8.578e-10, 8.262e-10, 8.117e-10, 7.987e-10, 7.875e-10,
2295 7.741e-10, 7.762e-10, 7.537e-10, 7.424e-10, 7.474e-10, 7.294e-10,
2296 7.216e-10, 7.233e-10, 7.075e-10, 6.892e-10, 6.618e-10, 6.314e-10,
2297 6.208e-10, 5.689e-10, 5.55e-10, 4.984e-10, 4.6e-10, 4.078e-10,
2298 3.879e-10, 3.459e-10, 2.982e-10, 2.626e-10, 2.329e-10, 1.988e-10,
2299 1.735e-10, 1.487e-10, 1.297e-10, 1.133e-10, 9.943e-11, 8.736e-11,
2300 7.726e-11, 6.836e-11, 6.053e-11, 5.384e-11, 4.789e-11, 4.267e-11,
2301 3.804e-11, 3.398e-11, 3.034e-11, 2.71e-11, 2.425e-11, 2.173e-11,
2302 1.95e-11, 1.752e-11, 1.574e-11, 1.418e-11, 1.278e-11, 1.154e-11,
2303 1.044e-11, 9.463e-12, 8.602e-12, 7.841e-12, 7.171e-12, 6.584e-12,
2304 6.073e-12, 5.631e-12, 5.254e-12, 4.937e-12, 4.679e-12, 4.476e-12,
2305 4.328e-12, 4.233e-12, 4.194e-12, 4.211e-12, 4.286e-12, 4.424e-12,
2306 4.628e-12, 4.906e-12, 5.262e-12, 5.708e-12, 6.254e-12, 6.914e-12,
2307 7.714e-12, 8.677e-12, 9.747e-12, 1.101e-11, 1.256e-11, 1.409e-11,
2308 1.597e-11, 1.807e-11, 2.034e-11, 2.316e-11, 2.622e-11, 2.962e-11,
2309 3.369e-11, 3.819e-11, 4.329e-11, 4.932e-11, 5.589e-11, 6.364e-11,
2310 7.284e-11, 8.236e-11, 9.447e-11, 1.078e-10, 1.229e-10, 1.417e-10,
2311 1.614e-10, 1.843e-10, 2.107e-10, 2.406e-10, 2.728e-10, 3.195e-10,
2312 3.595e-10, 4.153e-10, 4.736e-10, 5.41e-10, 6.088e-10, 6.769e-10,
2313 7.691e-10, 8.545e-10, 9.621e-10, 1.047e-9, 1.161e-9, 1.296e-9,
2314 1.424e-9, 1.576e-9, 1.739e-9, 1.893e-9, 2.08e-9, 2.336e-9,
2315 2.604e-9, 2.76e-9, 3.001e-9, 3.365e-9, 3.55e-9, 3.895e-9,
2316 4.183e-9, 4.614e-9, 4.846e-9, 5.068e-9, 5.427e-9, 5.541e-9,
2317 5.864e-9, 5.997e-9, 5.997e-9, 6.061e-9, 5.944e-9, 5.855e-9,
2318 5.661e-9, 5.523e-9, 5.374e-9, 4.94e-9, 4.688e-9, 4.17e-9,
2319 3.913e-9, 3.423e-9, 2.997e-9, 2.598e-9, 2.253e-9, 1.946e-9,
2320 1.71e-9, 1.507e-9, 1.336e-9, 1.19e-9, 1.068e-9, 9.623e-10,
2321 8.772e-10, 8.007e-10, 7.42e-10, 6.884e-10, 6.483e-10, 6.162e-10,
2322 5.922e-10, 5.688e-10, 5.654e-10, 5.637e-10, 5.701e-10, 5.781e-10,
2323 5.874e-10, 6.268e-10, 6.357e-10, 6.525e-10, 7.137e-10, 7.441e-10,
2324 8.024e-10, 8.485e-10, 9.143e-10, 9.536e-10, 9.717e-10, 1.018e-9,
2325 1.042e-9, 1.054e-9, 1.092e-9, 1.079e-9, 1.064e-9, 1.043e-9,
2326 1.02e-9, 9.687e-10, 9.273e-10, 9.208e-10, 9.068e-10, 7.687e-10,
2327 7.385e-10, 6.595e-10, 5.87e-10, 5.144e-10, 4.417e-10, 3.804e-10,
2328 3.301e-10, 2.866e-10, 2.509e-10, 2.202e-10, 1.947e-10, 1.719e-10,
2329 1.525e-10, 1.361e-10, 1.21e-10, 1.084e-10, 9.8e-11, 8.801e-11,
2330 7.954e-11, 7.124e-11, 6.335e-11, 5.76e-11, 5.132e-11, 4.601e-11,
2331 4.096e-11, 3.657e-11, 3.25e-11, 2.909e-11, 2.587e-11, 2.297e-11,
2332 2.05e-11, 1.828e-11, 1.632e-11, 1.462e-11, 1.314e-11, 1.185e-11,
2333 1.073e-11, 9.76e-12, 8.922e-12, 8.206e-12, 7.602e-12, 7.1e-12,
2334 6.694e-12, 6.378e-12, 6.149e-12, 6.004e-12, 5.941e-12, 5.962e-12,
2335 6.069e-12, 6.265e-12, 6.551e-12, 6.935e-12, 7.457e-12, 8.074e-12,
2336 8.811e-12, 9.852e-12, 1.086e-11, 1.207e-11, 1.361e-11, 1.553e-11,
2337 1.737e-11, 1.93e-11, 2.175e-11, 2.41e-11, 2.706e-11, 3.023e-11,
2338 3.313e-11, 3.657e-11, 4.118e-11, 4.569e-11, 5.025e-11, 5.66e-11,
2339 6.231e-11, 6.881e-11, 7.996e-11, 8.526e-11, 9.694e-11, 1.106e-10,
2340 1.222e-10, 1.355e-10, 1.525e-10, 1.775e-10, 1.924e-10, 2.181e-10,
2341 2.379e-10, 2.662e-10, 2.907e-10, 3.154e-10, 3.366e-10, 3.579e-10,
2342 3.858e-10, 4.046e-10, 4.196e-10, 4.166e-10, 4.457e-10, 4.466e-10,
2343 4.404e-10, 4.337e-10, 4.15e-10, 4.083e-10, 3.91e-10, 3.723e-10,
2344 3.514e-10, 3.303e-10, 2.847e-10, 2.546e-10, 2.23e-10, 1.994e-10,
2345 1.733e-10, 1.488e-10, 1.297e-10, 1.144e-10, 1.004e-10, 8.741e-11,
2346 7.928e-11, 7.034e-11, 6.323e-11, 5.754e-11, 5.25e-11, 4.85e-11,
2347 4.502e-11, 4.286e-11, 4.028e-11, 3.899e-11, 3.824e-11, 3.761e-11,
2348 3.804e-11, 3.839e-11, 3.845e-11, 4.244e-11, 4.382e-11, 4.582e-11,
2349 4.847e-11, 5.209e-11, 5.384e-11, 5.887e-11, 6.371e-11, 6.737e-11,
2350 7.168e-11, 7.415e-11, 7.827e-11, 8.037e-11, 8.12e-11, 8.071e-11,
2351 8.008e-11, 7.851e-11, 7.544e-11, 7.377e-11, 7.173e-11, 6.801e-11,
2352 6.267e-11, 5.727e-11, 5.288e-11, 4.853e-11, 4.082e-11, 3.645e-11,
2353 3.136e-11, 2.672e-11, 2.304e-11, 1.986e-11, 1.725e-11, 1.503e-11,
2354 1.315e-11, 1.153e-11, 1.014e-11, 8.942e-12, 7.901e-12, 6.993e-12,
2355 6.199e-12, 5.502e-12, 4.89e-12, 4.351e-12, 3.878e-12, 3.461e-12,
2356 3.094e-12, 2.771e-12, 2.488e-12, 2.241e-12, 2.025e-12, 1.838e-12,
2357 1.677e-12, 1.541e-12, 1.427e-12, 1.335e-12, 1.262e-12, 1.209e-12,
2358 1.176e-12, 1.161e-12, 1.165e-12, 1.189e-12, 1.234e-12, 1.3e-12,
2359 1.389e-12, 1.503e-12, 1.644e-12, 1.814e-12, 2.017e-12, 2.255e-12,
2360 2.534e-12, 2.858e-12, 3.231e-12, 3.661e-12, 4.153e-12, 4.717e-12,
2361 5.36e-12, 6.094e-12, 6.93e-12, 7.882e-12, 8.966e-12, 1.02e-11,
2362 1.162e-11, 1.324e-11, 1.51e-11, 1.72e-11, 1.965e-11, 2.237e-11,
2363 2.56e-11, 2.927e-11, 3.371e-11, 3.842e-11, 4.429e-11, 5.139e-11,
2364 5.798e-11, 6.697e-11, 7.626e-11, 8.647e-11, 1.022e-10, 1.136e-10,
2365 1.3e-10, 1.481e-10, 1.672e-10, 1.871e-10, 2.126e-10, 2.357e-10,
2366 2.583e-10, 2.997e-10, 3.289e-10, 3.702e-10, 4.012e-10, 4.319e-10,
2367 4.527e-10, 5.001e-10, 5.448e-10, 5.611e-10, 5.76e-10, 5.965e-10,
2368 6.079e-10, 6.207e-10, 6.276e-10, 6.222e-10, 6.137e-10, 6e-10,
2369 5.814e-10, 5.393e-10, 5.35e-10, 4.947e-10, 4.629e-10, 4.117e-10,
2370 3.712e-10, 3.372e-10, 2.923e-10, 2.55e-10, 2.232e-10, 1.929e-10,
2371 1.679e-10, 1.46e-10, 1.289e-10, 1.13e-10, 9.953e-11, 8.763e-11,
2372 7.76e-11, 6.9e-11, 6.16e-11, 5.525e-11, 4.958e-11, 4.489e-11,
2373 4.072e-11, 3.728e-11, 3.438e-11, 3.205e-11, 3.006e-11, 2.848e-11,
2374 2.766e-11, 2.688e-11, 2.664e-11, 2.67e-11, 2.696e-11, 2.786e-11,
2375 2.861e-11, 3.009e-11, 3.178e-11, 3.389e-11, 3.587e-11, 3.819e-11,
2376 4.054e-11, 4.417e-11, 4.703e-11, 5.137e-11, 5.46e-11, 6.055e-11,
2377 6.333e-11, 6.773e-11, 7.219e-11, 7.717e-11, 8.131e-11, 8.491e-11,
2378 8.574e-11, 9.01e-11, 9.017e-11, 8.999e-11, 8.959e-11, 8.838e-11,
2379 8.579e-11, 8.162e-11, 8.098e-11, 7.472e-11, 7.108e-11, 6.559e-11,
2380 5.994e-11, 5.172e-11, 4.424e-11, 3.951e-11, 3.34e-11, 2.902e-11,
2381 2.541e-11, 2.215e-11, 1.945e-11, 1.716e-11, 1.503e-11, 1.339e-11,
2382 1.185e-11, 1.05e-11, 9.336e-12, 8.307e-12, 7.312e-12, 6.55e-12,
2383 5.836e-12, 5.178e-12, 4.6e-12, 4.086e-12, 3.639e-12, 3.247e-12,
2384 2.904e-12, 2.604e-12, 2.341e-12, 2.112e-12, 1.914e-12, 1.744e-12,
2385 1.598e-12, 1.476e-12, 1.374e-12, 1.293e-12, 1.23e-12, 1.185e-12,
2386 1.158e-12, 1.147e-12, 1.154e-12, 1.177e-12, 1.219e-12, 1.28e-12,
2387 1.36e-12, 1.463e-12, 1.591e-12, 1.75e-12, 1.94e-12, 2.156e-12,
2388 2.43e-12, 2.748e-12, 3.052e-12, 3.533e-12, 3.967e-12, 4.471e-12,
2389 5.041e-12, 5.86e-12, 6.664e-12, 7.522e-12, 8.342e-12, 9.412e-12,
2390 1.072e-11, 1.213e-11, 1.343e-11, 1.496e-11, 1.664e-11, 1.822e-11,
2391 2.029e-11, 2.233e-11, 2.457e-11, 2.709e-11, 2.928e-11, 3.115e-11,
2392 3.356e-11, 3.592e-11, 3.818e-11, 3.936e-11, 4.061e-11, 4.149e-11,
2393 4.299e-11, 4.223e-11, 4.251e-11, 4.287e-11, 4.177e-11, 4.094e-11,
2394 3.942e-11, 3.772e-11, 3.614e-11, 3.394e-11, 3.222e-11, 2.791e-11,
2395 2.665e-11, 2.309e-11, 2.032e-11, 1.74e-11, 1.535e-11, 1.323e-11,
2396 1.151e-11, 9.803e-12, 8.65e-12, 7.54e-12, 6.619e-12, 5.832e-12,
2397 5.113e-12, 4.503e-12, 3.975e-12, 3.52e-12, 3.112e-12, 2.797e-12,
2398 2.5e-12, 2.24e-12, 2.013e-12, 1.819e-12, 1.653e-12, 1.513e-12,
2399 1.395e-12, 1.299e-12, 1.225e-12, 1.168e-12, 1.124e-12, 1.148e-12,
2400 1.107e-12, 1.128e-12, 1.169e-12, 1.233e-12, 1.307e-12, 1.359e-12,
2401 1.543e-12, 1.686e-12, 1.794e-12, 2.028e-12, 2.21e-12, 2.441e-12,
2402 2.653e-12, 2.828e-12, 3.093e-12, 3.28e-12, 3.551e-12, 3.677e-12,
2403 3.803e-12, 3.844e-12, 4.068e-12, 4.093e-12, 4.002e-12, 3.904e-12,
2404 3.624e-12, 3.633e-12, 3.622e-12, 3.443e-12, 3.184e-12, 2.934e-12,
2405 2.476e-12, 2.212e-12, 1.867e-12, 1.594e-12, 1.37e-12, 1.192e-12,
2406 1.045e-12, 9.211e-13, 8.17e-13, 7.29e-13, 6.55e-13, 5.929e-13,
2407 5.415e-13, 4.995e-13, 4.661e-13, 4.406e-13, 4.225e-13, 4.116e-13,
2408 4.075e-13, 4.102e-13, 4.198e-13, 4.365e-13, 4.606e-13, 4.925e-13,
2409 5.326e-13, 5.818e-13, 6.407e-13, 7.104e-13, 7.92e-13, 8.868e-13,
2410 9.964e-13, 1.123e-12, 1.268e-12, 1.434e-12, 1.626e-12, 1.848e-12,
2411 2.107e-12, 2.422e-12, 2.772e-12, 3.145e-12, 3.704e-12, 4.27e-12,
2412 4.721e-12, 5.361e-12, 6.083e-12, 7.095e-12, 7.968e-12, 9.228e-12,
2413 1.048e-11, 1.187e-11, 1.336e-11, 1.577e-11, 1.772e-11, 2.017e-11,
2414 2.25e-11, 2.63e-11, 2.911e-11, 3.356e-11, 3.82e-11, 4.173e-11,
2415 4.811e-11, 5.254e-11, 5.839e-11, 6.187e-11, 6.805e-11, 7.118e-11,
2416 7.369e-11, 7.664e-11, 7.794e-11, 7.947e-11, 8.036e-11, 7.954e-11,
2417 7.849e-11, 7.518e-11, 7.462e-11, 6.926e-11, 6.531e-11, 6.197e-11,
2418 5.421e-11, 4.777e-11, 4.111e-11, 3.679e-11, 3.166e-11, 2.786e-11,
2419 2.436e-11, 2.144e-11, 1.859e-11, 1.628e-11, 1.414e-11, 1.237e-11,
2420 1.093e-11, 9.558e-12
2421 };
2422
2423 static const double h2o260[2001] =
2424 { .2752, .2732, .2749, .2676, .2667, .2545,
2425 .2497, .2327, .2218, .2036, .1825, .1694, .1497, .1353, .121,
2426 .1014, .09405, .07848, .07195, .06246, .05306, .04853, .04138,
2427 .03735, .03171, .02785, .02431, .02111, .01845, .0164, .01405,
2428 .01255, .01098, .009797, .008646, .007779, .006898, .006099,
2429 .005453, .004909, .004413, .003959, .003581, .003199, .002871,
2430 .002583, .00233, .002086, .001874, .001684, .001512, .001361,
2431 .001225, .0011, 9.89e-4, 8.916e-4, 8.039e-4, 7.256e-4, 6.545e-4,
2432 5.918e-4, 5.359e-4, 4.867e-4, 4.426e-4, 4.033e-4, 3.682e-4,
2433 3.366e-4, 3.085e-4, 2.833e-4, 2.605e-4, 2.403e-4, 2.221e-4,
2434 2.055e-4, 1.908e-4, 1.774e-4, 1.653e-4, 1.544e-4, 1.443e-4,
2435 1.351e-4, 1.267e-4, 1.19e-4, 1.119e-4, 1.053e-4, 9.922e-5,
2436 9.355e-5, 8.831e-5, 8.339e-5, 7.878e-5, 7.449e-5, 7.043e-5,
2437 6.664e-5, 6.307e-5, 5.969e-5, 5.654e-5, 5.357e-5, 5.075e-5,
2438 4.81e-5, 4.56e-5, 4.322e-5, 4.102e-5, 3.892e-5, 3.696e-5,
2439 3.511e-5, 3.339e-5, 3.177e-5, 3.026e-5, 2.886e-5, 2.756e-5,
2440 2.636e-5, 2.527e-5, 2.427e-5, 2.337e-5, 2.257e-5, 2.185e-5,
2441 2.127e-5, 2.08e-5, 2.041e-5, 2.013e-5, 2e-5, 1.997e-5, 2.009e-5,
2442 2.031e-5, 2.068e-5, 2.124e-5, 2.189e-5, 2.267e-5, 2.364e-5,
2443 2.463e-5, 2.618e-5, 2.774e-5, 2.937e-5, 3.144e-5, 3.359e-5,
2444 3.695e-5, 4.002e-5, 4.374e-5, 4.947e-5, 5.431e-5, 6.281e-5,
2445 7.169e-5, 8.157e-5, 9.728e-5, 1.079e-4, 1.337e-4, 1.442e-4,
2446 1.683e-4, 1.879e-4, 2.223e-4, 2.425e-4, 2.838e-4, 3.143e-4,
2447 3.527e-4, 4.012e-4, 4.237e-4, 4.747e-4, 5.057e-4, 5.409e-4,
2448 5.734e-4, 5.944e-4, 6.077e-4, 6.175e-4, 6.238e-4, 6.226e-4,
2449 6.248e-4, 6.192e-4, 6.098e-4, 5.818e-4, 5.709e-4, 5.465e-4,
2450 5.043e-4, 4.699e-4, 4.294e-4, 3.984e-4, 3.672e-4, 3.152e-4,
2451 2.883e-4, 2.503e-4, 2.211e-4, 1.92e-4, 1.714e-4, 1.485e-4,
2452 1.358e-4, 1.156e-4, 1.021e-4, 8.887e-5, 7.842e-5, 7.12e-5,
2453 6.186e-5, 5.73e-5, 4.792e-5, 4.364e-5, 3.72e-5, 3.28e-5,
2454 2.946e-5, 2.591e-5, 2.261e-5, 2.048e-5, 1.813e-5, 1.63e-5,
2455 1.447e-5, 1.282e-5, 1.167e-5, 1.041e-5, 9.449e-6, 8.51e-6,
2456 7.596e-6, 6.961e-6, 6.272e-6, 5.728e-6, 5.198e-6, 4.667e-6,
2457 4.288e-6, 3.897e-6, 3.551e-6, 3.235e-6, 2.952e-6, 2.688e-6,
2458 2.449e-6, 2.241e-6, 2.05e-6, 1.879e-6, 1.722e-6, 1.582e-6,
2459 1.456e-6, 1.339e-6, 1.236e-6, 1.144e-6, 1.06e-6, 9.83e-7,
2460 9.149e-7, 8.535e-7, 7.973e-7, 7.466e-7, 6.999e-7, 6.574e-7,
2461 6.18e-7, 5.821e-7, 5.487e-7, 5.18e-7, 4.896e-7, 4.631e-7,
2462 4.386e-7, 4.16e-7, 3.945e-7, 3.748e-7, 3.562e-7, 3.385e-7,
2463 3.222e-7, 3.068e-7, 2.922e-7, 2.788e-7, 2.659e-7, 2.539e-7,
2464 2.425e-7, 2.318e-7, 2.219e-7, 2.127e-7, 2.039e-7, 1.958e-7,
2465 1.885e-7, 1.818e-7, 1.758e-7, 1.711e-7, 1.662e-7, 1.63e-7,
2466 1.605e-7, 1.58e-7, 1.559e-7, 1.545e-7, 1.532e-7, 1.522e-7,
2467 1.51e-7, 1.495e-7, 1.465e-7, 1.483e-7, 1.469e-7, 1.448e-7,
2468 1.444e-7, 1.436e-7, 1.426e-7, 1.431e-7, 1.425e-7, 1.445e-7,
2469 1.477e-7, 1.515e-7, 1.567e-7, 1.634e-7, 1.712e-7, 1.802e-7,
2470 1.914e-7, 2.024e-7, 2.159e-7, 2.295e-7, 2.461e-7, 2.621e-7,
2471 2.868e-7, 3.102e-7, 3.394e-7, 3.784e-7, 4.223e-7, 4.864e-7,
2472 5.501e-7, 6.039e-7, 7.193e-7, 7.728e-7, 9.514e-7, 1.073e-6,
2473 1.18e-6, 1.333e-6, 1.472e-6, 1.566e-6, 1.677e-6, 1.784e-6,
2474 1.904e-6, 1.953e-6, 2.02e-6, 2.074e-6, 2.128e-6, 2.162e-6,
2475 2.219e-6, 2.221e-6, 2.249e-6, 2.239e-6, 2.235e-6, 2.185e-6,
2476 2.141e-6, 2.124e-6, 2.09e-6, 2.068e-6, 2.1e-6, 2.104e-6,
2477 2.142e-6, 2.181e-6, 2.257e-6, 2.362e-6, 2.5e-6, 2.664e-6,
2478 2.884e-6, 3.189e-6, 3.48e-6, 3.847e-6, 4.313e-6, 4.79e-6,
2479 5.25e-6, 5.989e-6, 6.692e-6, 7.668e-6, 8.52e-6, 9.606e-6,
2480 1.073e-5, 1.225e-5, 1.377e-5, 1.582e-5, 1.761e-5, 2.029e-5,
2481 2.284e-5, 2.602e-5, 2.94e-5, 3.483e-5, 3.928e-5, 4.618e-5,
2482 5.24e-5, 6.132e-5, 7.183e-5, 8.521e-5, 9.111e-5, 1.07e-4,
2483 1.184e-4, 1.264e-4, 1.475e-4, 1.612e-4, 1.704e-4, 1.818e-4,
2484 1.924e-4, 1.994e-4, 2.061e-4, 2.18e-4, 2.187e-4, 2.2e-4,
2485 2.196e-4, 2.131e-4, 2.015e-4, 1.988e-4, 1.847e-4, 1.729e-4,
2486 1.597e-4, 1.373e-4, 1.262e-4, 1.087e-4, 9.439e-5, 8.061e-5,
2487 7.093e-5, 6.049e-5, 5.12e-5, 4.435e-5, 3.817e-5, 3.34e-5,
2488 2.927e-5, 2.573e-5, 2.291e-5, 2.04e-5, 1.827e-5, 1.636e-5,
2489 1.463e-5, 1.309e-5, 1.17e-5, 1.047e-5, 9.315e-6, 8.328e-6,
2490 7.458e-6, 6.665e-6, 5.94e-6, 5.316e-6, 4.752e-6, 4.252e-6,
2491 3.825e-6, 3.421e-6, 3.064e-6, 2.746e-6, 2.465e-6, 2.216e-6,
2492 1.99e-6, 1.79e-6, 1.609e-6, 1.449e-6, 1.306e-6, 1.177e-6,
2493 1.063e-6, 9.607e-7, 8.672e-7, 7.855e-7, 7.118e-7, 6.46e-7,
2494 5.871e-7, 5.34e-7, 4.868e-7, 4.447e-7, 4.068e-7, 3.729e-7,
2495 3.423e-7, 3.151e-7, 2.905e-7, 2.686e-7, 2.484e-7, 2.306e-7,
2496 2.142e-7, 1.995e-7, 1.86e-7, 1.738e-7, 1.626e-7, 1.522e-7,
2497 1.427e-7, 1.338e-7, 1.258e-7, 1.183e-7, 1.116e-7, 1.056e-7,
2498 9.972e-8, 9.46e-8, 9.007e-8, 8.592e-8, 8.195e-8, 7.816e-8,
2499 7.483e-8, 7.193e-8, 6.892e-8, 6.642e-8, 6.386e-8, 6.154e-8,
2500 5.949e-8, 5.764e-8, 5.622e-8, 5.479e-8, 5.364e-8, 5.301e-8,
2501 5.267e-8, 5.263e-8, 5.313e-8, 5.41e-8, 5.55e-8, 5.745e-8,
2502 6.003e-8, 6.311e-8, 6.713e-8, 7.173e-8, 7.724e-8, 8.368e-8,
2503 9.121e-8, 9.986e-8, 1.097e-7, 1.209e-7, 1.338e-7, 1.486e-7,
2504 1.651e-7, 1.837e-7, 2.048e-7, 2.289e-7, 2.557e-7, 2.857e-7,
2505 3.195e-7, 3.587e-7, 4.015e-7, 4.497e-7, 5.049e-7, 5.665e-7,
2506 6.366e-7, 7.121e-7, 7.996e-7, 8.946e-7, 1.002e-6, 1.117e-6,
2507 1.262e-6, 1.416e-6, 1.611e-6, 1.807e-6, 2.056e-6, 2.351e-6,
2508 2.769e-6, 3.138e-6, 3.699e-6, 4.386e-6, 5.041e-6, 6.074e-6,
2509 6.812e-6, 7.79e-6, 8.855e-6, 1.014e-5, 1.095e-5, 1.245e-5,
2510 1.316e-5, 1.39e-5, 1.504e-5, 1.583e-5, 1.617e-5, 1.652e-5,
2511 1.713e-5, 1.724e-5, 1.715e-5, 1.668e-5, 1.629e-5, 1.552e-5,
2512 1.478e-5, 1.34e-5, 1.245e-5, 1.121e-5, 9.575e-6, 8.956e-6,
2513 7.345e-6, 6.597e-6, 5.612e-6, 4.818e-6, 4.165e-6, 3.579e-6,
2514 3.041e-6, 2.623e-6, 2.29e-6, 1.984e-6, 1.748e-6, 1.534e-6,
2515 1.369e-6, 1.219e-6, 1.092e-6, 9.8e-7, 8.762e-7, 7.896e-7,
2516 7.104e-7, 6.364e-7, 5.691e-7, 5.107e-7, 4.575e-7, 4.09e-7,
2517 3.667e-7, 3.287e-7, 2.931e-7, 2.633e-7, 2.356e-7, 2.111e-7,
2518 1.895e-7, 1.697e-7, 1.525e-7, 1.369e-7, 1.233e-7, 1.114e-7,
2519 9.988e-8, 9.004e-8, 8.149e-8, 7.352e-8, 6.662e-8, 6.03e-8,
2520 5.479e-8, 4.974e-8, 4.532e-8, 4.129e-8, 3.781e-8, 3.462e-8,
2521 3.176e-8, 2.919e-8, 2.687e-8, 2.481e-8, 2.292e-8, 2.119e-8,
2522 1.967e-8, 1.828e-8, 1.706e-8, 1.589e-8, 1.487e-8, 1.393e-8,
2523 1.307e-8, 1.228e-8, 1.156e-8, 1.089e-8, 1.028e-8, 9.696e-9,
2524 9.159e-9, 8.658e-9, 8.187e-9, 7.746e-9, 7.34e-9, 6.953e-9,
2525 6.594e-9, 6.259e-9, 5.948e-9, 5.66e-9, 5.386e-9, 5.135e-9,
2526 4.903e-9, 4.703e-9, 4.515e-9, 4.362e-9, 4.233e-9, 4.117e-9,
2527 4.017e-9, 3.962e-9, 3.924e-9, 3.905e-9, 3.922e-9, 3.967e-9,
2528 4.046e-9, 4.165e-9, 4.32e-9, 4.522e-9, 4.769e-9, 5.083e-9,
2529 5.443e-9, 5.872e-9, 6.366e-9, 6.949e-9, 7.601e-9, 8.371e-9,
2530 9.22e-9, 1.02e-8, 1.129e-8, 1.251e-8, 1.393e-8, 1.542e-8,
2531 1.72e-8, 1.926e-8, 2.152e-8, 2.392e-8, 2.678e-8, 3.028e-8,
2532 3.39e-8, 3.836e-8, 4.309e-8, 4.9e-8, 5.481e-8, 6.252e-8,
2533 7.039e-8, 7.883e-8, 8.849e-8, 1.012e-7, 1.142e-7, 1.3e-7,
2534 1.475e-7, 1.732e-7, 1.978e-7, 2.304e-7, 2.631e-7, 2.988e-7,
2535 3.392e-7, 3.69e-7, 4.355e-7, 4.672e-7, 5.11e-7, 5.461e-7,
2536 5.828e-7, 6.233e-7, 6.509e-7, 6.672e-7, 6.969e-7, 7.104e-7,
2537 7.439e-7, 7.463e-7, 7.708e-7, 7.466e-7, 7.668e-7, 7.549e-7,
2538 7.586e-7, 7.384e-7, 7.439e-7, 7.785e-7, 7.915e-7, 8.31e-7,
2539 8.745e-7, 9.558e-7, 1.038e-6, 1.173e-6, 1.304e-6, 1.452e-6,
2540 1.671e-6, 1.931e-6, 2.239e-6, 2.578e-6, 3.032e-6, 3.334e-6,
2541 3.98e-6, 4.3e-6, 4.518e-6, 5.321e-6, 5.508e-6, 6.211e-6, 6.59e-6,
2542 7.046e-6, 7.555e-6, 7.558e-6, 7.875e-6, 8.319e-6, 8.433e-6,
2543 8.59e-6, 8.503e-6, 8.304e-6, 8.336e-6, 7.739e-6, 7.301e-6,
2544 6.827e-6, 6.078e-6, 5.551e-6, 4.762e-6, 4.224e-6, 3.538e-6,
2545 2.984e-6, 2.619e-6, 2.227e-6, 1.923e-6, 1.669e-6, 1.462e-6,
2546 1.294e-6, 1.155e-6, 1.033e-6, 9.231e-7, 8.238e-7, 7.36e-7,
2547 6.564e-7, 5.869e-7, 5.236e-7, 4.673e-7, 4.174e-7, 3.736e-7,
2548 3.33e-7, 2.976e-7, 2.657e-7, 2.367e-7, 2.106e-7, 1.877e-7,
2549 1.671e-7, 1.494e-7, 1.332e-7, 1.192e-7, 1.065e-7, 9.558e-8,
2550 8.586e-8, 7.717e-8, 6.958e-8, 6.278e-8, 5.666e-8, 5.121e-8,
2551 4.647e-8, 4.213e-8, 3.815e-8, 3.459e-8, 3.146e-8, 2.862e-8,
2552 2.604e-8, 2.375e-8, 2.162e-8, 1.981e-8, 1.817e-8, 1.67e-8,
2553 1.537e-8, 1.417e-8, 1.31e-8, 1.215e-8, 1.128e-8, 1.05e-8,
2554 9.793e-9, 9.158e-9, 8.586e-9, 8.068e-9, 7.595e-9, 7.166e-9,
2555 6.778e-9, 6.427e-9, 6.108e-9, 5.826e-9, 5.571e-9, 5.347e-9,
2556 5.144e-9, 4.968e-9, 4.822e-9, 4.692e-9, 4.589e-9, 4.506e-9,
2557 4.467e-9, 4.44e-9, 4.466e-9, 4.515e-9, 4.718e-9, 4.729e-9,
2558 4.937e-9, 5.249e-9, 5.466e-9, 5.713e-9, 6.03e-9, 6.436e-9,
2559 6.741e-9, 7.33e-9, 7.787e-9, 8.414e-9, 8.908e-9, 9.868e-9,
2560 1.069e-8, 1.158e-8, 1.253e-8, 1.3e-8, 1.409e-8, 1.47e-8,
2561 1.548e-8, 1.612e-8, 1.666e-8, 1.736e-8, 1.763e-8, 1.812e-8,
2562 1.852e-8, 1.923e-8, 1.897e-8, 1.893e-8, 1.888e-8, 1.868e-8,
2563 1.895e-8, 1.899e-8, 1.876e-8, 1.96e-8, 2.02e-8, 2.121e-8,
2564 2.239e-8, 2.379e-8, 2.526e-8, 2.766e-8, 2.994e-8, 3.332e-8,
2565 3.703e-8, 4.158e-8, 4.774e-8, 5.499e-8, 6.355e-8, 7.349e-8,
2566 8.414e-8, 9.846e-8, 1.143e-7, 1.307e-7, 1.562e-7, 1.817e-7,
2567 2.011e-7, 2.192e-7, 2.485e-7, 2.867e-7, 3.035e-7, 3.223e-7,
2568 3.443e-7, 3.617e-7, 3.793e-7, 3.793e-7, 3.839e-7, 4.081e-7,
2569 4.117e-7, 4.085e-7, 3.92e-7, 3.851e-7, 3.754e-7, 3.49e-7,
2570 3.229e-7, 2.978e-7, 2.691e-7, 2.312e-7, 2.029e-7, 1.721e-7,
2571 1.472e-7, 1.308e-7, 1.132e-7, 9.736e-8, 8.458e-8, 7.402e-8,
2572 6.534e-8, 5.811e-8, 5.235e-8, 4.762e-8, 4.293e-8, 3.896e-8,
2573 3.526e-8, 3.165e-8, 2.833e-8, 2.551e-8, 2.288e-8, 2.036e-8,
2574 1.82e-8, 1.626e-8, 1.438e-8, 1.299e-8, 1.149e-8, 1.03e-8,
2575 9.148e-9, 8.122e-9, 7.264e-9, 6.425e-9, 5.777e-9, 5.06e-9,
2576 4.502e-9, 4.013e-9, 3.567e-9, 3.145e-9, 2.864e-9, 2.553e-9,
2577 2.311e-9, 2.087e-9, 1.886e-9, 1.716e-9, 1.556e-9, 1.432e-9,
2578 1.311e-9, 1.202e-9, 1.104e-9, 1.013e-9, 9.293e-10, 8.493e-10,
2579 7.79e-10, 7.185e-10, 6.642e-10, 6.141e-10, 5.684e-10, 5.346e-10,
2580 5.032e-10, 4.725e-10, 4.439e-10, 4.176e-10, 3.93e-10, 3.714e-10,
2581 3.515e-10, 3.332e-10, 3.167e-10, 3.02e-10, 2.887e-10, 2.769e-10,
2582 2.665e-10, 2.578e-10, 2.503e-10, 2.436e-10, 2.377e-10, 2.342e-10,
2583 2.305e-10, 2.296e-10, 2.278e-10, 2.321e-10, 2.355e-10, 2.402e-10,
2584 2.478e-10, 2.67e-10, 2.848e-10, 2.982e-10, 3.263e-10, 3.438e-10,
2585 3.649e-10, 3.829e-10, 4.115e-10, 4.264e-10, 4.473e-10, 4.63e-10,
2586 4.808e-10, 4.995e-10, 5.142e-10, 5.313e-10, 5.318e-10, 5.358e-10,
2587 5.452e-10, 5.507e-10, 5.698e-10, 5.782e-10, 5.983e-10, 6.164e-10,
2588 6.532e-10, 6.811e-10, 7.624e-10, 8.302e-10, 9.067e-10, 9.937e-10,
2589 1.104e-9, 1.221e-9, 1.361e-9, 1.516e-9, 1.675e-9, 1.883e-9,
2590 2.101e-9, 2.349e-9, 2.614e-9, 2.92e-9, 3.305e-9, 3.724e-9,
2591 4.142e-9, 4.887e-9, 5.614e-9, 6.506e-9, 7.463e-9, 8.817e-9,
2592 9.849e-9, 1.187e-8, 1.321e-8, 1.474e-8, 1.698e-8, 1.794e-8,
2593 2.09e-8, 2.211e-8, 2.362e-8, 2.556e-8, 2.729e-8, 2.88e-8,
2594 3.046e-8, 3.167e-8, 3.367e-8, 3.457e-8, 3.59e-8, 3.711e-8,
2595 3.826e-8, 4.001e-8, 4.211e-8, 4.315e-8, 4.661e-8, 5.01e-8,
2596 5.249e-8, 5.84e-8, 6.628e-8, 7.512e-8, 8.253e-8, 9.722e-8,
2597 1.067e-7, 1.153e-7, 1.347e-7, 1.428e-7, 1.577e-7, 1.694e-7,
2598 1.833e-7, 1.938e-7, 2.108e-7, 2.059e-7, 2.157e-7, 2.185e-7,
2599 2.208e-7, 2.182e-7, 2.093e-7, 2.014e-7, 1.962e-7, 1.819e-7,
2600 1.713e-7, 1.51e-7, 1.34e-7, 1.154e-7, 9.89e-8, 8.88e-8, 7.673e-8,
2601 6.599e-8, 5.73e-8, 5.081e-8, 4.567e-8, 4.147e-8, 3.773e-8,
2602 3.46e-8, 3.194e-8, 2.953e-8, 2.759e-8, 2.594e-8, 2.442e-8,
2603 2.355e-8, 2.283e-8, 2.279e-8, 2.231e-8, 2.279e-8, 2.239e-8,
2604 2.21e-8, 2.309e-8, 2.293e-8, 2.352e-8, 2.415e-8, 2.43e-8,
2605 2.426e-8, 2.465e-8, 2.5e-8, 2.496e-8, 2.465e-8, 2.445e-8,
2606 2.383e-8, 2.299e-8, 2.165e-8, 2.113e-8, 1.968e-8, 1.819e-8,
2607 1.644e-8, 1.427e-8, 1.27e-8, 1.082e-8, 9.428e-9, 8.091e-9,
2608 6.958e-9, 5.988e-9, 5.246e-9, 4.601e-9, 4.098e-9, 3.664e-9,
2609 3.287e-9, 2.942e-9, 2.656e-9, 2.364e-9, 2.118e-9, 1.903e-9,
2610 1.703e-9, 1.525e-9, 1.365e-9, 1.229e-9, 1.107e-9, 9.96e-10,
2611 8.945e-10, 8.08e-10, 7.308e-10, 6.616e-10, 5.994e-10, 5.422e-10,
2612 4.929e-10, 4.478e-10, 4.07e-10, 3.707e-10, 3.379e-10, 3.087e-10,
2613 2.823e-10, 2.592e-10, 2.385e-10, 2.201e-10, 2.038e-10, 1.897e-10,
2614 1.774e-10, 1.667e-10, 1.577e-10, 1.502e-10, 1.437e-10, 1.394e-10,
2615 1.358e-10, 1.324e-10, 1.329e-10, 1.324e-10, 1.36e-10, 1.39e-10,
2616 1.424e-10, 1.544e-10, 1.651e-10, 1.817e-10, 1.984e-10, 2.195e-10,
2617 2.438e-10, 2.7e-10, 2.991e-10, 3.322e-10, 3.632e-10, 3.957e-10,
2618 4.36e-10, 4.701e-10, 5.03e-10, 5.381e-10, 5.793e-10, 6.19e-10,
2619 6.596e-10, 7.004e-10, 7.561e-10, 7.934e-10, 8.552e-10, 9.142e-10,
2620 9.57e-10, 1.027e-9, 1.097e-9, 1.193e-9, 1.334e-9, 1.47e-9,
2621 1.636e-9, 1.871e-9, 2.122e-9, 2.519e-9, 2.806e-9, 3.203e-9,
2622 3.846e-9, 4.362e-9, 5.114e-9, 5.643e-9, 6.305e-9, 6.981e-9,
2623 7.983e-9, 8.783e-9, 9.419e-9, 1.017e-8, 1.063e-8, 1.121e-8,
2624 1.13e-8, 1.201e-8, 1.225e-8, 1.232e-8, 1.223e-8, 1.177e-8,
2625 1.151e-8, 1.116e-8, 1.047e-8, 9.698e-9, 8.734e-9, 8.202e-9,
2626 7.041e-9, 6.074e-9, 5.172e-9, 4.468e-9, 3.913e-9, 3.414e-9,
2627 2.975e-9, 2.65e-9, 2.406e-9, 2.173e-9, 2.009e-9, 1.861e-9,
2628 1.727e-9, 1.612e-9, 1.514e-9, 1.43e-9, 1.362e-9, 1.333e-9,
2629 1.288e-9, 1.249e-9, 1.238e-9, 1.228e-9, 1.217e-9, 1.202e-9,
2630 1.209e-9, 1.177e-9, 1.157e-9, 1.165e-9, 1.142e-9, 1.131e-9,
2631 1.138e-9, 1.117e-9, 1.1e-9, 1.069e-9, 1.023e-9, 1.005e-9,
2632 9.159e-10, 8.863e-10, 7.865e-10, 7.153e-10, 6.247e-10, 5.846e-10,
2633 5.133e-10, 4.36e-10, 3.789e-10, 3.335e-10, 2.833e-10, 2.483e-10,
2634 2.155e-10, 1.918e-10, 1.709e-10, 1.529e-10, 1.374e-10, 1.235e-10,
2635 1.108e-10, 9.933e-11, 8.932e-11, 8.022e-11, 7.224e-11, 6.52e-11,
2636 5.896e-11, 5.328e-11, 4.813e-11, 4.365e-11, 3.961e-11, 3.594e-11,
2637 3.266e-11, 2.967e-11, 2.701e-11, 2.464e-11, 2.248e-11, 2.054e-11,
2638 1.878e-11, 1.721e-11, 1.579e-11, 1.453e-11, 1.341e-11, 1.241e-11,
2639 1.154e-11, 1.078e-11, 1.014e-11, 9.601e-12, 9.167e-12, 8.838e-12,
2640 8.614e-12, 8.493e-12, 8.481e-12, 8.581e-12, 8.795e-12, 9.131e-12,
2641 9.601e-12, 1.021e-11, 1.097e-11, 1.191e-11, 1.303e-11, 1.439e-11,
2642 1.601e-11, 1.778e-11, 1.984e-11, 2.234e-11, 2.474e-11, 2.766e-11,
2643 3.085e-11, 3.415e-11, 3.821e-11, 4.261e-11, 4.748e-11, 5.323e-11,
2644 5.935e-11, 6.619e-11, 7.418e-11, 8.294e-11, 9.26e-11, 1.039e-10,
2645 1.156e-10, 1.297e-10, 1.46e-10, 1.641e-10, 1.858e-10, 2.1e-10,
2646 2.383e-10, 2.724e-10, 3.116e-10, 3.538e-10, 4.173e-10, 4.727e-10,
2647 5.503e-10, 6.337e-10, 7.32e-10, 8.298e-10, 9.328e-10, 1.059e-9,
2648 1.176e-9, 1.328e-9, 1.445e-9, 1.593e-9, 1.77e-9, 1.954e-9,
2649 2.175e-9, 2.405e-9, 2.622e-9, 2.906e-9, 3.294e-9, 3.713e-9,
2650 3.98e-9, 4.384e-9, 4.987e-9, 5.311e-9, 5.874e-9, 6.337e-9,
2651 7.027e-9, 7.39e-9, 7.769e-9, 8.374e-9, 8.605e-9, 9.165e-9,
2652 9.415e-9, 9.511e-9, 9.704e-9, 9.588e-9, 9.45e-9, 9.086e-9,
2653 8.798e-9, 8.469e-9, 7.697e-9, 7.168e-9, 6.255e-9, 5.772e-9,
2654 4.97e-9, 4.271e-9, 3.653e-9, 3.154e-9, 2.742e-9, 2.435e-9,
2655 2.166e-9, 1.936e-9, 1.731e-9, 1.556e-9, 1.399e-9, 1.272e-9,
2656 1.157e-9, 1.066e-9, 9.844e-10, 9.258e-10, 8.787e-10, 8.421e-10,
2657 8.083e-10, 8.046e-10, 8.067e-10, 8.181e-10, 8.325e-10, 8.517e-10,
2658 9.151e-10, 9.351e-10, 9.677e-10, 1.071e-9, 1.126e-9, 1.219e-9,
2659 1.297e-9, 1.408e-9, 1.476e-9, 1.517e-9, 1.6e-9, 1.649e-9,
2660 1.678e-9, 1.746e-9, 1.742e-9, 1.728e-9, 1.699e-9, 1.655e-9,
2661 1.561e-9, 1.48e-9, 1.451e-9, 1.411e-9, 1.171e-9, 1.106e-9,
2662 9.714e-10, 8.523e-10, 7.346e-10, 6.241e-10, 5.371e-10, 4.704e-10,
2663 4.144e-10, 3.683e-10, 3.292e-10, 2.942e-10, 2.62e-10, 2.341e-10,
2664 2.104e-10, 1.884e-10, 1.7e-10, 1.546e-10, 1.394e-10, 1.265e-10,
2665 1.14e-10, 1.019e-10, 9.279e-11, 8.283e-11, 7.458e-11, 6.668e-11,
2666 5.976e-11, 5.33e-11, 4.794e-11, 4.289e-11, 3.841e-11, 3.467e-11,
2667 3.13e-11, 2.832e-11, 2.582e-11, 2.356e-11, 2.152e-11, 1.97e-11,
2668 1.808e-11, 1.664e-11, 1.539e-11, 1.434e-11, 1.344e-11, 1.269e-11,
2669 1.209e-11, 1.162e-11, 1.129e-11, 1.108e-11, 1.099e-11, 1.103e-11,
2670 1.119e-11, 1.148e-11, 1.193e-11, 1.252e-11, 1.329e-11, 1.421e-11,
2671 1.555e-11, 1.685e-11, 1.839e-11, 2.054e-11, 2.317e-11, 2.571e-11,
2672 2.839e-11, 3.171e-11, 3.49e-11, 3.886e-11, 4.287e-11, 4.645e-11,
2673 5.047e-11, 5.592e-11, 6.109e-11, 6.628e-11, 7.381e-11, 8.088e-11,
2674 8.966e-11, 1.045e-10, 1.12e-10, 1.287e-10, 1.486e-10, 1.662e-10,
2675 1.866e-10, 2.133e-10, 2.524e-10, 2.776e-10, 3.204e-10, 3.559e-10,
2676 4.028e-10, 4.448e-10, 4.882e-10, 5.244e-10, 5.605e-10, 6.018e-10,
2677 6.328e-10, 6.579e-10, 6.541e-10, 7.024e-10, 7.074e-10, 7.068e-10,
2678 7.009e-10, 6.698e-10, 6.545e-10, 6.209e-10, 5.834e-10, 5.412e-10,
2679 5.001e-10, 4.231e-10, 3.727e-10, 3.211e-10, 2.833e-10, 2.447e-10,
2680 2.097e-10, 1.843e-10, 1.639e-10, 1.449e-10, 1.27e-10, 1.161e-10,
2681 1.033e-10, 9.282e-11, 8.407e-11, 7.639e-11, 7.023e-11, 6.474e-11,
2682 6.142e-11, 5.76e-11, 5.568e-11, 5.472e-11, 5.39e-11, 5.455e-11,
2683 5.54e-11, 5.587e-11, 6.23e-11, 6.49e-11, 6.868e-11, 7.382e-11,
2684 8.022e-11, 8.372e-11, 9.243e-11, 1.004e-10, 1.062e-10, 1.13e-10,
2685 1.176e-10, 1.244e-10, 1.279e-10, 1.298e-10, 1.302e-10, 1.312e-10,
2686 1.295e-10, 1.244e-10, 1.211e-10, 1.167e-10, 1.098e-10, 9.927e-11,
2687 8.854e-11, 8.011e-11, 7.182e-11, 5.923e-11, 5.212e-11, 4.453e-11,
2688 3.832e-11, 3.371e-11, 2.987e-11, 2.651e-11, 2.354e-11, 2.093e-11,
2689 1.863e-11, 1.662e-11, 1.486e-11, 1.331e-11, 1.193e-11, 1.071e-11,
2690 9.628e-12, 8.66e-12, 7.801e-12, 7.031e-12, 6.347e-12, 5.733e-12,
2691 5.182e-12, 4.695e-12, 4.26e-12, 3.874e-12, 3.533e-12, 3.235e-12,
2692 2.979e-12, 2.76e-12, 2.579e-12, 2.432e-12, 2.321e-12, 2.246e-12,
2693 2.205e-12, 2.196e-12, 2.223e-12, 2.288e-12, 2.387e-12, 2.525e-12,
2694 2.704e-12, 2.925e-12, 3.191e-12, 3.508e-12, 3.876e-12, 4.303e-12,
2695 4.793e-12, 5.347e-12, 5.978e-12, 6.682e-12, 7.467e-12, 8.34e-12,
2696 9.293e-12, 1.035e-11, 1.152e-11, 1.285e-11, 1.428e-11, 1.586e-11,
2697 1.764e-11, 1.972e-11, 2.214e-11, 2.478e-11, 2.776e-11, 3.151e-11,
2698 3.591e-11, 4.103e-11, 4.66e-11, 5.395e-11, 6.306e-11, 7.172e-11,
2699 8.358e-11, 9.67e-11, 1.11e-10, 1.325e-10, 1.494e-10, 1.736e-10,
2700 2.007e-10, 2.296e-10, 2.608e-10, 3.004e-10, 3.361e-10, 3.727e-10,
2701 4.373e-10, 4.838e-10, 5.483e-10, 6.006e-10, 6.535e-10, 6.899e-10,
2702 7.687e-10, 8.444e-10, 8.798e-10, 9.135e-10, 9.532e-10, 9.757e-10,
2703 9.968e-10, 1.006e-9, 9.949e-10, 9.789e-10, 9.564e-10, 9.215e-10,
2704 8.51e-10, 8.394e-10, 7.707e-10, 7.152e-10, 6.274e-10, 5.598e-10,
2705 5.028e-10, 4.3e-10, 3.71e-10, 3.245e-10, 2.809e-10, 2.461e-10,
2706 2.154e-10, 1.91e-10, 1.685e-10, 1.487e-10, 1.313e-10, 1.163e-10,
2707 1.031e-10, 9.172e-11, 8.221e-11, 7.382e-11, 6.693e-11, 6.079e-11,
2708 5.581e-11, 5.167e-11, 4.811e-11, 4.506e-11, 4.255e-11, 4.083e-11,
2709 3.949e-11, 3.881e-11, 3.861e-11, 3.858e-11, 3.951e-11, 4.045e-11,
2710 4.24e-11, 4.487e-11, 4.806e-11, 5.133e-11, 5.518e-11, 5.919e-11,
2711 6.533e-11, 7.031e-11, 7.762e-11, 8.305e-11, 9.252e-11, 9.727e-11,
2712 1.045e-10, 1.117e-10, 1.2e-10, 1.275e-10, 1.341e-10, 1.362e-10,
2713 1.438e-10, 1.45e-10, 1.455e-10, 1.455e-10, 1.434e-10, 1.381e-10,
2714 1.301e-10, 1.276e-10, 1.163e-10, 1.089e-10, 9.911e-11, 8.943e-11,
2715 7.618e-11, 6.424e-11, 5.717e-11, 4.866e-11, 4.257e-11, 3.773e-11,
2716 3.331e-11, 2.958e-11, 2.629e-11, 2.316e-11, 2.073e-11, 1.841e-11,
2717 1.635e-11, 1.464e-11, 1.31e-11, 1.16e-11, 1.047e-11, 9.408e-12,
2718 8.414e-12, 7.521e-12, 6.705e-12, 5.993e-12, 5.371e-12, 4.815e-12,
2719 4.338e-12, 3.921e-12, 3.567e-12, 3.265e-12, 3.01e-12, 2.795e-12,
2720 2.613e-12, 2.464e-12, 2.346e-12, 2.256e-12, 2.195e-12, 2.165e-12,
2721 2.166e-12, 2.198e-12, 2.262e-12, 2.364e-12, 2.502e-12, 2.682e-12,
2722 2.908e-12, 3.187e-12, 3.533e-12, 3.946e-12, 4.418e-12, 5.013e-12,
2723 5.708e-12, 6.379e-12, 7.43e-12, 8.39e-12, 9.51e-12, 1.078e-11,
2724 1.259e-11, 1.438e-11, 1.63e-11, 1.814e-11, 2.055e-11, 2.348e-11,
2725 2.664e-11, 2.956e-11, 3.3e-11, 3.677e-11, 4.032e-11, 4.494e-11,
2726 4.951e-11, 5.452e-11, 6.014e-11, 6.5e-11, 6.915e-11, 7.45e-11,
2727 7.971e-11, 8.468e-11, 8.726e-11, 8.995e-11, 9.182e-11, 9.509e-11,
2728 9.333e-11, 9.386e-11, 9.457e-11, 9.21e-11, 9.019e-11, 8.68e-11,
2729 8.298e-11, 7.947e-11, 7.46e-11, 7.082e-11, 6.132e-11, 5.855e-11,
2730 5.073e-11, 4.464e-11, 3.825e-11, 3.375e-11, 2.911e-11, 2.535e-11,
2731 2.16e-11, 1.907e-11, 1.665e-11, 1.463e-11, 1.291e-11, 1.133e-11,
2732 9.997e-12, 8.836e-12, 7.839e-12, 6.943e-12, 6.254e-12, 5.6e-12,
2733 5.029e-12, 4.529e-12, 4.102e-12, 3.737e-12, 3.428e-12, 3.169e-12,
2734 2.959e-12, 2.798e-12, 2.675e-12, 2.582e-12, 2.644e-12, 2.557e-12,
2735 2.614e-12, 2.717e-12, 2.874e-12, 3.056e-12, 3.187e-12, 3.631e-12,
2736 3.979e-12, 4.248e-12, 4.817e-12, 5.266e-12, 5.836e-12, 6.365e-12,
2737 6.807e-12, 7.47e-12, 7.951e-12, 8.636e-12, 8.972e-12, 9.314e-12,
2738 9.445e-12, 1.003e-11, 1.013e-11, 9.937e-12, 9.729e-12, 9.064e-12,
2739 9.119e-12, 9.124e-12, 8.704e-12, 8.078e-12, 7.47e-12, 6.329e-12,
2740 5.674e-12, 4.808e-12, 4.119e-12, 3.554e-12, 3.103e-12, 2.731e-12,
2741 2.415e-12, 2.15e-12, 1.926e-12, 1.737e-12, 1.578e-12, 1.447e-12,
2742 1.34e-12, 1.255e-12, 1.191e-12, 1.146e-12, 1.121e-12, 1.114e-12,
2743 1.126e-12, 1.156e-12, 1.207e-12, 1.278e-12, 1.372e-12, 1.49e-12,
2744 1.633e-12, 1.805e-12, 2.01e-12, 2.249e-12, 2.528e-12, 2.852e-12,
2745 3.228e-12, 3.658e-12, 4.153e-12, 4.728e-12, 5.394e-12, 6.176e-12,
2746 7.126e-12, 8.188e-12, 9.328e-12, 1.103e-11, 1.276e-11, 1.417e-11,
2747 1.615e-11, 1.84e-11, 2.155e-11, 2.429e-11, 2.826e-11, 3.222e-11,
2748 3.664e-11, 4.14e-11, 4.906e-11, 5.536e-11, 6.327e-11, 7.088e-11,
2749 8.316e-11, 9.242e-11, 1.07e-10, 1.223e-10, 1.341e-10, 1.553e-10,
2750 1.703e-10, 1.9e-10, 2.022e-10, 2.233e-10, 2.345e-10, 2.438e-10,
2751 2.546e-10, 2.599e-10, 2.661e-10, 2.703e-10, 2.686e-10, 2.662e-10,
2752 2.56e-10, 2.552e-10, 2.378e-10, 2.252e-10, 2.146e-10, 1.885e-10,
2753 1.668e-10, 1.441e-10, 1.295e-10, 1.119e-10, 9.893e-11, 8.687e-11,
2754 7.678e-11, 6.685e-11, 5.879e-11, 5.127e-11, 4.505e-11, 3.997e-11,
2755 3.511e-11
2756 };
2757
2758 static const double h2ofrn[2001] = { .01095, .01126, .01205, .01322, .0143,
2759 .01506, .01548, .01534, .01486, .01373, .01262, .01134, .01001,
2760 .008702, .007475, .006481, .00548, .0046, .003833, .00311,
2761 .002543, .002049, .00168, .001374, .001046, 8.193e-4, 6.267e-4,
2762 4.968e-4, 3.924e-4, 2.983e-4, 2.477e-4, 1.997e-4, 1.596e-4,
2763 1.331e-4, 1.061e-4, 8.942e-5, 7.168e-5, 5.887e-5, 4.848e-5,
2764 3.817e-5, 3.17e-5, 2.579e-5, 2.162e-5, 1.768e-5, 1.49e-5,
2765 1.231e-5, 1.013e-5, 8.555e-6, 7.328e-6, 6.148e-6, 5.207e-6,
2766 4.387e-6, 3.741e-6, 3.22e-6, 2.753e-6, 2.346e-6, 1.985e-6,
2767 1.716e-6, 1.475e-6, 1.286e-6, 1.122e-6, 9.661e-7, 8.284e-7,
2768 7.057e-7, 6.119e-7, 5.29e-7, 4.571e-7, 3.948e-7, 3.432e-7,
2769 2.983e-7, 2.589e-7, 2.265e-7, 1.976e-7, 1.704e-7, 1.456e-7,
2770 1.26e-7, 1.101e-7, 9.648e-8, 8.415e-8, 7.34e-8, 6.441e-8,
2771 5.643e-8, 4.94e-8, 4.276e-8, 3.703e-8, 3.227e-8, 2.825e-8,
2772 2.478e-8, 2.174e-8, 1.898e-8, 1.664e-8, 1.458e-8, 1.278e-8,
2773 1.126e-8, 9.891e-9, 8.709e-9, 7.652e-9, 6.759e-9, 5.975e-9,
2774 5.31e-9, 4.728e-9, 4.214e-9, 3.792e-9, 3.463e-9, 3.226e-9,
2775 2.992e-9, 2.813e-9, 2.749e-9, 2.809e-9, 2.913e-9, 3.037e-9,
2776 3.413e-9, 3.738e-9, 4.189e-9, 4.808e-9, 5.978e-9, 7.088e-9,
2777 8.071e-9, 9.61e-9, 1.21e-8, 1.5e-8, 1.764e-8, 2.221e-8, 2.898e-8,
2778 3.948e-8, 5.068e-8, 6.227e-8, 7.898e-8, 1.033e-7, 1.437e-7,
2779 1.889e-7, 2.589e-7, 3.59e-7, 4.971e-7, 7.156e-7, 9.983e-7,
2780 1.381e-6, 1.929e-6, 2.591e-6, 3.453e-6, 4.57e-6, 5.93e-6,
2781 7.552e-6, 9.556e-6, 1.183e-5, 1.425e-5, 1.681e-5, 1.978e-5,
2782 2.335e-5, 2.668e-5, 3.022e-5, 3.371e-5, 3.715e-5, 3.967e-5,
2783 4.06e-5, 4.01e-5, 3.809e-5, 3.491e-5, 3.155e-5, 2.848e-5,
2784 2.678e-5, 2.66e-5, 2.811e-5, 3.071e-5, 3.294e-5, 3.459e-5,
2785 3.569e-5, 3.56e-5, 3.434e-5, 3.186e-5, 2.916e-5, 2.622e-5,
2786 2.275e-5, 1.918e-5, 1.62e-5, 1.373e-5, 1.182e-5, 1.006e-5,
2787 8.556e-6, 7.26e-6, 6.107e-6, 5.034e-6, 4.211e-6, 3.426e-6,
2788 2.865e-6, 2.446e-6, 1.998e-6, 1.628e-6, 1.242e-6, 1.005e-6,
2789 7.853e-7, 6.21e-7, 5.071e-7, 4.156e-7, 3.548e-7, 2.825e-7,
2790 2.261e-7, 1.916e-7, 1.51e-7, 1.279e-7, 1.059e-7, 9.14e-8,
2791 7.707e-8, 6.17e-8, 5.311e-8, 4.263e-8, 3.518e-8, 2.961e-8,
2792 2.457e-8, 2.119e-8, 1.712e-8, 1.439e-8, 1.201e-8, 1.003e-8,
2793 8.564e-9, 7.199e-9, 6.184e-9, 5.206e-9, 4.376e-9, 3.708e-9,
2794 3.157e-9, 2.725e-9, 2.361e-9, 2.074e-9, 1.797e-9, 1.562e-9,
2795 1.364e-9, 1.196e-9, 1.042e-9, 8.862e-10, 7.648e-10, 6.544e-10,
2796 5.609e-10, 4.791e-10, 4.108e-10, 3.531e-10, 3.038e-10, 2.618e-10,
2797 2.268e-10, 1.969e-10, 1.715e-10, 1.496e-10, 1.308e-10, 1.147e-10,
2798 1.008e-10, 8.894e-11, 7.885e-11, 7.031e-11, 6.355e-11, 5.854e-11,
2799 5.534e-11, 5.466e-11, 5.725e-11, 6.447e-11, 7.943e-11, 1.038e-10,
2800 1.437e-10, 2.04e-10, 2.901e-10, 4.051e-10, 5.556e-10, 7.314e-10,
2801 9.291e-10, 1.134e-9, 1.321e-9, 1.482e-9, 1.596e-9, 1.669e-9,
2802 1.715e-9, 1.762e-9, 1.817e-9, 1.828e-9, 1.848e-9, 1.873e-9,
2803 1.902e-9, 1.894e-9, 1.864e-9, 1.841e-9, 1.797e-9, 1.704e-9,
2804 1.559e-9, 1.382e-9, 1.187e-9, 1.001e-9, 8.468e-10, 7.265e-10,
2805 6.521e-10, 6.381e-10, 6.66e-10, 7.637e-10, 9.705e-10, 1.368e-9,
2806 1.856e-9, 2.656e-9, 3.954e-9, 5.96e-9, 8.72e-9, 1.247e-8,
2807 1.781e-8, 2.491e-8, 3.311e-8, 4.272e-8, 5.205e-8, 6.268e-8,
2808 7.337e-8, 8.277e-8, 9.185e-8, 1.004e-7, 1.091e-7, 1.159e-7,
2809 1.188e-7, 1.175e-7, 1.124e-7, 1.033e-7, 9.381e-8, 8.501e-8,
2810 7.956e-8, 7.894e-8, 8.331e-8, 9.102e-8, 9.836e-8, 1.035e-7,
2811 1.064e-7, 1.06e-7, 1.032e-7, 9.808e-8, 9.139e-8, 8.442e-8,
2812 7.641e-8, 6.881e-8, 6.161e-8, 5.404e-8, 4.804e-8, 4.446e-8,
2813 4.328e-8, 4.259e-8, 4.421e-8, 4.673e-8, 4.985e-8, 5.335e-8,
2814 5.796e-8, 6.542e-8, 7.714e-8, 8.827e-8, 1.04e-7, 1.238e-7,
2815 1.499e-7, 1.829e-7, 2.222e-7, 2.689e-7, 3.303e-7, 3.981e-7,
2816 4.84e-7, 5.91e-7, 7.363e-7, 9.087e-7, 1.139e-6, 1.455e-6,
2817 1.866e-6, 2.44e-6, 3.115e-6, 3.941e-6, 4.891e-6, 5.992e-6,
2818 7.111e-6, 8.296e-6, 9.21e-6, 9.987e-6, 1.044e-5, 1.073e-5,
2819 1.092e-5, 1.106e-5, 1.138e-5, 1.171e-5, 1.186e-5, 1.186e-5,
2820 1.179e-5, 1.166e-5, 1.151e-5, 1.16e-5, 1.197e-5, 1.241e-5,
2821 1.268e-5, 1.26e-5, 1.184e-5, 1.063e-5, 9.204e-6, 7.584e-6,
2822 6.053e-6, 4.482e-6, 3.252e-6, 2.337e-6, 1.662e-6, 1.18e-6,
2823 8.15e-7, 5.95e-7, 4.354e-7, 3.302e-7, 2.494e-7, 1.93e-7,
2824 1.545e-7, 1.25e-7, 1.039e-7, 8.602e-8, 7.127e-8, 5.897e-8,
2825 4.838e-8, 4.018e-8, 3.28e-8, 2.72e-8, 2.307e-8, 1.972e-8,
2826 1.654e-8, 1.421e-8, 1.174e-8, 1.004e-8, 8.739e-9, 7.358e-9,
2827 6.242e-9, 5.303e-9, 4.567e-9, 3.94e-9, 3.375e-9, 2.864e-9,
2828 2.422e-9, 2.057e-9, 1.75e-9, 1.505e-9, 1.294e-9, 1.101e-9,
2829 9.401e-10, 8.018e-10, 6.903e-10, 5.965e-10, 5.087e-10, 4.364e-10,
2830 3.759e-10, 3.247e-10, 2.809e-10, 2.438e-10, 2.123e-10, 1.853e-10,
2831 1.622e-10, 1.426e-10, 1.26e-10, 1.125e-10, 1.022e-10, 9.582e-11,
2832 9.388e-11, 9.801e-11, 1.08e-10, 1.276e-10, 1.551e-10, 1.903e-10,
2833 2.291e-10, 2.724e-10, 3.117e-10, 3.4e-10, 3.562e-10, 3.625e-10,
2834 3.619e-10, 3.429e-10, 3.221e-10, 2.943e-10, 2.645e-10, 2.338e-10,
2835 2.062e-10, 1.901e-10, 1.814e-10, 1.827e-10, 1.906e-10, 1.984e-10,
2836 2.04e-10, 2.068e-10, 2.075e-10, 2.018e-10, 1.959e-10, 1.897e-10,
2837 1.852e-10, 1.791e-10, 1.696e-10, 1.634e-10, 1.598e-10, 1.561e-10,
2838 1.518e-10, 1.443e-10, 1.377e-10, 1.346e-10, 1.342e-10, 1.375e-10,
2839 1.525e-10, 1.767e-10, 2.108e-10, 2.524e-10, 2.981e-10, 3.477e-10,
2840 4.262e-10, 5.326e-10, 6.646e-10, 8.321e-10, 1.069e-9, 1.386e-9,
2841 1.743e-9, 2.216e-9, 2.808e-9, 3.585e-9, 4.552e-9, 5.907e-9,
2842 7.611e-9, 9.774e-9, 1.255e-8, 1.666e-8, 2.279e-8, 3.221e-8,
2843 4.531e-8, 6.4e-8, 9.187e-8, 1.295e-7, 1.825e-7, 2.431e-7,
2844 3.181e-7, 4.009e-7, 4.941e-7, 5.88e-7, 6.623e-7, 7.155e-7,
2845 7.451e-7, 7.594e-7, 7.541e-7, 7.467e-7, 7.527e-7, 7.935e-7,
2846 8.461e-7, 8.954e-7, 9.364e-7, 9.843e-7, 1.024e-6, 1.05e-6,
2847 1.059e-6, 1.074e-6, 1.072e-6, 1.043e-6, 9.789e-7, 8.803e-7,
2848 7.662e-7, 6.378e-7, 5.133e-7, 3.958e-7, 2.914e-7, 2.144e-7,
2849 1.57e-7, 1.14e-7, 8.47e-8, 6.2e-8, 4.657e-8, 3.559e-8, 2.813e-8,
2850 2.222e-8, 1.769e-8, 1.391e-8, 1.125e-8, 9.186e-9, 7.704e-9,
2851 6.447e-9, 5.381e-9, 4.442e-9, 3.669e-9, 3.057e-9, 2.564e-9,
2852 2.153e-9, 1.784e-9, 1.499e-9, 1.281e-9, 1.082e-9, 9.304e-10,
2853 8.169e-10, 6.856e-10, 5.866e-10, 5.043e-10, 4.336e-10, 3.731e-10,
2854 3.175e-10, 2.745e-10, 2.374e-10, 2.007e-10, 1.737e-10, 1.508e-10,
2855 1.302e-10, 1.13e-10, 9.672e-11, 8.375e-11, 7.265e-11, 6.244e-11,
2856 5.343e-11, 4.654e-11, 3.975e-11, 3.488e-11, 3.097e-11, 2.834e-11,
2857 2.649e-11, 2.519e-11, 2.462e-11, 2.443e-11, 2.44e-11, 2.398e-11,
2858 2.306e-11, 2.183e-11, 2.021e-11, 1.821e-11, 1.599e-11, 1.403e-11,
2859 1.196e-11, 1.023e-11, 8.728e-12, 7.606e-12, 6.941e-12, 6.545e-12,
2860 6.484e-12, 6.6e-12, 6.718e-12, 6.785e-12, 6.746e-12, 6.724e-12,
2861 6.764e-12, 6.995e-12, 7.144e-12, 7.32e-12, 7.33e-12, 7.208e-12,
2862 6.789e-12, 6.09e-12, 5.337e-12, 4.62e-12, 4.037e-12, 3.574e-12,
2863 3.311e-12, 3.346e-12, 3.566e-12, 3.836e-12, 4.076e-12, 4.351e-12,
2864 4.691e-12, 5.114e-12, 5.427e-12, 6.167e-12, 7.436e-12, 8.842e-12,
2865 1.038e-11, 1.249e-11, 1.54e-11, 1.915e-11, 2.48e-11, 3.256e-11,
2866 4.339e-11, 5.611e-11, 7.519e-11, 1.037e-10, 1.409e-10, 1.883e-10,
2867 2.503e-10, 3.38e-10, 4.468e-10, 5.801e-10, 7.335e-10, 8.98e-10,
2868 1.11e-9, 1.363e-9, 1.677e-9, 2.104e-9, 2.681e-9, 3.531e-9,
2869 4.621e-9, 6.106e-9, 8.154e-9, 1.046e-8, 1.312e-8, 1.607e-8,
2870 1.948e-8, 2.266e-8, 2.495e-8, 2.655e-8, 2.739e-8, 2.739e-8,
2871 2.662e-8, 2.589e-8, 2.59e-8, 2.664e-8, 2.833e-8, 3.023e-8,
2872 3.305e-8, 3.558e-8, 3.793e-8, 3.961e-8, 4.056e-8, 4.102e-8,
2873 4.025e-8, 3.917e-8, 3.706e-8, 3.493e-8, 3.249e-8, 3.096e-8,
2874 3.011e-8, 3.111e-8, 3.395e-8, 3.958e-8, 4.875e-8, 6.066e-8,
2875 7.915e-8, 1.011e-7, 1.3e-7, 1.622e-7, 2.003e-7, 2.448e-7,
2876 2.863e-7, 3.317e-7, 3.655e-7, 3.96e-7, 4.098e-7, 4.168e-7,
2877 4.198e-7, 4.207e-7, 4.289e-7, 4.384e-7, 4.471e-7, 4.524e-7,
2878 4.574e-7, 4.633e-7, 4.785e-7, 5.028e-7, 5.371e-7, 5.727e-7,
2879 5.955e-7, 5.998e-7, 5.669e-7, 5.082e-7, 4.397e-7, 3.596e-7,
2880 2.814e-7, 2.074e-7, 1.486e-7, 1.057e-7, 7.25e-8, 4.946e-8,
2881 3.43e-8, 2.447e-8, 1.793e-8, 1.375e-8, 1.096e-8, 9.091e-9,
2882 7.709e-9, 6.631e-9, 5.714e-9, 4.886e-9, 4.205e-9, 3.575e-9,
2883 3.07e-9, 2.631e-9, 2.284e-9, 2.002e-9, 1.745e-9, 1.509e-9,
2884 1.284e-9, 1.084e-9, 9.163e-10, 7.663e-10, 6.346e-10, 5.283e-10,
2885 4.354e-10, 3.59e-10, 2.982e-10, 2.455e-10, 2.033e-10, 1.696e-10,
2886 1.432e-10, 1.211e-10, 1.02e-10, 8.702e-11, 7.38e-11, 6.293e-11,
2887 5.343e-11, 4.532e-11, 3.907e-11, 3.365e-11, 2.945e-11, 2.558e-11,
2888 2.192e-11, 1.895e-11, 1.636e-11, 1.42e-11, 1.228e-11, 1.063e-11,
2889 9.348e-12, 8.2e-12, 7.231e-12, 6.43e-12, 5.702e-12, 5.052e-12,
2890 4.469e-12, 4e-12, 3.679e-12, 3.387e-12, 3.197e-12, 3.158e-12,
2891 3.327e-12, 3.675e-12, 4.292e-12, 5.437e-12, 7.197e-12, 1.008e-11,
2892 1.437e-11, 2.035e-11, 2.905e-11, 4.062e-11, 5.528e-11, 7.177e-11,
2893 9.064e-11, 1.109e-10, 1.297e-10, 1.473e-10, 1.652e-10, 1.851e-10,
2894 2.079e-10, 2.313e-10, 2.619e-10, 2.958e-10, 3.352e-10, 3.796e-10,
2895 4.295e-10, 4.923e-10, 5.49e-10, 5.998e-10, 6.388e-10, 6.645e-10,
2896 6.712e-10, 6.549e-10, 6.38e-10, 6.255e-10, 6.253e-10, 6.459e-10,
2897 6.977e-10, 7.59e-10, 8.242e-10, 8.92e-10, 9.403e-10, 9.701e-10,
2898 9.483e-10, 9.135e-10, 8.617e-10, 7.921e-10, 7.168e-10, 6.382e-10,
2899 5.677e-10, 5.045e-10, 4.572e-10, 4.312e-10, 4.145e-10, 4.192e-10,
2900 4.541e-10, 5.368e-10, 6.771e-10, 8.962e-10, 1.21e-9, 1.659e-9,
2901 2.33e-9, 3.249e-9, 4.495e-9, 5.923e-9, 7.642e-9, 9.607e-9,
2902 1.178e-8, 1.399e-8, 1.584e-8, 1.73e-8, 1.816e-8, 1.87e-8,
2903 1.868e-8, 1.87e-8, 1.884e-8, 1.99e-8, 2.15e-8, 2.258e-8,
2904 2.364e-8, 2.473e-8, 2.602e-8, 2.689e-8, 2.731e-8, 2.816e-8,
2905 2.859e-8, 2.839e-8, 2.703e-8, 2.451e-8, 2.149e-8, 1.787e-8,
2906 1.449e-8, 1.111e-8, 8.282e-9, 6.121e-9, 4.494e-9, 3.367e-9,
2907 2.487e-9, 1.885e-9, 1.503e-9, 1.249e-9, 1.074e-9, 9.427e-10,
2908 8.439e-10, 7.563e-10, 6.772e-10, 6.002e-10, 5.254e-10, 4.588e-10,
2909 3.977e-10, 3.449e-10, 3.003e-10, 2.624e-10, 2.335e-10, 2.04e-10,
2910 1.771e-10, 1.534e-10, 1.296e-10, 1.097e-10, 9.173e-11, 7.73e-11,
2911 6.547e-11, 5.191e-11, 4.198e-11, 3.361e-11, 2.732e-11, 2.244e-11,
2912 1.791e-11, 1.509e-11, 1.243e-11, 1.035e-11, 8.969e-12, 7.394e-12,
2913 6.323e-12, 5.282e-12, 4.543e-12, 3.752e-12, 3.14e-12, 2.6e-12,
2914 2.194e-12, 1.825e-12, 1.511e-12, 1.245e-12, 1.024e-12, 8.539e-13,
2915 7.227e-13, 6.102e-13, 5.189e-13, 4.43e-13, 3.774e-13, 3.236e-13,
2916 2.8e-13, 2.444e-13, 2.156e-13, 1.932e-13, 1.775e-13, 1.695e-13,
2917 1.672e-13, 1.704e-13, 1.825e-13, 2.087e-13, 2.614e-13, 3.377e-13,
2918 4.817e-13, 6.989e-13, 1.062e-12, 1.562e-12, 2.288e-12, 3.295e-12,
2919 4.55e-12, 5.965e-12, 7.546e-12, 9.395e-12, 1.103e-11, 1.228e-11,
2920 1.318e-11, 1.38e-11, 1.421e-11, 1.39e-11, 1.358e-11, 1.336e-11,
2921 1.342e-11, 1.356e-11, 1.424e-11, 1.552e-11, 1.73e-11, 1.951e-11,
2922 2.128e-11, 2.249e-11, 2.277e-11, 2.226e-11, 2.111e-11, 1.922e-11,
2923 1.775e-11, 1.661e-11, 1.547e-11, 1.446e-11, 1.323e-11, 1.21e-11,
2924 1.054e-11, 9.283e-12, 8.671e-12, 8.67e-12, 9.429e-12, 1.062e-11,
2925 1.255e-11, 1.506e-11, 1.818e-11, 2.26e-11, 2.831e-11, 3.723e-11,
2926 5.092e-11, 6.968e-11, 9.826e-11, 1.349e-10, 1.87e-10, 2.58e-10,
2927 3.43e-10, 4.424e-10, 5.521e-10, 6.812e-10, 8.064e-10, 9.109e-10,
2928 9.839e-10, 1.028e-9, 1.044e-9, 1.029e-9, 1.005e-9, 1.002e-9,
2929 1.038e-9, 1.122e-9, 1.233e-9, 1.372e-9, 1.524e-9, 1.665e-9,
2930 1.804e-9, 1.908e-9, 2.015e-9, 2.117e-9, 2.219e-9, 2.336e-9,
2931 2.531e-9, 2.805e-9, 3.189e-9, 3.617e-9, 4.208e-9, 4.911e-9,
2932 5.619e-9, 6.469e-9, 7.188e-9, 7.957e-9, 8.503e-9, 9.028e-9,
2933 9.571e-9, 9.99e-9, 1.055e-8, 1.102e-8, 1.132e-8, 1.141e-8,
2934 1.145e-8, 1.145e-8, 1.176e-8, 1.224e-8, 1.304e-8, 1.388e-8,
2935 1.445e-8, 1.453e-8, 1.368e-8, 1.22e-8, 1.042e-8, 8.404e-9,
2936 6.403e-9, 4.643e-9, 3.325e-9, 2.335e-9, 1.638e-9, 1.19e-9,
2937 9.161e-10, 7.412e-10, 6.226e-10, 5.516e-10, 5.068e-10, 4.831e-10,
2938 4.856e-10, 5.162e-10, 5.785e-10, 6.539e-10, 7.485e-10, 8.565e-10,
2939 9.534e-10, 1.052e-9, 1.115e-9, 1.173e-9, 1.203e-9, 1.224e-9,
2940 1.243e-9, 1.248e-9, 1.261e-9, 1.265e-9, 1.25e-9, 1.217e-9,
2941 1.176e-9, 1.145e-9, 1.153e-9, 1.199e-9, 1.278e-9, 1.366e-9,
2942 1.426e-9, 1.444e-9, 1.365e-9, 1.224e-9, 1.051e-9, 8.539e-10,
2943 6.564e-10, 4.751e-10, 3.404e-10, 2.377e-10, 1.631e-10, 1.114e-10,
2944 7.87e-11, 5.793e-11, 4.284e-11, 3.3e-11, 2.62e-11, 2.152e-11,
2945 1.777e-11, 1.496e-11, 1.242e-11, 1.037e-11, 8.725e-12, 7.004e-12,
2946 5.718e-12, 4.769e-12, 3.952e-12, 3.336e-12, 2.712e-12, 2.213e-12,
2947 1.803e-12, 1.492e-12, 1.236e-12, 1.006e-12, 8.384e-13, 7.063e-13,
2948 5.879e-13, 4.93e-13, 4.171e-13, 3.569e-13, 3.083e-13, 2.688e-13,
2949 2.333e-13, 2.035e-13, 1.82e-13, 1.682e-13, 1.635e-13, 1.674e-13,
2950 1.769e-13, 2.022e-13, 2.485e-13, 3.127e-13, 4.25e-13, 5.928e-13,
2951 8.514e-13, 1.236e-12, 1.701e-12, 2.392e-12, 3.231e-12, 4.35e-12,
2952 5.559e-12, 6.915e-12, 8.519e-12, 1.013e-11, 1.146e-11, 1.24e-11,
2953 1.305e-11, 1.333e-11, 1.318e-11, 1.263e-11, 1.238e-11, 1.244e-11,
2954 1.305e-11, 1.432e-11, 1.623e-11, 1.846e-11, 2.09e-11, 2.328e-11,
2955 2.526e-11, 2.637e-11, 2.702e-11, 2.794e-11, 2.889e-11, 2.989e-11,
2956 3.231e-11, 3.68e-11, 4.375e-11, 5.504e-11, 7.159e-11, 9.502e-11,
2957 1.279e-10, 1.645e-10, 2.098e-10, 2.618e-10, 3.189e-10, 3.79e-10,
2958 4.303e-10, 4.753e-10, 5.027e-10, 5.221e-10, 5.293e-10, 5.346e-10,
2959 5.467e-10, 5.796e-10, 6.2e-10, 6.454e-10, 6.705e-10, 6.925e-10,
2960 7.233e-10, 7.35e-10, 7.538e-10, 7.861e-10, 8.077e-10, 8.132e-10,
2961 7.749e-10, 7.036e-10, 6.143e-10, 5.093e-10, 4.089e-10, 3.092e-10,
2962 2.299e-10, 1.705e-10, 1.277e-10, 9.723e-11, 7.533e-11, 6.126e-11,
2963 5.154e-11, 4.428e-11, 3.913e-11, 3.521e-11, 3.297e-11, 3.275e-11,
2964 3.46e-11, 3.798e-11, 4.251e-11, 4.745e-11, 5.232e-11, 5.606e-11,
2965 5.82e-11, 5.88e-11, 5.79e-11, 5.661e-11, 5.491e-11, 5.366e-11,
2966 5.341e-11, 5.353e-11, 5.336e-11, 5.293e-11, 5.248e-11, 5.235e-11,
2967 5.208e-11, 5.322e-11, 5.521e-11, 5.725e-11, 5.827e-11, 5.685e-11,
2968 5.245e-11, 4.612e-11, 3.884e-11, 3.129e-11, 2.404e-11, 1.732e-11,
2969 1.223e-11, 8.574e-12, 5.888e-12, 3.986e-12, 2.732e-12, 1.948e-12,
2970 1.414e-12, 1.061e-12, 8.298e-13, 6.612e-13, 5.413e-13, 4.472e-13,
2971 3.772e-13, 3.181e-13, 2.645e-13, 2.171e-13, 1.778e-13, 1.464e-13,
2972 1.183e-13, 9.637e-14, 7.991e-14, 6.668e-14, 5.57e-14, 4.663e-14,
2973 3.848e-14, 3.233e-14, 2.706e-14, 2.284e-14, 1.944e-14, 1.664e-14,
2974 1.43e-14, 1.233e-14, 1.066e-14, 9.234e-15, 8.023e-15, 6.993e-15,
2975 6.119e-15, 5.384e-15, 4.774e-15, 4.283e-15, 3.916e-15, 3.695e-15,
2976 3.682e-15, 4.004e-15, 4.912e-15, 6.853e-15, 1.056e-14, 1.712e-14,
2977 2.804e-14, 4.516e-14, 7.113e-14, 1.084e-13, 1.426e-13, 1.734e-13,
2978 1.978e-13, 2.194e-13, 2.388e-13, 2.489e-13, 2.626e-13, 2.865e-13,
2979 3.105e-13, 3.387e-13, 3.652e-13, 3.984e-13, 4.398e-13, 4.906e-13,
2980 5.55e-13, 6.517e-13, 7.813e-13, 9.272e-13, 1.164e-12, 1.434e-12,
2981 1.849e-12, 2.524e-12, 3.328e-12, 4.523e-12, 6.108e-12, 8.207e-12,
2982 1.122e-11, 1.477e-11, 1.9e-11, 2.412e-11, 2.984e-11, 3.68e-11,
2983 4.353e-11, 4.963e-11, 5.478e-11, 5.903e-11, 6.233e-11, 6.483e-11,
2984 6.904e-11, 7.569e-11, 8.719e-11, 1.048e-10, 1.278e-10, 1.557e-10,
2985 1.869e-10, 2.218e-10, 2.61e-10, 2.975e-10, 3.371e-10, 3.746e-10,
2986 4.065e-10, 4.336e-10, 4.503e-10, 4.701e-10, 4.8e-10, 4.917e-10,
2987 5.038e-10, 5.128e-10, 5.143e-10, 5.071e-10, 5.019e-10, 5.025e-10,
2988 5.183e-10, 5.496e-10, 5.877e-10, 6.235e-10, 6.42e-10, 6.234e-10,
2989 5.698e-10, 4.916e-10, 4.022e-10, 3.126e-10, 2.282e-10, 1.639e-10,
2990 1.142e-10, 7.919e-11, 5.69e-11, 4.313e-11, 3.413e-11, 2.807e-11,
2991 2.41e-11, 2.166e-11, 2.024e-11, 1.946e-11, 1.929e-11, 1.963e-11,
2992 2.035e-11, 2.162e-11, 2.305e-11, 2.493e-11, 2.748e-11, 3.048e-11,
2993 3.413e-11, 3.754e-11, 4.155e-11, 4.635e-11, 5.11e-11, 5.734e-11,
2994 6.338e-11, 6.99e-11, 7.611e-11, 8.125e-11, 8.654e-11, 8.951e-11,
2995 9.182e-11, 9.31e-11, 9.273e-11, 9.094e-11, 8.849e-11, 8.662e-11,
2996 8.67e-11, 8.972e-11, 9.566e-11, 1.025e-10, 1.083e-10, 1.111e-10,
2997 1.074e-10, 9.771e-11, 8.468e-11, 6.958e-11, 5.47e-11, 4.04e-11,
2998 2.94e-11, 2.075e-11, 1.442e-11, 1.01e-11, 7.281e-12, 5.409e-12,
2999 4.138e-12, 3.304e-12, 2.784e-12, 2.473e-12, 2.273e-12, 2.186e-12,
3000 2.118e-12, 2.066e-12, 1.958e-12, 1.818e-12, 1.675e-12, 1.509e-12,
3001 1.349e-12, 1.171e-12, 9.838e-13, 8.213e-13, 6.765e-13, 5.378e-13,
3002 4.161e-13, 3.119e-13, 2.279e-13, 1.637e-13, 1.152e-13, 8.112e-14,
3003 5.919e-14, 4.47e-14, 3.492e-14, 2.811e-14, 2.319e-14, 1.948e-14,
3004 1.66e-14, 1.432e-14, 1.251e-14, 1.109e-14, 1.006e-14, 9.45e-15,
3005 9.384e-15, 1.012e-14, 1.216e-14, 1.636e-14, 2.305e-14, 3.488e-14,
3006 5.572e-14, 8.479e-14, 1.265e-13, 1.905e-13, 2.73e-13, 3.809e-13,
3007 4.955e-13, 6.303e-13, 7.861e-13, 9.427e-13, 1.097e-12, 1.212e-12,
3008 1.328e-12, 1.415e-12, 1.463e-12, 1.495e-12, 1.571e-12, 1.731e-12,
3009 1.981e-12, 2.387e-12, 2.93e-12, 3.642e-12, 4.584e-12, 5.822e-12,
3010 7.278e-12, 9.193e-12, 1.135e-11, 1.382e-11, 1.662e-11, 1.958e-11,
3011 2.286e-11, 2.559e-11, 2.805e-11, 2.988e-11, 3.106e-11, 3.182e-11,
3012 3.2e-11, 3.258e-11, 3.362e-11, 3.558e-11, 3.688e-11, 3.8e-11,
3013 3.929e-11, 4.062e-11, 4.186e-11, 4.293e-11, 4.48e-11, 4.643e-11,
3014 4.704e-11, 4.571e-11, 4.206e-11, 3.715e-11, 3.131e-11, 2.541e-11,
3015 1.978e-11, 1.508e-11, 1.146e-11, 8.7e-12, 6.603e-12, 5.162e-12,
3016 4.157e-12, 3.408e-12, 2.829e-12, 2.405e-12, 2.071e-12, 1.826e-12,
3017 1.648e-12, 1.542e-12, 1.489e-12, 1.485e-12, 1.493e-12, 1.545e-12,
3018 1.637e-12, 1.814e-12, 2.061e-12, 2.312e-12, 2.651e-12, 3.03e-12,
3019 3.46e-12, 3.901e-12, 4.306e-12, 4.721e-12, 5.008e-12, 5.281e-12,
3020 5.541e-12, 5.791e-12, 6.115e-12, 6.442e-12, 6.68e-12, 6.791e-12,
3021 6.831e-12, 6.839e-12, 6.946e-12, 7.128e-12, 7.537e-12, 8.036e-12,
3022 8.392e-12, 8.526e-12, 8.11e-12, 7.325e-12, 6.329e-12, 5.183e-12,
3023 4.081e-12, 2.985e-12, 2.141e-12, 1.492e-12, 1.015e-12, 6.684e-13,
3024 4.414e-13, 2.987e-13, 2.038e-13, 1.391e-13, 9.86e-14, 7.24e-14,
3025 5.493e-14, 4.288e-14, 3.427e-14, 2.787e-14, 2.296e-14, 1.909e-14,
3026 1.598e-14, 1.344e-14, 1.135e-14, 9.616e-15, 8.169e-15, 6.957e-15,
3027 5.938e-15, 5.08e-15, 4.353e-15, 3.738e-15, 3.217e-15, 2.773e-15,
3028 2.397e-15, 2.077e-15, 1.805e-15, 1.575e-15, 1.382e-15, 1.221e-15,
3029 1.09e-15, 9.855e-16, 9.068e-16, 8.537e-16, 8.27e-16, 8.29e-16,
3030 8.634e-16, 9.359e-16, 1.055e-15, 1.233e-15, 1.486e-15, 1.839e-15,
3031 2.326e-15, 2.998e-15, 3.934e-15, 5.256e-15, 7.164e-15, 9.984e-15,
3032 1.427e-14, 2.099e-14, 3.196e-14, 5.121e-14, 7.908e-14, 1.131e-13,
3033 1.602e-13, 2.239e-13, 3.075e-13, 4.134e-13, 5.749e-13, 7.886e-13,
3034 1.071e-12, 1.464e-12, 2.032e-12, 2.8e-12, 3.732e-12, 4.996e-12,
3035 6.483e-12, 8.143e-12, 1.006e-11, 1.238e-11, 1.484e-11, 1.744e-11,
3036 2.02e-11, 2.274e-11, 2.562e-11, 2.848e-11, 3.191e-11, 3.617e-11,
3037 4.081e-11, 4.577e-11, 4.937e-11, 5.204e-11, 5.401e-11, 5.462e-11,
3038 5.507e-11, 5.51e-11, 5.605e-11, 5.686e-11, 5.739e-11, 5.766e-11,
3039 5.74e-11, 5.754e-11, 5.761e-11, 5.777e-11, 5.712e-11, 5.51e-11,
3040 5.088e-11, 4.438e-11, 3.728e-11, 2.994e-11, 2.305e-11, 1.715e-11,
3041 1.256e-11, 9.208e-12, 6.745e-12, 5.014e-12, 3.785e-12, 2.9e-12,
3042 2.239e-12, 1.757e-12, 1.414e-12, 1.142e-12, 9.482e-13, 8.01e-13,
3043 6.961e-13, 6.253e-13, 5.735e-13, 5.433e-13, 5.352e-13, 5.493e-13,
3044 5.706e-13, 6.068e-13, 6.531e-13, 7.109e-13, 7.767e-13, 8.59e-13,
3045 9.792e-13, 1.142e-12, 1.371e-12, 1.65e-12, 1.957e-12, 2.302e-12,
3046 2.705e-12, 3.145e-12, 3.608e-12, 4.071e-12, 4.602e-12, 5.133e-12,
3047 5.572e-12, 5.987e-12, 6.248e-12, 6.533e-12, 6.757e-12, 6.935e-12,
3048 7.224e-12, 7.422e-12, 7.538e-12, 7.547e-12, 7.495e-12, 7.543e-12,
3049 7.725e-12, 8.139e-12, 8.627e-12, 9.146e-12, 9.443e-12, 9.318e-12,
3050 8.649e-12, 7.512e-12, 6.261e-12, 4.915e-12, 3.647e-12, 2.597e-12,
3051 1.785e-12, 1.242e-12, 8.66e-13, 6.207e-13, 4.61e-13, 3.444e-13,
3052 2.634e-13, 2.1e-13, 1.725e-13, 1.455e-13, 1.237e-13, 1.085e-13,
3053 9.513e-14, 7.978e-14, 6.603e-14, 5.288e-14, 4.084e-14, 2.952e-14,
3054 2.157e-14, 1.593e-14, 1.199e-14, 9.267e-15, 7.365e-15, 6.004e-15,
3055 4.995e-15, 4.218e-15, 3.601e-15, 3.101e-15, 2.692e-15, 2.36e-15,
3056 2.094e-15, 1.891e-15, 1.755e-15, 1.699e-15, 1.755e-15, 1.987e-15,
3057 2.506e-15, 3.506e-15, 5.289e-15, 8.311e-15, 1.325e-14, 2.129e-14,
3058 3.237e-14, 4.595e-14, 6.441e-14, 8.433e-14, 1.074e-13, 1.383e-13,
3059 1.762e-13, 2.281e-13, 2.831e-13, 3.523e-13, 4.38e-13, 5.304e-13,
3060 6.29e-13, 7.142e-13, 8.032e-13, 8.934e-13, 9.888e-13, 1.109e-12,
3061 1.261e-12, 1.462e-12, 1.74e-12, 2.099e-12, 2.535e-12, 3.008e-12,
3062 3.462e-12, 3.856e-12, 4.098e-12, 4.239e-12, 4.234e-12, 4.132e-12,
3063 3.986e-12, 3.866e-12, 3.829e-12, 3.742e-12, 3.705e-12, 3.694e-12,
3064 3.765e-12, 3.849e-12, 3.929e-12, 4.056e-12, 4.092e-12, 4.047e-12,
3065 3.792e-12, 3.407e-12, 2.953e-12, 2.429e-12, 1.931e-12, 1.46e-12,
3066 1.099e-12, 8.199e-13, 6.077e-13, 4.449e-13, 3.359e-13, 2.524e-13,
3067 1.881e-13, 1.391e-13, 1.02e-13, 7.544e-14, 5.555e-14, 4.22e-14,
3068 3.321e-14, 2.686e-14, 2.212e-14, 1.78e-14, 1.369e-14, 1.094e-14,
3069 9.13e-15, 8.101e-15, 7.828e-15, 8.393e-15, 1.012e-14, 1.259e-14,
3070 1.538e-14, 1.961e-14, 2.619e-14, 3.679e-14, 5.049e-14, 6.917e-14,
3071 8.88e-14, 1.115e-13, 1.373e-13, 1.619e-13, 1.878e-13, 2.111e-13,
3072 2.33e-13, 2.503e-13, 2.613e-13, 2.743e-13, 2.826e-13, 2.976e-13,
3073 3.162e-13, 3.36e-13, 3.491e-13, 3.541e-13, 3.595e-13, 3.608e-13,
3074 3.709e-13, 3.869e-13, 4.12e-13, 4.366e-13, 4.504e-13, 4.379e-13,
3075 3.955e-13, 3.385e-13, 2.741e-13, 2.089e-13, 1.427e-13, 9.294e-14,
3076 5.775e-14, 3.565e-14, 2.21e-14, 1.398e-14, 9.194e-15, 6.363e-15,
3077 4.644e-15, 3.55e-15, 2.808e-15, 2.274e-15, 1.871e-15, 1.557e-15,
3078 1.308e-15, 1.108e-15, 9.488e-16, 8.222e-16, 7.238e-16, 6.506e-16,
3079 6.008e-16, 5.742e-16, 5.724e-16, 5.991e-16, 6.625e-16, 7.775e-16,
3080 9.734e-16, 1.306e-15, 1.88e-15, 2.879e-15, 4.616e-15, 7.579e-15,
3081 1.248e-14, 2.03e-14, 3.244e-14, 5.171e-14, 7.394e-14, 9.676e-14,
3082 1.199e-13, 1.467e-13, 1.737e-13, 2.02e-13, 2.425e-13, 3.016e-13,
3083 3.7e-13, 4.617e-13, 5.949e-13, 7.473e-13, 9.378e-13, 1.191e-12,
3084 1.481e-12, 1.813e-12, 2.232e-12, 2.722e-12, 3.254e-12, 3.845e-12,
3085 4.458e-12, 5.048e-12, 5.511e-12, 5.898e-12, 6.204e-12, 6.293e-12,
3086 6.386e-12, 6.467e-12, 6.507e-12, 6.466e-12, 6.443e-12, 6.598e-12,
3087 6.873e-12, 7.3e-12, 7.816e-12, 8.368e-12, 8.643e-12, 8.466e-12,
3088 7.871e-12, 6.853e-12, 5.714e-12, 4.482e-12, 3.392e-12, 2.613e-12,
3089 2.008e-12, 1.562e-12, 1.228e-12, 9.888e-13, 7.646e-13, 5.769e-13,
3090 4.368e-13, 3.324e-13, 2.508e-13, 1.916e-13
3091 };
3092
3093 static const double xfcrev[15] =
3094 { 1.003, 1.009, 1.015, 1.023, 1.029, 1.033, 1.037,
3095 1.039, 1.04, 1.046, 1.036, 1.027, 1.01, 1.002, 1.
3096 };
3097
3098 double sfac;
3099
3100 /* Get H2O continuum absorption... */
3101 const double xw = nu / 10 + 1;
3102 if (xw >= 1 && xw < 2001) {
3103 const int iw = (int) xw;
3104 const double dw = xw - iw;
3105 const double ew = 1 - dw;
3106 const double cw296 = ew * h2o296[iw - 1] + dw * h2o296[iw];
3107 const double cw260 = ew * h2o260[iw - 1] + dw * h2o260[iw];
3108 const double cwfrn = ew * h2ofrn[iw - 1] + dw * h2ofrn[iw];
3109 if (nu <= 820 || nu >= 960) {
3110 sfac = 1;
3111 } else {
3112 const double xx = (nu - 820) / 10;
3113 const int ix = (int) xx;
3114 const double dx = xx - ix;
3115 sfac = (1 - dx) * xfcrev[ix] + dx * xfcrev[ix + 1];
3116 }
3117 const double ctwslf =
3118 sfac * cw296 * pow(cw260 / cw296, (296 - t) / (296 - 260));
3119 const double vf2 = POW2(nu - 370);
3120 const double vf6 = POW3(vf2);
3121 const double fscal = 36100 / (vf2 + vf6 * 1e-8 + 36100) * -.25 + 1;
3122 const double ctwfrn = cwfrn * fscal;
3123 const double a1 = nu * u * tanh(.7193876 / t * nu);
3124 const double a2 = 296 / t;
3125 const double a3 = p / P0 * (q * ctwslf + (1 - q) * ctwfrn) * 1e-20;
3126 return a1 * a2 * a3;
3127 } else
3128 return 0;
3129}
#define POW3(x)
Compute the cube of a value.
Definition: jurassic.h:974

◆ ctmn2()

double ctmn2 ( const double  nu,
const double  p,
const double  t 
)

Compute N₂ collision-induced absorption coefficient.

Calculates the nitrogen (N₂) absorption coefficient due to collision-induced absorption (CIA) near the 4.3 µm CO₂ band using tabulated laboratory data for the absorption strength (B) and temperature exponent (β).

The function linearly interpolates B and β as a function of wavenumber, then applies a temperature- and pressure-dependent scaling relation to compute the absorption coefficient.

Parameters
[in]nuWavenumber [cm⁻¹].
[in]pPressure [hPa].
[in]tTemperature [K].
Returns
N₂ absorption coefficient [km⁻¹].
Note
Valid for approximately 2120–2600 cm⁻¹ (4.0–4.7 µm) where N₂–N₂ and N₂–O₂ CIA dominates. Returns zero outside the tabulated range.
See also
locate_reg, LIN, P0, N2
Reference
Lafferty et al., J. Quant. Spectrosc. Radiat. Transf., 68, 473–479 (2001)
Author
Lars Hoffmann

Definition at line 3133 of file jurassic.c.

3136 {
3137
3138 static const double ba[98] =
3139 { 0., 4.45e-8, 5.22e-8, 6.46e-8, 7.75e-8, 9.03e-8,
3140 1.06e-7, 1.21e-7, 1.37e-7, 1.57e-7, 1.75e-7, 2.01e-7, 2.3e-7,
3141 2.59e-7, 2.95e-7, 3.26e-7, 3.66e-7, 4.05e-7, 4.47e-7, 4.92e-7,
3142 5.34e-7, 5.84e-7, 6.24e-7, 6.67e-7, 7.14e-7, 7.26e-7, 7.54e-7,
3143 7.84e-7, 8.09e-7, 8.42e-7, 8.62e-7, 8.87e-7, 9.11e-7, 9.36e-7,
3144 9.76e-7, 1.03e-6, 1.11e-6, 1.23e-6, 1.39e-6, 1.61e-6, 1.76e-6,
3145 1.94e-6, 1.97e-6, 1.87e-6, 1.75e-6, 1.56e-6, 1.42e-6, 1.35e-6,
3146 1.32e-6, 1.29e-6, 1.29e-6, 1.29e-6, 1.3e-6, 1.32e-6, 1.33e-6,
3147 1.34e-6, 1.35e-6, 1.33e-6, 1.31e-6, 1.29e-6, 1.24e-6, 1.2e-6,
3148 1.16e-6, 1.1e-6, 1.04e-6, 9.96e-7, 9.38e-7, 8.63e-7, 7.98e-7,
3149 7.26e-7, 6.55e-7, 5.94e-7, 5.35e-7, 4.74e-7, 4.24e-7, 3.77e-7,
3150 3.33e-7, 2.96e-7, 2.63e-7, 2.34e-7, 2.08e-7, 1.85e-7, 1.67e-7,
3151 1.47e-7, 1.32e-7, 1.2e-7, 1.09e-7, 9.85e-8, 9.08e-8, 8.18e-8,
3152 7.56e-8, 6.85e-8, 6.14e-8, 5.83e-8, 5.77e-8, 5e-8, 4.32e-8, 0.
3153 };
3154
3155 static const double betaa[98] =
3156 { 802., 802., 761., 722., 679., 646., 609., 562.,
3157 511., 472., 436., 406., 377., 355., 338., 319., 299., 278., 255.,
3158 233., 208., 184., 149., 107., 66., 25., -13., -49., -82., -104.,
3159 -119., -130., -139., -144., -146., -146., -147., -148., -150.,
3160 -153., -160., -169., -181., -189., -195., -200., -205., -209.,
3161 -211., -210., -210., -209., -205., -199., -190., -180., -168.,
3162 -157., -143., -126., -108., -89., -63., -32., 1., 35., 65., 95.,
3163 121., 141., 152., 161., 164., 164., 161., 155., 148., 143., 137.,
3164 133., 131., 133., 139., 150., 165., 187., 213., 248., 284., 321.,
3165 372., 449., 514., 569., 609., 642., 673., 673.
3166 };
3167
3168 static const double nua[98] =
3169 { 2120., 2125., 2130., 2135., 2140., 2145., 2150.,
3170 2155., 2160., 2165., 2170., 2175., 2180., 2185., 2190., 2195.,
3171 2200., 2205., 2210., 2215., 2220., 2225., 2230., 2235., 2240.,
3172 2245., 2250., 2255., 2260., 2265., 2270., 2275., 2280., 2285.,
3173 2290., 2295., 2300., 2305., 2310., 2315., 2320., 2325., 2330.,
3174 2335., 2340., 2345., 2350., 2355., 2360., 2365., 2370., 2375.,
3175 2380., 2385., 2390., 2395., 2400., 2405., 2410., 2415., 2420.,
3176 2425., 2430., 2435., 2440., 2445., 2450., 2455., 2460., 2465.,
3177 2470., 2475., 2480., 2485., 2490., 2495., 2500., 2505., 2510.,
3178 2515., 2520., 2525., 2530., 2535., 2540., 2545., 2550., 2555.,
3179 2560., 2565., 2570., 2575., 2580., 2585., 2590., 2595., 2600., 2605.
3180 };
3181
3182 const double t0 = 273.0, tr = 296.0;
3183
3184 /* Check wavenumber range... */
3185 if (nu < nua[0] || nu > nua[97])
3186 return 0;
3187
3188 /* Interpolate B and beta... */
3189 const int idx = locate_reg(nua, 98, nu);
3190 const double b =
3191 1e6 * LIN(nua[idx], ba[idx], nua[idx + 1], ba[idx + 1], nu);
3192 const double beta =
3193 LIN(nua[idx], betaa[idx], nua[idx + 1], betaa[idx + 1], nu);
3194
3195 /* Compute absorption coefficient... */
3196 return 0.1 * POW2(p / P0 * t0 / t) * exp(beta * (1 / tr - 1 / t))
3197 * N2 * b * (N2 + (1 - N2) * (1.294 - 0.4545 * t / tr));
3198}
Here is the call graph for this function:

◆ ctmo2()

double ctmo2 ( const double  nu,
const double  p,
const double  t 
)

Compute O₂ collision-induced absorption coefficient.

Calculates the molecular oxygen (O₂) absorption coefficient due to collision-induced absorption (CIA) using tabulated laboratory data for the absorption strength (B) and temperature exponent (β).

The function linearly interpolates B and β as a function of wavenumber and applies a pressure- and temperature-dependent scaling relation to compute the absorption coefficient.

Parameters
[in]nuWavenumber [cm⁻¹].
[in]pPressure [hPa].
[in]tTemperature [K].
Returns
O₂ absorption coefficient [km⁻¹].
Note
Valid for approximately 1360–1800 cm⁻¹ (∼ 7.4–5.5 µm), corresponding to the O₂ CIA band. Returns zero outside the tabulated range.
See also
locate_reg, LIN, P0, O2
References
Greenblatt et al., J. Quant. Spectrosc. Radiat. Transf., 33, 127–140 (1985) Smith and Newnham, Appl. Opt., 39, 318–326 (2000)
Author
Lars Hoffmann

Definition at line 3202 of file jurassic.c.

3205 {
3206
3207 static const double ba[90] =
3208 { 0., .061, .074, .084, .096, .12, .162, .208, .246,
3209 .285, .314, .38, .444, .5, .571, .673, .768, .853, .966, 1.097,
3210 1.214, 1.333, 1.466, 1.591, 1.693, 1.796, 1.922, 2.037, 2.154,
3211 2.264, 2.375, 2.508, 2.671, 2.847, 3.066, 3.417, 3.828, 4.204,
3212 4.453, 4.599, 4.528, 4.284, 3.955, 3.678, 3.477, 3.346, 3.29,
3213 3.251, 3.231, 3.226, 3.212, 3.192, 3.108, 3.033, 2.911, 2.798,
3214 2.646, 2.508, 2.322, 2.13, 1.928, 1.757, 1.588, 1.417, 1.253,
3215 1.109, .99, .888, .791, .678, .587, .524, .464, .403, .357, .32,
3216 .29, .267, .242, .215, .182, .16, .146, .128, .103, .087, .081,
3217 .071, .064, 0.
3218 };
3219
3220 static const double betaa[90] =
3221 { 467., 467., 400., 315., 379., 368., 475., 521.,
3222 531., 512., 442., 444., 430., 381., 335., 324., 296., 248., 215.,
3223 193., 158., 127., 101., 71., 31., -6., -26., -47., -63., -79.,
3224 -88., -88., -87., -90., -98., -99., -109., -134., -160., -167.,
3225 -164., -158., -153., -151., -156., -166., -168., -173., -170.,
3226 -161., -145., -126., -108., -84., -59., -29., 4., 41., 73., 97.,
3227 123., 159., 198., 220., 242., 256., 281., 311., 334., 319., 313.,
3228 321., 323., 310., 315., 320., 335., 361., 378., 373., 338., 319.,
3229 346., 322., 291., 290., 350., 371., 504., 504.
3230 };
3231
3232 static const double nua[90] =
3233 { 1360., 1365., 1370., 1375., 1380., 1385., 1390.,
3234 1395., 1400., 1405., 1410., 1415., 1420., 1425., 1430., 1435.,
3235 1440., 1445., 1450., 1455., 1460., 1465., 1470., 1475., 1480.,
3236 1485., 1490., 1495., 1500., 1505., 1510., 1515., 1520., 1525.,
3237 1530., 1535., 1540., 1545., 1550., 1555., 1560., 1565., 1570.,
3238 1575., 1580., 1585., 1590., 1595., 1600., 1605., 1610., 1615.,
3239 1620., 1625., 1630., 1635., 1640., 1645., 1650., 1655., 1660.,
3240 1665., 1670., 1675., 1680., 1685., 1690., 1695., 1700., 1705.,
3241 1710., 1715., 1720., 1725., 1730., 1735., 1740., 1745., 1750.,
3242 1755., 1760., 1765., 1770., 1775., 1780., 1785., 1790., 1795.,
3243 1800., 1805.
3244 };
3245
3246 const double t0 = 273, tr = 296;
3247
3248 /* Check wavenumber range... */
3249 if (nu < nua[0] || nu > nua[89])
3250 return 0;
3251
3252 /* Interpolate B and beta... */
3253 const int idx = locate_reg(nua, 90, nu);
3254 const double b = LIN(nua[idx], ba[idx], nua[idx + 1], ba[idx + 1], nu);
3255 const double beta =
3256 LIN(nua[idx], betaa[idx], nua[idx + 1], betaa[idx + 1], nu);
3257
3258 /* Compute absorption coefficient... */
3259 return 0.1 * POW2(p / P0 * t0 / t) * exp(beta * (1 / tr - 1 / t)) * O2 * b;
3260}
Here is the call graph for this function:

◆ copy_atm()

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.

Copies all fields from one atmospheric structure (atm_src) to another (atm_dest), including geolocation, thermodynamic, gas, extinction, cloud, and surface parameters. If init is nonzero, the destination fields are instead initialized to default values (zeros for most fields, unity for surface emissivity).

Parameters
[in]ctlControl structure defining array dimensions.
[out]atm_destDestination atmospheric structure.
[in]atm_srcSource atmospheric structure.
[in]initInitialization flag:
  • 0 → copy data from atm_src
  • 1 → initialize atm_dest to default values
Note
The number of vertical levels (atm_src->np) determines the amount of data copied. The function performs shallow copies using memcpy for efficiency.
See also
atm_t, ctl_t
Author
Lars Hoffmann

Definition at line 3264 of file jurassic.c.

3268 {
3269
3270 /* Data size... */
3271 const size_t s = (size_t) atm_src->np * sizeof(double);
3272
3273 /* Copy data... */
3274 atm_dest->np = atm_src->np;
3275 memcpy(atm_dest->time, atm_src->time, s);
3276 memcpy(atm_dest->z, atm_src->z, s);
3277 memcpy(atm_dest->lon, atm_src->lon, s);
3278 memcpy(atm_dest->lat, atm_src->lat, s);
3279 memcpy(atm_dest->p, atm_src->p, s);
3280 memcpy(atm_dest->t, atm_src->t, s);
3281 for (int ig = 0; ig < ctl->ng; ig++)
3282 memcpy(atm_dest->q[ig], atm_src->q[ig], s);
3283 for (int iw = 0; iw < ctl->nw; iw++)
3284 memcpy(atm_dest->k[iw], atm_src->k[iw], s);
3285 atm_dest->clz = atm_src->clz;
3286 atm_dest->cldz = atm_src->cldz;
3287 for (int icl = 0; icl < ctl->ncl; icl++)
3288 atm_dest->clk[icl] = atm_src->clk[icl];
3289 atm_dest->sft = atm_src->sft;
3290 for (int isf = 0; isf < ctl->nsf; isf++)
3291 atm_dest->sfeps[isf] = atm_src->sfeps[isf];
3292
3293 /* Initialize... */
3294 if (init)
3295 for (int ip = 0; ip < atm_dest->np; ip++) {
3296 atm_dest->p[ip] = 0;
3297 atm_dest->t[ip] = 0;
3298 for (int ig = 0; ig < ctl->ng; ig++)
3299 atm_dest->q[ig][ip] = 0;
3300 for (int iw = 0; iw < ctl->nw; iw++)
3301 atm_dest->k[iw][ip] = 0;
3302 atm_dest->clz = 0;
3303 atm_dest->cldz = 0;
3304 for (int icl = 0; icl < ctl->ncl; icl++)
3305 atm_dest->clk[icl] = 0;
3306 atm_dest->sft = 0;
3307 for (int isf = 0; isf < ctl->nsf; isf++)
3308 atm_dest->sfeps[isf] = 1;
3309 }
3310}
double lat[NP]
Latitude [deg].
Definition: jurassic.h:1258
double lon[NP]
Longitude [deg].
Definition: jurassic.h:1255

◆ copy_obs()

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.

Copies all observation fields from a source structure (obs_src) to a destination structure (obs_dest), including observer, view, and tangent point geometry, as well as radiance and transmittance data. If init is nonzero, radiance and transmittance values are reset to zero wherever finite values are found.

Parameters
[in]ctlControl structure defining the number of channels (ctl_t::nd) and other dimensions.
[out]obs_destDestination observation structure.
[in]obs_srcSource observation structure.
[in]initInitialization flag:
  • 0 → copy data from obs_src
  • 1 → initialize obs_dest (set rad and tau to zero)
Note
The number of ray paths (obs_src->nr) defines the copied data size. Shallow copies are performed via memcpy for efficiency.
See also
obs_t, ctl_t
Author
Lars Hoffmann

Definition at line 3314 of file jurassic.c.

3318 {
3319
3320 /* Data size... */
3321 const size_t s = (size_t) obs_src->nr * sizeof(double);
3322
3323 /* Copy data... */
3324 obs_dest->nr = obs_src->nr;
3325 memcpy(obs_dest->time, obs_src->time, s);
3326 memcpy(obs_dest->obsz, obs_src->obsz, s);
3327 memcpy(obs_dest->obslon, obs_src->obslon, s);
3328 memcpy(obs_dest->obslat, obs_src->obslat, s);
3329 memcpy(obs_dest->vpz, obs_src->vpz, s);
3330 memcpy(obs_dest->vplon, obs_src->vplon, s);
3331 memcpy(obs_dest->vplat, obs_src->vplat, s);
3332 memcpy(obs_dest->tpz, obs_src->tpz, s);
3333 memcpy(obs_dest->tplon, obs_src->tplon, s);
3334 memcpy(obs_dest->tplat, obs_src->tplat, s);
3335 for (int id = 0; id < ctl->nd; id++)
3336 memcpy(obs_dest->rad[id], obs_src->rad[id], s);
3337 for (int id = 0; id < ctl->nd; id++)
3338 memcpy(obs_dest->tau[id], obs_src->tau[id], s);
3339
3340 /* Initialize... */
3341 if (init)
3342 for (int id = 0; id < ctl->nd; id++)
3343 for (int ir = 0; ir < obs_dest->nr; ir++)
3344 if (isfinite(obs_dest->rad[id][ir])) {
3345 obs_dest->rad[id][ir] = 0;
3346 obs_dest->tau[id][ir] = 0;
3347 }
3348}
int nd
Number of radiance channels.
Definition: jurassic.h:1317
double tau[ND][NR]
Transmittance of ray path.
Definition: jurassic.h:1558
double rad[ND][NR]
Radiance [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1561
double tplon[NR]
Tangent point longitude [deg].
Definition: jurassic.h:1552
double vpz[NR]
View point altitude [km].
Definition: jurassic.h:1540
double vplat[NR]
View point latitude [deg].
Definition: jurassic.h:1546
double obslon[NR]
Observer longitude [deg].
Definition: jurassic.h:1534
double obslat[NR]
Observer latitude [deg].
Definition: jurassic.h:1537
double obsz[NR]
Observer altitude [km].
Definition: jurassic.h:1531
double tplat[NR]
Tangent point latitude [deg].
Definition: jurassic.h:1555
double vplon[NR]
View point longitude [deg].
Definition: jurassic.h:1543
double time[NR]
Time (seconds since 2000-01-01T00:00Z).
Definition: jurassic.h:1528
double tpz[NR]
Tangent point altitude [km].
Definition: jurassic.h:1549
int nr
Number of ray paths.
Definition: jurassic.h:1525

◆ day2doy()

void day2doy ( int  year,
int  mon,
int  day,
int *  doy 
)

Convert a calendar date to day-of-year.

This function computes the day-of-year (1–365 or 1–366 for leap years) corresponding to a given Gregorian date specified by year, month, and day.

Leap years are determined using the standard Gregorian rules:

  • Every year divisible by 4 is a leap year,
  • except years divisible by 100, unless also divisible by 400.
Parameters
yearThe full year (e.g., 2025).
monThe month of the year (1–12).
dayThe day of the month (1–31).
[out]doyPointer to an integer where the resulting day-of-year will be stored (1–365 or 1–366).
Note
The caller must ensure that the input date is valid.
Author
Lars Hoffmann

Definition at line 3352 of file jurassic.c.

3356 {
3357
3358 const int d0[12] =
3359 { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
3360 const int d0l[12] =
3361 { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
3362
3363 /* Get day of year... */
3364 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
3365 *doy = d0l[mon - 1] + day - 1;
3366 else
3367 *doy = d0[mon - 1] + day - 1;
3368}

◆ doy2day()

void doy2day ( int  year,
int  doy,
int *  mon,
int *  day 
)

Convert a day-of-year value to a calendar date.

This function computes the month and day corresponding to a given day-of-year (1–365 or 1–366 for leap years) in the Gregorian calendar.

Leap years are determined using the standard Gregorian rules:

  • Every year divisible by 4 is a leap year,
  • except years divisible by 100, unless also divisible by 400.
Parameters
yearThe full year (e.g., 2025).
doyThe day-of-year (1–365 or 1–366).
[out]monPointer to an integer where the calculated month (1–12) will be stored.
[out]dayPointer to an integer where the calculated day-of-month will be stored.
Note
The caller must ensure that doy is within the valid range for the specified year.
Author
Lars Hoffmann

Definition at line 3372 of file jurassic.c.

3376 {
3377
3378 const int d0[12] =
3379 { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
3380 const int d0l[12] =
3381 { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
3382 int i;
3383
3384 /* Get month and day... */
3385 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
3386 for (i = 11; i >= 0; i--)
3387 if (d0l[i] <= doy)
3388 break;
3389 *mon = i + 1;
3390 *day = doy - d0l[i] + 1;
3391 } else {
3392 for (i = 11; i >= 0; i--)
3393 if (d0[i] <= doy)
3394 break;
3395 *mon = i + 1;
3396 *day = doy - d0[i] + 1;
3397 }
3398}

◆ find_emitter()

int find_emitter ( const ctl_t ctl,
const char *  emitter 
)

Find gas species index by name.

Searches the list of emitter (gas) names defined in the control structure for a case-insensitive match to the given string. Returns the corresponding gas index if found, or -1 otherwise.

Parameters
[in]ctlControl structure containing the list of gas emitters.
[in]emitterName of the gas species to search for (e.g. "H2O", "CO2").
Returns
Index of the matching emitter (0 ≤ index < ctl->ng), or -1 if no match is found.
Note
Comparison is case-insensitive using strcasecmp().
See also
ctl_t
Author
Lars Hoffmann

Definition at line 3402 of file jurassic.c.

3404 {
3405
3406 for (int ig = 0; ig < ctl->ng; ig++)
3407 if (strcasecmp(ctl->emitter[ig], emitter) == 0)
3408 return ig;
3409
3410 return -1;
3411}

◆ formod()

void formod ( const ctl_t ctl,
const tbl_t tbl,
atm_t atm,
obs_t obs 
)

Execute the selected forward model.

Computes synthetic radiances or brightness temperatures for the given atmospheric state and observation geometry using the selected forward-model method (CGA, EGA, or RFM). The function also applies hydrostatic adjustment, field-of-view convolution, and optional brightness-temperature conversion.

Parameters
[in]ctlControl structure defining model settings and options.
[in]tblEmissivity and source-function lookup tables.
[in,out]atmAtmospheric profile; may be adjusted for hydrostatic balance.
[in,out]obsObservation geometry and radiance data; populated with model output.
Note
The model type is selected via ctl_t::formod:
The function preserves obs->rad elements marked as invalid (NaN) by applying an internal observation mask.
See also
ctl_t, atm_t, obs_t, tbl_t, formod_pencil, formod_rfm, formod_fov, hydrostatic
Author
Lars Hoffmann

Definition at line 3415 of file jurassic.c.

3419 {
3420
3421 /* Allocate... */
3422 int *mask;
3423 ALLOC(mask, int,
3424 ND * NR);
3425
3426 /* Save observation mask... */
3427 for (int id = 0; id < ctl->nd; id++)
3428 for (int ir = 0; ir < obs->nr; ir++)
3429 mask[id * NR + ir] = !isfinite(obs->rad[id][ir]);
3430
3431 /* Hydrostatic equilibrium... */
3432 hydrostatic(ctl, atm);
3433
3434 /* CGA or EGA forward model... */
3435 if (ctl->formod == 0 || ctl->formod == 1)
3436 for (int ir = 0; ir < obs->nr; ir++)
3437 formod_pencil(ctl, tbl, atm, obs, ir);
3438
3439 /* Call RFM... */
3440 else if (ctl->formod == 2)
3441 formod_rfm(ctl, tbl, atm, obs);
3442
3443 /* Apply field-of-view convolution... */
3444 formod_fov(ctl, obs);
3445
3446 /* Convert radiance to brightness temperature... */
3447 if (ctl->write_bbt)
3448 for (int id = 0; id < ctl->nd; id++)
3449 for (int ir = 0; ir < obs->nr; ir++)
3450 obs->rad[id][ir] = BRIGHT(obs->rad[id][ir], ctl->nu[id]);
3451
3452 /* Apply observation mask... */
3453 for (int id = 0; id < ctl->nd; id++)
3454 for (int ir = 0; ir < obs->nr; ir++)
3455 if (mask[id * NR + ir])
3456 obs->rad[id][ir] = NAN;
3457
3458 /* Free... */
3459 free(mask);
3460}
void formod_rfm(const ctl_t *ctl, const tbl_t *tbl, const atm_t *atm, obs_t *obs)
Forward-model radiance and transmittance with the Reference Forward Model (RFM).
Definition: jurassic.c:3701
void formod_pencil(const ctl_t *ctl, const tbl_t *tbl, const atm_t *atm, obs_t *obs, const int ir)
Compute line-of-sight radiances using the pencil-beam forward model.
Definition: jurassic.c:3564
void formod_fov(const ctl_t *ctl, obs_t *obs)
Apply field-of-view (FOV) convolution to modeled radiances.
Definition: jurassic.c:3500
void hydrostatic(const ctl_t *ctl, atm_t *atm)
Adjust pressure profile using the hydrostatic equation.
Definition: jurassic.c:3897
#define BRIGHT(rad, nu)
Compute brightness temperature from radiance.
Definition: jurassic.h:408
#define ND
Maximum number of radiance channels.
Definition: jurassic.h:238
#define NR
Maximum number of ray paths.
Definition: jurassic.h:253
double nu[ND]
Centroid wavenumber of each channel [cm^-1].
Definition: jurassic.h:1320
int formod
Forward model (0=CGA, 1=EGA, 2=RFM).
Definition: jurassic.h:1440
int write_bbt
Use brightness temperature instead of radiance (0=no, 1=yes).
Definition: jurassic.h:1434
Here is the call graph for this function:

◆ formod_continua()

void formod_continua ( const ctl_t ctl,
const los_t los,
const int  ip,
double *  beta 
)

Compute total extinction including gaseous continua.

Calculates the total extinction coefficient for a given line-of-sight point by summing spectrally dependent extinction and optional gaseous continuum contributions (CO₂, H₂O, N₂, O₂).

The function updates the extinction array beta for each spectral channel based on line-by-line extinction and enabled continua flags specified in ctl.

Parameters
[in]ctlControl structure defining model setup and continuum options.
[in]losLine-of-sight data containing pressure, temperature, gas concentrations, and extinction coefficients.
[in]ipIndex of the line-of-sight point to process.
[out]betaArray of total extinction coefficients [km⁻¹] per channel.
Note
Each continuum component is added only if its corresponding control flag (e.g., ctl_t::ctm_co2, ctl_t::ctm_h2o) is enabled and the gas index is valid.
See also
ctl_t, los_t, ctmco2, ctmh2o, ctmn2, ctmo2
Author
Lars Hoffmann

Definition at line 3464 of file jurassic.c.

3468 {
3469
3470 /* Extinction... */
3471 for (int id = 0; id < ctl->nd; id++)
3472 beta[id] = los->k[ip][id];
3473
3474 /* CO2 continuum... */
3475 if (ctl->ctm_co2 && ctl->ig_co2 >= 0)
3476 for (int id = 0; id < ctl->nd; id++)
3477 beta[id] += ctmco2(ctl->nu[id], los->p[ip], los->t[ip],
3478 los->u[ip][ctl->ig_co2]) / los->ds[ip];
3479
3480 /* H2O continuum... */
3481 if (ctl->ctm_h2o && ctl->ig_h2o >= 0)
3482 for (int id = 0; id < ctl->nd; id++)
3483 beta[id] += ctmh2o(ctl->nu[id], los->p[ip], los->t[ip],
3484 los->q[ip][ctl->ig_h2o], los->u[ip][ctl->ig_h2o])
3485 / los->ds[ip];
3486
3487 /* N2 continuum... */
3488 if (ctl->ctm_n2)
3489 for (int id = 0; id < ctl->nd; id++)
3490 beta[id] += ctmn2(ctl->nu[id], los->p[ip], los->t[ip]);
3491
3492 /* O2 continuum... */
3493 if (ctl->ctm_o2)
3494 for (int id = 0; id < ctl->nd; id++)
3495 beta[id] += ctmo2(ctl->nu[id], los->p[ip], los->t[ip]);
3496}
double ctmo2(const double nu, const double p, const double t)
Compute O₂ collision-induced absorption coefficient.
Definition: jurassic.c:3202
double ctmh2o(const double nu, const double p, const double t, const double q, const double u)
Compute water vapor continuum (optical depth).
Definition: jurassic.c:2081
double ctmco2(const double nu, const double p, const double t, const double u)
Compute carbon dioxide continuum (optical depth).
Definition: jurassic.c:1218
double ctmn2(const double nu, const double p, const double t)
Compute N₂ collision-induced absorption coefficient.
Definition: jurassic.c:3133
int ctm_co2
Compute CO2 continuum (0=no, 1=yes).
Definition: jurassic.h:1362
int ctm_n2
Compute N2 continuum (0=no, 1=yes).
Definition: jurassic.h:1368
int ctm_h2o
Compute H2O continuum (0=no, 1=yes).
Definition: jurassic.h:1365
int ctm_o2
Compute O2 continuum (0=no, 1=yes).
Definition: jurassic.h:1371
int ig_h2o
Emitter index of H2O.
Definition: jurassic.h:1308
double q[NLOS][NG]
Volume mixing ratio [ppv].
Definition: jurassic.h:1481
double ds[NLOS]
Segment length [km].
Definition: jurassic.h:1493
double u[NLOS][NG]
Column density [molecules/cm^2].
Definition: jurassic.h:1496
double k[NLOS][ND]
Extinction [km^-1].
Definition: jurassic.h:1484
double t[NLOS]
Temperature [K].
Definition: jurassic.h:1478
double p[NLOS]
Pressure [hPa].
Definition: jurassic.h:1475
Here is the call graph for this function:

◆ formod_fov()

void formod_fov ( const ctl_t ctl,
obs_t obs 
)

Apply field-of-view (FOV) convolution to modeled radiances.

Convolves pencil-beam radiances and transmittances along each ray path with the instrument field-of-view weighting function defined in the control structure. This simulates finite FOV effects on measured radiances and transmittances.

Parameters
[in]ctlControl structure containing FOV parameters (offsets ctl_t::fov_dz and weights ctl_t::fov_w).
[in,out]obsObservation structure; input pencil-beam data are replaced with FOV-convolved radiances and transmittances.
Note
The convolution is skipped if ctl_t::fov starts with '-' (indicating no FOV correction). Requires at least two valid altitude samples per time step.
Exceptions
ERRMSGif insufficient data are available for convolution.
Author
Lars Hoffmann

Definition at line 3500 of file jurassic.c.

3502 {
3503
3504 double rad[ND][NR], tau[ND][NR], z[NR];
3505
3506 /* Do not take into account FOV... */
3507 if (ctl->fov[0] == '-')
3508 return;
3509
3510 /* Allocate... */
3511 obs_t *obs2;
3512 ALLOC(obs2, obs_t, 1);
3513
3514 /* Copy observation data... */
3515 copy_obs(ctl, obs2, obs, 0);
3516
3517 /* Loop over ray paths... */
3518 for (int ir = 0; ir < obs->nr; ir++) {
3519
3520 /* Get radiance and transmittance profiles... */
3521 int nz = 0;
3522 for (int ir2 = MAX(ir - NFOV, 0);
3523 ir2 < MIN(ir + 1 + NFOV, obs->nr); ir2++)
3524 if (obs->time[ir2] == obs->time[ir]) {
3525 z[nz] = obs2->vpz[ir2];
3526 for (int id = 0; id < ctl->nd; id++) {
3527 rad[id][nz] = obs2->rad[id][ir2];
3528 tau[id][nz] = obs2->tau[id][ir2];
3529 }
3530 nz++;
3531 }
3532 if (nz < 2)
3533 ERRMSG("Cannot apply FOV convolution!");
3534
3535 /* Convolute profiles with FOV... */
3536 double wsum = 0;
3537 for (int id = 0; id < ctl->nd; id++) {
3538 obs->rad[id][ir] = 0;
3539 obs->tau[id][ir] = 0;
3540 }
3541 for (int i = 0; i < ctl->fov_n; i++) {
3542 const double zfov = obs->vpz[ir] + ctl->fov_dz[i];
3543 const int idx = locate_irr(z, nz, zfov);
3544 for (int id = 0; id < ctl->nd; id++) {
3545 obs->rad[id][ir] += ctl->fov_w[i]
3546 * LIN(z[idx], rad[id][idx], z[idx + 1], rad[id][idx + 1], zfov);
3547 obs->tau[id][ir] += ctl->fov_w[i]
3548 * LIN(z[idx], tau[id][idx], z[idx + 1], tau[id][idx + 1], zfov);
3549 }
3550 wsum += ctl->fov_w[i];
3551 }
3552 for (int id = 0; id < ctl->nd; id++) {
3553 obs->rad[id][ir] /= wsum;
3554 obs->tau[id][ir] /= wsum;
3555 }
3556 }
3557
3558 /* Free... */
3559 free(obs2);
3560}
int locate_irr(const double *xx, const int n, const double x)
Locate index for interpolation on an irregular grid.
Definition: jurassic.c:4475
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.
Definition: jurassic.c:3314
#define NFOV
Number of ray paths used for FOV calculations.
Definition: jurassic.h:298
#define MIN(a, b)
Determine the minimum of two values.
Definition: jurassic.h:626
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: jurassic.h:1193
#define MAX(a, b)
Determine the maximum of two values.
Definition: jurassic.h:608
char fov[LEN]
Field-of-view data file.
Definition: jurassic.h:1383
int fov_n
Field-of-view number of data points.
Definition: jurassic.h:1392
double fov_dz[NSHAPE]
Field-of-view vertical distance [km].
Definition: jurassic.h:1386
double fov_w[NSHAPE]
Field-of-view weighting factor.
Definition: jurassic.h:1389
Observation geometry and radiance data.
Definition: jurassic.h:1522
Here is the call graph for this function:

◆ formod_pencil()

void formod_pencil ( const ctl_t ctl,
const tbl_t tbl,
const atm_t atm,
obs_t obs,
const int  ir 
)

Compute line-of-sight radiances using the pencil-beam forward model.

Simulates monochromatic radiances and transmittances along a single line of sight using a layer-by-layer pencil-beam approximation. The model includes gaseous absorption, continuum extinction, surface emission, reflection, and optional solar illumination.

Parameters
[in]ctlControl structure defining model configuration, gas setup, surface type, and spectral parameters.
[in]tblEmissivity and source-function lookup tables.
[in]atmAtmospheric state containing pressure, temperature, and gas profiles.
[in,out]obsObservation data; updated with modeled radiances and transmittances for the specified ray path.
[in]irIndex of the current ray path in obs.
Note
Depending on ctl_t::formod, this function calls either intpol_tbl_cga() (CGA) or intpol_tbl_ega() (EGA) for gas absorption interpolation.
Surface effects include emission, reflection, and—if enabled— solar illumination based on the solar zenith angle.
See also
ctl_t, atm_t, obs_t, tbl_t, los_t, raytrace, formod_continua, formod_srcfunc, intpol_tbl_cga, intpol_tbl_ega, PLANCK
Author
Lars Hoffmann

Definition at line 3564 of file jurassic.c.

3569 {
3570
3571 double rad[ND], tau[ND], tau_path[ND][NG];
3572
3573 /* Allocate... */
3574 los_t *los;
3575 ALLOC(los, los_t, 1);
3576
3577 /* Initialize... */
3578 for (int id = 0; id < ctl->nd; id++) {
3579 rad[id] = 0;
3580 tau[id] = 1;
3581 for (int ig = 0; ig < ctl->ng; ig++)
3582 tau_path[id][ig] = 1;
3583 }
3584
3585 /* Raytracing... */
3586 raytrace(ctl, atm, obs, los, ir);
3587
3588 /* Loop over LOS points... */
3589 for (int ip = 0; ip < los->np; ip++) {
3590
3591 /* Get trace gas transmittance... */
3592 double tau_gas[ND];
3593 if (ctl->formod == 0)
3594 intpol_tbl_cga(ctl, tbl, los, ip, tau_path, tau_gas);
3595 else
3596 intpol_tbl_ega(ctl, tbl, los, ip, tau_path, tau_gas);
3597
3598 /* Get continuum absorption... */
3599 double beta_ctm[ND];
3600 formod_continua(ctl, los, ip, beta_ctm);
3601
3602 /* Compute Planck function... */
3603 formod_srcfunc(ctl, tbl, los->t[ip], los->src[ip]);
3604
3605 /* Loop over channels... */
3606 for (int id = 0; id < ctl->nd; id++)
3607 if (tau_gas[id] > 0) {
3608
3609 /* Get segment emissivity... */
3610 los->eps[ip][id] = 1 - tau_gas[id] * exp(-beta_ctm[id] * los->ds[ip]);
3611
3612 /* Compute radiance... */
3613 rad[id] += los->src[ip][id] * los->eps[ip][id] * tau[id];
3614
3615 /* Compute path transmittance... */
3616 tau[id] *= (1 - los->eps[ip][id]);
3617 }
3618 }
3619
3620 /* Check whether LOS hit the ground... */
3621 if (ctl->sftype >= 1 && los->sft > 0) {
3622
3623 /* Add surface emissions... */
3624 double src_sf[ND];
3625 formod_srcfunc(ctl, tbl, los->sft, src_sf);
3626 for (int id = 0; id < ctl->nd; id++)
3627 rad[id] += los->sfeps[id] * src_sf[id] * tau[id];
3628
3629 /* Check reflectivity... */
3630 int refl = 0;
3631 if (ctl->sftype >= 2)
3632 for (int id = 0; id < ctl->nd; id++)
3633 if (los->sfeps[id] < 1) {
3634 refl = 1;
3635 break;
3636 }
3637
3638 /* Calculate reflection... */
3639 if (refl) {
3640
3641 /* Initialize... */
3642 double tau_refl[ND];
3643 for (int id = 0; id < ctl->nd; id++)
3644 tau_refl[id] = 1;
3645
3646 /* Add down-welling radiance... */
3647 for (int ip = los->np - 1; ip >= 0; ip--)
3648 for (int id = 0; id < ctl->nd; id++) {
3649 rad[id] += los->src[ip][id] * los->eps[ip][id] * tau_refl[id]
3650 * tau[id] * (1 - los->sfeps[id]);
3651 tau_refl[id] *= (1 - los->eps[ip][id]);
3652 }
3653
3654 /* Add solar term... */
3655 if (ctl->sftype >= 3) {
3656
3657 /* Get cosine of solar zenith angle... */
3658 double cos_sza_val;
3659 if (ctl->sfsza < 0)
3660 cos_sza_val = cos_sza(obs->time[ir],
3661 los->lon[los->np - 1], los->lat[los->np - 1]);
3662 else
3663 cos_sza_val = cos(DEG2RAD(ctl->sfsza));
3664
3665 /* Check validity (avoid division by zero)... */
3666 if (cos_sza_val > 1e-6) {
3667
3668 /* Compute incidence direction cosine... */
3669 double x0[3], x1[3];
3670 geo2cart(los->z[los->np - 1], los->lon[los->np - 1],
3671 los->lat[los->np - 1], x0);
3672 geo2cart(los->z[0], los->lon[0], los->lat[0], x1);
3673 for (int i = 0; i < 3; i++)
3674 x1[i] -= x0[i];
3675 const double cosa = DOTP(x0, x1) / NORM(x0) / NORM(x1);
3676
3677 /* Ratio of incident direction to solar zenith direction... */
3678 const double rcos = cosa / cos_sza_val;
3679
3680 /* Add solar radiance contribution... */
3681 for (int id = 0; id < ctl->nd; id++)
3682 rad[id] += 6.764e-5 / (2. * M_PI) * PLANCK(TSUN, ctl->nu[id])
3683 * tau_refl[id] * (1 - los->sfeps[id]) * tau[id] * rcos;
3684 }
3685 }
3686 }
3687 }
3688
3689 /* Copy results... */
3690 for (int id = 0; id < ctl->nd; id++) {
3691 obs->rad[id][ir] = rad[id];
3692 obs->tau[id][ir] = tau[id];
3693 }
3694
3695 /* Free... */
3696 free(los);
3697}
double cos_sza(const double sec, const double lon, const double lat)
Calculates the cosine of the solar zenith angle.
Definition: jurassic.c:1146
void intpol_tbl_ega(const ctl_t *ctl, const tbl_t *tbl, const los_t *los, const int ip, double tau_path[ND][NG], double tau_seg[ND])
Interpolate emissivities and transmittances using the Emissivity Growth Approximation (EGA).
Definition: jurassic.c:4158
void formod_continua(const ctl_t *ctl, const los_t *los, const int ip, double *beta)
Compute total extinction including gaseous continua.
Definition: jurassic.c:3464
void raytrace(const ctl_t *ctl, const atm_t *atm, obs_t *obs, los_t *los, const int ir)
Perform line-of-sight (LOS) ray tracing through the atmosphere.
Definition: jurassic.c:4928
void intpol_tbl_cga(const ctl_t *ctl, const tbl_t *tbl, const los_t *los, const int ip, double tau_path[ND][NG], double tau_seg[ND])
Interpolate emissivities and transmittances using the Curtis–Godson approximation (CGA).
Definition: jurassic.c:4068
void formod_srcfunc(const ctl_t *ctl, const tbl_t *tbl, const double t, double *src)
Interpolate the source function (Planck radiance) at a given temperature.
Definition: jurassic.c:3862
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
Definition: jurassic.c:3879
#define DOTP(a, b)
Compute dot product of two 3D vectors.
Definition: jurassic.h:500
#define TSUN
Effective temperature of the sun [K].
Definition: jurassic.h:214
#define PLANCK(T, nu)
Compute spectral radiance using Planck’s law.
Definition: jurassic.h:947
double sfsza
Solar zenith angle at the surface [deg] (-999=auto).
Definition: jurassic.h:1344
int sftype
Surface treatment (0=none, 1=emissions, 2=downward, 3=solar).
Definition: jurassic.h:1341
Line-of-sight data.
Definition: jurassic.h:1460
double z[NLOS]
Altitude [km].
Definition: jurassic.h:1466
double eps[NLOS][ND]
Segment emissivity.
Definition: jurassic.h:1508
double sft
Surface temperature [K].
Definition: jurassic.h:1487
double lon[NLOS]
Longitude [deg].
Definition: jurassic.h:1469
int np
Number of LOS points.
Definition: jurassic.h:1463
double lat[NLOS]
Latitude [deg].
Definition: jurassic.h:1472
double src[NLOS][ND]
Segment source function [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1511
double sfeps[ND]
Surface emissivity.
Definition: jurassic.h:1490
Here is the call graph for this function:

◆ formod_rfm()

void formod_rfm ( const ctl_t ctl,
const tbl_t tbl,
const atm_t atm,
obs_t obs 
)

Forward-model radiance and transmittance with the Reference Forward Model (RFM).

This routine provides the JURASSIC interface to the external RFM executable. It writes an RFM atmospheric profile file and a per-channel RFM driver file, runs RFM, and reads back the resulting radiance and transmittance spectra. The spectra are then convolved with the instrument channel filter functions and stored in the observation structure.

Filter functions are taken exclusively from the lookup-table container tbl (i.e., tbl->filt_n, tbl->filt_nu, tbl->filt_f). This makes the behavior independent of the lookup-table format (ASCII, binary, or netCDF) and avoids reliance on external per-channel ASCII filter files.

Viewing geometry is classified as one of:

  • limb: uses tangent altitude
  • nadir: path intersects the surface (secant/air-mass-factor geometry)
  • zenith: upward-looking path exits the atmosphere at the top boundary

Mixed geometries (e.g., limb and nadir simultaneously) are not allowed and will trigger an error.

Limitations:

  • Requires identical observer positions for all rays.
  • Does not support extinction input data (atm->k must be zero everywhere).
  • Uses temporary files in the current working directory (e.g., rfm.atm, rfm.drv, rad_*.asc, tra_*.asc) and removes them on completion.
Parameters
[in]ctlControl and configuration parameters (RFM binary path, HITRAN/XSC settings, channel definitions, flags such as refraction and continua).
[in]tblLookup-table container providing per-channel filter functions.
[in]atmAtmospheric state (altitude grid, temperature, and gas profiles).
[out]obsObservation geometry and output arrays; on return, obs->rad[id][ir] and obs->tau[id][ir] are filled for all channels and rays.
Precondition
tbl contains valid filter functions for all channels used (tbl->filt_n[id] > 0).
All rays share identical observer position (obsz/obslon/obslat).
No extinction data is present (atm->k == 0 for all wavelengths/levels).
Postcondition
obs->rad and obs->tau are updated with channel-integrated radiance and transmittance computed by RFM.
Note
The surface temperature is taken as the temperature at the lowest altitude level of the atmospheric grid.
Warning
This function executes external commands via system(), and creates/removes files in the current working directory.
Reference
Dudhia, A., "The Reference Forward Model (RFM)", JQSRT 186, 243–253 (2017)
Author
Lars Hoffmann

Definition at line 3701 of file jurassic.c.

3705 {
3706
3707 los_t *los;
3708
3709 char cmd[2 * LEN], rfmflg[LEN] = { "RAD TRA MIX LIN SFC" };
3710
3711 double f[NSHAPE], nu[NSHAPE], nu0, nu1, obsz = -999, tsurf,
3712 xd[3], xo[3], xv[3], z[NR], zmin, zmax;
3713
3714 int n, nadir = 0, zenith = 0;
3715
3716 /* Allocate... */
3717 ALLOC(los, los_t, 1);
3718
3719 /* Check observer positions... */
3720 for (int ir = 1; ir < obs->nr; ir++)
3721 if (obs->obsz[ir] != obs->obsz[0]
3722 || obs->obslon[ir] != obs->obslon[0]
3723 || obs->obslat[ir] != obs->obslat[0])
3724 ERRMSG("RFM interface requires identical observer positions!");
3725
3726 /* Check extinction data... */
3727 for (int iw = 0; iw < ctl->nw; iw++)
3728 for (int ip = 0; ip < atm->np; ip++)
3729 if (atm->k[iw][ip] != 0)
3730 ERRMSG("RFM interface cannot handle extinction data!");
3731
3732 /* Get altitude range of atmospheric data... */
3733 gsl_stats_minmax(&zmin, &zmax, atm->z, 1, (size_t) atm->np);
3734
3735 /* Observer within atmosphere? */
3736 if (obs->obsz[0] >= zmin && obs->obsz[0] <= zmax) {
3737 obsz = obs->obsz[0];
3738 strcat(rfmflg, " OBS");
3739 }
3740
3741 /* Determine tangent altitude or air mass factor... */
3742 for (int ir = 0; ir < obs->nr; ir++) {
3743
3744 /* Raytracing... */
3745 raytrace(ctl, atm, obs, los, ir);
3746
3747 /* Nadir or zenith? (air mass factor / secant of zenith angle) */
3748 if (obs->tpz[ir] <= zmin) {
3749
3750 /* Nadir: path intersects the surface. */
3751 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xo);
3752 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xv);
3753 for (int i = 0; i < 3; i++)
3754 xd[i] = xo[i] - xv[i];
3755 z[ir] = NORM(xo) * NORM(xd) / DOTP(xo, xd);
3756 nadir++;
3757
3758 } else if (obs->tpz[ir] >= zmax - 1e-3 && obs->vpz[ir] > obs->obsz[ir]) {
3759
3760 /* Zenith: upward-looking path leaves the atmosphere at the top boundary. */
3761 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xo);
3762 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xv);
3763 for (int i = 0; i < 3; i++)
3764 xd[i] = xv[i] - xo[i];
3765 z[ir] = NORM(xo) * NORM(xd) / DOTP(xo, xd);
3766 zenith++;
3767
3768 } else
3769 /* Limb: use tangent altitude. */
3770 z[ir] = obs->tpz[ir];
3771 }
3772 if ((nadir > 0 && nadir < obs->nr)
3773 || (zenith > 0 && zenith < obs->nr)
3774 || (nadir > 0 && zenith > 0))
3775 ERRMSG("Limb, nadir, and zenith not simultaneously possible!");
3776
3777 /* Viewing geometry... */
3778 if (nadir)
3779 strcat(rfmflg, " NAD");
3780 if (zenith)
3781 strcat(rfmflg, " ZEN");
3782
3783 /* Get surface temperature... */
3784 tsurf = atm->t[gsl_stats_min_index(atm->z, 1, (size_t) atm->np)];
3785
3786 /* Refraction? */
3787 if (!nadir && !zenith && !ctl->refrac)
3788 strcat(rfmflg, " GEO");
3789
3790 /* Continua? */
3791 if (ctl->ctm_co2 || ctl->ctm_h2o || ctl->ctm_n2 || ctl->ctm_o2)
3792 strcat(rfmflg, " CTM");
3793
3794 /* Write atmospheric data file... */
3795 write_atm_rfm("rfm.atm", ctl, atm);
3796
3797 /* Loop over channels... */
3798 for (int id = 0; id < ctl->nd; id++) {
3799
3800 /* Get filter function from lookup table... */
3801 n = tbl->filt_n[id];
3802 if (n <= 0 || n > NSHAPE)
3803 ERRMSG("Missing or invalid filter function in lookup table!");
3804 memcpy(nu, tbl->filt_nu[id], (size_t) n * sizeof(double));
3805 memcpy(f, tbl->filt_f[id], (size_t) n * sizeof(double));
3806
3807 /* Set spectral range... */
3808 nu0 = nu[0];
3809 nu1 = nu[n - 1];
3810
3811 /* Create RFM driver file... */
3812 FILE *out;
3813 if (!(out = fopen("rfm.drv", "w")))
3814 ERRMSG("Cannot create file!");
3815 fprintf(out, "*HDR\nRFM call by JURASSIC.\n");
3816 fprintf(out, "*FLG\n%s\n", rfmflg);
3817 fprintf(out, "*SPC\n%.4f %.4f 0.0005\n", nu0, nu1);
3818 fprintf(out, "*GAS\n");
3819 for (int ig = 0; ig < ctl->ng; ig++)
3820 fprintf(out, "%s\n", ctl->emitter[ig]);
3821 fprintf(out, "*ATM\nrfm.atm\n");
3822 fprintf(out, "*TAN\n");
3823 for (int ir = 0; ir < obs->nr; ir++)
3824 fprintf(out, "%g\n", z[ir]);
3825 fprintf(out, "*SFC\n%g 1.0\n", tsurf);
3826 if (obsz >= 0)
3827 fprintf(out, "*OBS\n%g\n", obsz);
3828 fprintf(out, "*HIT\n%s\n", ctl->rfmhit);
3829 fprintf(out, "*XSC\n");
3830 for (int ig = 0; ig < ctl->ng; ig++)
3831 if (ctl->rfmxsc[ig][0] != '-')
3832 fprintf(out, "%s\n", ctl->rfmxsc[ig]);
3833 fprintf(out, "*END\n");
3834 fclose(out);
3835
3836 /* Remove temporary files... */
3837 if (system("rm -f rfm.runlog rad_*.asc tra_*.asc"))
3838 ERRMSG("Cannot remove temporary files!");
3839
3840 /* Call RFM... */
3841 sprintf(cmd, "echo | %s", ctl->rfmbin);
3842 if (system(cmd))
3843 ERRMSG("Error while calling RFM!");
3844
3845 /* Read data... */
3846 for (int ir = 0; ir < obs->nr; ir++) {
3847 obs->rad[id][ir] = read_obs_rfm("rad", z[ir], nu, f, n) * 1e-5;
3848 obs->tau[id][ir] = read_obs_rfm("tra", z[ir], nu, f, n);
3849 }
3850 }
3851
3852 /* Remove temporary files... */
3853 if (system("rm -f rfm.drv rfm.atm rfm.runlog rad_*.asc tra_*.asc"))
3854 ERRMSG("Error while removing temporary files!");
3855
3856 /* Free... */
3857 free(los);
3858}
double read_obs_rfm(const char *basename, const double z, const double *nu, const double *f, const int n)
Read and spectrally convolve an RFM output spectrum.
Definition: jurassic.c:5917
void write_atm_rfm(const char *filename, const ctl_t *ctl, const atm_t *atm)
Write atmospheric profile in RFM-compatible format.
Definition: jurassic.c:7355
#define LEN
Maximum length of ASCII data lines.
Definition: jurassic.h:268
#define NSHAPE
Maximum number of shape function grid points.
Definition: jurassic.h:293
char rfmhit[LEN]
HITRAN file for RFM.
Definition: jurassic.h:1446
char rfmbin[LEN]
Path to RFM binary.
Definition: jurassic.h:1443
char rfmxsc[NG][LEN]
Emitter cross-section files for RFM.
Definition: jurassic.h:1449
int refrac
Take into account refractivity (0=no, 1=yes).
Definition: jurassic.h:1374
int filt_n[ND]
Filter function number of spectral grid points.
Definition: jurassic.h:1683
double filt_f[ND][NSHAPE]
Filter function values.
Definition: jurassic.h:1689
double filt_nu[ND][NSHAPE]
Filter function spectral grid points [cm^-1].
Definition: jurassic.h:1686
Here is the call graph for this function:

◆ formod_srcfunc()

void formod_srcfunc ( const ctl_t ctl,
const tbl_t tbl,
const double  t,
double *  src 
)

Interpolate the source function (Planck radiance) at a given temperature.

Computes source function values by linearly interpolating between precomputed Planck radiances in the lookup table. The resulting radiance spectrum corresponds to the input temperature and is stored in src for all spectral channels.

Parameters
[in]ctlControl structure defining the number of spectral channels.
[in]tblEmissivity and source-function lookup table containing Planck radiances (tbl_t::sr) and corresponding temperatures (tbl_t::st).
[in]tTemperature [K] for which the source function is evaluated.
[out]srcOutput array of interpolated source-function values [W·m⁻²·sr⁻¹·cm⁻¹] per spectral channel.
Note
Linear interpolation is used between the two nearest temperature grid points. The function does not extrapolate beyond the tabulated temperature range.
See also
ctl_t, tbl_t, LIN, locate_reg
Author
Lars Hoffmann

Definition at line 3862 of file jurassic.c.

3866 {
3867
3868 /* Determine index in temperature array... */
3869 const int it = locate_reg(tbl->st, TBLNS, t);
3870
3871 /* Interpolate Planck function value... */
3872 for (int id = 0; id < ctl->nd; id++)
3873 src[id] = LIN(tbl->st[it], tbl->sr[it][id],
3874 tbl->st[it + 1], tbl->sr[it + 1][id], t);
3875}
#define TBLNS
Maximum number of source function temperature levels.
Definition: jurassic.h:318
double sr[TBLNS][ND]
Source function radiance [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1695
double st[TBLNS]
Source function temperature [K].
Definition: jurassic.h:1692
Here is the call graph for this function:

◆ geo2cart()

void geo2cart ( const double  z,
const double  lon,
const double  lat,
double *  x 
)

Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.

This function converts geographic coordinates specified by longitude, latitude, and altitude into Cartesian coordinates. The Earth is approximated as a sphere with radius defined by the constant RE.

Parameters
zThe altitude above the Earth's surface in kilometers.
lonThe longitude in degrees.
latThe latitude in degrees.
xPointer to an array of three doubles where the computed Cartesian coordinates (x, y, z) will be stored.

The function computes the Cartesian coordinates using the given altitude, longitude, and latitude. It assumes the Earth is a perfect sphere and uses the following formulas:

  • \( x = (\textrm{radius}) \cos(\textrm{lat in radians}) \cos(\textrm{lon in radians}) \)
  • \( y = (\textrm{radius}) \cos(\textrm{lat in radians}) \sin(\textrm{lon in radians}) \)
  • \( z = (\textrm{radius}) \sin(\textrm{lat in radians}) \)
Note
The constant RE is defined as the Earth's radius in kilometers.
Longitude and latitude should be in degrees.
See also
https://en.wikipedia.org/wiki/Geographic_coordinate_conversion
Author
Lars Hoffmann

Definition at line 3879 of file jurassic.c.

3883 {
3884
3885 const double radius = z + RE;
3886 const double latrad = lat / 180. * M_PI;
3887 const double lonrad = lon / 180. * M_PI;
3888 const double coslat = cos(latrad);
3889
3890 x[0] = radius * coslat * cos(lonrad);
3891 x[1] = radius * coslat * sin(lonrad);
3892 x[2] = radius * sin(latrad);
3893}

◆ hydrostatic()

void hydrostatic ( const ctl_t ctl,
atm_t atm 
)

Adjust pressure profile using the hydrostatic equation.

Recomputes the atmospheric pressure field to ensure hydrostatic equilibrium with respect to altitude and temperature. Starting from a reference altitude (ctl_t::hydz), the routine integrates the hydrostatic balance equation both upward and downward through the profile using small interpolation steps.

The air density is corrected for humidity using the mean molecular mass of dry air and water vapor.

Parameters
[in]ctlControl structure providing model constants and reference altitude (ctl_t::hydz) and H₂O index (ctl_t::ig_h2o).
[in,out]atmAtmospheric state; input temperatures, heights, and humidities are used to update pressure [hPa].
Note
The integration is performed in log-pressure space assuming hydrostatic balance: \( \frac{dp}{dz} = -\rho g \),
using 20 linear substeps between adjacent levels.
See also
ctl_t, atm_t, LIN, G0, RI
Author
Lars Hoffmann

Definition at line 3897 of file jurassic.c.

3899 {
3900
3901 const double mmair = 28.96456e-3, mmh2o = 18.0153e-3;
3902
3903 const int ipts = 20;
3904
3905 double dzmin = 1e99, e = 0;
3906
3907 int ipref = 0;
3908
3909 /* Check reference height... */
3910 if (ctl->hydz < 0)
3911 return;
3912
3913 /* Find air parcel next to reference height... */
3914 for (int ip = 0; ip < atm->np; ip++)
3915 if (fabs(atm->z[ip] - ctl->hydz) < dzmin) {
3916 dzmin = fabs(atm->z[ip] - ctl->hydz);
3917 ipref = ip;
3918 }
3919
3920 /* Upper part of profile... */
3921 for (int ip = ipref + 1; ip < atm->np; ip++) {
3922 double mean = 0;
3923 for (int i = 0; i < ipts; i++) {
3924 if (ctl->ig_h2o >= 0)
3925 e = LIN(0.0, atm->q[ctl->ig_h2o][ip - 1],
3926 ipts - 1.0, atm->q[ctl->ig_h2o][ip], (double) i);
3927 mean += (e * mmh2o + (1 - e) * mmair)
3928 * G0 / RI
3929 / LIN(0.0, atm->t[ip - 1], ipts - 1.0, atm->t[ip], (double) i) / ipts;
3930 }
3931
3932 /* Compute p(z,T)... */
3933 atm->p[ip] =
3934 exp(log(atm->p[ip - 1]) - mean * 1000 * (atm->z[ip] - atm->z[ip - 1]));
3935 }
3936
3937 /* Lower part of profile... */
3938 for (int ip = ipref - 1; ip >= 0; ip--) {
3939 double mean = 0;
3940 for (int i = 0; i < ipts; i++) {
3941 if (ctl->ig_h2o >= 0)
3942 e = LIN(0.0, atm->q[ctl->ig_h2o][ip + 1],
3943 ipts - 1.0, atm->q[ctl->ig_h2o][ip], (double) i);
3944 mean += (e * mmh2o + (1 - e) * mmair)
3945 * G0 / RI
3946 / LIN(0.0, atm->t[ip + 1], ipts - 1.0, atm->t[ip], (double) i) / ipts;
3947 }
3948
3949 /* Compute p(z,T)... */
3950 atm->p[ip] =
3951 exp(log(atm->p[ip + 1]) - mean * 1000 * (atm->z[ip] - atm->z[ip + 1]));
3952 }
3953}
#define G0
Standard gravity [m/s^2].
Definition: jurassic.h:149
#define RI
Ideal gas constant [J/(mol K)].
Definition: jurassic.h:194
double hydz
Reference height for hydrostatic pressure profile (-999 to skip) [km].
Definition: jurassic.h:1359

◆ idx2name()

void idx2name ( const ctl_t ctl,
const int  idx,
char *  quantity 
)

Convert a quantity index to a descriptive name string.

Translates a model quantity index (e.g., pressure, temperature, gas mixing ratio, extinction, or surface parameter) into a human-readable name. The function uses the index mapping defined in the control structure to assign appropriate labels.

Parameters
[in]ctlControl structure containing gas, window, cloud, and surface setup information.
[in]idxQuantity index (see IDXP, IDXT, IDXQ, IDXK, etc.).
[out]quantityCharacter buffer to receive the descriptive quantity name (e.g., "PRESSURE", "H2O", "CLOUD_HEIGHT", "SURFACE_EMISSIVITY_1000.0").
Note
The function writes directly to quantity using sprintf(). The caller must ensure sufficient buffer size (≥ LEN).
See also
ctl_t, IDXP, IDXT, IDXQ, IDXK, IDXCLZ, IDXCLDZ, IDXCLK, IDXSFT, IDXSFEPS
Author
Lars Hoffmann

Definition at line 3957 of file jurassic.c.

3960 {
3961
3962 if (idx == IDXP)
3963 sprintf(quantity, "PRESSURE");
3964
3965 if (idx == IDXT)
3966 sprintf(quantity, "TEMPERATURE");
3967
3968 for (int ig = 0; ig < ctl->ng; ig++)
3969 if (idx == IDXQ(ig))
3970 sprintf(quantity, "%s", ctl->emitter[ig]);
3971
3972 for (int iw = 0; iw < ctl->nw; iw++)
3973 if (idx == IDXK(iw))
3974 sprintf(quantity, "EXTINCT_WINDOW_%d", iw);
3975
3976 if (idx == IDXCLZ)
3977 sprintf(quantity, "CLOUD_HEIGHT");
3978
3979 if (idx == IDXCLDZ)
3980 sprintf(quantity, "CLOUD_DEPTH");
3981
3982 for (int icl = 0; icl < ctl->ncl; icl++)
3983 if (idx == IDXCLK(icl))
3984 sprintf(quantity, "CLOUD_EXTINCT_%.4f", ctl->clnu[icl]);
3985
3986 if (idx == IDXSFT)
3987 sprintf(quantity, "SURFACE_TEMPERATURE");
3988
3989 for (int isf = 0; isf < ctl->nsf; isf++)
3990 if (idx == IDXSFEPS(isf))
3991 sprintf(quantity, "SURFACE_EMISSIVITY_%.4f", ctl->sfnu[isf]);
3992}
double sfnu[NSF]
Surface layer wavenumber [cm^-1].
Definition: jurassic.h:1338
double clnu[NCL]
Cloud layer wavenumber [cm^-1].
Definition: jurassic.h:1332

◆ init_srcfunc()

void init_srcfunc ( const ctl_t ctl,
tbl_t tbl 
)

Initialize source function lookup tables from emissivity data.

This function computes channel-dependent source function lookup tables based on the spectral filter functions and the Planck function. For each spectral channel, the Planck radiance is integrated over the corresponding filter function and stored as a function of temperature.

The resulting source function table represents the band-integrated thermal emission associated with the emissivity lookup tables and is later used in radiative transfer calculations.

The temperature grid is uniformly sampled between TMIN and TMAX with TBLNS points. The spectral integration is performed on the finest frequency spacing present in the filter function.

Parameters
[in]ctlPointer to the control structure defining the number of channels and their central wavenumbers.
[in,out]tblPointer to the lookup-table structure in which the source function tables and temperature grid are stored.
Note
The computation is parallelized over temperature grid points using OpenMP.
The source function is normalized by the integral of the filter function to yield a band-averaged Planck radiance.
Author
Lars Hoffmann

Definition at line 3996 of file jurassic.c.

3998 {
3999
4000 /* Write info... */
4001 LOG(1, "Initialize source function table...");
4002 LOG(2, "Number of data points: %d", TBLNS);
4003
4004 /* Loop over channels... */
4005 for (int id = 0; id < ctl->nd; id++) {
4006
4007 /* Get minimum grid spacing... */
4008 double dnu = 1.0;
4009 for (int i = 1; i < tbl->filt_n[id]; i++)
4010 dnu = MIN(dnu, tbl->filt_nu[id][i] - tbl->filt_nu[id][i - 1]);
4011
4012 /* Compute source function table... */
4013#pragma omp parallel for default(none) shared(ctl,tbl,id,dnu)
4014 for (int it = 0; it < TBLNS; it++) {
4015
4016 /* Set temperature... */
4017 tbl->st[it] = LIN(0.0, TMIN, TBLNS - 1.0, TMAX, (double) it);
4018
4019 /* Integrate Planck function... */
4020 double fsum = tbl->sr[it][id] = 0;
4021 for (double fnu = tbl->filt_nu[id][0];
4022 fnu <= tbl->filt_nu[id][tbl->filt_n[id] - 1]; fnu += dnu) {
4023 const int i = locate_irr(tbl->filt_nu[id], tbl->filt_n[id], fnu);
4024 const double ff = LIN(tbl->filt_nu[id][i], tbl->filt_f[id][i],
4025 tbl->filt_nu[id][i + 1], tbl->filt_f[id][i + 1],
4026 fnu);
4027 fsum += ff;
4028 tbl->sr[it][id] += ff * PLANCK(tbl->st[it], fnu);
4029 }
4030 tbl->sr[it][id] /= fsum;
4031 }
4032
4033 /* Write info... */
4034 LOG(2,
4035 "channel= %.4f cm^-1 | T= %g ... %g K | B= %g ... %g W/(m^2 sr cm^-1)",
4036 ctl->nu[id], tbl->st[0], tbl->st[TBLNS - 1], tbl->sr[0][id],
4037 tbl->sr[TBLNS - 1][id]);
4038 }
4039}
#define LOG(level,...)
Print a log message with a specified logging level.
Definition: jurassic.h:1123
#define TMAX
Maximum temperature for source function [K].
Definition: jurassic.h:209
#define TMIN
Minimum temperature for source function [K].
Definition: jurassic.h:204
Here is the call graph for this function:

◆ intpol_atm()

void intpol_atm ( const ctl_t ctl,
const atm_t atm,
const double  z,
double *  p,
double *  t,
double *  q,
double *  k 
)

Interpolate atmospheric state variables at a given altitude.

Computes pressure, temperature, volume mixing ratios, and extinction coefficients at the specified altitude by interpolating between adjacent model levels in the atmospheric profile.

Parameters
[in]ctlControl structure defining the number of gases (ctl_t::ng) and spectral windows (ctl_t::nw).
[in]atmAtmospheric profile providing altitude, pressure, temperature, gas mixing ratios, and extinction data.
[in]zTarget altitude [km].
[out]pInterpolated pressure [hPa].
[out]tInterpolated temperature [K].
[out]qInterpolated gas volume mixing ratios [ppv], length ctl_t::ng.
[out]kInterpolated extinction coefficients [km⁻¹], length ctl_t::nw.
Note
Pressure is interpolated logarithmically using LOGY, while other quantities use linear interpolation (LIN).
See also
ctl_t, atm_t, locate_irr, LIN, LOGY
Author
Lars Hoffmann

Definition at line 4043 of file jurassic.c.

4050 {
4051
4052 /* Get array index... */
4053 const int ip = locate_irr(atm->z, atm->np, z);
4054
4055 /* Interpolate... */
4056 *p = LOGY(atm->z[ip], atm->p[ip], atm->z[ip + 1], atm->p[ip + 1], z);
4057 *t = LIN(atm->z[ip], atm->t[ip], atm->z[ip + 1], atm->t[ip + 1], z);
4058 for (int ig = 0; ig < ctl->ng; ig++)
4059 q[ig] =
4060 LIN(atm->z[ip], atm->q[ig][ip], atm->z[ip + 1], atm->q[ig][ip + 1], z);
4061 for (int iw = 0; iw < ctl->nw; iw++)
4062 k[iw] =
4063 LIN(atm->z[ip], atm->k[iw][ip], atm->z[ip + 1], atm->k[iw][ip + 1], z);
4064}
Here is the call graph for this function:

◆ intpol_tbl_cga()

void intpol_tbl_cga ( const ctl_t ctl,
const tbl_t tbl,
const los_t los,
const int  ip,
double  tau_path[ND][NG],
double  tau_seg[ND] 
)

Interpolate emissivities and transmittances using the Curtis–Godson approximation (CGA).

Computes gas transmittance along a line-of-sight segment by interpolating precomputed emissivity values from lookup tables. The interpolation is performed in pressure, temperature, and column density space using bilinear (in p, T) and logarithmic (in p) interpolation.

Parameters
[in]ctlControl structure defining number of gases (ctl_t::ng) and channels (ctl_t::nd).
[in]tblEmissivity lookup tables (tbl_t) containing tabulated pressure, temperature, and column density grids.
[in]losLine-of-sight structure providing Curtis–Godson mean parameters and column densities.
[in]ipIndex of the current LOS point.
[in,out]tau_pathPath transmittance array [nd][ng]; updated cumulatively for each gas.
[out]tau_segTotal segment transmittance per channel [nd].
  • Uses pretabulated emissivity data (tbl->eps) for each gas and channel.
  • Applies logarithmic interpolation in pressure (LOGX) and linear interpolation in temperature (LIN).
  • Enforces emissivity limits in the range [0, 1].
  • Returns unity transmittance if data are missing or column density ≤ 0.
See also
ctl_t, tbl_t, los_t, intpol_tbl_eps, LIN, LOGX, locate_irr, locate_reg
Author
Lars Hoffmann

Definition at line 4068 of file jurassic.c.

4074 {
4075
4076 double eps, lnp[NG];
4077
4078 /* Precompute log-pressure... */
4079 for (int ig = 0; ig < ctl->ng; ig++)
4080 lnp[ig] = log(los->cgp[ip][ig]);
4081
4082 /* Loop over channels... */
4083 for (int id = 0; id < ctl->nd; id++) {
4084
4085 /* Initialize... */
4086 tau_seg[id] = 1;
4087
4088 /* Loop over emitters.... */
4089 for (int ig = 0; ig < ctl->ng; ig++) {
4090
4091 /* Check size of table (pressure) and column density... */
4092 if (tbl->np[id][ig] < 30 || los->cgu[ip][ig] <= 0)
4093 eps = 0;
4094
4095 /* Check transmittance... */
4096 else if (tau_path[id][ig] < 1e-9)
4097 eps = 1;
4098
4099 /* Interpolate... */
4100 else {
4101
4102 /* Determine pressure and temperature indices... */
4103 const int ipr =
4104 locate_irr(tbl->p[id][ig], tbl->np[id][ig], los->cgp[ip][ig]);
4105 const int it0 = locate_reg(tbl->t[id][ig][ipr], tbl->nt[id][ig][ipr],
4106 los->cgt[ip][ig]);
4107 const int it1 =
4108 locate_reg(tbl->t[id][ig][ipr + 1], tbl->nt[id][ig][ipr + 1],
4109 los->cgt[ip][ig]);
4110
4111 /* Check size of table (temperature and column density)... */
4112 if (tbl->nt[id][ig][ipr] < 2 || tbl->nt[id][ig][ipr + 1] < 2
4113 || tbl->nu[id][ig][ipr][it0] < 2
4114 || tbl->nu[id][ig][ipr][it0 + 1] < 2
4115 || tbl->nu[id][ig][ipr + 1][it1] < 2
4116 || tbl->nu[id][ig][ipr + 1][it1 + 1] < 2)
4117 eps = 0;
4118
4119 else {
4120
4121 /* Get emissivities of extended path... */
4122 const double logu = log(los->cgu[ip][ig]);
4123 double eps00 = intpol_tbl_eps(tbl, ig, id, ipr, it0, logu);
4124 double eps01 = intpol_tbl_eps(tbl, ig, id, ipr, it0 + 1, logu);
4125 double eps10 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1, logu);
4126 double eps11 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1 + 1, logu);
4127
4128 /* Interpolate with respect to temperature... */
4129 eps00 = LIN(tbl->t[id][ig][ipr][it0], eps00,
4130 tbl->t[id][ig][ipr][it0 + 1], eps01, los->cgt[ip][ig]);
4131 eps11 = LIN(tbl->t[id][ig][ipr + 1][it1], eps10,
4132 tbl->t[id][ig][ipr + 1][it1 + 1],
4133 eps11, los->cgt[ip][ig]);
4134
4135 /* Interpolate with respect to log-pressure... */
4136 eps00 = LIN(tbl->lnp[id][ig][ipr], eps00,
4137 tbl->lnp[id][ig][ipr + 1], eps11, lnp[ig]);
4138
4139 /* Check emissivity range... */
4140 eps00 = CLAMP(eps00, 0, 1);
4141
4142 /* Determine segment emissivity... */
4143 eps = 1 - (1 - eps00) / tau_path[id][ig];
4144 }
4145 }
4146
4147 /* Get transmittance of extended path... */
4148 tau_path[id][ig] *= (1 - eps);
4149
4150 /* Get segment transmittance... */
4151 tau_seg[id] *= (1 - eps);
4152 }
4153 }
4154}
double intpol_tbl_eps(const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double logu)
Interpolate gas emissivity as a function of column amount.
Definition: jurassic.c:4257
#define CLAMP(v, lo, hi)
Clamp a value to a specified range.
Definition: jurassic.h:430
double cgu[NLOS][NG]
Curtis-Godson column density [molecules/cm^2].
Definition: jurassic.h:1505
double cgt[NLOS][NG]
Curtis-Godson temperature [K].
Definition: jurassic.h:1502
double cgp[NLOS][NG]
Curtis-Godson pressure [hPa].
Definition: jurassic.h:1499
double p[ND][NG][TBLNP]
Pressure [hPa].
Definition: jurassic.h:1668
int nu[ND][NG][TBLNP][TBLNT]
Number of column densities.
Definition: jurassic.h:1665
int nt[ND][NG][TBLNP]
Number of temperatures.
Definition: jurassic.h:1662
double t[ND][NG][TBLNP][TBLNT]
Temperature [K].
Definition: jurassic.h:1674
double lnp[ND][NG][TBLNP]
Log-pressure [hPa].
Definition: jurassic.h:1671
int np[ND][NG]
Number of pressure levels.
Definition: jurassic.h:1659
Here is the call graph for this function:

◆ intpol_tbl_ega()

void intpol_tbl_ega ( const ctl_t ctl,
const tbl_t tbl,
const los_t los,
const int  ip,
double  tau_path[ND][NG],
double  tau_seg[ND] 
)

Interpolate emissivities and transmittances using the Emissivity Growth Approximation (EGA).

Computes gas transmittance along a line-of-sight segment by interpolating emissivity values from lookup tables based on the Emissivity Growth Approximation (EGA). The interpolation is performed in pressure, temperature, and effective column density space derived from the local LOS properties.

Parameters
[in]ctlControl structure defining number of gases (ctl_t::ng) and channels (ctl_t::nd).
[in]tblEmissivity lookup tables (tbl_t) containing tabulated pressure, temperature, and column density grids.
[in]losLine-of-sight structure providing local pressure, temperature, and column density data.
[in]ipIndex of the current LOS point.
[in,out]tau_pathPath transmittance array [nd][ng]; updated cumulatively for each gas.
[out]tau_segTotal segment transmittance per channel [nd].
  • Uses pretabulated emissivity data (tbl->eps) and performs bilinear interpolation in pressure and temperature.
  • Column density interpolation is handled by intpol_tbl_u according to the emissivity growth relation.
  • Enforces emissivity limits within [0, 1].
  • Returns unity transmittance if lookup data are invalid or column density ≤ 0.
See also
ctl_t, tbl_t, los_t, intpol_tbl_u, intpol_tbl_eps, LIN, locate_irr, locate_reg
Note
Implements the EGA variant of the forward model, selected when ctl_t::formod = 1.
Author
Lars Hoffmann

Definition at line 4158 of file jurassic.c.

4164 {
4165
4166 const double lnp = log(los->p[ip]);
4167
4168 double eps, u;
4169
4170 /* Loop over channels... */
4171 for (int id = 0; id < ctl->nd; id++) {
4172
4173 /* Initialize... */
4174 tau_seg[id] = 1;
4175
4176 /* Loop over emitters.... */
4177 for (int ig = 0; ig < ctl->ng; ig++) {
4178
4179 /* Check size of table (pressure) and column density... */
4180 if (tbl->np[id][ig] < 30 || los->cgu[ip][ig] <= 0)
4181 eps = 0;
4182
4183 /* Check transmittance... */
4184 else if (tau_path[id][ig] < 1e-9)
4185 eps = 1;
4186
4187 /* Interpolate... */
4188 else {
4189
4190 /* Determine pressure and temperature indices... */
4191 const int ipr =
4192 locate_irr(tbl->p[id][ig], tbl->np[id][ig], los->p[ip]);
4193 const int it0 =
4194 locate_reg(tbl->t[id][ig][ipr], tbl->nt[id][ig][ipr], los->t[ip]);
4195 const int it1 =
4196 locate_reg(tbl->t[id][ig][ipr + 1], tbl->nt[id][ig][ipr + 1],
4197 los->t[ip]);
4198
4199 /* Check size of table (temperature and column density)... */
4200 if (tbl->nt[id][ig][ipr] < 2 || tbl->nt[id][ig][ipr + 1] < 2
4201 || tbl->nu[id][ig][ipr][it0] < 2
4202 || tbl->nu[id][ig][ipr][it0 + 1] < 2
4203 || tbl->nu[id][ig][ipr + 1][it1] < 2
4204 || tbl->nu[id][ig][ipr + 1][it1 + 1] < 2)
4205 eps = 0;
4206
4207 else {
4208
4209 /* Get emissivities of extended path... */
4210 const double logeps = log(1.0 - tau_path[id][ig]);
4211
4212 u = intpol_tbl_u(tbl, ig, id, ipr, it0, logeps);
4213 double eps00
4214 = intpol_tbl_eps(tbl, ig, id, ipr, it0, log(u + los->u[ip][ig]));
4215
4216 u = intpol_tbl_u(tbl, ig, id, ipr, it0 + 1, logeps);
4217 double eps01 = intpol_tbl_eps(tbl, ig, id, ipr, it0 + 1,
4218 log(u + los->u[ip][ig]));
4219
4220 u = intpol_tbl_u(tbl, ig, id, ipr + 1, it1, logeps);
4221 double eps10 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1,
4222 log(u + los->u[ip][ig]));
4223
4224 u = intpol_tbl_u(tbl, ig, id, ipr + 1, it1 + 1, logeps);
4225 double eps11 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1 + 1,
4226 log(u + los->u[ip][ig]));
4227
4228 /* Interpolate with respect to temperature... */
4229 eps00 = LIN(tbl->t[id][ig][ipr][it0], eps00,
4230 tbl->t[id][ig][ipr][it0 + 1], eps01, los->t[ip]);
4231 eps11 = LIN(tbl->t[id][ig][ipr + 1][it1], eps10,
4232 tbl->t[id][ig][ipr + 1][it1 + 1], eps11, los->t[ip]);
4233
4234 /* Interpolate with respect to log-pressure... */
4235 eps00 = LIN(tbl->lnp[id][ig][ipr], eps00,
4236 tbl->lnp[id][ig][ipr + 1], eps11, lnp);
4237
4238 /* Check emissivity range... */
4239 eps00 = CLAMP(eps00, 0, 1);
4240
4241 /* Determine segment emissivity... */
4242 eps = 1 - (1 - eps00) / tau_path[id][ig];
4243 }
4244 }
4245
4246 /* Get transmittance of extended path... */
4247 tau_path[id][ig] *= (1 - eps);
4248
4249 /* Get segment transmittance... */
4250 tau_seg[id] *= (1 - eps);
4251 }
4252 }
4253}
double intpol_tbl_u(const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double logeps)
Interpolate column amount as a function of emissivity.
Definition: jurassic.c:4302
Here is the call graph for this function:

◆ intpol_tbl_eps()

double intpol_tbl_eps ( const tbl_t tbl,
const int  ig,
const int  id,
const int  ip,
const int  it,
const double  logu 
)
inline

Interpolate gas emissivity as a function of column amount.

Computes emissivity \(\varepsilon(u)\) from tabulated data using linear interpolation in \(\log u\)– \(\log\varepsilon\) space. The input column amount must be provided as \(\log(u)\).

Behavior:

  • For \(u < u_{\min}\), emissivity scales linearly with column amount.
  • For \(u > u_{\max}\), emissivity asymptotically approaches unity using an exponential tail matched at \((u_{\max}, \varepsilon_{\max})\).

The implementation uses log1p/expm1 for numerical stability and minimizes conversions between linear and logarithmic space.

Parameters
tblLookup table structure.
igGas index.
idSpectral/channel index.
ipPressure index.
itTemperature index.
loguNatural logarithm of the column amount [molecules/cm²].
Returns
Emissivity in the range \([0,1]\).
Author
Lars Hoffmann

Definition at line 4257 of file jurassic.c.

4263 {
4264
4265 const int nu = tbl->nu[id][ig][ip][it];
4266 const float *logu_arr = tbl->logu[id][ig][ip][it];
4267 const float *logeps_arr = tbl->logeps[id][ig][ip][it];
4268
4269 /* Work in log-space and only convert back when needed... */
4270 const double logu_min = (double) logu_arr[0];
4271 const double logu_max = (double) logu_arr[nu - 1];
4272
4273 /* Lower boundary extrapolation (u < u_min)...
4274 eps ~ eps_min * u/u_min => log(eps) = logeps_min + log(u) - log(u_min) */
4275 if (logu < logu_min) {
4276 const double logeps_min = (double) logeps_arr[0];
4277 return exp(logeps_min + logu - logu_min);
4278 }
4279
4280 /* Upper boundary extrapolation (u > u_max)...
4281 * Assume eps(u) approaches 1 exponentially:
4282 * eps(u) = 1 - exp(a * u), a < 0
4283 * Continuity at (u_max, eps_max) gives
4284 * a = log(1 - eps_max) / u_max.
4285 * Use log1p/expm1 and u/u_max = exp(log(u) - log(u_max)) for stability.
4286 */
4287 if (logu > logu_max) {
4288 const double eps_max = exp((double) logeps_arr[nu - 1]);
4289 const double l1m_eps_max = log1p(-eps_max);
4290 const double r = exp(logu - logu_max);
4291 return -expm1(l1m_eps_max * r);
4292 }
4293
4294 /* Interpolation (log-log using precomputed logs)... */
4295 const int idx = locate_tbl(logu_arr, nu, logu);
4296 return exp(LIN(logu_arr[idx], logeps_arr[idx],
4297 logu_arr[idx + 1], logeps_arr[idx + 1], logu));
4298}
int locate_tbl(const float *xx, const int n, const double x)
Locate index for interpolation within emissivity table grids.
Definition: jurassic.c:4524
float * logu[ND][NG][TBLNP][TBLNT]
Logarithm of column density [molecules/cm^2].
Definition: jurassic.h:1677
float * logeps[ND][NG][TBLNP][TBLNT]
Logarithm of emissivity.
Definition: jurassic.h:1680
Here is the call graph for this function:

◆ intpol_tbl_u()

double intpol_tbl_u ( const tbl_t tbl,
const int  ig,
const int  id,
const int  ip,
const int  it,
const double  logeps 
)
inline

Interpolate column amount as a function of emissivity.

Computes the column amount \(u(\varepsilon)\) from tabulated data using linear interpolation in \(\log\varepsilon\)– \(\log u\) space. The emissivity must be provided as \(\log(\varepsilon)\) together with \(\log(1-\varepsilon)\).

Behavior:

  • For \(\varepsilon < \varepsilon_{\min}\), column amount scales linearly with emissivity.
  • For \(\varepsilon > \varepsilon_{\max}\), the exponential tail used in intpol_tbl_eps() is analytically inverted.

The implementation operates primarily in log-space and uses log1p for numerical stability near \(\varepsilon \rightarrow 1\).

Parameters
tblLookup table structure.
igGas index.
idSpectral/channel index.
ipPressure index.
itTemperature index.
logepsNatural logarithm of emissivity ( \(\log\varepsilon\)).
Returns
Column amount \(u\).
See also
intpol_tbl_eps
Author
Lars Hoffmann

Definition at line 4302 of file jurassic.c.

4308 {
4309
4310 const int nu = tbl->nu[id][ig][ip][it];
4311 const float *logeps_arr = tbl->logeps[id][ig][ip][it];
4312 const float *logu_arr = tbl->logu[id][ig][ip][it];
4313
4314 /* Work in log-space and only convert back when needed.... */
4315 const double logeps_min = (double) logeps_arr[0];
4316 const double logeps_max = (double) logeps_arr[nu - 1];
4317
4318 /* Lower boundary extrapolation (eps < eps_min)...
4319 u ~ u_min * eps/eps_min => log(u) = log(u_min) + log(eps) - log(eps_min) */
4320 if (logeps < logeps_min) {
4321 const double logu_min = (double) logu_arr[0];
4322 return exp(logu_min + logeps - logeps_min);
4323 }
4324
4325 /* Upper boundary extrapolation (eps > eps_max):
4326 * Invert the exponential tail used for eps(u):
4327 * u = log(1 - eps) / a,
4328 * with a = log(1 - eps_max) / u_max.
4329 * Rewritten as
4330 * u = u_max * log(tau) / log(1 - eps_max)
4331 * for numerical stability (log1p).
4332 */
4333 if (logeps > logeps_max) {
4334 const double u_max = exp((double) logu_arr[nu - 1]);
4335 const double l1m_eps_max = log1p(-exp(logeps_max));
4336 const double logtau = log1p(-exp(logeps));
4337 return u_max * (logtau / l1m_eps_max);
4338 }
4339
4340 /* Interpolation (log-log using precomputed logs)... */
4341 const int idx = locate_tbl(logeps_arr, nu, logeps);
4342 return exp(LIN(logeps_arr[idx], logu_arr[idx],
4343 logeps_arr[idx + 1], logu_arr[idx + 1], logeps));
4344}
Here is the call graph for this function:

◆ jsec2time()

void jsec2time ( const double  jsec,
int *  year,
int *  mon,
int *  day,
int *  hour,
int *  min,
int *  sec,
double *  remain 
)

Converts Julian seconds to calendar date and time components.

This function converts Julian seconds to calendar date and time components, including year, month, day, hour, minute, and second. It also calculates the fractional part of the seconds.

Parameters
jsecJulian seconds to convert.
yearPointer to store the year.
monPointer to store the month.
dayPointer to store the day.
hourPointer to store the hour.
minPointer to store the minute.
secPointer to store the second.
remainPointer to store the fractional part of seconds.

The function initializes a time structure t0 with a fixed starting date and time. It then converts the Julian seconds to a time_t type by adding the seconds to the epoch time. Next, it converts the time_t value to a UTC time structure t1. Finally, it extracts the year, month, day, hour, minute, and second components from t1 and calculates the fractional part of seconds, which is stored in remain.

Author
Lars Hoffmann

Definition at line 4348 of file jurassic.c.

4356 {
4357
4358 struct tm t0, *t1;
4359
4360 t0.tm_year = 100;
4361 t0.tm_mon = 0;
4362 t0.tm_mday = 1;
4363 t0.tm_hour = 0;
4364 t0.tm_min = 0;
4365 t0.tm_sec = 0;
4366
4367 const time_t jsec0 = (time_t) jsec + timegm(&t0);
4368 t1 = gmtime(&jsec0);
4369
4370 *year = t1->tm_year + 1900;
4371 *mon = t1->tm_mon + 1;
4372 *day = t1->tm_mday;
4373 *hour = t1->tm_hour;
4374 *min = t1->tm_min;
4375 *sec = t1->tm_sec;
4376 *remain = jsec - floor(jsec);
4377}

◆ kernel()

void kernel ( const ctl_t ctl,
const tbl_t tbl,
atm_t atm,
obs_t obs,
gsl_matrix *  k 
)

Compute the Jacobian (kernel) matrix by finite differences.

Evaluates the sensitivity of the simulated radiances to each element of the atmospheric state vector by perturbing one parameter at a time and re-running the forward model. The result is the Jacobian matrix \( K = \partial y / \partial x \), where y is the measurement vector and x is the state vector.

Parameters
[in]ctlControl structure defining retrieval configuration and model setup.
[in]tblEmissivity lookup tables used by the forward model.
[in]atmAtmospheric state vector and profile data.
[in]obsObservation geometry and radiance data.
[out]kJacobian matrix [m×n], where m is the number of measurements and n the number of state variables.
  • The undisturbed forward model is first computed to obtain the reference measurement vector.
  • Each state vector element is perturbed by an adaptive step h depending on its physical type (pressure, temperature, VMR, etc.).
  • For each perturbation, the forward model is re-evaluated, and the corresponding column of K is estimated using finite differences.
  • Parallelized over state vector elements using OpenMP.
Note
Typical perturbation sizes:
  • Pressure: 1 % or ≥ 1e–7 hPa
  • Temperature: 1 K
  • VMR: 1 % or ≥ 1e–15
  • Extinction: 1e–4 km⁻¹
  • Cloud and surface parameters: 1 K or 1e–2 as appropriate.
See also
ctl_t, tbl_t, atm_t, obs_t, formod, x2atm, atm2x, obs2y, copy_atm, copy_obs
Warning
Computationally intensive; requires one forward model evaluation per state vector element.
Author
Lars Hoffmann

Definition at line 4381 of file jurassic.c.

4386 {
4387
4388 /* Get sizes... */
4389 const size_t m = k->size1;
4390 const size_t n = k->size2;
4391
4392 /* Allocate... */
4393 gsl_vector *x0 = gsl_vector_alloc(n);
4394 gsl_vector *yy0 = gsl_vector_alloc(m);
4395 int *iqa;
4396 ALLOC(iqa, int,
4397 N);
4398
4399 /* Compute radiance for undisturbed atmospheric data... */
4400 formod(ctl, tbl, atm, obs);
4401
4402 /* Compose vectors... */
4403 atm2x(ctl, atm, x0, iqa, NULL);
4404 obs2y(ctl, obs, yy0, NULL, NULL);
4405
4406 /* Initialize kernel matrix... */
4407 gsl_matrix_set_zero(k);
4408
4409 /* Loop over state vector elements... */
4410#pragma omp parallel for default(none) shared(ctl,tbl,atm,obs,k,x0,yy0,n,m,iqa)
4411 for (size_t j = 0; j < n; j++) {
4412
4413 /* Allocate... */
4414 atm_t *atm1;
4415 obs_t *obs1;
4416 ALLOC(atm1, atm_t, 1);
4417 ALLOC(obs1, obs_t, 1);
4418 gsl_vector *x1 = gsl_vector_alloc(n);
4419 gsl_vector *yy1 = gsl_vector_alloc(m);
4420
4421 /* Set perturbation size... */
4422 double h;
4423 if (iqa[j] == IDXP)
4424 h = MAX(fabs(0.01 * gsl_vector_get(x0, j)), 1e-7);
4425 else if (iqa[j] == IDXT)
4426 h = 1.0;
4427 else if (iqa[j] >= IDXQ(0) && iqa[j] < IDXQ(ctl->ng))
4428 h = MAX(fabs(0.01 * gsl_vector_get(x0, j)), 1e-15);
4429 else if (iqa[j] >= IDXK(0) && iqa[j] < IDXK(ctl->nw))
4430 h = 1e-4;
4431 else if (iqa[j] == IDXCLZ || iqa[j] == IDXCLDZ)
4432 h = 1.0;
4433 else if (iqa[j] >= IDXCLK(0) && iqa[j] < IDXCLK(ctl->ncl))
4434 h = 1e-4;
4435 else if (iqa[j] == IDXSFT)
4436 h = 1.0;
4437 else if (iqa[j] >= IDXSFEPS(0) && iqa[j] < IDXSFEPS(ctl->nsf))
4438 h = 1e-2;
4439 else
4440 ERRMSG("Cannot set perturbation size!");
4441
4442 /* Disturb state vector element... */
4443 gsl_vector_memcpy(x1, x0);
4444 gsl_vector_set(x1, j, gsl_vector_get(x1, j) + h);
4445 copy_atm(ctl, atm1, atm, 0);
4446 copy_obs(ctl, obs1, obs, 0);
4447 x2atm(ctl, x1, atm1);
4448
4449 /* Compute radiance for disturbed atmospheric data... */
4450 formod(ctl, tbl, atm1, obs1);
4451
4452 /* Compose measurement vector for disturbed radiance data... */
4453 obs2y(ctl, obs1, yy1, NULL, NULL);
4454
4455 /* Compute derivatives... */
4456 for (size_t i = 0; i < m; i++)
4457 gsl_matrix_set(k, i, j,
4458 (gsl_vector_get(yy1, i) - gsl_vector_get(yy0, i)) / h);
4459
4460 /* Free... */
4461 gsl_vector_free(x1);
4462 gsl_vector_free(yy1);
4463 free(atm1);
4464 free(obs1);
4465 }
4466
4467 /* Free... */
4468 gsl_vector_free(x0);
4469 gsl_vector_free(yy0);
4470 free(iqa);
4471}
void x2atm(const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
Map retrieval state vector back to atmospheric structure.
Definition: jurassic.c:8193
void formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
Execute the selected forward model.
Definition: jurassic.c:3415
size_t obs2y(const ctl_t *ctl, const obs_t *obs, gsl_vector *y, int *ida, int *ira)
Convert observation radiances into a measurement vector.
Definition: jurassic.c:4621
size_t atm2x(const ctl_t *ctl, const atm_t *atm, gsl_vector *x, int *iqa, int *ipa)
Convert atmospheric data to state vector elements.
Definition: jurassic.c:118
Here is the call graph for this function:

◆ locate_irr()

int locate_irr ( const double *  xx,
const int  n,
const double  x 
)

Locate index for interpolation on an irregular grid.

Finds the lower index ilo such that \( xx[ilo] \le x < xx[ilo+1] \) for monotonically increasing or decreasing grids.
Used in interpolation routines for altitude, pressure, temperature, or wavenumber profiles that are not evenly spaced.

Parameters
[in]xxArray of monotonic grid values (increasing or decreasing).
[in]nNumber of grid points.
[in]xTarget value to locate within the grid range.
Returns
Index ilo of the lower grid point surrounding x.
  • Uses a binary search algorithm with \( O(\log n) \) complexity.
  • Handles both increasing and decreasing grids automatically.
  • Returns the index of the lower neighbor suitable for use in interpolation routines such as LIN, LOGX, or LOGY.
See also
LIN, LOGX, LOGY, locate_reg, locate_tbl
Warning
Assumes x lies within the range of xx; no bounds checking beyond the first and last grid points is performed.
Author
Lars Hoffmann

Definition at line 4475 of file jurassic.c.

4478 {
4479
4480 int ilo = 0;
4481 int ihi = n - 1;
4482 int i = (ihi + ilo) >> 1;
4483
4484 if (xx[i] < xx[i + 1])
4485 while (ihi > ilo + 1) {
4486 i = (ihi + ilo) >> 1;
4487 if (xx[i] > x)
4488 ihi = i;
4489 else
4490 ilo = i;
4491 } else
4492 while (ihi > ilo + 1) {
4493 i = (ihi + ilo) >> 1;
4494 if (xx[i] <= x)
4495 ihi = i;
4496 else
4497 ilo = i;
4498 }
4499
4500 return ilo;
4501}

◆ locate_reg()

int locate_reg ( const double *  xx,
const int  n,
const double  x 
)

Locate index for interpolation on a regular (uniform) grid.

Computes the lower index i such that \( xx[i] \le x < xx[i+1] \) for evenly spaced grid points. Used for quick index lookup when the grid spacing is constant.

Parameters
[in]xxArray of regularly spaced grid values.
[in]nNumber of grid points.
[in]xTarget value to locate within the grid range.
Returns
Index i of the lower grid point surrounding x.
  • Computes the index directly from the grid spacing using \( i = (x - xx_0) / (xx_1 - xx_0) \).
  • Clamps the result to [0, n - 2] to avoid out-of-bounds indices.
  • Suitable for use with uniform grids such as pressure, temperature, or wavelength tables.
See also
locate_irr, locate_tbl, LIN, LOGX, LOGY
Warning
Assumes uniform grid spacing; results are invalid for irregularly spaced arrays.
Author
Lars Hoffmann

Definition at line 4505 of file jurassic.c.

4508 {
4509
4510 /* Calculate index... */
4511 const int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
4512
4513 /* Check range... */
4514 if (i < 0)
4515 return 0;
4516 else if (i > n - 2)
4517 return n - 2;
4518 else
4519 return i;
4520}

◆ locate_tbl()

int locate_tbl ( const float *  xx,
const int  n,
const double  x 
)
inline

Locate index for interpolation within emissivity table grids.

Finds the lower index ilo such that \( xx[ilo] \le x < xx[ilo+1] \) in a monotonically increasing single-precision grid.
Used for emissivity and column density interpolation in table-based routines such as intpol_tbl_eps and intpol_tbl_u.

Parameters
[in]xxMonotonic (increasing) single-precision grid array.
[in]nNumber of grid points.
[in]xTarget value to locate within the grid range.
Returns
Index ilo of the lower grid point surrounding x.
  • Implements a binary search with \( O(\log n) \) complexity.
  • Optimized for lookup tables stored in float to minimize memory use.
  • Returns an index suitable for linear interpolation with LIN.
See also
intpol_tbl_eps, intpol_tbl_u, LIN, locate_irr, locate_reg
Warning
Assumes monotonic grid input (increasing order) and that x lies within the table range.
Author
Lars Hoffmann

Definition at line 4524 of file jurassic.c.

4527 {
4528
4529 int ilo = 0;
4530 int ihi = n - 1;
4531 int i = (ihi + ilo) >> 1;
4532
4533 while (ihi > ilo + 1) {
4534 i = (ihi + ilo) >> 1;
4535 if (xx[i] > x)
4536 ihi = i;
4537 else
4538 ilo = i;
4539 }
4540
4541 return ilo;
4542}

◆ matrix_invert()

void matrix_invert ( gsl_matrix *  a)

Invert a square matrix, optimized for diagonal or symmetric positive-definite matrices.

Performs in-place inversion of the matrix \(\mathbf{A}\) using either:

  • Fast diagonal inversion, if the matrix is strictly diagonal.
  • Cholesky decomposition, if the matrix is full and symmetric positive-definite.
Parameters
[in,out]aSquare matrix (gsl_matrix) to be inverted in place.

The function first checks whether the input matrix is diagonal by testing all off-diagonal elements. If diagonal, each diagonal element \(a_{ii}\) is replaced by its reciprocal \(1/a_{ii}\).

For non-diagonal matrices, a Cholesky decomposition is performed:

\[ \mathbf{A} = \mathbf{L}\mathbf{L}^T \]

followed by inversion using the Cholesky factors, yielding \(\mathbf{A}^{-1}\).

This approach assumes \(\mathbf{A}\) is symmetric and positive-definite.

See also
gsl_linalg_cholesky_decomp, gsl_linalg_cholesky_invert
Note
  • The inversion is performed in place; the input matrix is overwritten.
  • No explicit symmetry or definiteness checks are performed — invalid input may result in numerical instability or GSL errors.
  • Diagonal detection assumes exact zeros for off-diagonal elements.
Warning
For ill-conditioned matrices, consider using singular value decomposition (SVD) or regularization methods instead of direct inversion.
Author
Lars Hoffmann

Definition at line 4546 of file jurassic.c.

4547 {
4548
4549 size_t diag = 1;
4550
4551 /* Get size... */
4552 const size_t n = a->size1;
4553
4554 /* Check if matrix is diagonal... */
4555 for (size_t i = 0; i < n && diag; i++)
4556 for (size_t j = i + 1; j < n; j++)
4557 if (gsl_matrix_get(a, i, j) != 0) {
4558 diag = 0;
4559 break;
4560 }
4561
4562 /* Quick inversion of diagonal matrix... */
4563 if (diag)
4564 for (size_t i = 0; i < n; i++)
4565 gsl_matrix_set(a, i, i, 1 / gsl_matrix_get(a, i, i));
4566
4567 /* Matrix inversion by means of Cholesky decomposition... */
4568 else {
4569 gsl_linalg_cholesky_decomp(a);
4570 gsl_linalg_cholesky_invert(a);
4571 }
4572}

◆ matrix_product()

void matrix_product ( const gsl_matrix *  a,
const gsl_vector *  b,
const int  transpose,
gsl_matrix *  c 
)

Compute structured matrix products of the form \(A^T B A\) or \(A B A^T\).

Evaluates matrix products commonly used in covariance propagation and optimal estimation, depending on the specified transpose mode:

  • transpose = 1 → computes \(\mathbf{A}^T \mathbf{B} \mathbf{A}\)
  • transpose = 2 → computes \(\mathbf{A} \mathbf{B} \mathbf{A}^T\)

The vector \(\mathbf{b}\) represents the diagonal elements of \(\mathbf{B}\), i.e. a diagonal weighting or covariance matrix.

Parameters
[in]aInput matrix \(\mathbf{A}\) (size m×n).
[in]bVector representing the diagonal of \(\mathbf{B}\) (length m or n).
[in]transposeOperation selector:
  • 1 → compute \(A^T B A\)
  • 2 → compute \(A B A^T\)
[out]cOutput matrix to store the resulting product.
  • The function internally forms the scaled matrix \((B^{1/2} A)\) or \((A B^{1/2})\), then multiplies it using BLAS dgemm routines for efficiency:

    \[ A^T B A = (B^{1/2}A)^T (B^{1/2}A), \quad A B A^T = (A B^{1/2}) (A B^{1/2})^T \]

  • The input matrix \(\mathbf{A}\) is not modified.
  • This operation is typically used in computing gain matrices, propagated covariances, or sensitivity matrices in retrieval algorithms.
See also
gsl_blas_dgemm, matrix_invert
Note
  • Assumes \(\mathbf{B}\) is diagonal (provided as a vector of its diagonal elements).
  • The output matrix \(\mathbf{C}\) must be pre-allocated to the correct size.
  • No symmetry enforcement or normalization is applied.
Warning
  • If transpose is not 1 or 2, the function performs no operation.
  • Numerical stability depends on the conditioning of A and the scaling of B.
Author
Lars Hoffmann

Definition at line 4576 of file jurassic.c.

4580 {
4581
4582 /* Set sizes... */
4583 const size_t m = a->size1;
4584 const size_t n = a->size2;
4585
4586 /* Allocate... */
4587 gsl_matrix *aux = gsl_matrix_alloc(m, n);
4588
4589 /* Compute A^T B A... */
4590 if (transpose == 1) {
4591
4592 /* Compute B^1/2 A... */
4593 for (size_t i = 0; i < m; i++)
4594 for (size_t j = 0; j < n; j++)
4595 gsl_matrix_set(aux, i, j,
4596 gsl_vector_get(b, i) * gsl_matrix_get(a, i, j));
4597
4598 /* Compute A^T B A = (B^1/2 A)^T (B^1/2 A)... */
4599 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, aux, aux, 0.0, c);
4600 }
4601
4602 /* Compute A B A^T... */
4603 else if (transpose == 2) {
4604
4605 /* Compute A B^1/2... */
4606 for (size_t i = 0; i < m; i++)
4607 for (size_t j = 0; j < n; j++)
4608 gsl_matrix_set(aux, i, j,
4609 gsl_matrix_get(a, i, j) * gsl_vector_get(b, j));
4610
4611 /* Compute A B A^T = (A B^1/2) (A B^1/2)^T... */
4612 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, aux, aux, 0.0, c);
4613 }
4614
4615 /* Free... */
4616 gsl_matrix_free(aux);
4617}

◆ obs2y()

size_t obs2y ( const ctl_t ctl,
const obs_t obs,
gsl_vector *  y,
int *  ida,
int *  ira 
)

Convert observation radiances into a measurement vector.

Extracts all finite radiance values from the observation structure and stores them sequentially in a GSL vector.
Optionally records detector (id) and ray path (ir) indices for each measurement element.

Parameters
[in]ctlControl structure containing observation setup (e.g. number of detectors).
[in]obsObservation data structure containing radiances.
[out]yMeasurement vector to store radiances (may be NULL).
[out]idaOptional array to store detector indices (may be NULL).
[out]iraOptional array to store ray path indices (may be NULL).
Returns
Number of valid (finite) radiance values added to the vector.
  • Loops over all detector channels (nd) and ray paths (nr).
  • Skips non-finite (NaN or Inf) radiance values.
  • Produces a compact measurement vector for use in retrievals and Jacobian computations.
See also
atm2x, x2atm, kernel, formod
Warning
Arrays ida and ira must be preallocated with sufficient size to hold all finite radiances if provided.
Author
Lars Hoffmann

Definition at line 4621 of file jurassic.c.

4626 {
4627
4628 size_t m = 0;
4629
4630 /* Determine measurement vector... */
4631 for (int ir = 0; ir < obs->nr; ir++)
4632 for (int id = 0; id < ctl->nd; id++)
4633 if (isfinite(obs->rad[id][ir])) {
4634 if (y != NULL)
4635 gsl_vector_set(y, m, obs->rad[id][ir]);
4636 if (ida != NULL)
4637 ida[m] = id;
4638 if (ira != NULL)
4639 ira[m] = ir;
4640 m++;
4641 }
4642
4643 return m;
4644}

◆ optimal_estimation()

void optimal_estimation ( ret_t ret,
ctl_t ctl,
tbl_t tbl,
obs_t obs_meas,
obs_t obs_i,
atm_t atm_apr,
atm_t atm_i,
double *  chisq 
)

Perform optimal estimation retrieval using Levenberg–Marquardt minimization.

This function performs an optimal estimation of atmospheric state variables based on measured observations, a priori information, and forward radiative transfer modeling. The estimation follows the Rodgers (2000) formalism and uses a Levenberg–Marquardt algorithm to iteratively minimize the cost function:

χ² = (x - x_a)^T S_a⁻¹ (x - x_a) + (y - F(x))^T S_ε⁻¹ (y - F(x)),

where x is the atmospheric state vector, x_a is its a priori estimate, S_a is the a priori covariance matrix, y is the measurement vector, F(x) is the forward model, and S_ε is the measurement error covariance.

The routine updates the atmospheric state until convergence criteria are met or the maximum number of iterations is reached. Optionally, the full retrieval error budget and averaging kernel analysis are computed.

Parameters
[out]retRetrieval configuration and output container. Determines convergence, kernel recomputation frequency, and error analysis options.
[in]ctlControl parameters describing problem setup (grids, species, etc.).
[in]tblLookup tables required by the forward model.
[in]obs_measMeasured observations used as input.
[out]obs_iIntermediate and final modeled observations corresponding to the retrieved state.
[in]atm_aprA priori atmospheric state used as reference.
[out]atm_iAtmospheric state vector to be iteratively retrieved and updated.
[out]chisqFinal value of the cost function (χ²) upon convergence.
Note
  • Aborts early if the problem dimension is zero (no observations or unknowns).
  • State updates are constrained to physically meaningful bounds (pressure, temperature, etc.).
  • Matrix computations are performed using GSL (GNU Scientific Library).
  • If retrieval error analysis is enabled (ret->err_ana), the function produces:
    • Retrieval covariance matrix
    • Error decomposition (noise, forward model)
    • Gain matrix
    • Averaging kernel matrix and diagnostic analysis
Warning
Input structures must be properly initialized. The function allocates several GSL matrices and vectors, all of which are freed before returning. The caller is responsible only for memory outside this function.
See also
formod(), cost_function(), analyze_avk(), set_cov_apr(), set_cov_meas()
Reference
Rodgers, C. D. (2000). Inverse Methods for Atmospheric Sounding: Theory and Practice.
Author
Lars Hoffmann

Definition at line 4648 of file jurassic.c.

4656 {
4657
4658 double disq = 0, lmpar = 0.001;
4659
4660 /* ------------------------------------------------------------
4661 Initialize...
4662 ------------------------------------------------------------ */
4663
4664 /* Allocate... */
4665 int *ipa, *iqa;
4666 ALLOC(ipa, int,
4667 N);
4668 ALLOC(iqa, int,
4669 N);
4670
4671 /* Get sizes... */
4672 const size_t m = obs2y(ctl, obs_meas, NULL, NULL, NULL);
4673 const size_t n = atm2x(ctl, atm_apr, NULL, iqa, ipa);
4674 if (m == 0 || n == 0) {
4675 WARN("Check problem definition (m = 0 or n = 0)!");
4676 *chisq = GSL_NAN;
4677 return;
4678 }
4679
4680 /* Allocate... */
4681 gsl_matrix *a = gsl_matrix_alloc(n, n);
4682 gsl_matrix *cov = gsl_matrix_alloc(n, n);
4683 gsl_matrix *k_i = gsl_matrix_alloc(m, n);
4684 gsl_matrix *s_a_inv = gsl_matrix_alloc(n, n);
4685
4686 gsl_vector *b = gsl_vector_alloc(n);
4687 gsl_vector *dx = gsl_vector_alloc(n);
4688 gsl_vector *dy = gsl_vector_alloc(m);
4689 gsl_vector *sig_eps_inv = gsl_vector_alloc(m);
4690 gsl_vector *sig_formod = gsl_vector_alloc(m);
4691 gsl_vector *sig_noise = gsl_vector_alloc(m);
4692 gsl_vector *x_a = gsl_vector_alloc(n);
4693 gsl_vector *x_i = gsl_vector_alloc(n);
4694 gsl_vector *x_step = gsl_vector_alloc(n);
4695 gsl_vector *y_aux = gsl_vector_alloc(m);
4696 gsl_vector *y_i = gsl_vector_alloc(m);
4697 gsl_vector *y_m = gsl_vector_alloc(m);
4698
4699 /* Set initial state... */
4700 copy_atm(ctl, atm_i, atm_apr, 0);
4701 copy_obs(ctl, obs_i, obs_meas, 0);
4702 formod(ctl, tbl, atm_i, obs_i);
4703
4704 /* Set state vectors and observation vectors... */
4705 atm2x(ctl, atm_apr, x_a, NULL, NULL);
4706 atm2x(ctl, atm_i, x_i, NULL, NULL);
4707 obs2y(ctl, obs_meas, y_m, NULL, NULL);
4708 obs2y(ctl, obs_i, y_i, NULL, NULL);
4709
4710 /* Set inverse a priori covariance S_a^-1... */
4711 set_cov_apr(ret, ctl, atm_apr, iqa, ipa, s_a_inv);
4712 write_matrix(ret->dir, "matrix_cov_apr.tab", ctl, s_a_inv,
4713 atm_i, obs_i, "x", "x", "r");
4714 matrix_invert(s_a_inv);
4715
4716 /* Get measurement errors... */
4717 set_cov_meas(ret, ctl, obs_meas, sig_noise, sig_formod, sig_eps_inv);
4718
4719 /* Determine dx = x_i - x_a and dy = y - F(x_i) ... */
4720 gsl_vector_memcpy(dx, x_i);
4721 gsl_vector_sub(dx, x_a);
4722 gsl_vector_memcpy(dy, y_m);
4723 gsl_vector_sub(dy, y_i);
4724
4725 /* Compute cost function... */
4726 *chisq = cost_function(dx, dy, s_a_inv, sig_eps_inv);
4727
4728 /* Write info... */
4729 LOG(2, "it= %d / chi^2/m= %g", 0, *chisq);
4730
4731 /* Compute initial kernel... */
4732 kernel(ctl, tbl, atm_i, obs_i, k_i);
4733
4734 /* ------------------------------------------------------------
4735 Levenberg-Marquardt minimization...
4736 ------------------------------------------------------------ */
4737
4738 /* Outer loop... */
4739 for (int it = 1; it <= ret->conv_itmax; it++) {
4740
4741 /* Store current cost function value... */
4742 double chisq_old = *chisq;
4743
4744 /* Compute kernel matrix K_i... */
4745 if (it > 1 && it % ret->kernel_recomp == 0)
4746 kernel(ctl, tbl, atm_i, obs_i, k_i);
4747
4748 /* Compute K_i^T * S_eps^{-1} * K_i ... */
4749 if (it == 1 || it % ret->kernel_recomp == 0)
4750 matrix_product(k_i, sig_eps_inv, 1, cov);
4751
4752 /* Determine b = K_i^T * S_eps^{-1} * dy - S_a^{-1} * dx ... */
4753 for (size_t i = 0; i < m; i++)
4754 gsl_vector_set(y_aux, i, gsl_vector_get(dy, i)
4755 * POW2(gsl_vector_get(sig_eps_inv, i)));
4756 gsl_blas_dgemv(CblasTrans, 1.0, k_i, y_aux, 0.0, b);
4757 gsl_blas_dgemv(CblasNoTrans, -1.0, s_a_inv, dx, 1.0, b);
4758
4759 /* Inner loop... */
4760 for (int it2 = 0; it2 < 20; it2++) {
4761
4762 /* Compute A = (1 + lmpar) * S_a^{-1} + K_i^T * S_eps^{-1} * K_i ... */
4763 gsl_matrix_memcpy(a, s_a_inv);
4764 gsl_matrix_scale(a, 1 + lmpar);
4765 gsl_matrix_add(a, cov);
4766
4767 /* Solve A * x_step = b by means of Cholesky decomposition... */
4768 gsl_linalg_cholesky_decomp(a);
4769 gsl_linalg_cholesky_solve(a, b, x_step);
4770
4771 /* Update atmospheric state... */
4772 gsl_vector_add(x_i, x_step);
4773 copy_atm(ctl, atm_i, atm_apr, 0);
4774 copy_obs(ctl, obs_i, obs_meas, 0);
4775 x2atm(ctl, x_i, atm_i);
4776
4777 /* Check atmospheric state... */
4778 for (int ip = 0; ip < atm_i->np; ip++) {
4779 atm_i->p[ip] = CLAMP(atm_i->p[ip], 5e-7, 5e4);
4780 atm_i->t[ip] = CLAMP(atm_i->t[ip], 100, 400);
4781 for (int ig = 0; ig < ctl->ng; ig++)
4782 atm_i->q[ig][ip] = CLAMP(atm_i->q[ig][ip], 0, 1);
4783 for (int iw = 0; iw < ctl->nw; iw++)
4784 atm_i->k[iw][ip] = MAX(atm_i->k[iw][ip], 0);
4785 }
4786 atm_i->clz = MAX(atm_i->clz, 0);
4787 atm_i->cldz = MAX(atm_i->cldz, 0.1);
4788 for (int icl = 0; icl < ctl->ncl; icl++)
4789 atm_i->clk[icl] = MAX(atm_i->clk[icl], 0);
4790 atm_i->sft = CLAMP(atm_i->sft, 100, 400);
4791 for (int isf = 0; isf < ctl->nsf; isf++)
4792 atm_i->sfeps[isf] = CLAMP(atm_i->sfeps[isf], 0, 1);
4793
4794 /* Forward calculation... */
4795 formod(ctl, tbl, atm_i, obs_i);
4796 obs2y(ctl, obs_i, y_i, NULL, NULL);
4797
4798 /* Determine dx = x_i - x_a and dy = y - F(x_i) ... */
4799 gsl_vector_memcpy(dx, x_i);
4800 gsl_vector_sub(dx, x_a);
4801 gsl_vector_memcpy(dy, y_m);
4802 gsl_vector_sub(dy, y_i);
4803
4804 /* Compute cost function... */
4805 *chisq = cost_function(dx, dy, s_a_inv, sig_eps_inv);
4806
4807 /* Modify Levenberg-Marquardt parameter... */
4808 if (*chisq > chisq_old) {
4809 lmpar *= 10;
4810 gsl_vector_sub(x_i, x_step);
4811 } else {
4812 lmpar /= 10;
4813 break;
4814 }
4815 }
4816
4817 /* Write info... */
4818 LOG(2, "it= %d / chi^2/m= %g", it, *chisq);
4819
4820 /* Get normalized step size in state space... */
4821 gsl_blas_ddot(x_step, b, &disq);
4822 disq /= (double) n;
4823
4824 /* Convergence test... */
4825 if ((it == 1 || it % ret->kernel_recomp == 0) && disq < ret->conv_dmin)
4826 break;
4827 }
4828
4829 /* ------------------------------------------------------------
4830 Analysis of retrieval results...
4831 ------------------------------------------------------------ */
4832
4833 /* Check if error analysis is requested... */
4834 if (ret->err_ana) {
4835
4836 /* Store results... */
4837 write_atm(ret->dir, "atm_final.tab", ctl, atm_i);
4838 write_obs(ret->dir, "obs_final.tab", ctl, obs_i);
4839 write_matrix(ret->dir, "matrix_kernel.tab", ctl, k_i,
4840 atm_i, obs_i, "y", "x", "r");
4841
4842 /* Allocate... */
4843 gsl_matrix *auxnm = gsl_matrix_alloc(n, m);
4844 gsl_matrix *corr = gsl_matrix_alloc(n, n);
4845 gsl_matrix *gain = gsl_matrix_alloc(n, m);
4846
4847 /* Compute inverse retrieval covariance...
4848 cov^{-1} = S_a^{-1} + K_i^T * S_eps^{-1} * K_i */
4849 matrix_product(k_i, sig_eps_inv, 1, cov);
4850 gsl_matrix_add(cov, s_a_inv);
4851
4852 /* Compute retrieval covariance... */
4853 matrix_invert(cov);
4854 write_matrix(ret->dir, "matrix_cov_ret.tab", ctl, cov,
4855 atm_i, obs_i, "x", "x", "r");
4856 write_stddev("total", ret, ctl, atm_i, cov);
4857
4858 /* Compute correlation matrix... */
4859 for (size_t i = 0; i < n; i++)
4860 for (size_t j = 0; j < n; j++)
4861 gsl_matrix_set(corr, i, j, gsl_matrix_get(cov, i, j)
4862 / sqrt(gsl_matrix_get(cov, i, i))
4863 / sqrt(gsl_matrix_get(cov, j, j)));
4864 write_matrix(ret->dir, "matrix_corr.tab", ctl, corr,
4865 atm_i, obs_i, "x", "x", "r");
4866
4867 /* Compute gain matrix...
4868 G = cov * K^T * S_eps^{-1} */
4869 for (size_t i = 0; i < n; i++)
4870 for (size_t j = 0; j < m; j++)
4871 gsl_matrix_set(auxnm, i, j, gsl_matrix_get(k_i, j, i)
4872 * POW2(gsl_vector_get(sig_eps_inv, j)));
4873 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, cov, auxnm, 0.0, gain);
4874 write_matrix(ret->dir, "matrix_gain.tab", ctl, gain,
4875 atm_i, obs_i, "x", "y", "c");
4876
4877 /* Compute retrieval error due to noise... */
4878 matrix_product(gain, sig_noise, 2, a);
4879 write_stddev("noise", ret, ctl, atm_i, a);
4880
4881 /* Compute retrieval error due to forward model errors... */
4882 matrix_product(gain, sig_formod, 2, a);
4883 write_stddev("formod", ret, ctl, atm_i, a);
4884
4885 /* Compute averaging kernel matrix
4886 A = G * K ... */
4887 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, gain, k_i, 0.0, a);
4888 write_matrix(ret->dir, "matrix_avk.tab", ctl, a,
4889 atm_i, obs_i, "x", "x", "r");
4890
4891 /* Analyze averaging kernel matrix... */
4892 analyze_avk(ret, ctl, atm_i, iqa, ipa, a);
4893
4894 /* Free... */
4895 gsl_matrix_free(auxnm);
4896 gsl_matrix_free(corr);
4897 gsl_matrix_free(gain);
4898 }
4899
4900 /* ------------------------------------------------------------
4901 Finalize...
4902 ------------------------------------------------------------ */
4903
4904 gsl_matrix_free(a);
4905 gsl_matrix_free(cov);
4906 gsl_matrix_free(k_i);
4907 gsl_matrix_free(s_a_inv);
4908
4909 gsl_vector_free(b);
4910 gsl_vector_free(dx);
4911 gsl_vector_free(dy);
4912 gsl_vector_free(sig_eps_inv);
4913 gsl_vector_free(sig_formod);
4914 gsl_vector_free(sig_noise);
4915 gsl_vector_free(x_a);
4916 gsl_vector_free(x_i);
4917 gsl_vector_free(x_step);
4918 gsl_vector_free(y_aux);
4919 gsl_vector_free(y_i);
4920 gsl_vector_free(y_m);
4921
4922 free(ipa);
4923 free(iqa);
4924}
void analyze_avk(const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const int *iqa, const int *ipa, const gsl_matrix *avk)
Analyze averaging kernel (AVK) matrix for retrieval diagnostics.
Definition: jurassic.c:29
double cost_function(const gsl_vector *dx, const gsl_vector *dy, const gsl_matrix *s_a_inv, const gsl_vector *sig_eps_inv)
Compute the normalized quadratic cost function for optimal estimation.
Definition: jurassic.c:1187
void matrix_product(const gsl_matrix *a, const gsl_vector *b, const int transpose, gsl_matrix *c)
Compute structured matrix products of the form or .
Definition: jurassic.c:4576
void set_cov_meas(const ret_t *ret, const ctl_t *ctl, const obs_t *obs, gsl_vector *sig_noise, gsl_vector *sig_formod, gsl_vector *sig_eps_inv)
Construct measurement error standard deviations and their inverse.
Definition: jurassic.c:6587
void write_obs(const char *dirname, const char *filename, const ctl_t *ctl, const obs_t *obs)
Write observation data to an output file in ASCII or binary format.
Definition: jurassic.c:7569
void kernel(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs, gsl_matrix *k)
Compute the Jacobian (kernel) matrix by finite differences.
Definition: jurassic.c:4381
void matrix_invert(gsl_matrix *a)
Invert a square matrix, optimized for diagonal or symmetric positive-definite matrices.
Definition: jurassic.c:4546
void write_matrix(const char *dirname, const char *filename, const ctl_t *ctl, const gsl_matrix *matrix, const atm_t *atm, const obs_t *obs, const char *rowspace, const char *colspace, const char *sort)
Write a fully annotated matrix (e.g., Jacobian or gain matrix) to file.
Definition: jurassic.c:7392
void set_cov_apr(const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const int *iqa, const int *ipa, gsl_matrix *s_a)
Construct the a priori covariance matrix for retrieval parameters.
Definition: jurassic.c:6476
void write_stddev(const char *quantity, const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const gsl_matrix *s)
Write retrieval standard deviation profiles to disk.
Definition: jurassic.c:7969
#define WARN(...)
Print a warning message with contextual information.
Definition: jurassic.h:1160
int err_ana
Carry out error analysis (0=no, 1=yes).
Definition: jurassic.h:1589
double conv_dmin
Minimum normalized step size in state space.
Definition: jurassic.h:1586
int kernel_recomp
Re-computation of kernel matrix (number of iterations).
Definition: jurassic.h:1580
int conv_itmax
Maximum number of iterations.
Definition: jurassic.h:1583
Here is the call graph for this function:

◆ raytrace()

void raytrace ( const ctl_t ctl,
const atm_t atm,
obs_t obs,
los_t los,
const int  ir 
)

Perform line-of-sight (LOS) ray tracing through the atmosphere.

Computes the geometric path of a viewing ray from the observer to the atmosphere (and possibly the surface), accounting for spherical geometry, optional refraction, and cloud or surface interactions.
Fills the LOS structure with pressure, temperature, gas concentrations, extinction, and path length at each step.

Parameters
[in]ctlControl structure containing model and numerical settings.
[in]atmAtmospheric state structure (profiles of p, T, q, k, etc.).
[in,out]obsObservation geometry and radiance data; updated tangent point.
[out]losLine-of-sight structure to be populated with sampled quantities.
[in]irIndex of the current ray path in the observation set.
  • Integrates along the viewing ray starting at the observer position.
  • Performs stepwise propagation with step length ds determined by altitude and user-specified controls (rayds, raydz).
  • Interpolates atmospheric variables at each step using intpol_atm.
  • Detects surface intersection or top-of-atmosphere exit and terminates accordingly.
  • Optionally accounts for refraction via the refractive index n(p, T).
  • Accumulates column densities and Curtis–Godson means for each gas.
  • Supports cloud extinction and surface emissivity interpolation.
Note
The routine enforces that atmospheric grids include the surface (z = 0 km). Rays starting above the atmosphere are propagated downward until entry.
See also
intpol_atm, tangent_point, formod_pencil, hydrostatic
Warning
  • Fails if the observer is below the surface or the atmosphere lacks z = 0.
  • Aborts if the number of LOS points exceeds NLOS.
  • Assumes monotonic altitude ordering in atmospheric data.
Author
Lars Hoffmann

Definition at line 4928 of file jurassic.c.

4933 {
4934
4935 const double h = 0.02, zrefrac = 60;
4936
4937 double ex0[3], ex1[3], k[NW], lat, lon, n, ng[3], norm, p, q[NG], t,
4938 x[3], xh[3], xobs[3], xvp[3], z = 1e99, zmax, zmin;
4939
4940 int stop = 0;
4941
4942 /* Initialize... */
4943 los->np = 0;
4944 los->sft = -999;
4945 obs->tpz[ir] = obs->vpz[ir];
4946 obs->tplon[ir] = obs->vplon[ir];
4947 obs->tplat[ir] = obs->vplat[ir];
4948
4949 /* Get altitude range of atmospheric data... */
4950 gsl_stats_minmax(&zmin, &zmax, atm->z, 1, (size_t) atm->np);
4951
4952 /* Check observer altitude... */
4953 if (obs->obsz[ir] < zmin)
4954 ERRMSG("Observer below surface!");
4955
4956 /* Determine Cartesian coordinates for observer and view point... */
4957 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xobs);
4958 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xvp);
4959
4960 /* Determine initial tangent vector... */
4961 for (int i = 0; i < 3; i++)
4962 ex0[i] = xvp[i] - xobs[i];
4963 norm = NORM(ex0);
4964 for (int i = 0; i < 3; i++)
4965 ex0[i] /= norm;
4966
4967 /* Observer within atmosphere... */
4968 for (int i = 0; i < 3; i++)
4969 x[i] = xobs[i];
4970
4971 /* Observer above atmosphere (search entry point)... */
4972 if (obs->obsz[ir] > zmax) {
4973 double dmax = norm, dmin = 0;
4974 while (fabs(dmin - dmax) > 0.001) {
4975 const double d = (dmax + dmin) / 2;
4976 for (int i = 0; i < 3; i++)
4977 x[i] = xobs[i] + d * ex0[i];
4978 cart2geo(x, &z, &lon, &lat);
4979 if (z <= zmax && z > zmax - 0.001)
4980 break;
4981 if (z < zmax - 0.0005)
4982 dmax = d;
4983 else
4984 dmin = d;
4985 }
4986 }
4987
4988 /* Ray-tracing... */
4989 while (1) {
4990
4991 /* Set step length... */
4992 double ds = ctl->rayds;
4993 if (ctl->raydz > 0) {
4994 norm = NORM(x);
4995 for (int i = 0; i < 3; i++)
4996 xh[i] = x[i] / norm;
4997 const double cosa = fabs(DOTP(ex0, xh));
4998 if (cosa != 0)
4999 ds = MIN(ctl->rayds, ctl->raydz / cosa);
5000 }
5001
5002 /* Determine geolocation... */
5003 cart2geo(x, &z, &lon, &lat);
5004
5005 /* Check if LOS hits the ground or has left atmosphere... */
5006 if (z < zmin || z > zmax) {
5007 stop = (z < zmin ? 2 : 1);
5008 const double frac =
5009 ((z <
5010 zmin ? zmin : zmax) - los->z[los->np - 1]) / (z - los->z[los->np -
5011 1]);
5012 geo2cart(los->z[los->np - 1], los->lon[los->np - 1],
5013 los->lat[los->np - 1], xh);
5014 for (int i = 0; i < 3; i++)
5015 x[i] = xh[i] + frac * (x[i] - xh[i]);
5016 cart2geo(x, &z, &lon, &lat);
5017 los->ds[los->np - 1] = ds * frac;
5018 ds = 0;
5019 }
5020
5021 /* Interpolate atmospheric data... */
5022 intpol_atm(ctl, atm, z, &p, &t, q, k);
5023
5024 /* Save data... */
5025 los->lon[los->np] = lon;
5026 los->lat[los->np] = lat;
5027 los->z[los->np] = z;
5028 los->p[los->np] = p;
5029 los->t[los->np] = t;
5030 for (int ig = 0; ig < ctl->ng; ig++)
5031 los->q[los->np][ig] = q[ig];
5032 for (int id = 0; id < ctl->nd; id++)
5033 los->k[los->np][id] = k[ctl->window[id]];
5034 los->ds[los->np] = ds;
5035
5036 /* Add cloud extinction... */
5037 if (ctl->ncl > 0 && atm->cldz > 0) {
5038 const double aux = exp(-0.5 * POW2((z - atm->clz) / atm->cldz));
5039 for (int id = 0; id < ctl->nd; id++) {
5040 const int icl = locate_irr(ctl->clnu, ctl->ncl, ctl->nu[id]);
5041 los->k[los->np][id]
5042 += aux * LIN(ctl->clnu[icl], atm->clk[icl],
5043 ctl->clnu[icl + 1], atm->clk[icl + 1], ctl->nu[id]);
5044 }
5045 }
5046
5047 /* Increment and check number of LOS points... */
5048 if ((++los->np) > NLOS)
5049 ERRMSG("Too many LOS points!");
5050
5051 /* Check stop flag... */
5052 if (stop) {
5053
5054 /* Set surface temperature... */
5055 if (ctl->nsf > 0 && atm->sft > 0)
5056 t = atm->sft;
5057 los->sft = (stop == 2 ? t : -999);
5058
5059 /* Set surface emissivity... */
5060 for (int id = 0; id < ctl->nd; id++) {
5061 los->sfeps[id] = 1.0;
5062 if (ctl->nsf > 0) {
5063 const int isf = locate_irr(ctl->sfnu, ctl->nsf, ctl->nu[id]);
5064 los->sfeps[id] = LIN(ctl->sfnu[isf], atm->sfeps[isf],
5065 ctl->sfnu[isf + 1], atm->sfeps[isf + 1],
5066 ctl->nu[id]);
5067 }
5068 }
5069
5070 /* Leave raytracer... */
5071 break;
5072 }
5073
5074 /* Determine refractivity... */
5075 if (ctl->refrac && z <= zrefrac)
5076 n = 1 + REFRAC(p, t);
5077 else
5078 n = 1;
5079
5080 /* Construct new tangent vector (first term)... */
5081 for (int i = 0; i < 3; i++)
5082 ex1[i] = ex0[i] * n;
5083
5084 /* Compute gradient of refractivity... */
5085 if (ctl->refrac && z <= zrefrac) {
5086 for (int i = 0; i < 3; i++)
5087 xh[i] = x[i] + 0.5 * ds * ex0[i];
5088 cart2geo(xh, &z, &lon, &lat);
5089 intpol_atm(ctl, atm, z, &p, &t, q, k);
5090 n = REFRAC(p, t);
5091 for (int i = 0; i < 3; i++) {
5092 xh[i] += h;
5093 cart2geo(xh, &z, &lon, &lat);
5094 intpol_atm(ctl, atm, z, &p, &t, q, k);
5095 ng[i] = (REFRAC(p, t) - n) / h;
5096 xh[i] -= h;
5097 }
5098 } else
5099 for (int i = 0; i < 3; i++)
5100 ng[i] = 0;
5101
5102 /* Construct new tangent vector (second term)... */
5103 for (int i = 0; i < 3; i++)
5104 ex1[i] += ds * ng[i];
5105
5106 /* Normalize new tangent vector... */
5107 norm = NORM(ex1);
5108 for (int i = 0; i < 3; i++)
5109 ex1[i] /= norm;
5110
5111 /* Determine next point of LOS... */
5112 for (int i = 0; i < 3; i++)
5113 x[i] += 0.5 * ds * (ex0[i] + ex1[i]);
5114
5115 /* Copy tangent vector... */
5116 for (int i = 0; i < 3; i++)
5117 ex0[i] = ex1[i];
5118 }
5119
5120 /* Get tangent point (to be done before changing segment lengths!)... */
5121 tangent_point(los, &obs->tpz[ir], &obs->tplon[ir], &obs->tplat[ir]);
5122
5123 /* Change segment lengths according to trapezoid rule... */
5124 for (int ip = los->np - 1; ip >= 1; ip--)
5125 los->ds[ip] = 0.5 * (los->ds[ip - 1] + los->ds[ip]);
5126 los->ds[0] *= 0.5;
5127
5128 /* Compute column density... */
5129 for (int ip = 0; ip < los->np; ip++)
5130 for (int ig = 0; ig < ctl->ng; ig++)
5131 los->u[ip][ig] = 10 * los->q[ip][ig] * los->p[ip]
5132 / (KB * los->t[ip]) * los->ds[ip];
5133
5134 /* Compute Curtis-Godson means... */
5135 for (int ig = 0; ig < ctl->ng; ig++) {
5136 los->cgu[0][ig] = los->u[0][ig];
5137 los->cgp[0][ig] = los->u[0][ig] * los->p[0];
5138 los->cgt[0][ig] = los->u[0][ig] * los->t[0];
5139 }
5140 for (int ip = 1; ip < los->np; ip++)
5141 for (int ig = 0; ig < ctl->ng; ig++) {
5142 los->cgu[ip][ig] = los->cgu[ip - 1][ig] + los->u[ip][ig];
5143 los->cgp[ip][ig] = los->cgp[ip - 1][ig] + los->u[ip][ig] * los->p[ip];
5144 los->cgt[ip][ig] = los->cgt[ip - 1][ig] + los->u[ip][ig] * los->t[ip];
5145 }
5146 for (int ip = 0; ip < los->np; ip++)
5147 for (int ig = 0; ig < ctl->ng; ig++)
5148 if (los->cgu[ip][ig] != 0) {
5149 los->cgp[ip][ig] /= los->cgu[ip][ig];
5150 los->cgt[ip][ig] /= los->cgu[ip][ig];
5151 }
5152}
void intpol_atm(const ctl_t *ctl, const atm_t *atm, const double z, double *p, double *t, double *q, double *k)
Interpolate atmospheric state variables at a given altitude.
Definition: jurassic.c:4043
void tangent_point(const los_t *los, double *tpz, double *tplon, double *tplat)
Determine the tangent point along a line of sight (LOS).
Definition: jurassic.c:6636
void cart2geo(const double *x, double *z, double *lon, double *lat)
Converts Cartesian coordinates to geographic coordinates.
Definition: jurassic.c:193
#define KB
Boltzmann constant [kg m^2/(K s^2)].
Definition: jurassic.h:159
#define REFRAC(p, T)
Compute air refractivity (n - 1).
Definition: jurassic.h:1006
#define NLOS
Maximum number of LOS points.
Definition: jurassic.h:288
#define NW
Maximum number of spectral windows.
Definition: jurassic.h:263
int window[ND]
Window index of each channel.
Definition: jurassic.h:1326
double rayds
Maximum step length for raytracing [km].
Definition: jurassic.h:1377
double raydz
Vertical step length for raytracing [km].
Definition: jurassic.h:1380
Here is the call graph for this function:

◆ read_atm()

void read_atm ( const char *  dirname,
const char *  filename,
const ctl_t ctl,
atm_t atm 
)

Read atmospheric input data from a file.

This function reads atmospheric data from the file specified by filename, optionally prefixed by the directory dirname. The file format (ASCII or binary) is determined by the control structure ctl. The data are stored in the atmospheric structure atm.

Supported file formats are:

  • ASCII format (ctl->atmfmt == 1)
  • Binary format (ctl->atmfmt == 2)

The function initializes the atmospheric data container, opens the specified file, reads its contents according to the selected format, and performs sanity checks on the number of data points. It also logs basic statistical information about the loaded atmospheric fields (time, altitude, longitude, latitude, pressure, temperature, and species/emitter mixing ratios).

Parameters
dirnameOptional directory path where the atmospheric file resides. If NULL, only filename is used.
filenameName of the atmospheric data file to read.
ctlPointer to a control structure specifying input parameters, file format, number of emitters, spectral windows, and additional atmospheric configuration.
atmPointer to an atmospheric data structure that will be filled with the values read from the file. The structure must be allocated before calling this function.
Note
The function aborts execution using ERRMSG on critical errors, such as failure to open the file, unknown file format, or absence of readable data.
Warning
Ensure that the atm structure has been properly allocated, and that the control parameters in ctl are valid before calling this function.
Author
Lars Hoffmann

Definition at line 5156 of file jurassic.c.

5160 {
5161
5162 /* Init... */
5163 atm->np = 0;
5164
5165 /* Set filename... */
5166 char file[LEN];
5167 if (dirname != NULL)
5168 sprintf(file, "%s/%s", dirname, filename);
5169 else
5170 sprintf(file, "%s", filename);
5171
5172 /* Write info... */
5173 LOG(1, "Read atmospheric data: %s", file);
5174
5175 /* Read ASCII data... */
5176 if (ctl->atmfmt == 1)
5177 read_atm_asc(file, ctl, atm);
5178
5179 /* Read binary data... */
5180 else if (ctl->atmfmt == 2)
5181 read_atm_bin(file, ctl, atm);
5182
5183 /* Read netCDF data... */
5184 else if (ctl->atmfmt == 3)
5185 read_atm_nc(file, ctl, atm, 0);
5186
5187 /* Check number of points... */
5188 if (atm->np < 1)
5189 ERRMSG("Could not read any data!");
5190
5191 /* Write info... */
5192 double mini, maxi;
5193 LOG(2, "Number of data points: %d", atm->np);
5194 gsl_stats_minmax(&mini, &maxi, atm->time, 1, (size_t) atm->np);
5195 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
5196 gsl_stats_minmax(&mini, &maxi, atm->z, 1, (size_t) atm->np);
5197 LOG(2, "Altitude range: %g ... %g km", mini, maxi);
5198 gsl_stats_minmax(&mini, &maxi, atm->lon, 1, (size_t) atm->np);
5199 LOG(2, "Longitude range: %g ... %g deg", mini, maxi);
5200 gsl_stats_minmax(&mini, &maxi, atm->lat, 1, (size_t) atm->np);
5201 LOG(2, "Latitude range: %g ... %g deg", mini, maxi);
5202 gsl_stats_minmax(&mini, &maxi, atm->p, 1, (size_t) atm->np);
5203 LOG(2, "Pressure range: %g ... %g hPa", maxi, mini);
5204 gsl_stats_minmax(&mini, &maxi, atm->t, 1, (size_t) atm->np);
5205 LOG(2, "Temperature range: %g ... %g K", mini, maxi);
5206 for (int ig = 0; ig < ctl->ng; ig++) {
5207 gsl_stats_minmax(&mini, &maxi, atm->q[ig], 1, (size_t) atm->np);
5208 LOG(2, "Emitter %s range: %g ... %g ppv", ctl->emitter[ig], mini, maxi);
5209 }
5210 for (int iw = 0; iw < ctl->nw; iw++) {
5211 gsl_stats_minmax(&mini, &maxi, atm->k[iw], 1, (size_t) atm->np);
5212 LOG(2, "Extinction range (window %d): %g ... %g km^-1", iw, mini, maxi);
5213 }
5214 if (ctl->ncl > 0) {
5215 LOG(2, "Cloud layer: z= %g km | dz= %g km | k= %g ... %g km^-1",
5216 atm->clz, atm->cldz, atm->clk[0], atm->clk[ctl->ncl - 1]);
5217 } else
5218 LOG(2, "Cloud layer: none");
5219 if (ctl->nsf > 0) {
5220 LOG(2,
5221 "Surface: T_s = %g K | eps= %g ... %g",
5222 atm->sft, atm->sfeps[0], atm->sfeps[ctl->nsf - 1]);
5223 } else
5224 LOG(2, "Surface: none");
5225}
void read_atm_bin(const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric data in binary format.
Definition: jurassic.c:5280
void read_atm_asc(const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric data in ASCII format.
Definition: jurassic.c:5229
void read_atm_nc(const char *filename, const ctl_t *ctl, atm_t *atm, int profile)
Read one atmospheric profile from a netCDF file.
Definition: jurassic.c:5374
int atmfmt
Atmospheric data file format (1=ASCII, 2=binary, 3=netCDF).
Definition: jurassic.h:1353
Here is the call graph for this function:

◆ read_atm_asc()

void read_atm_asc ( const char *  filename,
const ctl_t ctl,
atm_t atm 
)

Read atmospheric data in ASCII format.

This function reads and parses atmospheric input data from an ASCII file specified by its filename and stores the values in the atmospheric structure atm. The number and type of fields to read are determined by the control structure ctl. Each line of the ASCII file corresponds to a single atmospheric data point.

The expected order of fields in each line is:

  • Time
  • Altitude
  • Longitude
  • Latitude
  • Pressure
  • Temperature
  • Mixing ratios for each gas/emitter (ctl->ng values)
  • Extinction coefficients for each spectral window (ctl->nw values)

Additionally, if cloud or surface layer parameters are enabled in ctl, they are read once from the first line only:

  • Cloud layer: altitude, thickness, and extinction (ctl->ncl values)
  • Surface layer: temperature and emissivity (ctl->nsf values)
Parameters
filenamePath to the ASCII file containing atmospheric data.
ctlPointer to a control structure defining the number of gases, spectral windows, and whether cloud or surface layer information should be read.
atmPointer to an initialized atmospheric structure where the parsed data points will be stored. The function updates atm->np to reflect the number of successfully read data records.
Note
The function reads until end-of-file is reached. Each successfully parsed line increments the atmospheric data point counter.
Warning
The function terminates execution using ERRMSG if more than NP data points are encountered, or if the input format deviates from expectations.
Author
Lars Hoffmann

Definition at line 5229 of file jurassic.c.

5232 {
5233
5234 /* Init... */
5235 atm->np = 0;
5236
5237 /* Open file... */
5238 FILE *in;
5239 if (!(in = fopen(filename, "r")))
5240 ERRMSG("Cannot open file!");
5241
5242 /* Read line... */
5243 char line[LEN], *tok;
5244 while (fgets(line, LEN, in)) {
5245
5246 /* Read data... */
5247 TOK(line, tok, "%lg", atm->time[atm->np]);
5248 TOK(NULL, tok, "%lg", atm->z[atm->np]);
5249 TOK(NULL, tok, "%lg", atm->lon[atm->np]);
5250 TOK(NULL, tok, "%lg", atm->lat[atm->np]);
5251 TOK(NULL, tok, "%lg", atm->p[atm->np]);
5252 TOK(NULL, tok, "%lg", atm->t[atm->np]);
5253 for (int ig = 0; ig < ctl->ng; ig++)
5254 TOK(NULL, tok, "%lg", atm->q[ig][atm->np]);
5255 for (int iw = 0; iw < ctl->nw; iw++)
5256 TOK(NULL, tok, "%lg", atm->k[iw][atm->np]);
5257 if (ctl->ncl > 0 && atm->np == 0) {
5258 TOK(NULL, tok, "%lg", atm->clz);
5259 TOK(NULL, tok, "%lg", atm->cldz);
5260 for (int icl = 0; icl < ctl->ncl; icl++)
5261 TOK(NULL, tok, "%lg", atm->clk[icl]);
5262 }
5263 if (ctl->nsf > 0 && atm->np == 0) {
5264 TOK(NULL, tok, "%lg", atm->sft);
5265 for (int isf = 0; isf < ctl->nsf; isf++)
5266 TOK(NULL, tok, "%lg", atm->sfeps[isf]);
5267 }
5268
5269 /* Increment data point counter... */
5270 if ((++atm->np) > NP)
5271 ERRMSG("Too many data points!");
5272 }
5273
5274 /* Close file... */
5275 fclose(in);
5276}
#define TOK(line, tok, format, var)
Tokenize a string and parse a variable.
Definition: jurassic.h:1079
#define NP
Maximum number of atmospheric data points.
Definition: jurassic.h:248

◆ read_atm_bin()

void read_atm_bin ( const char *  filename,
const ctl_t ctl,
atm_t atm 
)

Read atmospheric data in binary format.

This function reads atmospheric input data from a binary file specified by its filename and stores the decoded values in the atmospheric structure atm. The expected binary format is predefined and must match the configuration provided in the control structure ctl. The function reads a header containing metadata describing the dataset, followed by the atmospheric fields and optional cloud and surface layer properties.

The binary file layout is expected to follow this structure:

  1. Magic identifier (4 bytes, ignored except for presence)
  2. Header integers:
    • Number of gas species (ng)
    • Number of spectral windows (nw)
    • Number of cloud layer extinction elements (ncl)
    • Number of surface emissivity elements (nsf) These must match the corresponding values in ctl.
  3. Data payload:
    • Number of points (np)
    • Arrays of size np for time, altitude, longitude, latitude, pressure, and temperature
    • For each gas species: mixing ratio array of length np
    • For each spectral window: extinction coefficient array of length np
  4. Optional layered parameters:
    • Cloud layer altitude, thickness, and extinction (ctl->ncl values)
    • Surface temperature and emissivity (ctl->nsf values)
Parameters
filenamePath to the binary file containing atmospheric data.
ctlPointer to a control structure specifying the expected dimensions of atmospheric fields and optional layers. Used for header validation.
atmPointer to an allocated atmospheric data structure that will be filled with the contents of the binary file. All arrays must be allocated prior to calling this function.
Note
This function does not allocate memory; it assumes storage for all atmospheric variables already exists and matches the expected sizes.
Warning
Execution is terminated via ERRMSG if:
  • The binary header does not match the control structure.
  • The binary file does not contain the expected amount of data.
Author
Lars Hoffmann

Definition at line 5280 of file jurassic.c.

5283 {
5284
5285 /* Open file... */
5286 FILE *in;
5287 if (!(in = fopen(filename, "r")))
5288 ERRMSG("Cannot open file!");
5289
5290 /* Read header... */
5291 char magic[4];
5292 FREAD(magic, char,
5293 4,
5294 in);
5295 if (memcmp(magic, "ATM1", 4) != 0)
5296 ERRMSG("Invalid magic string!");
5297
5298 int ng, nw, ncl, nsf;
5299 FREAD(&ng, int,
5300 1,
5301 in);
5302 FREAD(&nw, int,
5303 1,
5304 in);
5305 FREAD(&ncl, int,
5306 1,
5307 in);
5308 FREAD(&nsf, int,
5309 1,
5310 in);
5311 if (ng != ctl->ng || nw != ctl->nw || ncl != ctl->ncl || nsf != ctl->nsf)
5312 ERRMSG("Error reading file header!");
5313
5314 /* Read data... */
5315 size_t np;
5316 FREAD(&np, size_t,
5317 1,
5318 in);
5319 atm->np = (int) np;
5320 if (atm->np > NP)
5321 ERRMSG("Too many data points!");
5322 FREAD(atm->time, double,
5323 np,
5324 in);
5325 FREAD(atm->z, double,
5326 np,
5327 in);
5328 FREAD(atm->lon, double,
5329 np,
5330 in);
5331 FREAD(atm->lat, double,
5332 np,
5333 in);
5334 FREAD(atm->p, double,
5335 np,
5336 in);
5337 FREAD(atm->t, double,
5338 np,
5339 in);
5340 for (int ig = 0; ig < ctl->ng; ig++)
5341 FREAD(atm->q[ig], double,
5342 np,
5343 in);
5344 for (int iw = 0; iw < ctl->nw; iw++)
5345 FREAD(atm->k[iw], double,
5346 np,
5347 in);
5348 if (ctl->ncl > 0) {
5349 FREAD(&atm->clz, double,
5350 1,
5351 in);
5352 FREAD(&atm->cldz, double,
5353 1,
5354 in);
5355 FREAD(atm->clk, double,
5356 (size_t) ctl->ncl,
5357 in);
5358 }
5359 if (ctl->nsf) {
5360 FREAD(&atm->sft, double,
5361 1,
5362 in);
5363 FREAD(atm->sfeps, double,
5364 (size_t) ctl->nsf,
5365 in);
5366 }
5367
5368 /* Close file... */
5369 fclose(in);
5370}
#define FREAD(ptr, type, size, out)
Read binary data from a file.
Definition: jurassic.h:520

◆ read_atm_nc()

void read_atm_nc ( const char *  filename,
const ctl_t ctl,
atm_t atm,
int  profile 
)

Read one atmospheric profile from a netCDF file.

This routine reads a single profile (record) from a netCDF file into an atm_t structure. The file is expected to follow the JURASSIC netCDF layout produced by write_atm_nc(), using an unlimited profile dimension and a fixed level dimension.

The number of valid vertical levels for the requested profile is read from nlev(profile) and stored in atm->np. All 2-D profile variables are then read for the hyperslab (profile,0:atm->np-1).

File layout (expected)

Dimensions:

  • profile : unlimited (record dimension)
  • level : fixed (maximum number of vertical levels stored in the file)

Variables:

  • nlev(profile) : number of valid levels per profile (required)
  • Core state (2-D): time,z,lon,lat,p,t(profile,level)
  • Trace gases (2-D): one variable per species named ctl->emitter[ig] with dimensions (profile,level)
  • Extinction windows (2-D): ext_win_d(profile,level)
  • Clouds (1-D, optional if ctl->ncl>0): cld_z, cld_dz, cld_k_d(profile)
  • Surface (1-D, optional if ctl->nsf>0): sf_t, sf_eps_d(profile)
Parameters
filenameInput netCDF file name.
ctlControl structure (defines numbers/names of optional fields, e.g., ng, nw, ncl, nsf, and emitter[]).
atmAtmospheric profile structure to fill. On return, atm->np contains the number of valid levels for the requested profile.
profileRecord index along the unlimited profile dimension.
Note
This function assumes that arrays in atm have static capacity NP and checks that atm->np is within [1,NP]. Errors are handled via the NC(...) macro.
Author
Lars Hoffmann

Definition at line 5374 of file jurassic.c.

5378 {
5379
5380 int ncid, var_time, var_z, var_lon, var_lat, var_p, var_t, var_q[NG],
5381 var_k[NW], var_cz = -1, var_cdz = -1, var_ck[NCL], var_sft =
5382 -1, var_sfe[NSF], var_nlev = -1;
5383
5384 char varname[LEN];
5385
5386 /* Open file... */
5387 NC(nc_open(filename, NC_NOWRITE, &ncid));
5388
5389 /* Initialize hyperslab... */
5390 size_t start[2] = { (size_t) profile, 0 };
5391 size_t count[2] = { 1, 0 };
5392
5393 /* Determine atm->np... */
5394 NC(nc_inq_varid(ncid, "nlev", &var_nlev));
5395 NC(nc_get_vara_int(ncid, var_nlev, start, count, &atm->np));
5396 if (atm->np < 1 || atm->np > NP)
5397 ERRMSG("Number of level out of range!");
5398
5399 /* Update hyperslab... */
5400 count[1] = (size_t) atm->np;
5401
5402 /* Inquire core variables... */
5403 NC(nc_inq_varid(ncid, "time", &var_time));
5404 NC(nc_inq_varid(ncid, "z", &var_z));
5405 NC(nc_inq_varid(ncid, "lon", &var_lon));
5406 NC(nc_inq_varid(ncid, "lat", &var_lat));
5407 NC(nc_inq_varid(ncid, "p", &var_p));
5408 NC(nc_inq_varid(ncid, "t", &var_t));
5409
5410 /* Inquire emiters... */
5411 for (int ig = 0; ig < ctl->ng; ig++)
5412 NC(nc_inq_varid(ncid, ctl->emitter[ig], &var_q[ig]));
5413
5414 /* Inquire extinctions... */
5415 for (int iw = 0; iw < ctl->nw; iw++) {
5416 sprintf(varname, "ext_win_%d", iw);
5417 NC(nc_inq_varid(ncid, varname, &var_k[iw]));
5418 }
5419
5420 /* Inquire cloud variables... */
5421 if (ctl->ncl > 0) {
5422 NC(nc_inq_varid(ncid, "cld_z", &var_cz));
5423 NC(nc_inq_varid(ncid, "cld_dz", &var_cdz));
5424 for (int icl = 0; icl < ctl->ncl; icl++) {
5425 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
5426 NC(nc_inq_varid(ncid, varname, &var_ck[icl]));
5427 }
5428 }
5429
5430 /* Inquire surface variables... */
5431 if (ctl->nsf > 0) {
5432 NC(nc_inq_varid(ncid, "srf_t", &var_sft));
5433 for (int isf = 0; isf < ctl->nsf; isf++) {
5434 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
5435 NC(nc_inq_varid(ncid, varname, &var_sfe[isf]));
5436 }
5437 }
5438
5439 /* Read core variables... */
5440 NC(nc_get_vara_double(ncid, var_time, start, count, atm->time));
5441 NC(nc_get_vara_double(ncid, var_z, start, count, atm->z));
5442 NC(nc_get_vara_double(ncid, var_lon, start, count, atm->lon));
5443 NC(nc_get_vara_double(ncid, var_lat, start, count, atm->lat));
5444 NC(nc_get_vara_double(ncid, var_p, start, count, atm->p));
5445 NC(nc_get_vara_double(ncid, var_t, start, count, atm->t));
5446
5447 /* Read emitters... */
5448 for (int ig = 0; ig < ctl->ng; ig++)
5449 NC(nc_get_vara_double(ncid, var_q[ig], start, count, atm->q[ig]));
5450
5451 /* Read extinctions... */
5452 for (int iw = 0; iw < ctl->nw; iw++)
5453 NC(nc_get_vara_double(ncid, var_k[iw], start, count, atm->k[iw]));
5454
5455 /* Read cloud variables... */
5456 if (ctl->ncl > 0) {
5457 NC(nc_get_vara_double(ncid, var_cz, start, count, &atm->clz));
5458 NC(nc_get_vara_double(ncid, var_cdz, start, count, &atm->cldz));
5459 for (int icl = 0; icl < ctl->ncl; icl++)
5460 NC(nc_get_vara_double(ncid, var_ck[icl], start, count, &atm->clk[icl]));
5461 }
5462
5463 /* Read surface variables... */
5464 if (ctl->nsf > 0) {
5465 NC(nc_get_vara_double(ncid, var_sft, start, count, &atm->sft));
5466
5467 for (int isf = 0; isf < ctl->nsf; isf++)
5468 NC(nc_get_vara_double
5469 (ncid, var_sfe[isf], start, count, &atm->sfeps[isf]));
5470 }
5471
5472 /* Close file... */
5473 NC(nc_close(ncid));
5474}
#define NC(cmd)
Execute a NetCDF command and check for errors.
Definition: jurassic.h:639
#define NSF
Maximum number of surface layer spectral grid points.
Definition: jurassic.h:258
#define NCL
Maximum number of cloud layer spectral grid points.
Definition: jurassic.h:233

◆ read_ctl()

void read_ctl ( int  argc,
char *  argv[],
ctl_t ctl 
)

Read model control parameters from command-line and configuration input.

Parses all numerical and string parameters required to initialize a JURASSIC simulation, including atmospheric composition, radiative channels, cloud and surface options, continua, ray-tracing setup, retrieval parameters, and output settings.
Populates the ctl_t structure with all configuration values.

Parameters
[in]argcArgument count from the command line.
[in]argvArgument vector containing user-specified options.
[out]ctlControl structure to be filled with parsed settings.
  • Uses scan_ctl to extract key–value pairs from the command line or control file.
  • Initializes:
    • Emitters and gases (NG, EMITTER),
    • Spectral channels (ND, NU, WINDOW),
    • Cloud parameters (NCL, CLNU),
    • Surface parameters (NSF, SFNU, SFTYPE, SFSZA),
    • Hydrostatic reference height (HYDZ),
    • Continuum flags (CTM_CO2, CTM_H2O, CTM_N2, CTM_O2),
    • Ray-tracing options (REFRAC, RAYDS, RAYDZ),
    • Field-of-view (FOV),
    • Retrieval limits (RETP_ZMIN, RETQ_ZMAX, etc.),
    • Output flags (WRITE_BBT, WRITE_MATRIX),
    • External forward model paths (RFMBIN, RFMHIT, RFMXSC).
  • Validates array bounds and logical parameter ranges.
  • Automatically detects major gas species indices (e.g. CO₂, H₂O, N₂, O₂).
  • Logs the executable name, version, and compilation time at startup.
See also
ctl_t, scan_ctl, find_emitter, read_shape, formod
Warning
  • Aborts if mandatory keys are missing or exceed defined limits (e.g. NG > NG_MAX).
  • Requires consistent index ordering (e.g. NCL > 1, NSF > 1).
  • Undefined or invalid parameters trigger ERRMSG() aborts.
Author
Lars Hoffmann

Definition at line 5478 of file jurassic.c.

5481 {
5482
5483 /* Write info... */
5484 LOG(1, "\nJuelich Rapid Spectral Simulation Code (JURASSIC)\n"
5485 "(executable: %s | version: %s | compiled: %s, %s)\n",
5486 argv[0], VERSION, __DATE__, __TIME__);
5487
5488 /* Emitters... */
5489 ctl->ng = (int) scan_ctl(argc, argv, "NG", -1, "0", NULL);
5490 if (ctl->ng < 0 || ctl->ng > NG)
5491 ERRMSG("Set 0 <= NG <= MAX!");
5492 for (int ig = 0; ig < ctl->ng; ig++)
5493 scan_ctl(argc, argv, "EMITTER", ig, "", ctl->emitter[ig]);
5494 ctl->ig_co2 = find_emitter(ctl, "CO2");
5495 ctl->ig_h2o = find_emitter(ctl, "H2O");
5496 ctl->ig_n2 = find_emitter(ctl, "N2");
5497 ctl->ig_o2 = find_emitter(ctl, "O2");
5498
5499 /* Radiance channels... */
5500 ctl->nd = (int) scan_ctl(argc, argv, "ND", -1, "0", NULL);
5501 if (ctl->nd < 0 || ctl->nd > ND)
5502 ERRMSG("Set 0 <= ND <= MAX!");
5503 for (int id = 0; id < ctl->nd; id++)
5504 ctl->nu[id] = scan_ctl(argc, argv, "NU", id, "", NULL);
5505
5506 /* Spectral windows... */
5507 ctl->nw = (int) scan_ctl(argc, argv, "NW", -1, "1", NULL);
5508 if (ctl->nw < 0 || ctl->nw > NW)
5509 ERRMSG("Set 0 <= NW <= MAX!");
5510 for (int id = 0; id < ctl->nd; id++)
5511 ctl->window[id] = (int) scan_ctl(argc, argv, "WINDOW", id, "0", NULL);
5512
5513 /* Cloud data... */
5514 ctl->ncl = (int) scan_ctl(argc, argv, "NCL", -1, "0", NULL);
5515 if (ctl->ncl < 0 || ctl->ncl > NCL)
5516 ERRMSG("Set 0 <= NCL <= MAX!");
5517 if (ctl->ncl == 1)
5518 ERRMSG("Set NCL > 1!");
5519 for (int icl = 0; icl < ctl->ncl; icl++)
5520 ctl->clnu[icl] = scan_ctl(argc, argv, "CLNU", icl, "", NULL);
5521
5522 /* Surface data... */
5523 ctl->nsf = (int) scan_ctl(argc, argv, "NSF", -1, "0", NULL);
5524 if (ctl->nsf < 0 || ctl->nsf > NSF)
5525 ERRMSG("Set 0 <= NSF <= MAX!");
5526 if (ctl->nsf == 1)
5527 ERRMSG("Set NSF > 1!");
5528 for (int isf = 0; isf < ctl->nsf; isf++)
5529 ctl->sfnu[isf] = scan_ctl(argc, argv, "SFNU", isf, "", NULL);
5530 ctl->sftype = (int) scan_ctl(argc, argv, "SFTYPE", -1, "2", NULL);
5531 if (ctl->sftype < 0 || ctl->sftype > 3)
5532 ERRMSG("Set 0 <= SFTYPE <= 3!");
5533 ctl->sfsza = scan_ctl(argc, argv, "SFSZA", -1, "-999", NULL);
5534
5535 /* Emissivity look-up tables... */
5536 scan_ctl(argc, argv, "TBLBASE", -1, "-", ctl->tblbase);
5537 ctl->tblfmt = (int) scan_ctl(argc, argv, "TBLFMT", -1, "1", NULL);
5538 if (ctl->tblfmt < 1 || ctl->tblfmt > 3)
5539 ERRMSG("Unknown look-up table file format, set TBLFMT to 1, 2, or 3!");
5540
5541 /* File formats... */
5542 ctl->atmfmt = (int) scan_ctl(argc, argv, "ATMFMT", -1, "1", NULL);
5543 if (ctl->atmfmt < 1 || ctl->atmfmt > 3)
5544 ERRMSG("Unknown atmospheric file format, set ATMFMT to 1, 2, or 3!");
5545 ctl->obsfmt = (int) scan_ctl(argc, argv, "OBSFMT", -1, "1", NULL);
5546 if (ctl->obsfmt < 1 || ctl->obsfmt > 3)
5547 ERRMSG("Unknown observation file format, set OBSFMT to 1, 2, or 3!");
5548
5549 /* Hydrostatic equilibrium... */
5550 ctl->hydz = scan_ctl(argc, argv, "HYDZ", -1, "-999", NULL);
5551
5552 /* Continua... */
5553 ctl->ctm_co2 = (int) scan_ctl(argc, argv, "CTM_CO2", -1, "1", NULL);
5554 ctl->ctm_h2o = (int) scan_ctl(argc, argv, "CTM_H2O", -1, "1", NULL);
5555 ctl->ctm_n2 = (int) scan_ctl(argc, argv, "CTM_N2", -1, "1", NULL);
5556 ctl->ctm_o2 = (int) scan_ctl(argc, argv, "CTM_O2", -1, "1", NULL);
5557
5558 /* Ray-tracing... */
5559 ctl->refrac = (int) scan_ctl(argc, argv, "REFRAC", -1, "1", NULL);
5560 ctl->rayds = scan_ctl(argc, argv, "RAYDS", -1, "10", NULL);
5561 ctl->raydz = scan_ctl(argc, argv, "RAYDZ", -1, "0.1", NULL);
5562
5563 /* Field of view... */
5564 scan_ctl(argc, argv, "FOV", -1, "-", ctl->fov);
5565 if (ctl->fov[0] != '-')
5566 read_shape(ctl->fov, ctl->fov_dz, ctl->fov_w, &ctl->fov_n);
5567
5568 /* Retrieval interface... */
5569 ctl->retp_zmin = scan_ctl(argc, argv, "RETP_ZMIN", -1, "-999", NULL);
5570 ctl->retp_zmax = scan_ctl(argc, argv, "RETP_ZMAX", -1, "-999", NULL);
5571 ctl->rett_zmin = scan_ctl(argc, argv, "RETT_ZMIN", -1, "-999", NULL);
5572 ctl->rett_zmax = scan_ctl(argc, argv, "RETT_ZMAX", -1, "-999", NULL);
5573 for (int ig = 0; ig < ctl->ng; ig++) {
5574 ctl->retq_zmin[ig] = scan_ctl(argc, argv, "RETQ_ZMIN", ig, "-999", NULL);
5575 ctl->retq_zmax[ig] = scan_ctl(argc, argv, "RETQ_ZMAX", ig, "-999", NULL);
5576 }
5577 for (int iw = 0; iw < ctl->nw; iw++) {
5578 ctl->retk_zmin[iw] = scan_ctl(argc, argv, "RETK_ZMIN", iw, "-999", NULL);
5579 ctl->retk_zmax[iw] = scan_ctl(argc, argv, "RETK_ZMAX", iw, "-999", NULL);
5580 }
5581 ctl->ret_clz = (int) scan_ctl(argc, argv, "RET_CLZ", -1, "0", NULL);
5582 ctl->ret_cldz = (int) scan_ctl(argc, argv, "RET_CLDZ", -1, "0", NULL);
5583 ctl->ret_clk = (int) scan_ctl(argc, argv, "RET_CLK", -1, "0", NULL);
5584 ctl->ret_sft = (int) scan_ctl(argc, argv, "RET_SFT", -1, "0", NULL);
5585 ctl->ret_sfeps = (int) scan_ctl(argc, argv, "RET_SFEPS", -1, "0", NULL);
5586
5587 /* Output flags... */
5588 ctl->write_bbt = (int) scan_ctl(argc, argv, "WRITE_BBT", -1, "0", NULL);
5589 ctl->write_matrix =
5590 (int) scan_ctl(argc, argv, "WRITE_MATRIX", -1, "0", NULL);
5591
5592 /* External forward models... */
5593 ctl->formod = (int) scan_ctl(argc, argv, "FORMOD", -1, "1", NULL);
5594 scan_ctl(argc, argv, "RFMBIN", -1, "-", ctl->rfmbin);
5595 scan_ctl(argc, argv, "RFMHIT", -1, "-", ctl->rfmhit);
5596 for (int ig = 0; ig < ctl->ng; ig++)
5597 scan_ctl(argc, argv, "RFMXSC", ig, "-", ctl->rfmxsc[ig]);
5598}
int find_emitter(const ctl_t *ctl, const char *emitter)
Find gas species index by name.
Definition: jurassic.c:3402
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.
Definition: jurassic.c:6408
void read_shape(const char *filename, double *x, double *y, int *n)
Read a two-column shape function from an ASCII file.
Definition: jurassic.c:6087
int write_matrix
Write matrix file (0=no, 1=yes).
Definition: jurassic.h:1437
char tblbase[LEN]
Basename for table files and filter function files.
Definition: jurassic.h:1347
int obsfmt
Observation data file format (1=ASCII, 2=binary, 3=netCDF).
Definition: jurassic.h:1356
int tblfmt
Look-up table file format (1=ASCII, 2=binary, 3=netCDF).
Definition: jurassic.h:1350
Here is the call graph for this function:

◆ read_matrix()

void read_matrix ( const char *  dirname,
const char *  filename,
gsl_matrix *  matrix 
)

Read a numerical matrix from an ASCII file.

Loads values into a GSL matrix from a text file containing sparse or indexed entries in tabular format.
Each valid line is parsed for row and column indices and the corresponding value.

Parameters
[in]dirnameDirectory path containing the matrix file (may be NULL).
[in]filenameName of the matrix file to read.
[out]matrixPointer to the GSL matrix to be filled with values.
  • Opens the specified file and scans it line by line.
  • Initializes the matrix to zero before filling.
  • Each line is expected to contain at least 13 formatted fields, where:
    • The first integer gives the row index,
    • The seventh integer gives the column index,
    • The thirteenth floating-point number is the matrix element value.
  • All successfully parsed entries are written to the corresponding positions in the GSL matrix using gsl_matrix_set().
  • Non-matching lines are ignored.
See also
gsl_matrix, read_ctl, read_atm
Warning
  • Aborts if the file cannot be opened.
  • Expects 0-based integer indices consistent with matrix dimensions.
  • Lines not matching the expected 13-field format are skipped silently.
Author
Lars Hoffmann

Definition at line 5602 of file jurassic.c.

5605 {
5606
5607 char dum[LEN], file[LEN], line[LEN];
5608
5609 double value;
5610
5611 int i, j;
5612
5613 /* Set filename... */
5614 if (dirname != NULL)
5615 sprintf(file, "%s/%s", dirname, filename);
5616 else
5617 sprintf(file, "%s", filename);
5618
5619 /* Write info... */
5620 LOG(1, "Read matrix: %s", file);
5621
5622 /* Open file... */
5623 FILE *in;
5624 if (!(in = fopen(file, "r")))
5625 ERRMSG("Cannot open file!");
5626
5627 /* Read data... */
5628 gsl_matrix_set_zero(matrix);
5629 while (fgets(line, LEN, in))
5630 if (sscanf(line, "%d %s %s %s %s %s %d %s %s %s %s %s %lg",
5631 &i, dum, dum, dum, dum, dum,
5632 &j, dum, dum, dum, dum, dum, &value) == 13)
5633 gsl_matrix_set(matrix, (size_t) i, (size_t) j, value);
5634
5635 /* Close file... */
5636 fclose(in);
5637}

◆ read_obs()

void read_obs ( const char *  dirname,
const char *  filename,
const ctl_t ctl,
obs_t obs 
)

Read observation data from an input file.

This function reads atmospheric observation data from the specified file and stores the results in the provided obs_t structure. The file may be in ASCII or binary format, depending on the control settings passed via ctl_t. After reading the data, the routine performs basic validation (e.g., verifies that at least one observation entry was loaded) and logs diagnostic statistics such as ranges of times, observer coordinates, view point coordinates, tangent point coordinates, radiance or brightness temperature values, and transmittances.

The input file path is constructed from the provided directory and filename. If a directory name is given, the file is assumed to reside within it; otherwise, the filename is used as-is. Depending on the value of ctl->obsfmt, the function dispatches either to read_obs_asc() for ASCII files or read_obs_bin() for binary files.

Parameters
[in]dirnameDirectory containing the input file, or NULL to use only filename.
[in]filenameName of the observation file to read.
[in]ctlPointer to a control structure specifying file format and other options.
[out]obsPointer to an observation structure where the data will be stored.
Note
The function terminates with an error message if the file cannot be opened, the observation format is unknown, or no valid data is read.
Warning
The obs structure must be properly allocated before calling this function. The function assumes its arrays are large enough to store all values contained in the input file.
See also
read_obs_asc(), read_obs_bin(), ctl_t, obs_t
Author
Lars Hoffmann

Definition at line 5641 of file jurassic.c.

5645 {
5646
5647 /* Set filename... */
5648 char file[LEN];
5649 if (dirname != NULL)
5650 sprintf(file, "%s/%s", dirname, filename);
5651 else
5652 sprintf(file, "%s", filename);
5653
5654 /* Write info... */
5655 LOG(1, "Read observation data: %s", file);
5656
5657 /* Read ASCII data... */
5658 if (ctl->obsfmt == 1)
5659 read_obs_asc(file, ctl, obs);
5660
5661 /* Read binary data... */
5662 else if (ctl->obsfmt == 2)
5663 read_obs_bin(file, ctl, obs);
5664
5665 /* Read netCDF data... */
5666 else if (ctl->obsfmt == 3)
5667 read_obs_nc(file, ctl, obs, 0);
5668
5669 /* Check number of points... */
5670 if (obs->nr < 1)
5671 ERRMSG("Could not read any data!");
5672
5673 /* Write info... */
5674 double mini, maxi;
5675 LOG(2, "Number of ray paths: %d", obs->nr);
5676 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
5677 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
5678 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
5679 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
5680 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
5681 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
5682 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
5683 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
5684 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
5685 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
5686 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
5687 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
5688 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
5689 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
5690 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
5691 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
5692 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
5693 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
5694 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
5695 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
5696 for (int id = 0; id < ctl->nd; id++) {
5697 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
5698 if (ctl->write_bbt) {
5699 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
5700 ctl->nu[id], mini, maxi);
5701 } else {
5702 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
5703 ctl->nu[id], mini, maxi);
5704 }
5705 }
5706 for (int id = 0; id < ctl->nd; id++) {
5707 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
5708 if (ctl->write_bbt) {
5709 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
5710 ctl->nu[id], mini, maxi);
5711 }
5712 }
5713}
void read_obs_bin(const char *filename, const ctl_t *ctl, obs_t *obs)
Read binary-formatted observation data from a file.
Definition: jurassic.c:5761
void read_obs_nc(const char *filename, const ctl_t *ctl, obs_t *obs, const int profile)
Read one observation profile from a NetCDF file.
Definition: jurassic.c:5839
void read_obs_asc(const char *filename, const ctl_t *ctl, obs_t *obs)
Read ASCII-formatted observation data from a file.
Definition: jurassic.c:5717
Here is the call graph for this function:

◆ read_obs_asc()

void read_obs_asc ( const char *  filename,
const ctl_t ctl,
obs_t obs 
)

Read ASCII-formatted observation data from a file.

This function reads atmospheric observation data from an ASCII text file specified by its filename and stores it in the provided obs_t structure. Each line in the input file is expected to contain numerical values representing a single observation record, including time, observer coordinates, view point coordinates, tangent point coordinates, radiance or brightness temperature values, and transmittances. The number of radiance and transmittance values per record is determined by ctl->nd.

The function reads the file line by line, tokenizes the data fields, and fills the corresponding observation arrays. The number of successfully read observation entries is stored in obs->nr.

Parameters
filenamePath to the ASCII file containing the observation data.
ctlControl structure containing metadata such as the number of spectral channels (nd).
obsObservation structure where the parsed data will be stored.
Note
This is a C function and assumes that the obs structure has been preallocated with sufficient space for all records and spectral channels. No memory allocation is performed inside this routine.
Warning
The function terminates with an error message if the number of entries exceeds the predefined limit NR.
See also
read_obs(), read_obs_bin(), ctl_t, obs_t
Author
Lars Hoffmann

Definition at line 5717 of file jurassic.c.

5720 {
5721
5722 /* Init... */
5723 obs->nr = 0;
5724
5725 /* Open file... */
5726 FILE *in;
5727 if (!(in = fopen(filename, "r")))
5728 ERRMSG("Cannot open file!");
5729
5730 /* Read line... */
5731 char line[LEN], *tok;
5732 while (fgets(line, LEN, in)) {
5733
5734 /* Read data... */
5735 TOK(line, tok, "%lg", obs->time[obs->nr]);
5736 TOK(NULL, tok, "%lg", obs->obsz[obs->nr]);
5737 TOK(NULL, tok, "%lg", obs->obslon[obs->nr]);
5738 TOK(NULL, tok, "%lg", obs->obslat[obs->nr]);
5739 TOK(NULL, tok, "%lg", obs->vpz[obs->nr]);
5740 TOK(NULL, tok, "%lg", obs->vplon[obs->nr]);
5741 TOK(NULL, tok, "%lg", obs->vplat[obs->nr]);
5742 TOK(NULL, tok, "%lg", obs->tpz[obs->nr]);
5743 TOK(NULL, tok, "%lg", obs->tplon[obs->nr]);
5744 TOK(NULL, tok, "%lg", obs->tplat[obs->nr]);
5745 for (int id = 0; id < ctl->nd; id++)
5746 TOK(NULL, tok, "%lg", obs->rad[id][obs->nr]);
5747 for (int id = 0; id < ctl->nd; id++)
5748 TOK(NULL, tok, "%lg", obs->tau[id][obs->nr]);
5749
5750 /* Increment counter... */
5751 if ((++obs->nr) > NR)
5752 ERRMSG("Too many rays!");
5753 }
5754
5755 /* Close file... */
5756 fclose(in);
5757}

◆ read_obs_bin()

void read_obs_bin ( const char *  filename,
const ctl_t ctl,
obs_t obs 
)

Read binary-formatted observation data from a file.

This C function reads observation data stored in a compact binary format from a file specified by its filename and initializes the provided obs_t structure with the values retrieved. The binary format begins with a header that contains a magic identifier and the expected number of spectral channels. The number of channels in the file must match ctl->nd, otherwise the routine aborts with an error.

After verifying the header, the function reads the number of ray paths and then sequentially loads arrays corresponding to observation time, observer location, view point location, tangent point location, radiance (or brightness temperature), and transmittance data. The number of ray paths is assigned to obs->nr. All arrays must have been allocated prior to calling this function.

Parameters
filenamePath to the binary file containing the observation data.
ctlPointer to a control structure specifying the number of spectral channels (nd) and other configuration settings.
obsPointer to an observation structure where the decoded binary data will be stored.
Note
This function does not perform any memory allocation. The caller must ensure that all arrays in obs have sufficient capacity for the data being read.
Warning
The function terminates with an error message if the binary header does not match the expected channel count, if more data than allowed by NR is encountered, or if any read operation fails.
See also
read_obs(), read_obs_asc(), ctl_t, obs_t
Author
Lars Hoffmann

Definition at line 5761 of file jurassic.c.

5764 {
5765
5766 /* Open file... */
5767 FILE *in;
5768 if (!(in = fopen(filename, "r")))
5769 ERRMSG("Cannot open file!");
5770
5771 /* Read header... */
5772 char magic[4];
5773 FREAD(magic, char,
5774 4,
5775 in);
5776 if (memcmp(magic, "OBS1", 4) != 0)
5777 ERRMSG("Invalid magic string!");
5778
5779 int nd;
5780 FREAD(&nd, int,
5781 1,
5782 in);
5783 if (nd != ctl->nd)
5784 ERRMSG("Error reading file header!");
5785
5786 /* Read data... */
5787 size_t nr;
5788 FREAD(&nr, size_t,
5789 1,
5790 in);
5791 obs->nr = (int) nr;
5792 if (obs->nr > NR)
5793 ERRMSG("Too many ray paths!");
5794 FREAD(obs->time, double,
5795 nr,
5796 in);
5797 FREAD(obs->obsz, double,
5798 nr,
5799 in);
5800 FREAD(obs->obslon, double,
5801 nr,
5802 in);
5803 FREAD(obs->obslat, double,
5804 nr,
5805 in);
5806 FREAD(obs->vpz, double,
5807 nr,
5808 in);
5809 FREAD(obs->vplon, double,
5810 nr,
5811 in);
5812 FREAD(obs->vplat, double,
5813 nr,
5814 in);
5815 FREAD(obs->tpz, double,
5816 nr,
5817 in);
5818 FREAD(obs->tplon, double,
5819 nr,
5820 in);
5821 FREAD(obs->tplat, double,
5822 nr,
5823 in);
5824 for (int id = 0; id < ctl->nd; id++)
5825 FREAD(obs->rad[id], double,
5826 nr,
5827 in);
5828 for (int id = 0; id < ctl->nd; id++)
5829 FREAD(obs->tau[id], double,
5830 nr,
5831 in);
5832
5833 /* Close file... */
5834 fclose(in);
5835}

◆ read_obs_nc()

void read_obs_nc ( const char *  filename,
const ctl_t ctl,
obs_t obs,
const int  profile 
)

Read one observation profile from a NetCDF file.

This function reads all geometric and spectral observation data for a single profile from a NetCDF file using the variable-per-channel layout.

The NetCDF file is expected to contain:

  • A dimension profile (unlimited)
  • A dimension ray (number of ray paths)
  • A variable nray(profile) giving the number of rays for each profile
  • Geometry variables with dimensions (profile, ray):
    • time, obs_z, obs_lon, obs_lat
    • vp_z, vp_lon, vp_lat
    • tp_z, tp_lon, tp_lat
  • Spectral variables with dimensions (profile, ray), one per channel:
    • rad_%.4f (radiance or brightness temperature)
    • tau_%.4f (transmittance) where the formatted frequency corresponds to ctl->nu[id].

All data for the selected profile are read into the supplied obs_t structure. The number of rays is read from nray(profile) and stored in obs->nr. If the number of rays exceeds NR or is less than one, an error is raised.

Parameters
filenamePath to the NetCDF observation file.
ctlPointer to the control structure defining spectral channels.
obsPointer to the observation structure to be filled.
profileZero-based index of the profile to read.
Author
Lars Hoffmann

Definition at line 5839 of file jurassic.c.

5843 {
5844
5845 int ncid, var_nray = -1, var_time = -1, var_obsz = -1, var_obslon =
5846 -1, var_obslat = -1, var_vpz = -1, var_vplon = -1, var_vplat =
5847 -1, var_tpz = -1, var_tplon = -1, var_tplat =
5848 -1, var_rad[ND], var_tau[ND];
5849
5850 /* Open file... */
5851 NC(nc_open(filename, NC_NOWRITE, &ncid));
5852
5853 /* Initialize hyperslab... */
5854 size_t start[2] = { (size_t) profile, 0 };
5855 size_t count[2] = { 1, 0 };
5856
5857 /* Read nray(profile) -> obs->nr */
5858 NC(nc_inq_varid(ncid, "nray", &var_nray));
5859 NC(nc_get_vara_int(ncid, var_nray, start, count, &obs->nr));
5860 if (obs->nr < 1 || obs->nr > NR)
5861 ERRMSG("Number of ray paths out of range!");
5862
5863 /* Update hyperslab... */
5864 count[1] = (size_t) obs->nr;
5865
5866 /* Inquire geometry variables... */
5867 NC(nc_inq_varid(ncid, "time", &var_time));
5868 NC(nc_inq_varid(ncid, "obs_z", &var_obsz));
5869 NC(nc_inq_varid(ncid, "obs_lon", &var_obslon));
5870 NC(nc_inq_varid(ncid, "obs_lat", &var_obslat));
5871
5872 NC(nc_inq_varid(ncid, "vp_z", &var_vpz));
5873 NC(nc_inq_varid(ncid, "vp_lon", &var_vplon));
5874 NC(nc_inq_varid(ncid, "vp_lat", &var_vplat));
5875
5876 NC(nc_inq_varid(ncid, "tp_z", &var_tpz));
5877 NC(nc_inq_varid(ncid, "tp_lon", &var_tplon));
5878 NC(nc_inq_varid(ncid, "tp_lat", &var_tplat));
5879
5880 /* Inquire spectral variables per channel... */
5881 for (int id = 0; id < ctl->nd; id++) {
5882 char varname[LEN];
5883
5884 sprintf(varname, "rad_%.4f", ctl->nu[id]);
5885 NC(nc_inq_varid(ncid, varname, &var_rad[id]));
5886
5887 sprintf(varname, "tau_%.4f", ctl->nu[id]);
5888 NC(nc_inq_varid(ncid, varname, &var_tau[id]));
5889 }
5890
5891 /* Read geometry... */
5892 NC(nc_get_vara_double(ncid, var_time, start, count, obs->time));
5893 NC(nc_get_vara_double(ncid, var_obsz, start, count, obs->obsz));
5894 NC(nc_get_vara_double(ncid, var_obslon, start, count, obs->obslon));
5895 NC(nc_get_vara_double(ncid, var_obslat, start, count, obs->obslat));
5896
5897 NC(nc_get_vara_double(ncid, var_vpz, start, count, obs->vpz));
5898 NC(nc_get_vara_double(ncid, var_vplon, start, count, obs->vplon));
5899 NC(nc_get_vara_double(ncid, var_vplat, start, count, obs->vplat));
5900
5901 NC(nc_get_vara_double(ncid, var_tpz, start, count, obs->tpz));
5902 NC(nc_get_vara_double(ncid, var_tplon, start, count, obs->tplon));
5903 NC(nc_get_vara_double(ncid, var_tplat, start, count, obs->tplat));
5904
5905 /* Read radiance and transmittance... */
5906 for (int id = 0; id < ctl->nd; id++) {
5907 NC(nc_get_vara_double(ncid, var_rad[id], start, count, obs->rad[id]));
5908 NC(nc_get_vara_double(ncid, var_tau[id], start, count, obs->tau[id]));
5909 }
5910
5911 /* Close file... */
5912 NC(nc_close(ncid));
5913}

◆ read_obs_rfm()

double read_obs_rfm ( const char *  basename,
const double  z,
const double *  nu,
const double *  f,
const int  n 
)

Read and spectrally convolve an RFM output spectrum.

Opens the appropriate RFM ASCII spectrum file for a given tangent or observation altitude and convolves the high-resolution spectrum with a provided instrument filter function.
Returns the integrated (filtered) radiance value.

Parameters
[in]basenameBase filename of the RFM output (e.g. "rad" or "tra").
[in]zAltitude [km] used to select the corresponding RFM file.
[in]nuWavenumber grid [cm⁻¹] of the filter function.
[in]fFilter transmission values corresponding to nu.
[in]nNumber of points in nu and f arrays.
Returns
Filtered radiance value integrated over the instrument bandpass.
  • The routine looks for an RFM output file named basename_<altitude_in_meters>.asc (e.g. rad_04500.asc).
  • If not found, it retries with altitude+1 meter to tolerate rounding.
  • The file is read using read_rfm_spec() into arrays of wavenumbers (nurfm) and radiances (rad).
  • The input filter function \( f(\nu) \) is linearly interpolated onto the RFM wavenumber grid, and the spectrum is convolved as

    \[ R = \frac{\int f(\nu) \, I(\nu) \, d\nu}{\int f(\nu) \, d\nu} \]

  • Linear interpolation is used for both spectral alignment and filter sampling.
  • Returns the resulting band-averaged radiance in the same units as the input.
See also
read_rfm_spec, locate_irr, LIN, formod_rfm
Warning
  • Aborts if the corresponding RFM file cannot be found.
  • Assumes nu and f arrays are monotonic and have at least two points.
  • Files must contain RFM ASCII spectra in expected column format.
Author
Lars Hoffmann

Definition at line 5917 of file jurassic.c.

5922 {
5923
5924 double fsum = 0, nu2[NSHAPE], *nurfm, *rad, radsum = 0;
5925
5926 int npts;
5927
5928 /* Allocate... */
5929 ALLOC(nurfm, double,
5930 RFMNPTS);
5931 ALLOC(rad, double,
5932 RFMNPTS);
5933
5934 /* Search RFM spectrum... */
5935 FILE *in;
5936 char filename[LEN];
5937 sprintf(filename, "%s_%05d.asc", basename, (int) (z * 1000));
5938 if (!(in = fopen(filename, "r"))) {
5939 sprintf(filename, "%s_%05d.asc", basename, (int) (z * 1000) + 1);
5940 if (!(in = fopen(filename, "r")))
5941 ERRMSG("Cannot find RFM data file!");
5942 }
5943 fclose(in);
5944
5945 /* Read RFM spectrum... */
5946 read_rfm_spec(filename, nurfm, rad, &npts);
5947
5948 /* Set wavenumbers... */
5949 nu2[0] = nu[0];
5950 nu2[n - 1] = nu[n - 1];
5951 for (int i = 1; i < n - 1; i++)
5952 nu2[i] = LIN(0.0, nu2[0], n - 1.0, nu2[n - 1], i);
5953
5954 /* Convolute... */
5955 for (int ipts = 0; ipts < npts; ipts++)
5956 if (nurfm[ipts] >= nu2[0] && nurfm[ipts] <= nu2[n - 1]) {
5957 const int idx = locate_irr(nu2, n, nurfm[ipts]);
5958 const double filt =
5959 LIN(nu2[idx], f[idx], nu2[idx + 1], f[idx + 1], nurfm[ipts]);
5960 fsum += filt;
5961 radsum += filt * rad[ipts];
5962 }
5963
5964 /* Free... */
5965 free(nurfm);
5966 free(rad);
5967
5968 /* Return radiance... */
5969 return radsum / fsum;
5970}
void read_rfm_spec(const char *filename, double *nu, double *rad, int *npts)
Read a Reference Forward Model (RFM) ASCII spectrum.
Definition: jurassic.c:6027
#define RFMNPTS
Maximum number of RFM spectral grid points.
Definition: jurassic.h:323
Here is the call graph for this function:

◆ read_ret()

void read_ret ( int  argc,
char *  argv[],
const ctl_t ctl,
ret_t ret 
)

Read retrieval configuration and error parameters.

Initializes the retrieval control structure (ret_t) by reading all iteration and uncertainty parameters from the command line or an input control file using the scan_ctl() interface.

Parameters
[in]argcNumber of command-line arguments.
[in]argvCommand-line argument vector.
[in]ctlPointer to global control structure (ctl_t) defining the number of emitters, detectors, windows, clouds, etc.
[out]retPointer to retrieval configuration structure (ret_t) to be populated with iteration and error settings.

The function performs the following initialization steps:

  1. Iteration control parameters
    • KERNEL_RECOMP — number of iterations between kernel recomputations.
    • CONV_ITMAX — maximum number of retrieval iterations.
    • CONV_DMIN — minimum normalized step size for convergence.
  2. Error analysis flag
    • ERR_ANA — enables or disables retrieval error analysis (0 = off, 1 = on).
  3. Instrument and forward model errors
    • ERR_FORMOD[id] — relative (%) forward model uncertainty per detector channel.
    • ERR_NOISE[id] — absolute instrument noise per detector channel
      [W/(m²·sr·cm⁻¹)] or [K] depending on write_bbt.
  4. Pressure and temperature retrieval uncertainties
    • ERR_PRESS, ERR_PRESS_CZ, ERR_PRESS_CH — pressure error [%] and correlation lengths [km].
    • ERR_TEMP, ERR_TEMP_CZ, ERR_TEMP_CH — temperature error [K] and correlation lengths [km].
  5. Volume mixing ratio (VMR) errors
    • ERR_Q[ig], ERR_Q_CZ[ig], ERR_Q_CH[ig] — per gas [%] and correlation lengths [km].
  6. Extinction errors
    • ERR_K[iw], ERR_K_CZ[iw], ERR_K_CH[iw] — per spectral window [km⁻¹] and correlation lengths [km].
  7. Cloud retrieval parameters
    • ERR_CLZ — cloud top height error [km].
    • ERR_CLDZ — cloud depth error [km].
    • ERR_CLK[icl] — cloud extinction error per frequency [km⁻¹].
  8. Surface retrieval parameters
    • ERR_SFT — surface temperature error [K].
    • ERR_SFEPS[isf] — surface emissivity errors (dimensionless).
See also
scan_ctl, set_cov_apr, set_cov_meas, ret_t, ctl_t
Note
  • Each parameter can be specified either in the control file or on the command line (the latter overrides file values).
  • Default values are used when a parameter is not explicitly defined.
  • Correlation lengths of -999 indicate uncorrelated (diagonal) treatment.
Warning
  • Input validation is minimal; ensure consistency between ctl and ret dimensions.
  • Missing mandatory parameters trigger runtime errors.
Author
Lars Hoffmann

Definition at line 5974 of file jurassic.c.

5978 {
5979
5980 /* Iteration control... */
5981 ret->kernel_recomp =
5982 (int) scan_ctl(argc, argv, "KERNEL_RECOMP", -1, "3", NULL);
5983 ret->conv_itmax = (int) scan_ctl(argc, argv, "CONV_ITMAX", -1, "30", NULL);
5984 ret->conv_dmin = scan_ctl(argc, argv, "CONV_DMIN", -1, "0.1", NULL);
5985
5986 /* Error analysis... */
5987 ret->err_ana = (int) scan_ctl(argc, argv, "ERR_ANA", -1, "0", NULL);
5988
5989 for (int id = 0; id < ctl->nd; id++)
5990 ret->err_formod[id] = scan_ctl(argc, argv, "ERR_FORMOD", id, "0", NULL);
5991
5992 for (int id = 0; id < ctl->nd; id++)
5993 ret->err_noise[id] = scan_ctl(argc, argv, "ERR_NOISE", id, "0", NULL);
5994
5995 ret->err_press = scan_ctl(argc, argv, "ERR_PRESS", -1, "0", NULL);
5996 ret->err_press_cz = scan_ctl(argc, argv, "ERR_PRESS_CZ", -1, "-999", NULL);
5997 ret->err_press_ch = scan_ctl(argc, argv, "ERR_PRESS_CH", -1, "-999", NULL);
5998
5999 ret->err_temp = scan_ctl(argc, argv, "ERR_TEMP", -1, "0", NULL);
6000 ret->err_temp_cz = scan_ctl(argc, argv, "ERR_TEMP_CZ", -1, "-999", NULL);
6001 ret->err_temp_ch = scan_ctl(argc, argv, "ERR_TEMP_CH", -1, "-999", NULL);
6002
6003 for (int ig = 0; ig < ctl->ng; ig++) {
6004 ret->err_q[ig] = scan_ctl(argc, argv, "ERR_Q", ig, "0", NULL);
6005 ret->err_q_cz[ig] = scan_ctl(argc, argv, "ERR_Q_CZ", ig, "-999", NULL);
6006 ret->err_q_ch[ig] = scan_ctl(argc, argv, "ERR_Q_CH", ig, "-999", NULL);
6007 }
6008
6009 for (int iw = 0; iw < ctl->nw; iw++) {
6010 ret->err_k[iw] = scan_ctl(argc, argv, "ERR_K", iw, "0", NULL);
6011 ret->err_k_cz[iw] = scan_ctl(argc, argv, "ERR_K_CZ", iw, "-999", NULL);
6012 ret->err_k_ch[iw] = scan_ctl(argc, argv, "ERR_K_CH", iw, "-999", NULL);
6013 }
6014
6015 ret->err_clz = scan_ctl(argc, argv, "ERR_CLZ", -1, "0", NULL);
6016 ret->err_cldz = scan_ctl(argc, argv, "ERR_CLDZ", -1, "0", NULL);
6017 for (int icl = 0; icl < ctl->ncl; icl++)
6018 ret->err_clk[icl] = scan_ctl(argc, argv, "ERR_CLK", icl, "0", NULL);
6019
6020 ret->err_sft = scan_ctl(argc, argv, "ERR_SFT", -1, "0", NULL);
6021 for (int isf = 0; isf < ctl->nsf; isf++)
6022 ret->err_sfeps[isf] = scan_ctl(argc, argv, "ERR_SFEPS", isf, "0", NULL);
6023}
double err_press_cz
Vertical correlation length for pressure error [km].
Definition: jurassic.h:1601
double err_press
Pressure error [%].
Definition: jurassic.h:1598
double err_k_cz[NW]
Vertical correlation length for extinction error [km].
Definition: jurassic.h:1628
double err_k_ch[NW]
Horizontal correlation length for extinction error [km].
Definition: jurassic.h:1631
double err_temp_cz
Vertical correlation length for temperature error [km].
Definition: jurassic.h:1610
double err_formod[ND]
Forward model error [%].
Definition: jurassic.h:1592
double err_temp
Temperature error [K].
Definition: jurassic.h:1607
double err_q_cz[NG]
Vertical correlation length for volume mixing ratio error [km].
Definition: jurassic.h:1619
double err_noise[ND]
Noise error [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1595
double err_clz
Cloud height error [km].
Definition: jurassic.h:1634
double err_sft
Surface temperature error [K].
Definition: jurassic.h:1643
double err_clk[NCL]
Cloud extinction error [km^-1].
Definition: jurassic.h:1640
double err_temp_ch
Horizontal correlation length for temperature error [km].
Definition: jurassic.h:1613
double err_cldz
Cloud depth error [km].
Definition: jurassic.h:1637
double err_press_ch
Horizontal correlation length for pressure error [km].
Definition: jurassic.h:1604
double err_q_ch[NG]
Horizontal correlation length for volume mixing ratio error [km].
Definition: jurassic.h:1622
double err_q[NG]
Volume mixing ratio error [%].
Definition: jurassic.h:1616
double err_sfeps[NSF]
Surface emissivity error.
Definition: jurassic.h:1646
double err_k[NW]
Extinction error [km^-1].
Definition: jurassic.h:1625
Here is the call graph for this function:

◆ read_rfm_spec()

void read_rfm_spec ( const char *  filename,
double *  nu,
double *  rad,
int *  npts 
)

Read a Reference Forward Model (RFM) ASCII spectrum.

Parses an RFM output file containing high-resolution spectral radiances and fills the provided arrays with wavenumber and radiance values.

Parameters
[in]filenameName of the RFM ASCII spectrum file (e.g. "rad_04500.asc").
[out]nuArray to receive the spectral wavenumber grid [cm⁻¹].
[out]radArray to receive the corresponding radiances.
[out]nptsPointer to integer receiving the number of spectral points.
  • Expects the RFM file to begin with a four-line header. The final header line must contain, in order:
    • the number of spectral points (npts),
    • starting wavenumber nu0 [cm⁻¹],
    • spectral increment dnu [cm⁻¹],
    • ending wavenumber nu1 [cm⁻¹].
  • Radiance data follow as a sequence of floating-point values, separated by spaces, tabs, or line breaks.
  • The wavenumber grid is reconstructed using linear interpolation between nu0 and nu1:

    \[ \nu_i = \nu_0 + i \, \frac{\nu_1 - \nu_0}{N - 1}, \quad i = 0,\dots,N-1 \]

  • Uses dynamic line buffering and token-based parsing for efficiency.
See also
read_obs_rfm, locate_irr, LIN, formod_rfm
Warning
  • Aborts if the file cannot be opened or has an invalid header format.
  • Aborts if the number of grid points exceeds RFMNPTS.
  • Assumes ASCII format consistent with standard RFM .asc output.
Note
This routine reads only the spectral intensity data — additional metadata (e.g., gas profiles, geometry) must be handled separately.
Author
Lars Hoffmann

Definition at line 6027 of file jurassic.c.

6031 {
6032
6033 char *line = NULL, *tok;
6034
6035 size_t line_buf_size = 0;
6036
6037 double dnu, nu0, nu1;
6038
6039 int ipts = 0;
6040
6041 /* Write info... */
6042 LOG(1, "Read RFM data: %s", filename);
6043
6044 /* Open file... */
6045 FILE *in;
6046 if (!(in = fopen(filename, "r")))
6047 ERRMSG("Cannot open file!");
6048
6049 /* Read header... */
6050 for (int i = 0; i < 4; i++)
6051 if (getline(&line, &line_buf_size, in) == -1)
6052 ERRMSG("Error while reading file header!");
6053 if (sscanf(line, "%d %lg %lg %lg", npts, &nu0, &dnu, &nu1) != 4)
6054 ERRMSG("Invalid spectrum header format!");
6055
6056 /* Check number of spectral grid points... */
6057 if (*npts > RFMNPTS)
6058 ERRMSG("Too many spectral grid points!");
6059
6060 /* Read radiance data... */
6061 while (getline(&line, &line_buf_size, in) != -1 && ipts < *npts) {
6062 tok = strtok(line, " \t\n");
6063 while (tok != NULL && ipts < *npts) {
6064 if (sscanf(tok, "%lg", &rad[ipts]) == 1)
6065 ipts++;
6066 tok = strtok(NULL, " \t\n");
6067 }
6068 }
6069
6070 /* Check number of spectral grid points... */
6071 if (ipts != *npts)
6072 ERRMSG("Error while reading RFM data!");
6073
6074 /* Compute wavenumbers... */
6075 for (ipts = 0; ipts < *npts; ipts++)
6076 nu[ipts] = LIN(0.0, nu0, (double) (*npts - 1), nu1, (double) ipts);
6077
6078 /* Close file... */
6079 fclose(in);
6080
6081 /* Free.. */
6082 free(line);
6083}

◆ read_shape()

void read_shape ( const char *  filename,
double *  x,
double *  y,
int *  n 
)

Read a two-column shape function from an ASCII file.

Loads tabulated x–y data pairs (e.g., filter transmission or field-of-view weighting function) into the provided arrays.

Parameters
[in]filenameName of the ASCII file containing the shape function.
[out]xArray to receive the abscissa values.
[out]yArray to receive the ordinate values.
[out]nPointer to integer receiving the number of data points read.
  • The input file must contain at least two whitespace-separated columns:
    • Column 1: abscissa (x), typically wavenumber [cm⁻¹] or angular offset [deg].
    • Column 2: ordinate (y), typically transmission or weighting value.
  • Comment lines or malformed entries are ignored.
  • The routine logs the number of data points and their value ranges.
  • Data are stored directly in the provided arrays for subsequent interpolation or convolution.
See also
gsl_stats_minmax, formod_fov, init_srcfunc, read_obs_rfm
Warning
  • Aborts if the file cannot be opened or if fewer than two valid points are read.
  • Aborts if the number of data points exceeds NSHAPE.
  • Assumes numeric ASCII format and monotonic ordering of x values.
Note
This generic shape reader is used for both spectral filter functions and angular field-of-view profiles.
Author
Lars Hoffmann

Definition at line 6087 of file jurassic.c.

6091 {
6092
6093 char line[LEN];
6094
6095 /* Write info... */
6096 LOG(1, "Read shape function: %s", filename);
6097
6098 /* Open file... */
6099 FILE *in;
6100 if (!(in = fopen(filename, "r")))
6101 ERRMSG("Cannot open file!");
6102
6103 /* Read data... */
6104 *n = 0;
6105 while (fgets(line, LEN, in))
6106 if (sscanf(line, "%lg %lg", &x[*n], &y[*n]) == 2)
6107 if ((++(*n)) > NSHAPE)
6108 ERRMSG("Too many data points!");
6109
6110 /* Close file... */
6111 fclose(in);
6112
6113 /* Check number of data points... */
6114 if (*n < 2)
6115 ERRMSG("Could not read any data!");
6116
6117 /* Write info... */
6118 double mini, maxi;
6119 LOG(2, "Number of data points: %d", *n);
6120 gsl_stats_minmax(&mini, &maxi, x, 1, (size_t) *n);
6121 LOG(2, "Range of x values: %.4f ... %.4f", mini, maxi);
6122 gsl_stats_minmax(&mini, &maxi, y, 1, (size_t) *n);
6123 LOG(2, "Range of y values: %g ... %g", mini, maxi);
6124}

◆ read_tbl()

tbl_t * read_tbl ( const ctl_t ctl)

Read emissivity lookup tables from disk.

Loads emissivity lookup tables for all detector/channel indices id and all emitter/gas indices ig according to the configured table format ctl->tblfmt:

  • ASCII (ctl->tblfmt == 1)
  • compact binary (ctl->tblfmt == 2)
  • netCDF (ctl->tblfmt == 3)

The function allocates and initializes a tbl_t structure, reads the corresponding lookup tables, and (depending on the table format) also loads filter functions.

Missing per-table files (ASCII/binary) or missing netCDF files/variables are not fatal: the reader emits a warning and the corresponding lookup table is treated as empty (i.e., tbl->np[id][ig] == 0).

Diagnostic information about loaded tables (pressure levels, temperature ranges, absorber amounts, emissivity ranges) may be written to the log.

Parameters
[in]ctlPointer to the control structure defining lookup table format, filenames, emitters, and detector/channel frequencies.
Returns
Pointer to an allocated and initialized tbl_t structure containing the loaded lookup tables.
Warning
If an unsupported lookup table format is specified via ctl->tblfmt, the function aborts with an error message.
Note
Memory for the returned structure is dynamically allocated and must be released by the caller.
Author
Lars Hoffmann

Definition at line 6128 of file jurassic.c.

6129 {
6130
6131 /* Allocate... */
6132 tbl_t *tbl;
6133 ALLOC(tbl, tbl_t, 1);
6134
6135 /* Initialize filter function sizes... */
6136 for (int id = 0; id < ctl->nd; id++)
6137 tbl->filt_n[id] = 0;
6138
6139 /* Loop over trace gases... */
6140 for (int ig = 0; ig < ctl->ng; ig++) {
6141
6142 /* Read ASCII look-up tables... */
6143 if (ctl->tblfmt == 1)
6144 for (int id = 0; id < ctl->nd; id++) {
6145 read_tbl_asc(ctl, tbl, id, ig);
6146 TBL_LOG(tbl, id, ig);
6147 }
6148
6149 /* Read binary look-up tables... */
6150 else if (ctl->tblfmt == 2)
6151 for (int id = 0; id < ctl->nd; id++) {
6152 read_tbl_bin(ctl, tbl, id, ig);
6153 TBL_LOG(tbl, id, ig);
6154 }
6155
6156 /* Read netCDF look-up tables... */
6157 else if (ctl->tblfmt == 3) {
6158
6159 /* Open file... */
6160 int ncid;
6161 char filename[2 * LEN];
6162 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
6163 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6164 WARN("Missing emissivity table: %s", filename);
6165 continue;
6166 } else
6167 LOG(1, "Read emissivity table: %s", filename);
6168
6169 /* Read channels... */
6170 for (int id = 0; id < ctl->nd; id++) {
6171 read_tbl_nc_channel(ctl, tbl, id, ig, ncid);
6172 TBL_LOG(tbl, id, ig);
6173 }
6174
6175 /* Close file... */
6176 NC(nc_close(ncid));
6177 }
6178 }
6179
6180 /* Calculate log-pressure... */
6181 for (int id = 0; id < ctl->nd; id++)
6182 for (int ig = 0; ig < ctl->ng; ig++)
6183 for (int ip = 0; ip < tbl->np[id][ig]; ip++)
6184 tbl->lnp[id][ig][ip] = log(tbl->p[id][ig][ip]);
6185
6186 /* Read filter functions... */
6187 if (ctl->tblfmt == 1)
6188 for (int id = 0; id < ctl->nd; id++) {
6189 char filename[2 * LEN];
6190 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
6191 read_shape(filename, tbl->filt_nu[id], tbl->filt_f[id],
6192 &tbl->filt_n[id]);
6193 }
6194
6195 /* Initialize source function lookup tables... */
6196 init_srcfunc(ctl, tbl);
6197
6198 /* Return pointer... */
6199 return tbl;
6200}
void read_tbl_bin(const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
Read a single compact binary emissivity lookup table.
Definition: jurassic.c:6327
void init_srcfunc(const ctl_t *ctl, tbl_t *tbl)
Initialize source function lookup tables from emissivity data.
Definition: jurassic.c:3996
void read_tbl_asc(const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
Read a single ASCII emissivity lookup table.
Definition: jurassic.c:6204
void read_tbl_nc_channel(const ctl_t *ctl, tbl_t *tbl, int id, int ig, int ncid)
Read one packed emissivity lookup table from an open NetCDF file.
Definition: jurassic.c:6371
#define TBL_LOG(tbl, id, ig)
Log detailed statistics of an emissivity look-up table.
Definition: jurassic.h:1022
Emissivity look-up tables.
Definition: jurassic.h:1656
Here is the call graph for this function:

◆ read_tbl_asc()

void read_tbl_asc ( const ctl_t ctl,
tbl_t tbl,
const int  id,
const int  ig 
)

Read a single ASCII emissivity lookup table.

Reads one ASCII table for detector/channel index id and emitter/gas index ig from a file named:

<ctl->tblbase>_<ctl->nu[id]>_<ctl->emitter[ig]>.tab

The table file contains four columns:

  1. pressure [hPa]
  2. temperature [K]
  3. column density [molecules/cm^2]
  4. emissivity [-]

The routine infers the pressure/temperature/column-density indices from changes in the values read from the file. Values outside the supported ranges for column density or emissivity are skipped and counted.

If the file cannot be opened, a warning is issued and the table is treated as empty (i.e., tbl->np[id][ig] == 0).

Parameters
[in]ctlPointer to control structure specifying filenames and grids.
[in,out]tblPointer to the table structure to be filled.
[in]idDetector/channel index.
[in]igEmitter/gas index.
Warning
Aborts via ERRMSG() if table dimensions exceed TBLNP / TBLNT / TBLNU.
Note
Implementation detail: the ASCII reader may use an internal sentinel during parsing (historically np == -1 such that the first increment yields index 0). On return, tbl->np[id][ig] always represents the number of pressure levels (0 for an empty table).
Author
Lars Hoffmann

Definition at line 6204 of file jurassic.c.

6208 {
6209
6210 /* Initialize... */
6211 double eps, eps_old = -999, press, press_old = -999, temp,
6212 temp_old = -999, u, u_old = -999;
6213 int nrange = 0;
6214
6215 /* Set filename... */
6216 char filename[2 * LEN];
6217 sprintf(filename, "%s_%.4f_%s.tab", ctl->tblbase,
6218 ctl->nu[id], ctl->emitter[ig]);
6219
6220 /* Open file... */
6221 FILE *in;
6222 if (!(in = fopen(filename, "r"))) {
6223 WARN("Missing emissivity table: %s", filename);
6224 return;
6225 } else
6226 LOG(1, "Read emissivity table: %s", filename);
6227
6228 /* Init pressure level counter... */
6229 tbl->np[id][ig] = -1;
6230
6231 /* Read data... */
6232 char line[LEN];
6233 while (fgets(line, LEN, in)) {
6234
6235 /* Parse line... */
6236 if (sscanf(line, "%lg %lg %lg %lg", &press, &temp, &u, &eps) != 4)
6237 continue;
6238
6239 /* Check ranges... */
6240 if (u < UMIN || u > UMAX || eps < EPSMIN || eps > EPSMAX) {
6241 nrange++;
6242 continue;
6243 }
6244
6245 /* Determine pressure index... */
6246 if (press != press_old) {
6247 press_old = press;
6248 if ((++tbl->np[id][ig]) >= TBLNP)
6249 ERRMSG("Too many pressure levels!");
6250 tbl->nt[id][ig][tbl->np[id][ig]] = -1;
6251 }
6252
6253 /* Determine temperature index... */
6254 if (temp != temp_old) {
6255 temp_old = temp;
6256 if ((++tbl->nt[id][ig][tbl->np[id][ig]]) >= TBLNT)
6257 ERRMSG("Too many temperatures!");
6258 tbl->nu[id][ig][tbl->np[id][ig]]
6259 [tbl->nt[id][ig][tbl->np[id][ig]]] = -1;
6260
6261 /* Reset dynamic arrays for this (ip,it) node... */
6262 tbl->logu[id][ig][tbl->np[id][ig]]
6263 [tbl->nt[id][ig][tbl->np[id][ig]]] = NULL;
6264 tbl->logeps[id][ig][tbl->np[id][ig]]
6265 [tbl->nt[id][ig][tbl->np[id][ig]]] = NULL;
6266 }
6267
6268 /* Determine column density index... */
6269 if ((eps > eps_old && u > u_old) || tbl->nu[id][ig][tbl->np[id][ig]]
6270 [tbl->nt[id][ig][tbl->np[id][ig]]] < 0) {
6271 eps_old = eps;
6272 u_old = u;
6273 if ((++tbl->nu[id][ig][tbl->np[id][ig]]
6274 [tbl->nt[id][ig][tbl->np[id][ig]]]) >= TBLNU)
6275 ERRMSG("Too many column densities!");
6276
6277 /* Grow dynamic arrays (nu is used as an index during reading). */
6278 const int ip = tbl->np[id][ig];
6279 const int it = tbl->nt[id][ig][ip];
6280 const int iu = tbl->nu[id][ig][ip][it];
6281 const size_t nnew = (size_t) (iu + 1);
6282
6283 float *tmp = (float *) realloc(tbl->logu[id][ig][ip][it],
6284 nnew * sizeof(float));
6285 if (!tmp)
6286 ERRMSG("Out of memory!");
6287 tbl->logu[id][ig][ip][it] = tmp;
6288
6289 tmp =
6290 (float *) realloc(tbl->logeps[id][ig][ip][it], nnew * sizeof(float));
6291 if (!tmp)
6292 ERRMSG("Out of memory!");
6293 tbl->logeps[id][ig][ip][it] = tmp;
6294 }
6295
6296 /* Store data... */
6297 tbl->p[id][ig][tbl->np[id][ig]] = press;
6298 tbl->t[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
6299 = temp;
6300 tbl->logu[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
6301 [tbl->nu[id][ig][tbl->np[id][ig]]
6302 [tbl->nt[id][ig][tbl->np[id][ig]]]] = (float) log(u);
6303 tbl->logeps[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
6304 [tbl->nu[id][ig][tbl->np[id][ig]]
6305 [tbl->nt[id][ig][tbl->np[id][ig]]]] = (float) log(eps);
6306 }
6307
6308 /* Increment counters... */
6309 tbl->np[id][ig]++;
6310 for (int ip = 0; ip < tbl->np[id][ig]; ip++) {
6311 tbl->nt[id][ig][ip]++;
6312 for (int it = 0; it < tbl->nt[id][ig][ip]; it++)
6313 tbl->nu[id][ig][ip][it]++;
6314 }
6315
6316 /* Check ranges... */
6317 if (nrange > 0)
6318 WARN("Column density or emissivity out of range (%d data points)!",
6319 nrange);
6320
6321 /* Close file... */
6322 fclose(in);
6323}
#define UMAX
Maximum column density [molecules/cm^2].
Definition: jurassic.h:224
#define TBLNU
Maximum number of column densities per emissivity curve.
Definition: jurassic.h:313
#define TBLNT
Maximum number of temperatures in emissivity tables.
Definition: jurassic.h:308
#define EPSMAX
Maximum emissivity.
Definition: jurassic.h:144
#define TBLNP
Maximum number of pressure levels in emissivity tables.
Definition: jurassic.h:303

◆ read_tbl_bin()

void read_tbl_bin ( const ctl_t ctl,
tbl_t tbl,
const int  id,
const int  ig 
)

Read a single compact binary emissivity lookup table.

Reads one binary table for detector/channel index id and emitter/gas index ig from a file named:

<ctl->tblbase>_<ctl->nu[id]>_<ctl->emitter[ig]>.bin

The file contains a length field followed by a packed byte blob created by tbl_pack():

  • size_t nbytes : number of bytes in the packed blob
  • uint8_t blob[] : packed lookup table data

The blob is unpacked into tbl using tbl_unpack().

If the file cannot be opened, a warning is issued and the table is treated as empty (i.e., tbl->np[id][ig] == 0).

Parameters
[in]ctlPointer to control structure specifying filenames and grids.
[in,out]tblPointer to the table structure to be filled.
[in]idDetector/channel index.
[in]igEmitter/gas index.
Warning
Aborts via ERRMSG() if the file is malformed or unpacking fails.
See also
write_tbl_bin()
tbl_pack()
tbl_unpack()
Author
Lars Hoffmann

Definition at line 6327 of file jurassic.c.

6331 {
6332
6333 /* Set filename... */
6334 char filename[2 * LEN];
6335 sprintf(filename, "%s_%.4f_%s.bin",
6336 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
6337
6338 /* Open file... */
6339 FILE *in = fopen(filename, "rb");
6340 if (!in) {
6341 WARN("Missing emissivity table: %s", filename);
6342 return;
6343 } else
6344 LOG(1, "Read emissivity table: %s", filename);
6345
6346 /* Read length.. */
6347 size_t nbytes;
6348 FREAD(&nbytes, size_t,
6349 1,
6350 in);
6351 if (nbytes <= 0)
6352 ERRMSG("Invalid packed table size!");
6353
6354 /* Read packed blob... */
6355 uint8_t *work = NULL;
6356 ALLOC(work, uint8_t, nbytes);
6357 FREAD(work, uint8_t, nbytes, in);
6358
6359 /* Unpack... */
6360 tbl_unpack(tbl, id, ig, work);
6361
6362 /* Close file... */
6363 fclose(in);
6364
6365 /* Free... */
6366 free(work);
6367}
size_t tbl_unpack(tbl_t *tbl, int id, int ig, const uint8_t *buf)
Unpack a lookup table from a contiguous binary buffer.
Definition: jurassic.c:6806
Here is the call graph for this function:

◆ read_tbl_nc_channel()

void read_tbl_nc_channel ( const ctl_t ctl,
tbl_t tbl,
int  id,
int  ig,
int  ncid 
)

Read one packed emissivity lookup table from an open NetCDF file.

Loads a previously stored emissivity lookup table for detector/channel index id and emitter (trace gas) index ig from an already opened NetCDF file. The file is expected to have been created by write_tbl_nc().

The NetCDF variable name is derived from the detector/channel frequency:

tbl_XXXX

where XXXX is ctl->nu[id] formatted to four decimal places.

Each variable is stored as a one-dimensional NC_UBYTE array containing a packed lookup-table byte stream. The data are unpacked into tbl using tbl_unpack().

Missing variables are not fatal: a warning is issued and the corresponding table is left empty (i.e., tbl->np[id][ig] remains zero).

The NetCDF file handle ncid must refer to an open file and is not opened or closed by this function.

Parameters
[in]ctlControl structure defining emitters, detectors, and detector/channel frequencies.
[in,out]tblTable structure that receives the unpacked data.
[in]idDetector/channel index selecting ctl->nu[id].
[in]igEmitter (trace gas) index selecting ctl->emitter[ig].
[in]ncidNetCDF file identifier of an already opened file.
Note
A temporary buffer is allocated to hold the packed lookup-table data prior to unpacking.
Warning
Aborts via ERRMSG() if the NetCDF variable exists but cannot be read or unpacked (e.g., corrupted contents).
See also
write_tbl_nc()
tbl_unpack()
Author
Lars Hoffmann

Definition at line 6371 of file jurassic.c.

6376 {
6377
6378 char varname[LEN];
6379
6380 int varid, dimid;
6381
6382 size_t nbytes;
6383
6384 /* Inquire variable... */
6385 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
6386 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
6387 WARN("Missing emissivity table: %s", varname);
6388 return;
6389 } else
6390 LOG(1, "Read emissivity table: %s", varname);
6391 NC(nc_inq_vardimid(ncid, varid, &dimid));
6392 NC(nc_inq_dimlen(ncid, dimid, &nbytes));
6393
6394 /* Read variable... */
6395 uint8_t *work = NULL;
6396 ALLOC(work, uint8_t, nbytes);
6397 NC(nc_get_var_uchar(ncid, varid, (unsigned char *) work));
6398
6399 /* Unpack... */
6400 tbl_unpack(tbl, id, ig, work);
6401
6402 /* Free... */
6403 free(work);
6404}
Here is the call graph for this function:

◆ scan_ctl()

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.

Searches for a named variable in the JURASSIC control file or command-line arguments, returning its value as a double. Optionally stores the value as a string and supports array-style parameters (e.g., EMITTER[0], NU[5]).

Parameters
[in]argcNumber of command-line arguments.
[in]argvCommand-line argument vector.
[in]varnameName of the control variable to read.
[in]arridxArray index (use -1 for scalar variables).
[in]defvalueDefault value if variable is not found (can be empty).
[out]valueOptional pointer to a string buffer receiving the value (may be NULL if only numeric output is required).
Returns
The variable value converted to double.
  • The routine first attempts to open the control file provided as the first command-line argument (argv[1]), unless it starts with '-'.
  • Variable names may appear as either:
    • VAR (scalar)
    • VAR[index] (explicit array index)
    • VAR[*] (wildcard entry applying to all indices)
  • The search order is:
    1. Control file lines of the form:
      VAR[index] = VALUE
      VAR[*] = VALUE
    2. Command-line arguments:
      ./jurassic ctlfile VAR[index] VALUE
  • If no match is found:
    • The default value defvalue is used (if non-empty).
    • Otherwise, the routine aborts with an error.
  • The variable value is printed to the log at verbosity level 1.
See also
read_ctl, LOG, ERRMSG
Warning
  • Aborts if the control file cannot be opened (unless skipped with '-').
  • Aborts if a required variable is missing and no default is provided.
  • Array bounds are not validated against internal limits; use ctl_t checks to ensure consistency.
Note
  • This utility simplifies control input parsing by supporting both command-line overrides and configuration files with the same syntax.
  • String comparisons are case-insensitive.
Author
Lars Hoffmann

Definition at line 6408 of file jurassic.c.

6414 {
6415
6416 char dummy[LEN], fullname1[LEN], fullname2[LEN], line[LEN],
6417 rvarname[LEN], rval[LEN];
6418
6419 int contain = 0;
6420
6421 /* Open file... */
6422 FILE *in = NULL;
6423 if (argv[1][0] != '-')
6424 if (!(in = fopen(argv[1], "r")))
6425 ERRMSG("Cannot open file!");
6426
6427 /* Set full variable name... */
6428 if (arridx >= 0) {
6429 sprintf(fullname1, "%s[%d]", varname, arridx);
6430 sprintf(fullname2, "%s[*]", varname);
6431 } else {
6432 sprintf(fullname1, "%s", varname);
6433 sprintf(fullname2, "%s", varname);
6434 }
6435
6436 /* Read data... */
6437 if (in != NULL)
6438 while (fgets(line, LEN, in))
6439 if (sscanf(line, "%s %s %s", rvarname, dummy, rval) == 3)
6440 if (strcasecmp(rvarname, fullname1) == 0 ||
6441 strcasecmp(rvarname, fullname2) == 0) {
6442 contain = 1;
6443 break;
6444 }
6445 for (int i = 1; i < argc - 1; i++)
6446 if (strcasecmp(argv[i], fullname1) == 0 ||
6447 strcasecmp(argv[i], fullname2) == 0) {
6448 sprintf(rval, "%s", argv[i + 1]);
6449 contain = 1;
6450 break;
6451 }
6452
6453 /* Close file... */
6454 if (in != NULL)
6455 fclose(in);
6456
6457 /* Check for missing variables... */
6458 if (!contain) {
6459 if (strlen(defvalue) > 0)
6460 sprintf(rval, "%s", defvalue);
6461 else
6462 ERRMSG("Missing variable %s!\n", fullname1);
6463 }
6464
6465 /* Write info... */
6466 LOG(1, "%s = %s", fullname1, rval);
6467
6468 /* Return values... */
6469 if (value != NULL)
6470 sprintf(value, "%s", rval);
6471 return atof(rval);
6472}

◆ set_cov_apr()

void set_cov_apr ( const ret_t ret,
const ctl_t ctl,
const atm_t atm,
const int *  iqa,
const int *  ipa,
gsl_matrix *  s_a 
)

Construct the a priori covariance matrix \(\mathbf{S_a}\) for retrieval parameters.

Builds the full a priori covariance matrix based on specified retrieval error assumptions and correlation lengths defined in the ret_t structure. Each diagonal element represents the variance of an individual state vector element, while off-diagonal terms encode spatial correlations between parameters of the same type.

Parameters
[in]retRetrieval configuration and error parameters (ret_t).
[in]ctlControl structure defining retrieval setup and state vector mapping (ctl_t).
[in]atmAtmospheric profile structure containing geolocation and altitude information (atm_t).
[in]iqaIndex array linking state vector elements to physical quantities (e.g. pressure, temperature, gas, extinction, etc.).
[in]ipaIndex array linking state vector elements to atmospheric grid points.
[out]s_aOutput a priori covariance matrix \(\mathbf{S_a}\) (gsl_matrix), dimension n×n.
  • The function first converts atmospheric quantities to a state vector (atm2x) and scales them according to their a priori uncertainties:
    • Pressure and trace gas errors are relative (% of nominal value).
    • Temperature, extinction, cloud, and surface errors are absolute.
  • The diagonal of \(\mathbf{S_a}\) is filled with the variances \(\sigma_i^2\) of each element.
  • Off-diagonal elements are populated according to an exponential correlation model:

    \[ \rho_{ij} = \exp\left(-\frac{d_{ij}}{L_h} - \frac{|z_i - z_j|}{L_v}\right) \]

    where:
    • \(d_{ij}\) is the great-circle (horizontal) distance between state vector locations,
    • \(L_h\) and \(L_v\) are horizontal and vertical correlation lengths for the parameter type.
See also
atm2x, geo2cart, DIST, ret_t, ctl_t
Note
  • Parameters with identical type indices (iqa[i] == iqa[j]) are assumed to share correlation properties.
  • Correlation lengths are taken from ret_t, differing by parameter type:
    • Pressure: err_press_cz, err_press_ch
    • Temperature: err_temp_cz, err_temp_ch
    • Volume mixing ratio: err_q_cz[], err_q_ch[]
    • Extinction: err_k_cz[], err_k_ch[]
  • Cloud and surface parameters are assumed uncorrelated (diagonal only).
Warning
  • A zero or negative variance triggers a runtime error.
  • The matrix is constructed in full (dense), which may be large for high-resolution retrieval grids.
Author
Lars Hoffmann

Definition at line 6476 of file jurassic.c.

6482 {
6483
6484 /* Get sizes... */
6485 const size_t n = s_a->size1;
6486
6487 /* Allocate... */
6488 gsl_vector *x_a = gsl_vector_alloc(n);
6489
6490 /* Get sigma vector... */
6491 atm2x(ctl, atm, x_a, NULL, NULL);
6492 for (size_t i = 0; i < n; i++) {
6493 if (iqa[i] == IDXP)
6494 gsl_vector_set(x_a, i, ret->err_press / 100 * gsl_vector_get(x_a, i));
6495 if (iqa[i] == IDXT)
6496 gsl_vector_set(x_a, i, ret->err_temp);
6497 for (int ig = 0; ig < ctl->ng; ig++)
6498 if (iqa[i] == IDXQ(ig))
6499 gsl_vector_set(x_a, i, ret->err_q[ig] / 100 * gsl_vector_get(x_a, i));
6500 for (int iw = 0; iw < ctl->nw; iw++)
6501 if (iqa[i] == IDXK(iw))
6502 gsl_vector_set(x_a, i, ret->err_k[iw]);
6503 if (iqa[i] == IDXCLZ)
6504 gsl_vector_set(x_a, i, ret->err_clz);
6505 if (iqa[i] == IDXCLDZ)
6506 gsl_vector_set(x_a, i, ret->err_cldz);
6507 for (int icl = 0; icl < ctl->ncl; icl++)
6508 if (iqa[i] == IDXCLK(icl))
6509 gsl_vector_set(x_a, i, ret->err_clk[icl]);
6510 if (iqa[i] == IDXSFT)
6511 gsl_vector_set(x_a, i, ret->err_sft);
6512 for (int isf = 0; isf < ctl->nsf; isf++)
6513 if (iqa[i] == IDXSFEPS(isf))
6514 gsl_vector_set(x_a, i, ret->err_sfeps[isf]);
6515 }
6516
6517 /* Check standard deviations... */
6518 for (size_t i = 0; i < n; i++)
6519 if (POW2(gsl_vector_get(x_a, i)) <= 0)
6520 ERRMSG("Check a priori data (zero standard deviation)!");
6521
6522 /* Initialize diagonal covariance... */
6523 gsl_matrix_set_zero(s_a);
6524 for (size_t i = 0; i < n; i++)
6525 gsl_matrix_set(s_a, i, i, POW2(gsl_vector_get(x_a, i)));
6526
6527 /* Loop over matrix elements... */
6528 for (size_t i = 0; i < n; i++)
6529 for (size_t j = 0; j < n; j++)
6530 if (i != j && iqa[i] == iqa[j]) {
6531
6532 /* Initialize... */
6533 double cz = 0;
6534 double ch = 0;
6535
6536 /* Set correlation lengths for pressure... */
6537 if (iqa[i] == IDXP) {
6538 cz = ret->err_press_cz;
6539 ch = ret->err_press_ch;
6540 }
6541
6542 /* Set correlation lengths for temperature... */
6543 if (iqa[i] == IDXT) {
6544 cz = ret->err_temp_cz;
6545 ch = ret->err_temp_ch;
6546 }
6547
6548 /* Set correlation lengths for volume mixing ratios... */
6549 for (int ig = 0; ig < ctl->ng; ig++)
6550 if (iqa[i] == IDXQ(ig)) {
6551 cz = ret->err_q_cz[ig];
6552 ch = ret->err_q_ch[ig];
6553 }
6554
6555 /* Set correlation lengths for extinction... */
6556 for (int iw = 0; iw < ctl->nw; iw++)
6557 if (iqa[i] == IDXK(iw)) {
6558 cz = ret->err_k_cz[iw];
6559 ch = ret->err_k_ch[iw];
6560 }
6561
6562 /* Compute correlations... */
6563 if (cz > 0 && ch > 0) {
6564
6565 /* Get Cartesian coordinates... */
6566 double x0[3], x1[3];
6567 geo2cart(0, atm->lon[ipa[i]], atm->lat[ipa[i]], x0);
6568 geo2cart(0, atm->lon[ipa[j]], atm->lat[ipa[j]], x1);
6569
6570 /* Compute correlations... */
6571 const double rho =
6572 exp(-DIST(x0, x1) / ch -
6573 fabs(atm->z[ipa[i]] - atm->z[ipa[j]]) / cz);
6574
6575 /* Set covariance... */
6576 gsl_matrix_set(s_a, i, j, gsl_vector_get(x_a, i)
6577 * gsl_vector_get(x_a, j) * rho);
6578 }
6579 }
6580
6581 /* Free... */
6582 gsl_vector_free(x_a);
6583}
#define DIST(a, b)
Compute Cartesian distance between two 3D vectors.
Definition: jurassic.h:465
Here is the call graph for this function:

◆ set_cov_meas()

void set_cov_meas ( const ret_t ret,
const ctl_t ctl,
const obs_t obs,
gsl_vector *  sig_noise,
gsl_vector *  sig_formod,
gsl_vector *  sig_eps_inv 
)

Construct measurement error standard deviations and their inverse.

Builds the total measurement uncertainty vector used in the optimal estimation retrieval, accounting for both instrument noise and forward model (systematic) errors.

Parameters
[in]retRetrieval configuration and error parameters (ret_t).
[in]ctlControl structure defining spectral channels and setup (ctl_t).
[in]obsObservation dataset (obs_t), containing measured radiances or brightness temperatures.
[out]sig_noiseVector of instrument noise standard deviations (gsl_vector), length m.
[out]sig_formodVector of forward model error standard deviations (gsl_vector), length m.
[out]sig_eps_invVector of inverse total standard deviations, \(\sigma_\epsilon^{-1}\), used for normalization.
  • The function computes the total measurement uncertainty for each observation element \(i\) as:

    \[ \sigma_{\epsilon,i}^2 = \sigma_{\text{noise},i}^2 + \sigma_{\text{formod},i}^2 \]

    and stores its reciprocal square root:

    \[ (\sigma_{\epsilon,i}^{-1}) = \frac{1}{\sqrt{\sigma_{\epsilon,i}^2}} \]

  • **Noise error (sig_noise)**
    Determined from the instrument noise level defined in ret->err_noise[id] for each spectral channel. The noise term is always included in the fit.
  • **Forward model error (sig_formod)**
    Computed as a fixed percentage (ret->err_formod[id]) of the measured radiance (or brightness temperature) per channel. This represents uncertainty due to imperfect forward modeling.
  • The inverse total standard deviation vector (sig_eps_inv) is used to normalize the measurement residuals \((y - F(x))\) in the cost function.
See also
obs2y, copy_obs, cost_function, set_cov_apr
Note
  • Only finite observation elements are considered; invalid values are set to NAN.
  • Units correspond to the observation quantity:
    • Radiance: [W/(m²·sr·cm⁻¹)]
    • Brightness temperature: [K]
  • The forward model error is always relative, expressed in percent (%).
Warning
  • A zero or negative uncertainty triggers a runtime error.
  • Assumes obs and ctl are consistent in dimension and indexing.
Author
Lars Hoffmann

Definition at line 6587 of file jurassic.c.

6593 {
6594
6595 /* Allocate... */
6596 obs_t *obs_err;
6597 ALLOC(obs_err, obs_t, 1);
6598
6599 /* Get size... */
6600 const size_t m = sig_eps_inv->size;
6601
6602 /* Noise error (always considered in retrieval fit)... */
6603 copy_obs(ctl, obs_err, obs, 1);
6604 for (int ir = 0; ir < obs_err->nr; ir++)
6605 for (int id = 0; id < ctl->nd; id++)
6606 obs_err->rad[id][ir]
6607 = (isfinite(obs->rad[id][ir]) ? ret->err_noise[id] : NAN);
6608 obs2y(ctl, obs_err, sig_noise, NULL, NULL);
6609
6610 /* Forward model error (always considered in retrieval fit)... */
6611 copy_obs(ctl, obs_err, obs, 1);
6612 for (int ir = 0; ir < obs_err->nr; ir++)
6613 for (int id = 0; id < ctl->nd; id++)
6614 obs_err->rad[id][ir]
6615 = fabs(ret->err_formod[id] / 100 * obs->rad[id][ir]);
6616 obs2y(ctl, obs_err, sig_formod, NULL, NULL);
6617
6618 /* Total error... */
6619 for (size_t i = 0; i < m; i++)
6620 gsl_vector_set(sig_eps_inv, i, 1 / sqrt(POW2(gsl_vector_get(sig_noise, i))
6621 +
6622 POW2(gsl_vector_get
6623 (sig_formod, i))));
6624
6625 /* Check standard deviations... */
6626 for (size_t i = 0; i < m; i++)
6627 if (gsl_vector_get(sig_eps_inv, i) <= 0)
6628 ERRMSG("Check measurement errors (zero standard deviation)!");
6629
6630 /* Free... */
6631 free(obs_err);
6632}
Here is the call graph for this function:

◆ tangent_point()

void tangent_point ( const los_t los,
double *  tpz,
double *  tplon,
double *  tplat 
)

Determine the tangent point along a line of sight (LOS).

Computes the location of the tangent point — the point of minimum altitude — along the current line of sight, based on the LOS geometry stored in los_t.

Parameters
[in]losPointer to the line-of-sight (LOS) structure containing altitude, longitude, latitude, and segment length data.
[out]tpzPointer to variable receiving tangent point altitude [km].
[out]tplonPointer to variable receiving tangent point longitude [deg].
[out]tplatPointer to variable receiving tangent point latitude [deg].
  • For limb or occultation geometry, the routine:
    1. Identifies the LOS grid point with minimum altitude.
    2. Fits a quadratic interpolation polynomial: \( z = a x^2 + b x + c \) through the altitudes of the three neighboring LOS points.
    3. Solves analytically for the vertex position \( x = -b / (2a) \), corresponding to the tangent point.
    4. Converts this interpolated position back to geographic coordinates.
  • For nadir or zenith viewing (minimum altitude at the LOS endpoint), the tangent point defaults to the last grid point.
See also
raytrace, geo2cart, cart2geo, los_t
Note
  • The LOS segment lengths (ds) must be consistent with the geometric spacing between altitude points for the interpolation to be accurate.
  • The quadratic interpolation provides sub-kilometer precision for smooth limb rays.
  • Longitude and latitude are returned in degrees.
Warning
  • If the LOS contains fewer than three valid points, or the geometry is strongly curved, the tangent point estimate may be unreliable.
Author
Lars Hoffmann

Definition at line 6636 of file jurassic.c.

6640 {
6641
6642 /* Find minimum altitude... */
6643 const size_t ip = gsl_stats_min_index(los->z, 1, (size_t) los->np);
6644
6645 /* Nadir or zenith... */
6646 if (ip <= 0 || ip >= (size_t) los->np - 1) {
6647 *tpz = los->z[los->np - 1];
6648 *tplon = los->lon[los->np - 1];
6649 *tplat = los->lat[los->np - 1];
6650 }
6651
6652 /* Limb... */
6653 else {
6654
6655 /* Determine interpolating polynomial y=a*x^2+b*x+c... */
6656 const double yy0 = los->z[ip - 1];
6657 const double yy1 = los->z[ip];
6658 const double yy2 = los->z[ip + 1];
6659 const double x1 = sqrt(POW2(los->ds[ip]) - POW2(yy1 - yy0));
6660 const double x2 = x1 + sqrt(POW2(los->ds[ip + 1]) - POW2(yy2 - yy1));
6661 const double a = 1 / (x1 - x2) * (-(yy0 - yy1) / x1 + (yy0 - yy2) / x2);
6662 const double b = -(yy0 - yy1) / x1 - a * x1;
6663 const double c = yy0;
6664
6665 /* Get tangent point location... */
6666 double dummy, v[3], v0[3], v2[3];
6667 const double x = -b / (2 * a);
6668 *tpz = a * x * x + b * x + c;
6669 geo2cart(los->z[ip - 1], los->lon[ip - 1], los->lat[ip - 1], v0);
6670 geo2cart(los->z[ip + 1], los->lon[ip + 1], los->lat[ip + 1], v2);
6671 for (int i = 0; i < 3; i++)
6672 v[i] = LIN(0.0, v0[i], x2, v2[i], x);
6673 cart2geo(v, &dummy, tplon, tplat);
6674 }
6675}
Here is the call graph for this function:

◆ tbl_free()

void tbl_free ( const ctl_t ctl,
tbl_t tbl 
)

Free lookup table and all internally allocated memory.

Frees all dynamically allocated memory owned by a tbl_t object, including the spectral lookup arrays (logu and logeps) for all detector/emitter/pressure/temperature combinations. The tbl_t structure itself is freed at the end.

The function is safe to call with a NULL pointer and will return immediately in that case. Partially initialized tables are handled safely.

Parameters
[in,out]tblPointer to the lookup table to be freed.
[in]ctlControl structure providing the number of detectors and emitters used for looping.
Note
This function must be used instead of free(tbl) since tbl_t contains nested dynamically allocated members.
Author
Lars Hoffmann

Definition at line 6679 of file jurassic.c.

6681 {
6682
6683 /* Check pointer... */
6684 if (!tbl)
6685 return;
6686
6687 /* Loop over channels and emitters... */
6688 for (int id = 0; id < ctl->nd; id++)
6689 for (int ig = 0; ig < ctl->ng; ig++) {
6690
6691 /* Check number of pressure levels... */
6692 const int np = tbl->np[id][ig];
6693 if (np < 0)
6694 continue;
6695
6696 /* Loop over pressure levels... */
6697 for (int ip = 0; ip < np; ip++) {
6698
6699 /* Loop over temperature levels... */
6700 const int nt = tbl->nt[id][ig][ip];
6701 for (int it = 0; it < nt; it++) {
6702
6703 /* Free... */
6704 free(tbl->logu[id][ig][ip][it]);
6705 free(tbl->logeps[id][ig][ip][it]);
6706 tbl->logu[id][ig][ip][it] = NULL;
6707 tbl->logeps[id][ig][ip][it] = NULL;
6708 }
6709 }
6710 }
6711
6712 /* Free... */
6713 free(tbl);
6714}

◆ tbl_pack()

void tbl_pack ( const tbl_t tbl,
int  id,
int  ig,
uint8_t *  buf,
size_t *  bytes_used 
)

Pack a lookup table into a contiguous binary buffer.

This function serializes the lookup table data for a given detector (id) and emitter (ig) into a compact, platform-native binary representation. The packed data can be written to disk (e.g., in a NetCDF variable) and later reconstructed using tbl_unpack().

The packed layout in buf is, in order:

  • int np : number of pressure grid points
  • double p[np] : pressure grid
  • for each pressure index ip:
    • int nt : number of temperature grid points
    • double t[nt] : temperature grid
    • for each temperature index it:
      • int nu : number of spectral grid points
      • float u[nu] : spectral values
      • float eps[nu] : associated epsilon values

No byte-order conversion or padding is applied; the data are written exactly as laid out in memory.

Parameters
[in]tblTable structure containing the lookup data.
[in]idDetector index.
[in]igEmitter index.
[out]bufDestination buffer that will receive the packed binary data.
[out]bytes_usedNumber of bytes written to buf.
Warning
The caller must ensure that buf is large enough to hold the packed data for the selected detector/emitter pair. The packed representation includes the detector filter function (mandatory for binary/netCDF formats). No bounds checking is performed inside this function.
See also
tbl_unpack()
Author
Lars Hoffmann

Definition at line 6718 of file jurassic.c.

6723 {
6724
6725 uint8_t *cur = buf;
6726
6727 /* Pack lookup table... */
6728 int np = tbl->np[id][ig];
6729 memcpy(cur, &np, sizeof(np));
6730 cur += sizeof(np);
6731
6732 memcpy(cur, tbl->p[id][ig], (size_t) np * sizeof(double));
6733 cur += ((size_t) np * sizeof(double));
6734
6735 for (int ip = 0; ip < np; ip++) {
6736 int nt = tbl->nt[id][ig][ip];
6737 memcpy(cur, &nt, sizeof(nt));
6738 cur += sizeof(nt);
6739
6740 memcpy(cur, tbl->t[id][ig][ip], (size_t) nt * sizeof(double));
6741 cur += ((size_t) nt * sizeof(double));
6742
6743 for (int it = 0; it < nt; it++) {
6744 int nu = tbl->nu[id][ig][ip][it];
6745 memcpy(cur, &nu, sizeof(nu));
6746 cur += sizeof(nu);
6747
6748 memcpy(cur, tbl->logu[id][ig][ip][it], (size_t) nu * sizeof(float));
6749 cur += ((size_t) nu * sizeof(float));
6750
6751 memcpy(cur, tbl->logeps[id][ig][ip][it], (size_t) nu * sizeof(float));
6752 cur += ((size_t) nu * sizeof(float));
6753 }
6754 }
6755
6756 /* Pack filter function... */
6757 const int n = tbl->filt_n[id];
6758 memcpy(cur, &n, sizeof(n));
6759 cur += sizeof(n);
6760
6761 memcpy(cur, tbl->filt_nu[id], (size_t) n * sizeof(double));
6762 cur += ((size_t) n * sizeof(double));
6763
6764 memcpy(cur, tbl->filt_f[id], (size_t) n * sizeof(double));
6765 cur += ((size_t) n * sizeof(double));
6766
6767 *bytes_used = (size_t) (cur - buf);
6768}

◆ tbl_packed_size()

size_t tbl_packed_size ( const tbl_t tbl,
int  id,
int  ig 
)

Compute required buffer size (in bytes) for tbl_pack().

Returns the exact number of bytes that tbl_pack() will write for the given detector/emitter pair (including the mandatory filter function).

See also
tbl_pack()
Author
Lars Hoffmann

Definition at line 6772 of file jurassic.c.

6775 {
6776
6777 size_t bytes = 0;
6778
6779 /* Size of lookup table... */
6780 const int np = tbl->np[id][ig];
6781 bytes += sizeof(int);
6782 bytes += ((size_t) np * sizeof(double));
6783
6784 for (int ip = 0; ip < np; ip++) {
6785 const int nt = tbl->nt[id][ig][ip];
6786 bytes += sizeof(int);
6787 bytes += ((size_t) nt * sizeof(double));
6788
6789 for (int it = 0; it < nt; it++) {
6790 const int nu = tbl->nu[id][ig][ip][it];
6791 bytes += sizeof(int);
6792 bytes += (2 * (size_t) nu * sizeof(float));
6793 }
6794 }
6795
6796 /* Size of filter function... */
6797 const int n = tbl->filt_n[id];
6798 bytes += sizeof(int);
6799 bytes += (2 * (size_t) n * sizeof(double));
6800
6801 return bytes;
6802}

◆ tbl_unpack()

size_t tbl_unpack ( tbl_t tbl,
int  id,
int  ig,
const uint8_t *  buf 
)

Unpack a lookup table from a contiguous binary buffer.

This function reconstructs the lookup table data for a given detector (id) and emitter (ig) from a binary buffer previously produced by tbl_pack(). The packed data are read sequentially and copied into the corresponding fields of the tbl structure.

The expected layout of buf is:

  • int np
  • double p[np]
  • for each pressure index ip:
    • int nt
    • double t[nt]
    • for each temperature index it:
      • int nu
      • float u[nu]
      • float eps[nu]

Range checks are applied to np, nt, and nu against the compile-time limits TBLNP, TBLNT, and TBLNU to prevent buffer overruns and invalid table sizes.

Parameters
[in,out]tblTable structure that will receive the unpacked data.
[in]idDetector index.
[in]igEmitter index.
[in]bufSource buffer containing the packed binary table.
Returns
The number of bytes consumed from buf.
Warning
The buffer must contain a valid packed table created by tbl_pack(). Supplying malformed or truncated data will result in undefined behavior or an error.
See also
tbl_pack()
Author
Lars Hoffmann

Definition at line 6806 of file jurassic.c.

6810 {
6811
6812 const uint8_t *cur = buf;
6813
6814 /* Unpack lookup table... */
6815 int np;
6816 memcpy(&np, cur, sizeof(np));
6817 cur += sizeof(np);
6818
6819 if (np < 0 || np > TBLNP)
6820 ERRMSG("np out of range!");
6821 tbl->np[id][ig] = np;
6822
6823 memcpy(tbl->p[id][ig], cur, (size_t) np * sizeof(double));
6824 cur += ((size_t) np * sizeof(double));
6825
6826 for (int ip = 0; ip < np; ip++) {
6827
6828 int nt;
6829 memcpy(&nt, cur, sizeof(nt));
6830 cur += sizeof(nt);
6831
6832 if (nt < 0 || nt > TBLNT)
6833 ERRMSG("nt out of range!");
6834 tbl->nt[id][ig][ip] = nt;
6835
6836 memcpy(tbl->t[id][ig][ip], cur, (size_t) nt * sizeof(double));
6837 cur += ((size_t) nt * sizeof(double));
6838
6839 for (int it = 0; it < nt; it++) {
6840
6841 int nu;
6842 memcpy(&nu, cur, sizeof(nu));
6843 cur += sizeof(nu);
6844
6845 if (nu < 0 || nu > TBLNU)
6846 ERRMSG("nu out of range!");
6847 tbl->nu[id][ig][ip][it] = nu;
6848
6849 ALLOC(tbl->logu[id][ig][ip][it], float,
6850 nu);
6851 ALLOC(tbl->logeps[id][ig][ip][it], float,
6852 nu);
6853
6854 memcpy(tbl->logu[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
6855 cur += ((size_t) nu * sizeof(float));
6856
6857 memcpy(tbl->logeps[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
6858 cur += ((size_t) nu * sizeof(float));
6859 }
6860 }
6861
6862 /* Unpack filter function... */
6863 int n;
6864 memcpy(&n, cur, sizeof(n));
6865 cur += sizeof(n);
6866
6867 if (n < 2 || n > NSHAPE)
6868 ERRMSG("Missing or invalid filter function (filt_n) in packed table!");
6869 tbl->filt_n[id] = n;
6870
6871 memcpy(tbl->filt_nu[id], cur, (size_t) n * sizeof(double));
6872 cur += ((size_t) n * sizeof(double));
6873
6874 memcpy(tbl->filt_f[id], cur, (size_t) n * sizeof(double));
6875 cur += ((size_t) n * sizeof(double));
6876
6877 return (size_t) (cur - buf);
6878}

◆ time2jsec()

void time2jsec ( const int  year,
const int  mon,
const int  day,
const int  hour,
const int  min,
const int  sec,
const double  remain,
double *  jsec 
)

Converts time components to seconds since January 1, 2000, 12:00:00 UTC.

This function calculates the number of seconds elapsed since January 1, 2000, 12:00:00 UTC, based on the provided year, month, day, hour, minute, and second. It also includes a fractional part to represent the remaining seconds.

Parameters
yearThe year.
monThe month (1-12).
dayThe day of the month (1-31).
hourThe hour of the day (0-23).
minThe minute (0-59).
secThe second (0-59).
remainThe fractional part of seconds.
jsecPointer to store the calculated number of seconds since January 1, 2000, 12:00:00 UTC.

The function calculates the time elapsed since January 1, 2000, 12:00:00 UTC, up to the specified time and includes any fractional seconds indicated by the "remain" parameter.

Note
The function uses the timegm function, which is similar to mktime but operates in UTC.
Author
Lars Hoffmann

Definition at line 6882 of file jurassic.c.

6890 {
6891
6892 struct tm t0, t1;
6893
6894 t0.tm_year = 100;
6895 t0.tm_mon = 0;
6896 t0.tm_mday = 1;
6897 t0.tm_hour = 0;
6898 t0.tm_min = 0;
6899 t0.tm_sec = 0;
6900
6901 t1.tm_year = year - 1900;
6902 t1.tm_mon = mon - 1;
6903 t1.tm_mday = day;
6904 t1.tm_hour = hour;
6905 t1.tm_min = min;
6906 t1.tm_sec = sec;
6907
6908 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
6909}

◆ timer()

void timer ( const char *  name,
const char *  file,
const char *  func,
int  line,
int  mode 
)

Simple wall-clock timer for runtime diagnostics.

Provides a lightweight timing utility based on omp_get_wtime() to measure wall-clock durations between marked code regions. The function supports up to ten concurrent nested timers.

Parameters
[in]nameName or label of the timed code section.
[in]fileSource file name (usually __FILE__ macro).
[in]funcFunction name (usually __func__ macro).
[in]lineSource line number (usually __LINE__ macro).
[in]modeTimer operation mode:
  • 1: Start new timer.
  • 2: Write elapsed time since last start (without stopping).
  • 3: Write elapsed time and stop timer (pop one level).
  • Each call with mode == 1 starts a new timer instance and stores its start time and corresponding source line.
  • When mode == 2 or mode == 3 is called, the elapsed wall-clock time (in seconds) is computed using:

    \[ \Delta t = t_{\text{now}} - t_{\text{start}} \]

    and written to the log via the LOG macro.
  • Supports nested timers (up to 10 levels). Exceeding this limit triggers a runtime error via ERRMSG.
See also
LOG, ERRMSG, omp_get_wtime
Note
  • The timing precision and resolution depend on the OpenMP runtime.
  • Intended for coarse profiling and diagnostic output; not thread-safe.
  • Lines reported in log messages indicate the start–stop interval.
Warning
  • Exceeding 10 nested timers results in an error.
  • Calling mode == 2 or 3 without a prior start causes an internal error.
Author
Lars Hoffmann

Definition at line 6913 of file jurassic.c.

6918 {
6919
6920 static double w0[10];
6921
6922 static int l0[10], nt;
6923
6924 /* Start new timer... */
6925 if (mode == 1) {
6926 w0[nt] = omp_get_wtime();
6927 l0[nt] = line;
6928 if ((++nt) >= 10)
6929 ERRMSG("Too many timers!");
6930 }
6931
6932 /* Write elapsed time... */
6933 else {
6934
6935 /* Check timer index... */
6936 if (nt - 1 < 0)
6937 ERRMSG("Coding error!");
6938
6939 /* Write elapsed time... */
6940 LOG(1, "Timer '%s' (%s, %s, l%d-%d): %.3f sec",
6941 name, file, func, l0[nt - 1], line, omp_get_wtime() - w0[nt - 1]);
6942 }
6943
6944 /* Stop timer... */
6945 if (mode == 3)
6946 nt--;
6947}

◆ write_atm()

void write_atm ( const char *  dirname,
const char *  filename,
const ctl_t ctl,
const atm_t atm 
)

Write atmospheric data to a file.

This function writes the atmospheric dataset stored in atm to the file specified by filename, optionally prefixed by dirname. The output format (ASCII or binary) is selected based on the atmospheric format flag ctl->atmfmt. The function creates the output file, delegates the writing process to the appropriate format-specific routine, and logs summary statistics of the written atmospheric data.

Supported output formats:

The function writes:

  • Atmospheric profiles: time, altitude, longitude, latitude, pressure, temperature
  • Gas mixing ratios for each emitter (ctl->ng)
  • Extinction coefficients for each spectral window (ctl->nw)
  • Optional cloud layer or surface parameters if enabled in ctl

After writing, the function logs minimum and maximum values of the written fields for verification and diagnostic purposes.

Parameters
dirnameOptional directory in which the output file will be created. If NULL, only filename is used.
filenameName of the output file to be created and populated with atmospheric data.
ctlPointer to a control structure defining the output format and the sizes of gas, spectral, cloud, and surface parameter arrays.
atmPointer to the atmospheric data structure whose contents will be written. All required fields must be initialized and contain atm->np valid data points.
Note
The function aborts execution using ERRMSG if the file cannot be created or if an unsupported output format is requested.
Author
Lars Hoffmann

Definition at line 6951 of file jurassic.c.

6955 {
6956
6957 /* Set filename... */
6958 char file[LEN];
6959 if (dirname != NULL)
6960 sprintf(file, "%s/%s", dirname, filename);
6961 else
6962 sprintf(file, "%s", filename);
6963
6964 /* Write info... */
6965 LOG(1, "Write atmospheric data: %s", file);
6966
6967 /* Write ASCII data... */
6968 if (ctl->atmfmt == 1)
6969 write_atm_asc(file, ctl, atm);
6970
6971 /* Write binary data... */
6972 else if (ctl->atmfmt == 2)
6973 write_atm_bin(file, ctl, atm);
6974
6975 /* Write netCDF data... */
6976 else if (ctl->atmfmt == 3)
6977 write_atm_nc(file, ctl, atm, 0);
6978
6979 /* Error... */
6980 else
6981 ERRMSG("Unknown file format, check ATMFMT!");
6982
6983 /* Write info... */
6984 double mini, maxi;
6985 LOG(2, "Number of data points: %d", atm->np);
6986 gsl_stats_minmax(&mini, &maxi, atm->time, 1, (size_t) atm->np);
6987 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
6988 gsl_stats_minmax(&mini, &maxi, atm->z, 1, (size_t) atm->np);
6989 LOG(2, "Altitude range: %g ... %g km", mini, maxi);
6990 gsl_stats_minmax(&mini, &maxi, atm->lon, 1, (size_t) atm->np);
6991 LOG(2, "Longitude range: %g ... %g deg", mini, maxi);
6992 gsl_stats_minmax(&mini, &maxi, atm->lat, 1, (size_t) atm->np);
6993 LOG(2, "Latitude range: %g ... %g deg", mini, maxi);
6994 gsl_stats_minmax(&mini, &maxi, atm->p, 1, (size_t) atm->np);
6995 LOG(2, "Pressure range: %g ... %g hPa", maxi, mini);
6996 gsl_stats_minmax(&mini, &maxi, atm->t, 1, (size_t) atm->np);
6997 LOG(2, "Temperature range: %g ... %g K", mini, maxi);
6998 for (int ig = 0; ig < ctl->ng; ig++) {
6999 gsl_stats_minmax(&mini, &maxi, atm->q[ig], 1, (size_t) atm->np);
7000 LOG(2, "Emitter %s range: %g ... %g ppv", ctl->emitter[ig], mini, maxi);
7001 }
7002 for (int iw = 0; iw < ctl->nw; iw++) {
7003 gsl_stats_minmax(&mini, &maxi, atm->k[iw], 1, (size_t) atm->np);
7004 LOG(2, "Extinction range (window %d): %g ... %g km^-1", iw, mini, maxi);
7005 }
7006 if (ctl->ncl > 0) {
7007 LOG(2, "Cloud layer: z= %g km | dz= %g km | k= %g ... %g km^-1",
7008 atm->clz, atm->cldz, atm->clk[0], atm->clk[ctl->ncl - 1]);
7009 } else
7010 LOG(2, "Cloud layer: none");
7011 if (ctl->nsf > 0) {
7012 LOG(2,
7013 "Surface: T_s = %g K | eps= %g ... %g",
7014 atm->sft, atm->sfeps[0], atm->sfeps[ctl->nsf - 1]);
7015 } else
7016 LOG(2, "Surface: none");
7017}
void write_atm_nc(const char *filename, const ctl_t *ctl, const atm_t *atm, int profile)
Write one atmospheric profile to a netCDF file.
Definition: jurassic.c:7172
void write_atm_asc(const char *filename, const ctl_t *ctl, const atm_t *atm)
Write atmospheric data to an ASCII file.
Definition: jurassic.c:7021
void write_atm_bin(const char *filename, const ctl_t *ctl, const atm_t *atm)
Write atmospheric data to a binary file.
Definition: jurassic.c:7088
Here is the call graph for this function:

◆ write_atm_asc()

void write_atm_asc ( const char *  filename,
const ctl_t ctl,
const atm_t atm 
)

Write atmospheric data to an ASCII file.

This function writes the contents of an atmospheric structure atm to an ASCII file specified by its filename. A descriptive column header is written first, documenting the meaning, units, and ordering of each data field. Atmospheric data points are then written line by line, with optional cloud and surface layer parameters appended if they are enabled in the control structure ctl.

The output columns include, in order:

  1. Time (seconds since 2000-01-01T00:00Z)
  2. Altitude [km]
  3. Longitude [deg]
  4. Latitude [deg]
  5. Pressure [hPa]
  6. Temperature [K]
  • Gas/emitter mixing ratios for each species (ctl->ng) [ppv]
  • Extinction values for each spectral window (ctl->nw) [km^-1]

If cloud layer properties are enabled (ctl->ncl > 0), the following are added:

  • Cloud layer height [km]
  • Cloud layer depth [km]
  • Cloud extinction values for each frequency (ctl->ncl) [km^-1]

If surface layer properties are enabled (ctl->nsf > 0), the following are added:

  • Surface layer height [km]
  • Surface layer pressure [hPa]
  • Surface layer temperature [K]
  • Surface emissivity values (ctl->nsf)
Parameters
filenamePath to the ASCII output file.
ctlPointer to a control structure defining the number of gases, spectral windows, and whether cloud or surface layer information should be included.
atmPointer to the atmospheric structure containing the data to be written. The function writes all atm->np data points.
Note
A blank line is inserted each time the time coordinate changes, grouping data points belonging to different timestamps.
Warning
The function assumes that all arrays in atm are properly allocated and populated. No validation of data ranges is performed here.
Author
Lars Hoffmann

Definition at line 7021 of file jurassic.c.

7024 {
7025
7026 int n = 6;
7027
7028 /* Create file... */
7029 FILE *out;
7030 if (!(out = fopen(filename, "w")))
7031 ERRMSG("Cannot create file!");
7032
7033 /* Write header... */
7034 fprintf(out,
7035 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
7036 "# $2 = altitude [km]\n"
7037 "# $3 = longitude [deg]\n"
7038 "# $4 = latitude [deg]\n"
7039 "# $5 = pressure [hPa]\n" "# $6 = temperature [K]\n");
7040 for (int ig = 0; ig < ctl->ng; ig++)
7041 fprintf(out, "# $%d = %s volume mixing ratio [ppv]\n",
7042 ++n, ctl->emitter[ig]);
7043 for (int iw = 0; iw < ctl->nw; iw++)
7044 fprintf(out, "# $%d = extinction (window %d) [km^-1]\n", ++n, iw);
7045 if (ctl->ncl > 0) {
7046 fprintf(out, "# $%d = cloud layer height [km]\n", ++n);
7047 fprintf(out, "# $%d = cloud layer depth [km]\n", ++n);
7048 for (int icl = 0; icl < ctl->ncl; icl++)
7049 fprintf(out, "# $%d = cloud layer extinction (%.4f cm^-1) [km^-1]\n",
7050 ++n, ctl->clnu[icl]);
7051 }
7052 if (ctl->nsf > 0) {
7053 fprintf(out, "# $%d = surface temperature [K]\n", ++n);
7054 for (int isf = 0; isf < ctl->nsf; isf++)
7055 fprintf(out, "# $%d = surface emissivity (%.4f cm^-1)\n",
7056 ++n, ctl->sfnu[isf]);
7057 }
7058
7059 /* Write data... */
7060 for (int ip = 0; ip < atm->np; ip++) {
7061 if (ip == 0 || atm->time[ip] != atm->time[ip - 1])
7062 fprintf(out, "\n");
7063 fprintf(out, "%.2f %g %g %g %g %g", atm->time[ip], atm->z[ip],
7064 atm->lon[ip], atm->lat[ip], atm->p[ip], atm->t[ip]);
7065 for (int ig = 0; ig < ctl->ng; ig++)
7066 fprintf(out, " %g", atm->q[ig][ip]);
7067 for (int iw = 0; iw < ctl->nw; iw++)
7068 fprintf(out, " %g", atm->k[iw][ip]);
7069 if (ctl->ncl > 0) {
7070 fprintf(out, " %g %g", atm->clz, atm->cldz);
7071 for (int icl = 0; icl < ctl->ncl; icl++)
7072 fprintf(out, " %g", atm->clk[icl]);
7073 }
7074 if (ctl->nsf > 0) {
7075 fprintf(out, " %g", atm->sft);
7076 for (int isf = 0; isf < ctl->nsf; isf++)
7077 fprintf(out, " %g", atm->sfeps[isf]);
7078 }
7079 fprintf(out, "\n");
7080 }
7081
7082 /* Close file... */
7083 fclose(out);
7084}

◆ write_atm_bin()

void write_atm_bin ( const char *  filename,
const ctl_t ctl,
const atm_t atm 
)

Write atmospheric data to a binary file.

This function writes the atmospheric dataset contained in atm to a binary file specified by its filename. The output format is compact and includes a file header followed by the serialized atmospheric fields. The format is compatible with read_atm_bin(), ensuring that files written by this function can be read back without loss of information.

The binary file structure written is as follows:

  1. Magic identifier "ATM1" (4 bytes)
  2. Header integers describing dataset layout:
    • Number of gas/emitter species (ctl->ng)
    • Number of spectral windows (ctl->nw)
    • Number of cloud extinction values (ctl->ncl)
    • Number of surface emissivity values (ctl->nsf)
  3. Data payload:
    • Number of atmospheric points np
    • Arrays of length np containing:
      • Time
      • Altitude
      • Longitude
      • Latitude
      • Pressure
      • Temperature
    • Gas mixing ratios for all emitters (ctl->ng × np)
    • Extinction coefficients for all spectral windows (ctl->nw × np)
  4. Optional parameters written only if enabled in ctl:
    • Cloud layer height, depth, and extinction values (ctl->ncl)
    • Surface temperature and emissivity values (ctl->nsf)
Parameters
filenamePath to the binary output file.
ctlPointer to a control structure specifying the number of gases, spectral windows, and whether cloud or surface layer parameters must be included.
atmPointer to the atmospheric data structure containing values to be written. All arrays must be populated and atm->np must contain the number of valid atmospheric records.
Note
This function performs no range checking or validation of the atm contents. It assumes that the memory layout matches expectations.
Warning
The binary structure must remain consistent with read_atm_bin(); modifying either implementation requires updating the other accordingly.
Author
Lars Hoffmann

Definition at line 7088 of file jurassic.c.

7091 {
7092
7093 /* Create file... */
7094 FILE *out;
7095 if (!(out = fopen(filename, "w")))
7096 ERRMSG("Cannot create file!");
7097
7098 /* Write header... */
7099 FWRITE("ATM1", char,
7100 4,
7101 out);
7102 FWRITE(&ctl->ng, int,
7103 1,
7104 out);
7105 FWRITE(&ctl->nw, int,
7106 1,
7107 out);
7108 FWRITE(&ctl->ncl, int,
7109 1,
7110 out);
7111 FWRITE(&ctl->nsf, int,
7112 1,
7113 out);
7114
7115 /* Write data... */
7116 size_t np = (size_t) atm->np;
7117 FWRITE(&np, size_t,
7118 1,
7119 out);
7120 FWRITE(atm->time, double,
7121 np,
7122 out);
7123 FWRITE(atm->z, double,
7124 np,
7125 out);
7126 FWRITE(atm->lon, double,
7127 np,
7128 out);
7129 FWRITE(atm->lat, double,
7130 np,
7131 out);
7132 FWRITE(atm->p, double,
7133 np,
7134 out);
7135 FWRITE(atm->t, double,
7136 np,
7137 out);
7138 for (int ig = 0; ig < ctl->ng; ig++)
7139 FWRITE(atm->q[ig], double,
7140 np,
7141 out);
7142 for (int iw = 0; iw < ctl->nw; iw++)
7143 FWRITE(atm->k[iw], double,
7144 np,
7145 out);
7146 if (ctl->ncl > 0) {
7147 FWRITE(&atm->clz, double,
7148 1,
7149 out);
7150 FWRITE(&atm->cldz, double,
7151 1,
7152 out);
7153 FWRITE(atm->clk, double,
7154 (size_t) ctl->ncl,
7155 out);
7156 }
7157 if (ctl->nsf > 0) {
7158 FWRITE(&atm->sft, double,
7159 1,
7160 out);
7161 FWRITE(atm->sfeps, double,
7162 (size_t) ctl->nsf,
7163 out);
7164 }
7165
7166 /* Close file... */
7167 fclose(out);
7168}
#define FWRITE(ptr, type, size, out)
Write binary data to a file.
Definition: jurassic.h:543

◆ write_atm_nc()

void write_atm_nc ( const char *  filename,
const ctl_t ctl,
const atm_t atm,
int  profile 
)

Write one atmospheric profile to a netCDF file.

This routine writes a single profile from an atm_t structure into a netCDF file using an unlimited record dimension. Multiple profiles can be stored in the same file by calling this function repeatedly with increasing profile indices.

The function creates the file if it does not exist (netCDF-4/HDF5) and defines missing dimensions/variables on the fly. Existing definitions are reused.

File layout

Dimensions:

  • profile : unlimited (record dimension)
  • level : fixed (maximum number of vertical levels stored in the file)

Variables:

  • nlev(profile) : number of valid levels for each profile (written as atm->np)
  • Core state (2-D): time,z,lon,lat,p,t(profile,level)
  • Trace gases (2-D): one variable per species named ctl->emitter[ig] with dimensions (profile,level)
  • Extinction windows (2-D): ext_win_d(profile,level)
  • Clouds (1-D, optional if ctl->ncl>0): cld_z, cld_dz, cld_k_d(profile)
  • Surface (1-D, optional if ctl->nsf>0): sf_t, sf_eps_d(profile)

Only the first atm->np elements along level are written for 2-D variables. The effective number of levels is stored in nlev(profile). (If a profile is overwritten with fewer levels than previously written, old values above nlev may remain unless explicitly filled by the caller.)

Parameters
filenameOutput netCDF file name.
ctlControl structure (defines numbers/names of optional fields, e.g., ng, nw, ncl, nsf, and emitter[]).
atmAtmospheric profile data to write (uses atm->np levels).
profileRecord index along the unlimited profile dimension.
Note
This function requires netCDF support (HAVE_NETCDF) and uses the netCDF C API. Errors are handled via the NC(...) macro.
Author
Lars Hoffmann

Definition at line 7172 of file jurassic.c.

7176 {
7177
7178 char longname[LEN], varname[LEN];
7179
7180 int ncid, varid, dim_profile, dim_level;
7181
7182 size_t level_max;
7183
7184 /* Open or create file... */
7185 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR)
7186 NC(nc_create(filename, NC_NETCDF4, &ncid));
7187
7188 /* Enter define mode... */
7189 int r = nc_redef(ncid);
7190 if (r != NC_NOERR && r != NC_EINDEFINE)
7191 NC(r);
7192
7193 /* Define profile dimension (unlimited)... */
7194 if (nc_inq_dimid(ncid, "profile", &dim_profile) != NC_NOERR)
7195 NC(nc_def_dim(ncid, "profile", NC_UNLIMITED, &dim_profile));
7196
7197 /* Define level dimension (fixed)... */
7198 if (nc_inq_dimid(ncid, "level", &dim_level) == NC_NOERR) {
7199 NC(nc_inq_dimlen(ncid, dim_level, &level_max));
7200 if (level_max < 1 || level_max > (size_t) NP)
7201 ERRMSG("netCDF dimension level is out of range!");
7202 if ((size_t) atm->np > level_max)
7203 ERRMSG("profile has too many levels!");
7204 } else {
7205 level_max = (size_t) atm->np;
7206 NC(nc_def_dim(ncid, "level", level_max, &dim_level));
7207 }
7208
7209 /* Set dimension IDs... */
7210 int dimids[2] = { dim_profile, dim_level };
7211
7212 /* Tunables for compression/quantization... */
7213 const int deflate_level = 0;
7214 const int quant_digits = 0;
7215
7216 /* Define nlev (1D)... */
7217 if (nc_inq_varid(ncid, "nlev", &varid) != NC_NOERR)
7218 NC_DEF_VAR("nlev", NC_INT, 1, dimids,
7219 "number of vertical levels", "1", 0, 0);
7220
7221 /* Define core variables (2D)... */
7222 if (nc_inq_varid(ncid, "time", &varid) != NC_NOERR)
7223 NC_DEF_VAR("time", NC_DOUBLE, 2, dimids,
7224 "time in seconds since 2000-01-01, 00:00 UTC", "s",
7225 deflate_level, 0);
7226
7227 if (nc_inq_varid(ncid, "z", &varid) != NC_NOERR)
7228 NC_DEF_VAR("z", NC_DOUBLE, 2, dimids, "altitude", "km", deflate_level, 0);
7229
7230 if (nc_inq_varid(ncid, "lon", &varid) != NC_NOERR)
7231 NC_DEF_VAR("lon", NC_DOUBLE, 2, dimids,
7232 "longitude", "degrees_east", deflate_level, 0);
7233
7234 if (nc_inq_varid(ncid, "lat", &varid) != NC_NOERR)
7235 NC_DEF_VAR("lat", NC_DOUBLE, 2, dimids,
7236 "latitude", "degrees_north", deflate_level, 0);
7237
7238 if (nc_inq_varid(ncid, "p", &varid) != NC_NOERR)
7239 NC_DEF_VAR("p", NC_DOUBLE, 2, dimids,
7240 "pressure", "hPa", deflate_level, quant_digits);
7241
7242 if (nc_inq_varid(ncid, "t", &varid) != NC_NOERR)
7243 NC_DEF_VAR("t", NC_DOUBLE, 2, dimids,
7244 "temperature", "K", deflate_level, quant_digits);
7245
7246 /* Write emitters (2D)... */
7247 for (int ig = 0; ig < ctl->ng; ig++)
7248 if (nc_inq_varid(ncid, ctl->emitter[ig], &varid) != NC_NOERR) {
7249 sprintf(longname, "%s volume mixing ratio", ctl->emitter[ig]);
7250 NC_DEF_VAR(ctl->emitter[ig], NC_DOUBLE, 2, dimids,
7251 longname, "ppv", deflate_level, quant_digits);
7252 }
7253
7254 /* Write extinction (2D)... */
7255 for (int iw = 0; iw < ctl->nw; iw++) {
7256 sprintf(varname, "ext_win_%d", iw);
7257 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7258 sprintf(longname, "extinction (window %d)", iw);
7259 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids,
7260 longname, "km**-1", deflate_level, quant_digits);
7261 }
7262 }
7263
7264 /* Write cloud variables (1D)... */
7265 if (ctl->ncl > 0) {
7266 if (nc_inq_varid(ncid, "cld_z", &varid) != NC_NOERR)
7267 NC_DEF_VAR("cld_z", NC_DOUBLE, 1, dimids,
7268 "cloud layer height", "km", deflate_level, quant_digits);
7269
7270 if (nc_inq_varid(ncid, "cld_dz", &varid) != NC_NOERR)
7271 NC_DEF_VAR("cld_dz", NC_DOUBLE, 1, dimids,
7272 "cloud layer depth", "km", deflate_level, quant_digits);
7273
7274 for (int icl = 0; icl < ctl->ncl; icl++) {
7275 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
7276 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7277 sprintf(longname, "cloud layer extinction (%.4f cm^-1)",
7278 ctl->clnu[icl]);
7279 NC_DEF_VAR(varname, NC_DOUBLE, 1, dimids, longname, "km**-1",
7280 deflate_level, quant_digits);
7281 }
7282 }
7283 }
7284
7285 /* Write surface variables (1D)... */
7286 if (ctl->nsf > 0) {
7287 if (nc_inq_varid(ncid, "srf_t", &varid) != NC_NOERR)
7288 NC_DEF_VAR("srf_t", NC_DOUBLE, 1, dimids,
7289 "surface temperature", "K", deflate_level, quant_digits);
7290
7291 for (int isf = 0; isf < ctl->nsf; isf++) {
7292 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
7293 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7294 sprintf(longname, "surface emissivity (%.4f cm^-1)", ctl->sfnu[isf]);
7295 NC_DEF_VAR(varname, NC_DOUBLE, 1, dimids, longname, "1",
7296 deflate_level, quant_digits);
7297 }
7298 }
7299 }
7300
7301 /* Leave define mode... */
7302 NC(nc_enddef(ncid));
7303
7304 /* Define hyperslabs... */
7305 size_t start[2] = { (size_t) profile, 0 };
7306 size_t count[2] = { 1, (size_t) atm->np };
7307
7308 /* Write nlev... */
7309 NC_PUT_INT("nlev", &atm->np, 1);
7310
7311 /* Write core variables... */
7312 NC_PUT_DOUBLE("time", atm->time, 1);
7313 NC_PUT_DOUBLE("z", atm->z, 1);
7314 NC_PUT_DOUBLE("lon", atm->lon, 1);
7315 NC_PUT_DOUBLE("lat", atm->lat, 1);
7316 NC_PUT_DOUBLE("p", atm->p, 1);
7317 NC_PUT_DOUBLE("t", atm->t, 1);
7318
7319 /* Write emitters... */
7320 for (int ig = 0; ig < ctl->ng; ig++)
7321 NC_PUT_DOUBLE(ctl->emitter[ig], atm->q[ig], 1);
7322
7323 /* Write extinction... */
7324 for (int iw = 0; iw < ctl->nw; iw++) {
7325 sprintf(varname, "ext_win_%d", iw);
7326 NC_PUT_DOUBLE(varname, atm->k[iw], 1);
7327 }
7328
7329 /* Write cloud variables... */
7330 if (ctl->ncl > 0) {
7331 NC_PUT_DOUBLE("cld_z", &atm->clz, 1);
7332 NC_PUT_DOUBLE("cld_dz", &atm->cldz, 1);
7333 for (int icl = 0; icl < ctl->ncl; icl++) {
7334 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
7335 NC_PUT_DOUBLE(varname, &atm->clk[icl], 1);
7336 }
7337 }
7338
7339 /* Write surface variables... */
7340 if (ctl->nsf > 0) {
7341 NC_PUT_DOUBLE("srf_t", &atm->sft, 1);
7342 for (int isf = 0; isf < ctl->nsf; isf++) {
7343 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
7344 NC_PUT_DOUBLE(varname, &atm->sfeps[isf], 1);
7345 }
7346 }
7347
7348 /* Close file... */
7349 NC(nc_sync(ncid));
7350 NC(nc_close(ncid));
7351}
#define NC_PUT_INT(varname, ptr, hyperslab)
Write integer data to a NetCDF variable.
Definition: jurassic.h:799
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
Definition: jurassic.h:668
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
Definition: jurassic.h:752

◆ write_atm_rfm()

void write_atm_rfm ( const char *  filename,
const ctl_t ctl,
const atm_t atm 
)

Write atmospheric profile in RFM-compatible format.

Exports the current atmospheric state to a file formatted for use with the Reference Forward Model (RFM). The file includes altitude, pressure, temperature, and volume mixing ratio profiles for each active emitter.

Parameters
[in]filenameOutput file name for the RFM atmosphere file.
[in]ctlPointer to the control structure defining active emitters.
[in]atmPointer to the atmospheric profile to export.
  • Produces a plain-text RFM atmosphere file with the following sections:
    NLAYERS
    *HGT [km]
    <altitude_1>
    ...
    *PRE [mb]
    <pressure_1>
    ...
    *TEM [K]
    <temperature_1>
    ...
    *<EMITTER> [ppmv]
    <mixing_ratio_1>
    ...
    *END
  • The first line specifies the number of vertical layers (atm->np).
  • Each subsequent block begins with a keyword (e.g., *HGT, *PRE, etc.) and lists one value per line.
  • Mixing ratios are converted from parts per volume (ppv) to parts per million (ppmv).
See also
read_atm, ctl_t, atm_t
Note
  • Compatible with the RFM “ATM” input file format.
  • Units:
    • Altitude in kilometers [km]
    • Pressure in millibars [mb]
    • Temperature in Kelvin [K]
    • Mixing ratios in parts per million by volume [ppmv]
Warning
  • Existing files with the same name will be overwritten.
  • The function assumes consistent vertical ordering (surface → top of atmosphere).
Author
Lars Hoffmann

Definition at line 7355 of file jurassic.c.

7358 {
7359
7360 /* Write info... */
7361 LOG(1, "Write RFM data: %s", filename);
7362
7363 /* Create file... */
7364 FILE *out;
7365 if (!(out = fopen(filename, "w")))
7366 ERRMSG("Cannot create file!");
7367
7368 /* Write data... */
7369 fprintf(out, "%d\n", atm->np);
7370 fprintf(out, "*HGT [km]\n");
7371 for (int ip = 0; ip < atm->np; ip++)
7372 fprintf(out, "%g\n", atm->z[ip]);
7373 fprintf(out, "*PRE [mb]\n");
7374 for (int ip = 0; ip < atm->np; ip++)
7375 fprintf(out, "%g\n", atm->p[ip]);
7376 fprintf(out, "*TEM [K]\n");
7377 for (int ip = 0; ip < atm->np; ip++)
7378 fprintf(out, "%g\n", atm->t[ip]);
7379 for (int ig = 0; ig < ctl->ng; ig++) {
7380 fprintf(out, "*%s [ppmv]\n", ctl->emitter[ig]);
7381 for (int ip = 0; ip < atm->np; ip++)
7382 fprintf(out, "%g\n", atm->q[ig][ip] * 1e6);
7383 }
7384 fprintf(out, "*END\n");
7385
7386 /* Close file... */
7387 fclose(out);
7388}

◆ write_matrix()

void write_matrix ( const char *  dirname,
const char *  filename,
const ctl_t ctl,
const gsl_matrix *  matrix,
const atm_t atm,
const obs_t obs,
const char *  rowspace,
const char *  colspace,
const char *  sort 
)

Write a fully annotated matrix (e.g., Jacobian or gain matrix) to file.

Outputs a numerical matrix along with detailed metadata describing the row and column spaces. Depending on configuration, the rows and columns may correspond to measurement or state variables.

Parameters
[in]dirnameOutput directory path (may be NULL).
[in]filenameOutput file name.
[in]ctlPointer to control structure defining model setup and metadata.
[in]matrixPointer to GSL matrix to write (e.g., Jacobian, kernel, or covariance).
[in]atmPointer to atmospheric data structure (used when state-space indexing applies).
[in]obsPointer to observation data structure (used when measurement-space indexing applies).
[in]rowspaceSelects row labeling: "y" = measurement space, otherwise state space.
[in]colspaceSelects column labeling: "y" = measurement space, otherwise state space.
[in]sortDetermines writing order: "r" = row-major, otherwise column-major.
  • This routine writes one matrix element per line, including descriptive metadata:
    RowIndex RowMeta... ColIndex ColMeta... MatrixValue
  • The row and column metadata differ depending on space selection:
    • **Measurement space (‘'y’`)**:
      • Channel wavenumber [cm⁻¹]
      • Observation time [s since 2000-01-01T00:00Z]
      • View point altitude [km], longitude [°], latitude [°]
    • State space:
      • Quantity name (e.g., TEMPERATURE, H2O)
      • Time, altitude, longitude, latitude of the profile point
  • The header clearly documents all output columns for traceability.
See also
read_matrix, kernel, atm2x, obs2y, idx2name
Note
  • The function respects ctl->write_matrix — output is skipped if disabled.
  • Output is human-readable and can be post-processed using external tools (e.g., Python, MATLAB, GNU Octave).
  • Typically used for writing Jacobians, gain matrices, or averaging kernels.
  • Matrix orientation can be changed with sort to support row-major or column-major output.
Warning
  • Large matrices may produce very large output files.
  • Memory allocation is performed for temporary indexing arrays; ensure sufficient resources for large N, M.
  • The function overwrites existing files without confirmation.
Author
Lars Hoffmann

Definition at line 7392 of file jurassic.c.

7401 {
7402
7403 char file[LEN], quantity[LEN];
7404
7405 int *cida, *ciqa, *cipa, *cira, *rida, *riqa, *ripa, *rira;
7406
7407 size_t i, j, nc, nr;
7408
7409 /* Check output flag... */
7410 if (!ctl->write_matrix)
7411 return;
7412
7413 /* Allocate... */
7414 ALLOC(cida, int,
7415 M);
7416 ALLOC(ciqa, int,
7417 N);
7418 ALLOC(cipa, int,
7419 N);
7420 ALLOC(cira, int,
7421 M);
7422 ALLOC(rida, int,
7423 M);
7424 ALLOC(riqa, int,
7425 N);
7426 ALLOC(ripa, int,
7427 N);
7428 ALLOC(rira, int,
7429 M);
7430
7431 /* Set filename... */
7432 if (dirname != NULL)
7433 sprintf(file, "%s/%s", dirname, filename);
7434 else
7435 sprintf(file, "%s", filename);
7436
7437 /* Write info... */
7438 LOG(1, "Write matrix: %s", file);
7439
7440 /* Create file... */
7441 FILE *out;
7442 if (!(out = fopen(file, "w")))
7443 ERRMSG("Cannot create file!");
7444
7445 /* Write header (row space)... */
7446 if (rowspace[0] == 'y') {
7447
7448 fprintf(out,
7449 "# $1 = Row: index (measurement space)\n"
7450 "# $2 = Row: channel wavenumber [cm^-1]\n"
7451 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
7452 "# $4 = Row: view point altitude [km]\n"
7453 "# $5 = Row: view point longitude [deg]\n"
7454 "# $6 = Row: view point latitude [deg]\n");
7455
7456 /* Get number of rows... */
7457 nr = obs2y(ctl, obs, NULL, rida, rira);
7458
7459 } else {
7460
7461 fprintf(out,
7462 "# $1 = Row: index (state space)\n"
7463 "# $2 = Row: name of quantity\n"
7464 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
7465 "# $4 = Row: altitude [km]\n"
7466 "# $5 = Row: longitude [deg]\n" "# $6 = Row: latitude [deg]\n");
7467
7468 /* Get number of rows... */
7469 nr = atm2x(ctl, atm, NULL, riqa, ripa);
7470 }
7471
7472 /* Write header (column space)... */
7473 if (colspace[0] == 'y') {
7474
7475 fprintf(out,
7476 "# $7 = Col: index (measurement space)\n"
7477 "# $8 = Col: channel wavenumber [cm^-1]\n"
7478 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
7479 "# $10 = Col: view point altitude [km]\n"
7480 "# $11 = Col: view point longitude [deg]\n"
7481 "# $12 = Col: view point latitude [deg]\n");
7482
7483 /* Get number of columns... */
7484 nc = obs2y(ctl, obs, NULL, cida, cira);
7485
7486 } else {
7487
7488 fprintf(out,
7489 "# $7 = Col: index (state space)\n"
7490 "# $8 = Col: name of quantity\n"
7491 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
7492 "# $10 = Col: altitude [km]\n"
7493 "# $11 = Col: longitude [deg]\n" "# $12 = Col: latitude [deg]\n");
7494
7495 /* Get number of columns... */
7496 nc = atm2x(ctl, atm, NULL, ciqa, cipa);
7497 }
7498
7499 /* Write header entry... */
7500 fprintf(out, "# $13 = Matrix element\n\n");
7501
7502 /* Write matrix data... */
7503 i = j = 0;
7504 while (i < nr && j < nc) {
7505
7506 /* Write info about the row... */
7507 if (rowspace[0] == 'y')
7508 fprintf(out, "%d %.4f %.2f %g %g %g",
7509 (int) i, ctl->nu[rida[i]],
7510 obs->time[rira[i]], obs->vpz[rira[i]],
7511 obs->vplon[rira[i]], obs->vplat[rira[i]]);
7512 else {
7513 idx2name(ctl, riqa[i], quantity);
7514 fprintf(out, "%d %s %.2f %g %g %g", (int) i, quantity,
7515 atm->time[ripa[i]], atm->z[ripa[i]],
7516 atm->lon[ripa[i]], atm->lat[ripa[i]]);
7517 }
7518
7519 /* Write info about the column... */
7520 if (colspace[0] == 'y')
7521 fprintf(out, " %d %.4f %.2f %g %g %g",
7522 (int) j, ctl->nu[cida[j]],
7523 obs->time[cira[j]], obs->vpz[cira[j]],
7524 obs->vplon[cira[j]], obs->vplat[cira[j]]);
7525 else {
7526 idx2name(ctl, ciqa[j], quantity);
7527 fprintf(out, " %d %s %.2f %g %g %g", (int) j, quantity,
7528 atm->time[cipa[j]], atm->z[cipa[j]],
7529 atm->lon[cipa[j]], atm->lat[cipa[j]]);
7530 }
7531
7532 /* Write matrix entry... */
7533 fprintf(out, " %g\n", gsl_matrix_get(matrix, i, j));
7534
7535 /* Set matrix indices... */
7536 if (sort[0] == 'r') {
7537 j++;
7538 if (j >= nc) {
7539 j = 0;
7540 i++;
7541 fprintf(out, "\n");
7542 }
7543 } else {
7544 i++;
7545 if (i >= nr) {
7546 i = 0;
7547 j++;
7548 fprintf(out, "\n");
7549 }
7550 }
7551 }
7552
7553 /* Close file... */
7554 fclose(out);
7555
7556 /* Free... */
7557 free(cida);
7558 free(ciqa);
7559 free(cipa);
7560 free(cira);
7561 free(rida);
7562 free(riqa);
7563 free(ripa);
7564 free(rira);
7565}
void idx2name(const ctl_t *ctl, const int idx, char *quantity)
Convert a quantity index to a descriptive name string.
Definition: jurassic.c:3957
#define M
Maximum size of measurement vector.
Definition: jurassic.h:273
Here is the call graph for this function:

◆ write_obs()

void write_obs ( const char *  dirname,
const char *  filename,
const ctl_t ctl,
const obs_t obs 
)

Write observation data to an output file in ASCII or binary format.

This C function constructs the full output file path from the provided directory and filename, opens the file for writing, and exports the contents of the obs_t structure in either ASCII or binary format, depending on the observation format specified by ctl->obsfmt. The actual writing of formatted data is delegated to write_obs_asc() or write_obs_bin().

After writing, the function prints diagnostic information showing ranges of times, observer coordinates, view point coordinates, tangent point coordinates, radiance or brightness temperature values (depending on ctl->write_bbt), and transmittances. These diagnostics provide useful verification that the output data is valid and consistent.

Parameters
[in]dirnameOptional directory path. If NULL, only filename is used.
[in]filenameName of the output observation file.
[in]ctlControl structure specifying output format, spectral channel configuration, and brightness-temperature mode.
[in]obsObservation structure containing the data to be written.
Note
This is a C function. The output file is always overwritten if it already exists.
Warning
The routine aborts with an error message if the output file cannot be created, or if ctl->obsfmt specifies an unsupported format.
See also
write_obs_asc(), write_obs_bin(), read_obs(), ctl_t, obs_t
Author
Lars Hoffmann

Definition at line 7569 of file jurassic.c.

7573 {
7574
7575 /* Set filename... */
7576 char file[LEN];
7577 if (dirname != NULL)
7578 sprintf(file, "%s/%s", dirname, filename);
7579 else
7580 sprintf(file, "%s", filename);
7581
7582 /* Write info... */
7583 LOG(1, "Write observation data: %s", file);
7584
7585 /* Write ASCII data... */
7586 if (ctl->obsfmt == 1)
7587 write_obs_asc(file, ctl, obs);
7588
7589 /* Write binary data... */
7590 else if (ctl->obsfmt == 2)
7591 write_obs_bin(file, ctl, obs);
7592
7593 /* Write netCDF data... */
7594 else if (ctl->obsfmt == 3)
7595 write_obs_nc(file, ctl, obs, 0);
7596
7597 /* Write info... */
7598 double mini, maxi;
7599 LOG(2, "Number of ray paths: %d", obs->nr);
7600 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
7601 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
7602 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
7603 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
7604 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
7605 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
7606 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
7607 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
7608 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
7609 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
7610 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
7611 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
7612 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
7613 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
7614 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
7615 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
7616 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
7617 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
7618 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
7619 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
7620 for (int id = 0; id < ctl->nd; id++) {
7621 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
7622 if (ctl->write_bbt) {
7623 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
7624 ctl->nu[id], mini, maxi);
7625 } else {
7626 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
7627 ctl->nu[id], mini, maxi);
7628 }
7629 }
7630 for (int id = 0; id < ctl->nd; id++) {
7631 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
7632 if (ctl->write_bbt) {
7633 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
7634 ctl->nu[id], mini, maxi);
7635 }
7636 }
7637}
void write_obs_asc(const char *filename, const ctl_t *ctl, const obs_t *obs)
Write observation data to an ASCII text file.
Definition: jurassic.c:7641
void write_obs_nc(const char *filename, const ctl_t *ctl, const obs_t *obs, const int profile)
Write one observation profile to a NetCDF file.
Definition: jurassic.c:7765
void write_obs_bin(const char *filename, const ctl_t *ctl, const obs_t *obs)
Write observation data in binary format to a file.
Definition: jurassic.c:7697
Here is the call graph for this function:

◆ write_obs_asc()

void write_obs_asc ( const char *  filename,
const ctl_t ctl,
const obs_t obs 
)

Write observation data to an ASCII text file.

This C function writes the contents of the obs_t observation structure as human-readable ASCII text to a file specified by its filename. It first prints a descriptive header that documents each column of the output format, including observation time, observer and view geometry, tangent point information, and spectral values. The number and meaning of spectral fields depend on ctl->nd and whether brightness temperature output is enabled via ctl->write_bbt.

The function then writes one line of data per ray path, including the base geometric information followed by radiance or brightness temperature values and transmittances for each spectral channel. Blank lines are inserted whenever the time stamp changes, providing visual separation of distinct observation groups.

Parameters
filenamePath to the ASCII output file.
ctlControl structure specifying the number of spectral channels (nd), wavenumbers (nu), and output mode (write_bbt).
obsObservation structure containing the data to be written.
Note
This routine produces plain-text output intended for inspection, debugging, and compatibility with external processing tools.
Warning
The caller must ensure that the file specified by filename is writable. Existing files may be overwritten.
See also
write_obs(), write_obs_bin(), ctl_t, obs_t
Author
Lars Hoffmann

Definition at line 7641 of file jurassic.c.

7644 {
7645
7646 int n = 10;
7647
7648 /* Create file... */
7649 FILE *out;
7650 if (!(out = fopen(filename, "w")))
7651 ERRMSG("Cannot create file!");
7652
7653 /* Write header... */
7654 fprintf(out,
7655 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
7656 "# $2 = observer altitude [km]\n"
7657 "# $3 = observer longitude [deg]\n"
7658 "# $4 = observer latitude [deg]\n"
7659 "# $5 = view point altitude [km]\n"
7660 "# $6 = view point longitude [deg]\n"
7661 "# $7 = view point latitude [deg]\n"
7662 "# $8 = tangent point altitude [km]\n"
7663 "# $9 = tangent point longitude [deg]\n"
7664 "# $10 = tangent point latitude [deg]\n");
7665 for (int id = 0; id < ctl->nd; id++)
7666 if (ctl->write_bbt)
7667 fprintf(out, "# $%d = brightness temperature (%.4f cm^-1) [K]\n",
7668 ++n, ctl->nu[id]);
7669 else
7670 fprintf(out, "# $%d = radiance (%.4f cm^-1) [W/(m^2 sr cm^-1)]\n",
7671 ++n, ctl->nu[id]);
7672 for (int id = 0; id < ctl->nd; id++)
7673 fprintf(out, "# $%d = transmittance (%.4f cm^-1) [-]\n", ++n,
7674 ctl->nu[id]);
7675
7676 /* Write data... */
7677 for (int ir = 0; ir < obs->nr; ir++) {
7678 if (ir == 0 || obs->time[ir] != obs->time[ir - 1])
7679 fprintf(out, "\n");
7680 fprintf(out, "%.2f %g %g %g %g %g %g %g %g %g", obs->time[ir],
7681 obs->obsz[ir], obs->obslon[ir], obs->obslat[ir],
7682 obs->vpz[ir], obs->vplon[ir], obs->vplat[ir],
7683 obs->tpz[ir], obs->tplon[ir], obs->tplat[ir]);
7684 for (int id = 0; id < ctl->nd; id++)
7685 fprintf(out, " %g", obs->rad[id][ir]);
7686 for (int id = 0; id < ctl->nd; id++)
7687 fprintf(out, " %g", obs->tau[id][ir]);
7688 fprintf(out, "\n");
7689 }
7690
7691 /* Close file... */
7692 fclose(out);
7693}

◆ write_obs_bin()

void write_obs_bin ( const char *  filename,
const ctl_t ctl,
const obs_t obs 
)

Write observation data in binary format to a file.

This C function serializes the contents of the obs_t structure into a compact binary format and writes it to a file specified by its filename. The binary format begins with a header consisting of a magic identifier ("OBS1") and the number of spectral channels (ctl->nd). This header is used by read_obs_bin() to validate compatibility when reading.

Following the header, the function writes the number of ray paths and then sequentially outputs arrays of observation metadata, geometric parameters, radiance or brightness temperature values, and transmittances. All values are written in native binary representation using the FWRITE() macro, which performs buffered writes and error checking.

Parameters
filenamePath to the binary output file.
ctlControl structure specifying the number of spectral channels (nd) and corresponding configuration parameters.
obsObservation structure containing the data to be written.
Note
This routine does not perform any formatting or conversion. The resulting file is portable only to systems with compatible binary layouts (integer size, floating-point format, and endianness).
Warning
The caller must ensure that the file specified by filename is writable. Existing files may be overwritten.
See also
write_obs(), write_obs_asc(), read_obs_bin(), ctl_t, obs_t
Author
Lars Hoffmann

Definition at line 7697 of file jurassic.c.

7700 {
7701
7702 /* Create file... */
7703 FILE *out;
7704 if (!(out = fopen(filename, "w")))
7705 ERRMSG("Cannot create file!");
7706
7707 /* Write header... */
7708 FWRITE("OBS1", char,
7709 4,
7710 out);
7711 FWRITE(&ctl->nd, int,
7712 1,
7713 out);
7714
7715 /* Write data... */
7716 size_t nr = (size_t) obs->nr;
7717 FWRITE(&nr, size_t,
7718 1,
7719 out);
7720 FWRITE(obs->time, double,
7721 nr,
7722 out);
7723 FWRITE(obs->obsz, double,
7724 nr,
7725 out);
7726 FWRITE(obs->obslon, double,
7727 nr,
7728 out);
7729 FWRITE(obs->obslat, double,
7730 nr,
7731 out);
7732 FWRITE(obs->vpz, double,
7733 nr,
7734 out);
7735 FWRITE(obs->vplon, double,
7736 nr,
7737 out);
7738 FWRITE(obs->vplat, double,
7739 nr,
7740 out);
7741 FWRITE(obs->tpz, double,
7742 nr,
7743 out);
7744 FWRITE(obs->tplon, double,
7745 nr,
7746 out);
7747 FWRITE(obs->tplat, double,
7748 nr,
7749 out);
7750 for (int id = 0; id < ctl->nd; id++)
7751 FWRITE(obs->rad[id], double,
7752 nr,
7753 out);
7754 for (int id = 0; id < ctl->nd; id++)
7755 FWRITE(obs->tau[id], double,
7756 nr,
7757 out);
7758
7759 /* Close file... */
7760 fclose(out);
7761}

◆ write_obs_nc()

void write_obs_nc ( const char *  filename,
const ctl_t ctl,
const obs_t obs,
const int  profile 
)

Write one observation profile to a NetCDF file.

This function writes all geometric and spectral observation data for a single profile into a NetCDF file using a variable-per-channel layout. If the file does not exist it is created; if it already exists, the required dimensions and variables are created if missing and then extended by writing the specified profile.

The NetCDF file will contain:

  • A dimension profile (unlimited)
  • A dimension ray (fixed, number of ray paths)
  • A variable nray(profile) giving the number of rays for each profile
  • Geometry variables with dimensions (profile, ray):
    • time, obs_z, obs_lon, obs_lat
    • vp_z, vp_lon, vp_lat
    • tp_z, tp_lon, tp_lat
  • Spectral variables with dimensions (profile, ray), one per channel:
    • rad_%.4f (radiance or brightness temperature)
    • tau_%.4f (transmittance) where the formatted frequency corresponds to ctl->nu[id].

Radiance is written either as physical radiance or as brightness temperature depending on ctl->write_bbt. The ray dimension is fixed on first creation and all subsequently written profiles must not exceed this number of rays.

Parameters
filenamePath to the NetCDF observation file.
ctlPointer to the control structure defining spectral channels.
obsPointer to the observation structure containing the data to be written.
profileZero-based index of the profile to write.
Author
Lars Hoffmann

Definition at line 7765 of file jurassic.c.

7769 {
7770
7771 char longname[LEN], varname[LEN];
7772
7773 int ncid, varid, dim_profile, dim_ray;
7774
7775 size_t ray_max;
7776
7777 /* Open or create file... */
7778 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR)
7779 NC(nc_create(filename, NC_NETCDF4, &ncid));
7780
7781 /* Enter define mode... */
7782 int r = nc_redef(ncid);
7783 if (r != NC_NOERR && r != NC_EINDEFINE)
7784 NC(r);
7785
7786 /* Define profile dimension (unlimited)... */
7787 if (nc_inq_dimid(ncid, "profile", &dim_profile) != NC_NOERR)
7788 NC(nc_def_dim(ncid, "profile", NC_UNLIMITED, &dim_profile));
7789
7790 /* Define ray dimension (fixed)... */
7791 if (nc_inq_dimid(ncid, "ray", &dim_ray) == NC_NOERR) {
7792 NC(nc_inq_dimlen(ncid, dim_ray, &ray_max));
7793 if (ray_max < 1 || ray_max > (size_t) NR)
7794 ERRMSG("netCDF dimension ray is out of range!");
7795 if ((size_t) obs->nr > ray_max)
7796 ERRMSG("profile has too many rays!");
7797 } else {
7798 ray_max = (size_t) obs->nr;
7799 NC(nc_def_dim(ncid, "ray", ray_max, &dim_ray));
7800 }
7801
7802 /* Dimension ID array... */
7803 int dimids[2] = { dim_profile, dim_ray };
7804
7805 /* Tunables for compression/quantization... */
7806 const int deflate_level = 0;
7807 const int quant_digits = 0;
7808
7809 /* Define nray (1D over profile)... */
7810 if (nc_inq_varid(ncid, "nray", &varid) != NC_NOERR)
7811 NC_DEF_VAR("nray", NC_INT, 1, dimids, "number of ray paths", "1", 0, 0);
7812
7813 /* Define geometry variables (2D over profile, ray)... */
7814 if (nc_inq_varid(ncid, "time", &varid) != NC_NOERR)
7815 NC_DEF_VAR("time", NC_DOUBLE, 2, dimids,
7816 "time in seconds since 2000-01-01, 00:00 UTC", "s",
7817 deflate_level, 0);
7818
7819 if (nc_inq_varid(ncid, "obs_z", &varid) != NC_NOERR)
7820 NC_DEF_VAR("obs_z", NC_DOUBLE, 2, dimids,
7821 "observer altitude", "km", deflate_level, 0);
7822
7823 if (nc_inq_varid(ncid, "obs_lon", &varid) != NC_NOERR)
7824 NC_DEF_VAR("obs_lon", NC_DOUBLE, 2, dimids,
7825 "observer longitude", "degrees_east", deflate_level, 0);
7826
7827 if (nc_inq_varid(ncid, "obs_lat", &varid) != NC_NOERR)
7828 NC_DEF_VAR("obs_lat", NC_DOUBLE, 2, dimids,
7829 "observer latitude", "degrees_north", deflate_level, 0);
7830
7831 if (nc_inq_varid(ncid, "vp_z", &varid) != NC_NOERR)
7832 NC_DEF_VAR("vp_z", NC_DOUBLE, 2, dimids,
7833 "view point altitude", "km", deflate_level, 0);
7834
7835 if (nc_inq_varid(ncid, "vp_lon", &varid) != NC_NOERR)
7836 NC_DEF_VAR("vp_lon", NC_DOUBLE, 2, dimids,
7837 "view point longitude", "degrees_east", deflate_level, 0);
7838
7839 if (nc_inq_varid(ncid, "vp_lat", &varid) != NC_NOERR)
7840 NC_DEF_VAR("vp_lat", NC_DOUBLE, 2, dimids,
7841 "view point latitude", "degrees_north", deflate_level, 0);
7842
7843 if (nc_inq_varid(ncid, "tp_z", &varid) != NC_NOERR)
7844 NC_DEF_VAR("tp_z", NC_DOUBLE, 2, dimids,
7845 "tangent point altitude", "km", deflate_level, 0);
7846
7847 if (nc_inq_varid(ncid, "tp_lon", &varid) != NC_NOERR)
7848 NC_DEF_VAR("tp_lon", NC_DOUBLE, 2, dimids,
7849 "tangent point longitude", "degrees_east", deflate_level, 0);
7850
7851 if (nc_inq_varid(ncid, "tp_lat", &varid) != NC_NOERR)
7852 NC_DEF_VAR("tp_lat", NC_DOUBLE, 2, dimids,
7853 "tangent point latitude", "degrees_north", deflate_level, 0);
7854
7855 /* Define radiance/transmittance per channel (2D profile,ray)... */
7856 for (int id = 0; id < ctl->nd; id++) {
7857
7858 sprintf(varname, "rad_%.4f", ctl->nu[id]);
7859 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7860 if (ctl->write_bbt) {
7861 sprintf(longname, "brightness temperature (%.4f cm^-1)", ctl->nu[id]);
7862 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname, "K",
7863 deflate_level, quant_digits);
7864 } else {
7865 sprintf(longname, "radiance (%.4f cm^-1)", ctl->nu[id]);
7866 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname,
7867 "W/(m^2 sr cm^-1)", deflate_level, quant_digits);
7868 }
7869 }
7870
7871 sprintf(varname, "tau_%.4f", ctl->nu[id]);
7872 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7873 sprintf(longname, "transmittance (%.4f cm^-1)", ctl->nu[id]);
7874 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname, "1",
7875 deflate_level, quant_digits);
7876 }
7877 }
7878
7879 /* Leave define mode... */
7880 NC(nc_enddef(ncid));
7881
7882 /* Hyperslabs... */
7883 size_t start[2] = { (size_t) profile, 0 };
7884 size_t count[2] = { 1, (size_t) obs->nr };
7885
7886 /* Write nray(profile)... */
7887 int nr = obs->nr;
7888 NC(nc_inq_varid(ncid, "nray", &varid));
7889 NC(nc_put_vara_int(ncid, varid, start, count, &nr));
7890
7891 /* Write geometry... */
7892 NC(nc_inq_varid(ncid, "time", &varid));
7893 NC(nc_put_vara_double(ncid, varid, start, count, obs->time));
7894
7895 NC(nc_inq_varid(ncid, "obs_z", &varid));
7896 NC(nc_put_vara_double(ncid, varid, start, count, obs->obsz));
7897
7898 NC(nc_inq_varid(ncid, "obs_lon", &varid));
7899 NC(nc_put_vara_double(ncid, varid, start, count, obs->obslon));
7900
7901 NC(nc_inq_varid(ncid, "obs_lat", &varid));
7902 NC(nc_put_vara_double(ncid, varid, start, count, obs->obslat));
7903
7904 NC(nc_inq_varid(ncid, "vp_z", &varid));
7905 NC(nc_put_vara_double(ncid, varid, start, count, obs->vpz));
7906
7907 NC(nc_inq_varid(ncid, "vp_lon", &varid));
7908 NC(nc_put_vara_double(ncid, varid, start, count, obs->vplon));
7909
7910 NC(nc_inq_varid(ncid, "vp_lat", &varid));
7911 NC(nc_put_vara_double(ncid, varid, start, count, obs->vplat));
7912
7913 NC(nc_inq_varid(ncid, "tp_z", &varid));
7914 NC(nc_put_vara_double(ncid, varid, start, count, obs->tpz));
7915
7916 NC(nc_inq_varid(ncid, "tp_lon", &varid));
7917 NC(nc_put_vara_double(ncid, varid, start, count, obs->tplon));
7918
7919 NC(nc_inq_varid(ncid, "tp_lat", &varid));
7920 NC(nc_put_vara_double(ncid, varid, start, count, obs->tplat));
7921
7922 /* Write spectral variables per channel... */
7923 for (int id = 0; id < ctl->nd; id++) {
7924 sprintf(varname, "rad_%.4f", ctl->nu[id]);
7925 NC(nc_inq_varid(ncid, varname, &varid));
7926 NC(nc_put_vara_double(ncid, varid, start, count, obs->rad[id]));
7927
7928 sprintf(varname, "tau_%.4f", ctl->nu[id]);
7929 NC(nc_inq_varid(ncid, varname, &varid));
7930 NC(nc_put_vara_double(ncid, varid, start, count, obs->tau[id]));
7931 }
7932
7933 /* Close file... */
7934 NC(nc_sync(ncid));
7935 NC(nc_close(ncid));
7936}

◆ write_shape()

void write_shape ( const char *  filename,
const double *  x,
const double *  y,
const int  n 
)

Write tabulated shape function data to a text file.

Exports a shape function (typically a weighting or field-of-view profile) defined by paired arrays of x and y values to an ASCII file.

Parameters
[in]filenameOutput file name.
[in]xPointer to array of x-values (independent variable).
[in]yPointer to array of y-values (dependent variable).
[in]nNumber of data points to write.
  • Writes a plain-text table with two columns:
    # $1 = shape function x-value [-]
    # $2 = shape function y-value [-]
  • Each line contains one (x, y) pair written with high precision.
  • Typically used to export field-of-view functions, apodization kernels, or any other normalized shape profiles used by the model.
See also
read_shape
Note
  • Units are dimensionless unless otherwise defined by the application.
  • The file is fully compatible with read_shape() for re-import.
  • Output precision is set to 10 significant digits for numerical stability.
Warning
  • Existing files with the same name will be overwritten.
  • The number of points n must be consistent with the size of x and y arrays.
Author
Lars Hoffmann

Definition at line 7940 of file jurassic.c.

7944 {
7945
7946 /* Write info... */
7947 LOG(1, "Write shape function: %s", filename);
7948
7949 /* Create file... */
7950 FILE *out;
7951 if (!(out = fopen(filename, "w")))
7952 ERRMSG("Cannot create file!");
7953
7954 /* Write header... */
7955 fprintf(out,
7956 "# $1 = shape function x-value [-]\n"
7957 "# $2 = shape function y-value [-]\n\n");
7958
7959 /* Write data... */
7960 for (int i = 0; i < n; i++)
7961 fprintf(out, "%.10g %.10g\n", x[i], y[i]);
7962
7963 /* Close file... */
7964 fclose(out);
7965}

◆ write_stddev()

void write_stddev ( const char *  quantity,
const ret_t ret,
const ctl_t ctl,
const atm_t atm,
const gsl_matrix *  s 
)

Write retrieval standard deviation profiles to disk.

Extracts the diagonal elements of a covariance matrix (a priori, posterior, or error covariance) to obtain the standard deviations of retrieved quantities and writes them as an atmospheric profile file.

Parameters
[in]quantityName of the retrieved quantity (e.g., "apr", "pos", "err"), used to label the output file.
[in]retRetrieval configuration structure (ret_t), providing the working directory for output files.
[in]ctlGlobal control structure (ctl_t) defining retrieval setup and quantities.
[in]atmReference atmospheric state (atm_t) for spatial/geometric metadata.
[in]sCovariance matrix (gsl_matrix, n×n) from which standard deviations are derived (typically posterior covariance \(\mathbf{S}\)).

This function performs the following operations:

  1. Extracts the standard deviation vector \(\sigma_i = \sqrt{S_{ii}}\) from the diagonal of the covariance matrix \(\mathbf{S}\).
  2. Copies the reference atmospheric structure (atm) into an auxiliary structure (atm_aux) to preserve coordinate and geometric metadata.
  3. Converts the standard deviation vector into the atmospheric representation using x2atm(), thereby mapping elements of the state vector to the corresponding atmospheric quantities.
  4. Writes the result to disk as a diagnostic file:

    \[ \texttt{<ret->dir>/atm\_err\_<quantity>.tab} \]

    using the standard JURASSIC atmospheric file format.
See also
x2atm, copy_atm, write_atm, set_cov_apr, set_cov_meas
Note
  • The file naming convention follows atm_err_<quantity>.tab (e.g., atm_err_apr.tab, atm_err_pos.tab).
  • The output profile includes all state quantities defined in ctl.
  • Only diagonal uncertainties are written; correlations are not stored.
Warning
  • The covariance matrix s must be symmetric and positive-definite.
  • The state vector mapping (x2atm) must correspond to the matrix ordering.
Author
Lars Hoffmann

Definition at line 7969 of file jurassic.c.

7974 {
7975
7976 /* Get sizes... */
7977 const size_t n = s->size1;
7978
7979 /* Allocate... */
7980 atm_t *atm_aux;
7981 ALLOC(atm_aux, atm_t, 1);
7982 gsl_vector *x_aux = gsl_vector_alloc(n);
7983
7984 /* Compute standard deviation... */
7985 for (size_t i = 0; i < n; i++)
7986 gsl_vector_set(x_aux, i, sqrt(gsl_matrix_get(s, i, i)));
7987
7988 /* Write to disk... */
7989 char filename[LEN];
7990 copy_atm(ctl, atm_aux, atm, 1);
7991 x2atm(ctl, x_aux, atm_aux);
7992 sprintf(filename, "atm_err_%s.tab", quantity);
7993 write_atm(ret->dir, filename, ctl, atm_aux);
7994
7995 /* Free... */
7996 gsl_vector_free(x_aux);
7997}
Here is the call graph for this function:

◆ write_tbl()

void write_tbl ( const ctl_t ctl,
const tbl_t tbl 
)

Write emissivity lookup tables to disk.

Writes emissivity lookup tables stored in tbl using the output format specified by ctl->tblfmt:

  • ASCII (ctl->tblfmt == 1)
  • compact binary (ctl->tblfmt == 2)
  • netCDF (ctl->tblfmt == 3)

The function iterates over all emitters (ig) and detectors/channels (id) and dispatches the corresponding per-table writer.

Lookup tables with no pressure levels (i.e. tbl->np[id][ig] <= 0) are skipped intentionally. In this case, a warning is issued and no output artifact (file or NetCDF variable) is written for the affected table. This allows trace gases or channels with negligible contribution to be omitted cleanly from the output.

After writing the lookup tables, the associated spectral filter functions are written to separate files (format-dependent).

Parameters
[in]ctlPointer to the control structure defining the lookup table output format, base filenames, emitters, and spectral channels.
[in]tblPointer to the lookup-table structure containing the emissivity data and filter functions to be written.
Warning
If an unsupported lookup table format is specified via ctl->tblfmt, the function aborts with an error message.
Note
Missing output artifacts caused by skipped tables are handled gracefully by the corresponding readers, which treat missing tables as empty.
Author
Lars Hoffmann

Definition at line 8001 of file jurassic.c.

8003 {
8004
8005 /* Loop over emitters and detectors... */
8006 for (int ig = 0; ig < ctl->ng; ig++)
8007 for (int id = 0; id < ctl->nd; id++) {
8008
8009 /* Skip empty tables... */
8010 if (tbl->np[id][ig] <= 0) {
8011 WARN("Skip writing empty emissivity table: emitter=%s, nu=%.4f",
8012 ctl->emitter[ig], ctl->nu[id]);
8013 continue;
8014 }
8015
8016 /* Write ASCII look-up tables... */
8017 if (ctl->tblfmt == 1)
8018 write_tbl_asc(ctl, tbl, id, ig);
8019
8020 /* Write binary look-up tables... */
8021 else if (ctl->tblfmt == 2)
8022 write_tbl_bin(ctl, tbl, id, ig);
8023
8024 /* Write netCDF look-up tables... */
8025 else if (ctl->tblfmt == 3)
8026 write_tbl_nc(ctl, tbl, id, ig);
8027
8028 /* Write info... */
8029 TBL_LOG(tbl, id, ig);
8030 }
8031
8032 /* Write filter functions... */
8033 if (ctl->tblfmt == 1)
8034 for (int id = 0; id < ctl->nd; id++) {
8035 char filename[2 * LEN];
8036 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
8037 write_shape(filename, tbl->filt_nu[id], tbl->filt_f[id],
8038 tbl->filt_n[id]);
8039 }
8040}
void write_tbl_asc(const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
Write one emissivity lookup table in human-readable ASCII format.
Definition: jurassic.c:8044
void write_tbl_nc(const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
Write one packed lookup table to a NetCDF file.
Definition: jurassic.c:8128
void write_tbl_bin(const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
Write one emissivity lookup table in compact binary format.
Definition: jurassic.c:8086
void write_shape(const char *filename, const double *x, const double *y, const int n)
Write tabulated shape function data to a text file.
Definition: jurassic.c:7940
Here is the call graph for this function:

◆ write_tbl_asc()

void write_tbl_asc ( const ctl_t ctl,
const tbl_t tbl,
const int  id,
const int  ig 
)

Write one emissivity lookup table in human-readable ASCII format.

Writes the lookup table for detector/channel index id and emitter/gas index ig to a file named:

<ctl->tblbase>_<ctl->nu[id]>_<ctl->emitter[ig]>.tab

The ASCII file contains four columns:

  1. pressure [hPa]
  2. temperature [K]
  3. column density [molecules/cm^2]
  4. emissivity [-]

A header describing the columns is always written. If the table is empty (i.e. tbl->np[id][ig] == 0), the file will contain only the header.

Parameters
[in]ctlControl structure providing filename base, frequencies, and emitter names.
[in]tblLookup table data to be written.
[in]idDetector/channel index.
[in]igEmitter/gas index.
Author
Lars Hoffmann

Definition at line 8044 of file jurassic.c.

8048 {
8049
8050 /* Set filename... */
8051 char filename[2 * LEN];
8052 sprintf(filename, "%s_%.4f_%s.tab", ctl->tblbase,
8053 ctl->nu[id], ctl->emitter[ig]);
8054
8055 /* Create file... */
8056 FILE *out;
8057 if (!(out = fopen(filename, "w"))) {
8058 ERRMSG("Cannot create emissivity table: %s", filename);
8059 } else
8060 LOG(1, "Write emissivity table: %s", filename);
8061
8062 /* Write header... */
8063 fprintf(out,
8064 "# $1 = pressure [hPa]\n"
8065 "# $2 = temperature [K]\n"
8066 "# $3 = column density [molecules/cm^2]\n"
8067 "# $4 = emissivity [-]\n");
8068
8069 /* Save table file... */
8070 for (int ip = 0; ip < tbl->np[id][ig]; ip++)
8071 for (int it = 0; it < tbl->nt[id][ig][ip]; it++) {
8072 fprintf(out, "\n");
8073 for (int iu = 0; iu < tbl->nu[id][ig][ip][it]; iu++)
8074 fprintf(out, "%g %g %e %e\n",
8075 tbl->p[id][ig][ip], tbl->t[id][ig][ip][it],
8076 exp(tbl->logu[id][ig][ip][it][iu]),
8077 exp(tbl->logeps[id][ig][ip][it][iu]));
8078 }
8079
8080 /* Close file... */
8081 fclose(out);
8082}

◆ write_tbl_bin()

void write_tbl_bin ( const ctl_t ctl,
const tbl_t tbl,
const int  id,
const int  ig 
)

Write one emissivity lookup table in compact binary format.

Writes the lookup table for detector/channel index id and emitter/gas index ig to a file named:

<ctl->tblbase>_<ctl->nu[id]>_<ctl->emitter[ig]>.bin

The file contains a length field followed by a packed byte blob produced by tbl_pack():

  • size_t nbytes : number of bytes in the packed blob
  • uint8_t blob[] : packed lookup table data (see tbl_pack())

If the table is empty (tbl->np[id][ig] == 0), the packed blob still encodes this (it includes np = 0), so the file remains a valid representation of an empty table.

Parameters
[in]ctlControl structure providing filename base, frequencies, and emitter names.
[in]tblLookup table data to be packed and written.
[in]idDetector/channel index.
[in]igEmitter/gas index.
See also
tbl_pack()
Author
Lars Hoffmann

Definition at line 8086 of file jurassic.c.

8090 {
8091
8092 /* Set filename... */
8093 char filename[2 * LEN];
8094 sprintf(filename, "%s_%.4f_%s.bin",
8095 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
8096
8097 /* Create file... */
8098 FILE *out;
8099 if (!(out = fopen(filename, "w"))) {
8100 ERRMSG("Cannot create emissivity table: %s", filename);
8101 } else
8102 LOG(1, "Write emissivity table: %s", filename);
8103
8104 /* Pack... */
8105 size_t used = 0;
8106 const size_t need = tbl_packed_size(tbl, id, ig);
8107 uint8_t *work = NULL;
8108 ALLOC(work, uint8_t, need);
8109 tbl_pack(tbl, id, ig, work, &used);
8110 if (used != need)
8111 ERRMSG("Internal error: packed size mismatch!");
8112
8113 /* Write length and packed blob... */
8114 FWRITE(&used, size_t,
8115 1,
8116 out);
8117 FWRITE(work, uint8_t, used, out);
8118
8119 /* Close file... */
8120 fclose(out);
8121
8122 /* Free... */
8123 free(work);
8124}
void tbl_pack(const tbl_t *tbl, int id, int ig, uint8_t *buf, size_t *bytes_used)
Pack a lookup table into a contiguous binary buffer.
Definition: jurassic.c:6718
size_t tbl_packed_size(const tbl_t *tbl, int id, int ig)
Compute required buffer size (in bytes) for tbl_pack().
Definition: jurassic.c:6772
Here is the call graph for this function:

◆ write_tbl_nc()

void write_tbl_nc ( const ctl_t ctl,
const tbl_t tbl,
const int  id,
const int  ig 
)

Write one packed lookup table to a NetCDF file.

Writes the lookup table for detector/channel index id and emitter/gas index ig to the NetCDF file:

<ctl->tblbase>_<ctl->emitter[ig]>.nc

The table is stored as a packed byte blob (produced by tbl_pack()) in a variable named tbl_XXXX with a corresponding dimension len_XXXX, where XXXX is the formatted frequency ctl->nu[id]. The variable type is NC_UBYTE.

If the NetCDF file does not exist, it is created and initialized with the global attributes:

  • format_version = "1"
  • emitter = ctl->emitter[ig]

To prevent accidental overwrites, the function terminates with an error if the target variable already exists in the file.

Parameters
[in]ctlControl structure defining emitter names, frequencies, and base filename.
[in]tblLookup table data structure containing the lookup table to be packed and written.
[in]idDetector/channel index.
[in]igEmitter/gas index.
See also
tbl_pack()
Author
Lars Hoffmann

Definition at line 8128 of file jurassic.c.

8132 {
8133
8134 /* Set filename... */
8135 char filename[2 * LEN];
8136 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
8137
8138 /* Open or create file... */
8139 int ncid;
8140 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
8141 if (nc_create(filename, NC_NETCDF4 | NC_CLOBBER, &ncid) != NC_NOERR)
8142 ERRMSG("Cannot open or create emissivity table: %s", filename);
8143 NC_PUT_ATT_GLOBAL("format_version", "1");
8144 NC_PUT_ATT_GLOBAL("emitter", ctl->emitter[ig]);
8145 NC(nc_enddef(ncid));
8146 }
8147
8148 /* Set variable and dimension name... */
8149 char varname[LEN], dimname[LEN];
8150 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
8151 sprintf(dimname, "len_%.4f", ctl->nu[id]);
8152
8153 /* Write info... */
8154 LOG(1, "Write emissivity table: %s in %s", varname, filename);
8155
8156 /* Allocate work space... */
8157 size_t used = 0;
8158 const size_t need = tbl_packed_size(tbl, id, ig);
8159 uint8_t *work = NULL;
8160 ALLOC(work, uint8_t, need);
8161
8162 /* Pack table... */
8163 tbl_pack(tbl, id, ig, work, &used);
8164 if (used != need)
8165 ERRMSG("Internal error: packed size mismatch!");
8166
8167 /* Prevent overwrite... */
8168 int tmp;
8169 if (nc_inq_varid(ncid, varname, &tmp) == NC_NOERR)
8170 ERRMSG("Table already present!");
8171
8172 /* Add dimension and variable... */
8173 int dimid, varid;
8174 NC(nc_redef(ncid));
8175 NC(nc_def_dim(ncid, dimname, used, &dimid));
8176 int dimids[1] = { dimid };
8177 NC_DEF_VAR(varname, NC_UBYTE, 1, dimids,
8178 "Packed lookup table blob", "1", 0, 0);
8179 NC(nc_enddef(ncid));
8180
8181 /* Write data... */
8182 NC(nc_put_var_uchar(ncid, varid, (const unsigned char *) work));
8183
8184 /* Free... */
8185 free(work);
8186
8187 /* Close file... */
8188 NC(nc_close(ncid));
8189}
#define NC_PUT_ATT_GLOBAL(attname, text)
Add a global text attribute to a NetCDF file.
Definition: jurassic.h:838
Here is the call graph for this function:

◆ x2atm()

void x2atm ( const ctl_t ctl,
const gsl_vector *  x,
atm_t atm 
)

Map retrieval state vector back to atmospheric structure.

Updates the atmospheric data structure (atm_t) from the contents of a retrieval state vector (x). This function performs the inverse transformation of atm2x(), assigning retrieved quantities such as pressure, temperature, gas volume mixing ratios, extinction, and cloud/surface parameters to the corresponding atmospheric fields.

Parameters
[in]ctlPointer to control structure defining retrieval settings, vertical range limits, and active retrieval flags.
[in]xPointer to retrieval state vector containing the updated values.
[out]atmPointer to atmospheric data structure to be updated.
  • Each atmospheric quantity is updated only within its respective retrieval altitude range (ctl->ret*_zmin/ctl->ret*_zmax).
  • For each retrievable parameter, the helper routine x2atm_help() is called to sequentially read the next element from the state vector.
  • The order of assignments must match that in atm2x() to ensure one-to-one correspondence between state vector indices and atmospheric fields.

Quantities mapped:

  • Pressure (p[zmin:zmax])
  • Temperature (t[zmin:zmax])
  • Gas volume mixing ratios (q[ig][zmin:zmax])
  • Extinction coefficients (k[iw][zmin:zmax])
  • Cloud parameters (clz, cldz, clk)
  • Surface parameters (sft, sfeps)
See also
atm2x, x2atm_help, ctl_t, atm_t
Note
  • Only parameters marked as retrievable in ctl (e.g. ret_sft, ret_clk) are modified.
  • The state vector index (n) advances automatically as each element is read.
  • The helper function x2atm_help() abstracts sequential access to vector elements.
Warning
  • The atmospheric profile must be initialized before calling this function.
  • Retrieval ranges and flags in ctl must correspond exactly to those used in the forward-model configuration.
  • Mismatch between atm2x() and x2atm() ordering will cause incorrect mappings.
Author
Lars Hoffmann

Definition at line 8193 of file jurassic.c.

8196 {
8197
8198 size_t n = 0;
8199
8200 /* Get pressure... */
8201 for (int ip = 0; ip < atm->np; ip++)
8202 if (atm->z[ip] >= ctl->retp_zmin && atm->z[ip] <= ctl->retp_zmax)
8203 x2atm_help(&atm->p[ip], x, &n);
8204
8205 /* Get temperature... */
8206 for (int ip = 0; ip < atm->np; ip++)
8207 if (atm->z[ip] >= ctl->rett_zmin && atm->z[ip] <= ctl->rett_zmax)
8208 x2atm_help(&atm->t[ip], x, &n);
8209
8210 /* Get volume mixing ratio... */
8211 for (int ig = 0; ig < ctl->ng; ig++)
8212 for (int ip = 0; ip < atm->np; ip++)
8213 if (atm->z[ip] >= ctl->retq_zmin[ig]
8214 && atm->z[ip] <= ctl->retq_zmax[ig])
8215 x2atm_help(&atm->q[ig][ip], x, &n);
8216
8217 /* Get extinction... */
8218 for (int iw = 0; iw < ctl->nw; iw++)
8219 for (int ip = 0; ip < atm->np; ip++)
8220 if (atm->z[ip] >= ctl->retk_zmin[iw]
8221 && atm->z[ip] <= ctl->retk_zmax[iw])
8222 x2atm_help(&atm->k[iw][ip], x, &n);
8223
8224 /* Get cloud data... */
8225 if (ctl->ret_clz)
8226 x2atm_help(&atm->clz, x, &n);
8227 if (ctl->ret_cldz)
8228 x2atm_help(&atm->cldz, x, &n);
8229 if (ctl->ret_clk)
8230 for (int icl = 0; icl < ctl->ncl; icl++)
8231 x2atm_help(&atm->clk[icl], x, &n);
8232
8233 /* Get surface data... */
8234 if (ctl->ret_sft)
8235 x2atm_help(&atm->sft, x, &n);
8236 if (ctl->ret_sfeps)
8237 for (int isf = 0; isf < ctl->nsf; isf++)
8238 x2atm_help(&atm->sfeps[isf], x, &n);
8239}
void x2atm_help(double *value, const gsl_vector *x, size_t *n)
Helper function to extract a single value from the retrieval state vector.
Definition: jurassic.c:8243
Here is the call graph for this function:

◆ x2atm_help()

void x2atm_help ( double *  value,
const gsl_vector *  x,
size_t *  n 
)

Helper function to extract a single value from the retrieval state vector.

Retrieves the next element from the state vector x and assigns it to the provided scalar variable. This function is used by x2atm() to sequentially map the contents of the retrieval vector into the corresponding fields of the atmospheric structure.

Parameters
[out]valuePointer to the scalar variable to be updated.
[in]xPointer to the retrieval state vector (gsl_vector).
[in,out]nPointer to the current index in the state vector. The index is incremented after each extraction.
  • Acts as a lightweight iterator over the state vector elements.
  • Ensures consistent and sequential assignment order between atm2x() and x2atm().
  • Increments the index counter *n after reading a value, maintaining the correct position in the vector for subsequent calls.
See also
x2atm, atm2x
Note
  • The function performs no range checking; it assumes that the index is within valid bounds of the state vector length.
  • Typically used only internally by retrieval mapping routines.
Author
Lars Hoffmann

Definition at line 8243 of file jurassic.c.

8246 {
8247
8248 /* Get state vector element... */
8249 *value = gsl_vector_get(x, *n);
8250 (*n)++;
8251}

◆ y2obs()

void y2obs ( const ctl_t ctl,
const gsl_vector *  y,
obs_t obs 
)

Copy elements from the measurement vector y into the observation structure.

Decomposes the 1-D measurement vector y into its radiance components and writes them into the 2-D observation array obs->rad[id][ir], using the same ordering as produced by the corresponding forward model.

Only entries for which obs->rad[id][ir] is finite are updated. This allows missing or masked radiances to remain untouched in the observation structure.

Parameters
[in]ctlControl settings defining the number of detector channels (ctl->nd) and other retrieval configuration parameters.
[in]yMeasurement vector containing radiances in forward-model order.
[out]obsObservation structure whose radiance array (obs->rad) is to be filled with values from y.

The function loops over all ray paths (obs->nr) and detector channels (ctl->nd). For each pair (detector id, ray ir) where an existing value in obs->rad[id][ir] is finite, the next element from the measurement vector y is inserted. The counter m tracks progression through y.

This function is the inverse operation of the packing performed when constructing the measurement vector from an obs_t structure.

Note
The measurement vector y must contain as many finite elements as the number of finite entries in obs->rad, in the same scanning order.
See also
obs_t, ctl_t
Author
Lars Hoffmann

Definition at line 8255 of file jurassic.c.

8258 {
8259
8260 size_t m = 0;
8261
8262 /* Decompose measurement vector... */
8263 for (int ir = 0; ir < obs->nr; ir++)
8264 for (int id = 0; id < ctl->nd; id++)
8265 if (isfinite(obs->rad[id][ir])) {
8266 obs->rad[id][ir] = gsl_vector_get(y, m);
8267 m++;
8268 }
8269}