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 atm_t *atm, obs_t *obs)
 Interface routine for 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 the source-function (Planck radiance) lookup table. 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 u)
 Interpolate emissivity from lookup tables as a function of column density. More...
 
double intpol_tbl_u (const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double eps)
 Interpolate column density from lookup tables 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 look-up tables for all trace gases and channels. 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 binary emissivity lookup table. More...
 
void read_tbl_nc (const ctl_t *ctl, tbl_t *tbl, int id, int ig)
 Read a packed lookup table from a 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_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_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 look-up tables in the format specified by the control structure. More...
 
void write_tbl_asc (const ctl_t *ctl, const tbl_t *tbl)
 Write all lookup tables in human-readable ASCII format. More...
 
void write_tbl_bin (const ctl_t *ctl, const tbl_t *tbl)
 Write all lookup tables in compact binary format. More...
 
void write_tbl_nc (const ctl_t *ctl, const tbl_t *tbl)
 Write packed lookup tables to NetCDF files. 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 static atm_t atm_cont, atm_res;
38
39 size_t i, n0[NQ], n1[NQ];
40
41 /* Get sizes... */
42 const size_t n = avk->size1;
43
44 /* Find sub-matrices for different quantities... */
45 for (int iq = 0; iq < NQ; iq++) {
46 n0[iq] = N;
47 for (i = 0; i < n; i++) {
48 if (iqa[i] == iq && n0[iq] == N)
49 n0[iq] = i;
50 if (iqa[i] == iq)
51 n1[iq] = i - n0[iq] + 1;
52 }
53 }
54
55 /* Initialize... */
56 copy_atm(ctl, &atm_cont, atm, 1);
57 copy_atm(ctl, &atm_res, atm, 1);
58
59 /* Analyze quantities... */
60 analyze_avk_quantity(avk, IDXP, ipa, n0, n1, atm_cont.p, atm_res.p);
61 analyze_avk_quantity(avk, IDXT, ipa, n0, n1, atm_cont.t, atm_res.t);
62 for (int ig = 0; ig < ctl->ng; ig++)
63 analyze_avk_quantity(avk, IDXQ(ig), ipa, n0, n1,
64 atm_cont.q[ig], atm_res.q[ig]);
65 for (int iw = 0; iw < ctl->nw; iw++)
66 analyze_avk_quantity(avk, IDXK(iw), ipa, n0, n1,
67 atm_cont.k[iw], atm_res.k[iw]);
68 analyze_avk_quantity(avk, IDXCLZ, ipa, n0, n1, &atm_cont.clz, &atm_res.clz);
69 analyze_avk_quantity(avk, IDXCLDZ, ipa, n0, n1, &atm_cont.cldz,
70 &atm_res.cldz);
71 for (int icl = 0; icl < ctl->ncl; icl++)
72 analyze_avk_quantity(avk, IDXCLK(icl), ipa, n0, n1,
73 &atm_cont.clk[icl], &atm_res.clk[icl]);
74 analyze_avk_quantity(avk, IDXSFT, ipa, n0, n1, &atm_cont.sft, &atm_res.sft);
75 for (int isf = 0; isf < ctl->nsf; isf++)
76 analyze_avk_quantity(avk, IDXSFEPS(isf), ipa, n0, n1,
77 &atm_cont.sfeps[isf], &atm_res.sfeps[isf]);
78
79 /* Write results to disk... */
80 write_atm(ret->dir, "atm_cont.tab", ctl, &atm_cont);
81 write_atm(ret->dir, "atm_res.tab", ctl, &atm_res);
82}
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:6766
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:86
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:3256
#define N
Maximum size of state vector.
Definition: jurassic.h:278
#define IDXCLZ
Index for cloud layer height.
Definition: jurassic.h:348
#define IDXCLDZ
Index for cloud layer depth.
Definition: jurassic.h:351
#define IDXK(iw)
Indices for extinction.
Definition: jurassic.h:345
#define NQ
Maximum number of quantities.
Definition: jurassic.h:283
#define IDXSFT
Index for surface layer temperature.
Definition: jurassic.h:357
#define IDXSFEPS(isf)
Indices for surface layer emissivity.
Definition: jurassic.h:360
#define IDXCLK(icl)
Indices for cloud layer extinction.
Definition: jurassic.h:354
#define IDXP
Index for pressure.
Definition: jurassic.h:336
#define IDXQ(ig)
Indices for volume mixing ratios.
Definition: jurassic.h:342
#define IDXT
Index for temperature.
Definition: jurassic.h:339
Atmospheric profile data.
Definition: jurassic.h:1212
double sfeps[NSF]
Surface emissivity.
Definition: jurassic.h:1254
double k[NW][NP]
Extinction [km^-1].
Definition: jurassic.h:1239
double t[NP]
Temperature [K].
Definition: jurassic.h:1233
double clz
Cloud layer height [km].
Definition: jurassic.h:1242
double cldz
Cloud layer depth [km].
Definition: jurassic.h:1245
double sft
Surface temperature [K].
Definition: jurassic.h:1251
double clk[NCL]
Cloud layer extinction [km^-1].
Definition: jurassic.h:1248
double q[NG][NP]
Volume mixing ratio [ppv].
Definition: jurassic.h:1236
double p[NP]
Pressure [hPa].
Definition: jurassic.h:1230
int nw
Number of spectral windows.
Definition: jurassic.h:1292
int ng
Number of emitters.
Definition: jurassic.h:1268
int ncl
Number of cloud layer spectral grid points.
Definition: jurassic.h:1298
int nsf
Number of surface layer spectral grid points.
Definition: jurassic.h:1304
char dir[LEN]
Working directory.
Definition: jurassic.h:1546
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 86 of file jurassic.c.

93 {
94
95 /* Loop over state vector elements... */
96 if (n0[iq] < N)
97 for (size_t i = 0; i < n1[iq]; i++) {
98
99 /* Get area of averaging kernel... */
100 for (size_t j = 0; j < n1[iq]; j++)
101 cont[ipa[n0[iq] + i]] += gsl_matrix_get(avk, n0[iq] + i, n0[iq] + j);
102
103 /* Get information density... */
104 res[ipa[n0[iq] + i]] = 1 / gsl_matrix_get(avk, n0[iq] + i, n0[iq] + i);
105 }
106}

◆ 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 110 of file jurassic.c.

115 {
116
117 size_t n = 0;
118
119 /* Add pressure... */
120 for (int ip = 0; ip < atm->np; ip++)
121 if (atm->z[ip] >= ctl->retp_zmin && atm->z[ip] <= ctl->retp_zmax)
122 atm2x_help(atm->p[ip], IDXP, ip, x, iqa, ipa, &n);
123
124 /* Add temperature... */
125 for (int ip = 0; ip < atm->np; ip++)
126 if (atm->z[ip] >= ctl->rett_zmin && atm->z[ip] <= ctl->rett_zmax)
127 atm2x_help(atm->t[ip], IDXT, ip, x, iqa, ipa, &n);
128
129 /* Add volume mixing ratios... */
130 for (int ig = 0; ig < ctl->ng; ig++)
131 for (int ip = 0; ip < atm->np; ip++)
132 if (atm->z[ip] >= ctl->retq_zmin[ig]
133 && atm->z[ip] <= ctl->retq_zmax[ig])
134 atm2x_help(atm->q[ig][ip], IDXQ(ig), ip, x, iqa, ipa, &n);
135
136 /* Add extinction... */
137 for (int iw = 0; iw < ctl->nw; iw++)
138 for (int ip = 0; ip < atm->np; ip++)
139 if (atm->z[ip] >= ctl->retk_zmin[iw]
140 && atm->z[ip] <= ctl->retk_zmax[iw])
141 atm2x_help(atm->k[iw][ip], IDXK(iw), ip, x, iqa, ipa, &n);
142
143 /* Add cloud variables... */
144 if (ctl->ret_clz)
145 atm2x_help(atm->clz, IDXCLZ, 0, x, iqa, ipa, &n);
146 if (ctl->ret_cldz)
147 atm2x_help(atm->cldz, IDXCLDZ, 0, x, iqa, ipa, &n);
148 if (ctl->ret_clk)
149 for (int icl = 0; icl < ctl->ncl; icl++)
150 atm2x_help(atm->clk[icl], IDXCLK(icl), 0, x, iqa, ipa, &n);
151
152 /* Add surface variables... */
153 if (ctl->ret_sft)
154 atm2x_help(atm->sft, IDXSFT, 0, x, iqa, ipa, &n);
155 if (ctl->ret_sfeps)
156 for (int isf = 0; isf < ctl->nsf; isf++)
157 atm2x_help(atm->sfeps[isf], IDXSFEPS(isf), 0, x, iqa, ipa, &n);
158
159 return n;
160}
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:164
int np
Number of data points.
Definition: jurassic.h:1215
double z[NP]
Altitude [km].
Definition: jurassic.h:1221
double retp_zmin
Minimum altitude for pressure retrieval [km].
Definition: jurassic.h:1364
double retk_zmax[NW]
Maximum altitude for extinction retrieval [km].
Definition: jurassic.h:1385
double rett_zmax
Maximum altitude for temperature retrieval [km].
Definition: jurassic.h:1373
int ret_sfeps
Retrieve surface layer emissivity (0=no, 1=yes).
Definition: jurassic.h:1400
int ret_sft
Retrieve surface layer temperature (0=no, 1=yes).
Definition: jurassic.h:1397
int ret_clz
Retrieve cloud layer height (0=no, 1=yes).
Definition: jurassic.h:1388
double retq_zmax[NG]
Maximum altitude for volume mixing ratio retrieval [km].
Definition: jurassic.h:1379
double retq_zmin[NG]
Minimum altitude for volume mixing ratio retrieval [km].
Definition: jurassic.h:1376
double rett_zmin
Minimum altitude for temperature retrieval [km].
Definition: jurassic.h:1370
double retk_zmin[NW]
Minimum altitude for extinction retrieval [km].
Definition: jurassic.h:1382
int ret_clk
Retrieve cloud layer extinction (0=no, 1=yes).
Definition: jurassic.h:1394
int ret_cldz
Retrieve cloud layer depth (0=no, 1=yes).
Definition: jurassic.h:1391
double retp_zmax
Maximum altitude for pressure retrieval [km].
Definition: jurassic.h:1367
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 164 of file jurassic.c.

171 {
172
173 /* Add element to state vector... */
174 if (x != NULL)
175 gsl_vector_set(x, *n, value);
176 if (iqa != NULL)
177 iqa[*n] = value_iqa;
178 if (ipa != NULL)
179 ipa[*n] = value_ip;
180 (*n)++;
181}

◆ 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 185 of file jurassic.c.

189 {
190
191 const double radius = NORM(x);
192
193 *lat = RAD2DEG(asin(x[2] / radius));
194 *lon = RAD2DEG(atan2(x[1], x[0]));
195 *z = radius - RE;
196}
#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:922
#define RAD2DEG(rad)
Convert radians to degrees.
Definition: jurassic.h:996

◆ 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 200 of file jurassic.c.

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

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

◆ 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 1179 of file jurassic.c.

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

◆ 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 1210 of file jurassic.c.

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

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

◆ 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 3125 of file jurassic.c.

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

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

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

◆ 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 3306 of file jurassic.c.

3310 {
3311
3312 /* Data size... */
3313 const size_t s = (size_t) obs_src->nr * sizeof(double);
3314
3315 /* Copy data... */
3316 obs_dest->nr = obs_src->nr;
3317 memcpy(obs_dest->time, obs_src->time, s);
3318 memcpy(obs_dest->obsz, obs_src->obsz, s);
3319 memcpy(obs_dest->obslon, obs_src->obslon, s);
3320 memcpy(obs_dest->obslat, obs_src->obslat, s);
3321 memcpy(obs_dest->vpz, obs_src->vpz, s);
3322 memcpy(obs_dest->vplon, obs_src->vplon, s);
3323 memcpy(obs_dest->vplat, obs_src->vplat, s);
3324 memcpy(obs_dest->tpz, obs_src->tpz, s);
3325 memcpy(obs_dest->tplon, obs_src->tplon, s);
3326 memcpy(obs_dest->tplat, obs_src->tplat, s);
3327 for (int id = 0; id < ctl->nd; id++)
3328 memcpy(obs_dest->rad[id], obs_src->rad[id], s);
3329 for (int id = 0; id < ctl->nd; id++)
3330 memcpy(obs_dest->tau[id], obs_src->tau[id], s);
3331
3332 /* Initialize... */
3333 if (init)
3334 for (int id = 0; id < ctl->nd; id++)
3335 for (int ir = 0; ir < obs_dest->nr; ir++)
3336 if (isfinite(obs_dest->rad[id][ir])) {
3337 obs_dest->rad[id][ir] = 0;
3338 obs_dest->tau[id][ir] = 0;
3339 }
3340}
int nd
Number of radiance channels.
Definition: jurassic.h:1286
double tau[ND][NR]
Transmittance of ray path.
Definition: jurassic.h:1527
double rad[ND][NR]
Radiance [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1530
double tplon[NR]
Tangent point longitude [deg].
Definition: jurassic.h:1521
double vpz[NR]
View point altitude [km].
Definition: jurassic.h:1509
double vplat[NR]
View point latitude [deg].
Definition: jurassic.h:1515
double obslon[NR]
Observer longitude [deg].
Definition: jurassic.h:1503
double obslat[NR]
Observer latitude [deg].
Definition: jurassic.h:1506
double obsz[NR]
Observer altitude [km].
Definition: jurassic.h:1500
double tplat[NR]
Tangent point latitude [deg].
Definition: jurassic.h:1524
double vplon[NR]
View point longitude [deg].
Definition: jurassic.h:1512
double time[NR]
Time (seconds since 2000-01-01T00:00Z).
Definition: jurassic.h:1497
double tpz[NR]
Tangent point altitude [km].
Definition: jurassic.h:1518
int nr
Number of ray paths.
Definition: jurassic.h:1494

◆ 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 3344 of file jurassic.c.

3348 {
3349
3350 const int d0[12] =
3351 { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
3352 const int d0l[12] =
3353 { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
3354
3355 /* Get day of year... */
3356 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
3357 *doy = d0l[mon - 1] + day - 1;
3358 else
3359 *doy = d0[mon - 1] + day - 1;
3360}

◆ 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 3364 of file jurassic.c.

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

◆ 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 3394 of file jurassic.c.

3396 {
3397
3398 for (int ig = 0; ig < ctl->ng; ig++)
3399 if (strcasecmp(ctl->emitter[ig], emitter) == 0)
3400 return ig;
3401
3402 return -1;
3403}

◆ 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 3407 of file jurassic.c.

3411 {
3412
3413 int *mask;
3414
3415 /* Allocate... */
3416 ALLOC(mask, int,
3417 ND * NR);
3418
3419 /* Save observation mask... */
3420 for (int id = 0; id < ctl->nd; id++)
3421 for (int ir = 0; ir < obs->nr; ir++)
3422 mask[id * NR + ir] = !isfinite(obs->rad[id][ir]);
3423
3424 /* Hydrostatic equilibrium... */
3425 hydrostatic(ctl, atm);
3426
3427 /* CGA or EGA forward model... */
3428 if (ctl->formod == 0 || ctl->formod == 1)
3429 for (int ir = 0; ir < obs->nr; ir++)
3430 formod_pencil(ctl, tbl, atm, obs, ir);
3431
3432 /* Call RFM... */
3433 else if (ctl->formod == 2)
3434 formod_rfm(ctl, atm, obs);
3435
3436 /* Apply field-of-view convolution... */
3437 formod_fov(ctl, obs);
3438
3439 /* Convert radiance to brightness temperature... */
3440 if (ctl->write_bbt)
3441 for (int id = 0; id < ctl->nd; id++)
3442 for (int ir = 0; ir < obs->nr; ir++)
3443 obs->rad[id][ir] = BRIGHT(obs->rad[id][ir], ctl->nu[id]);
3444
3445 /* Apply observation mask... */
3446 for (int id = 0; id < ctl->nd; id++)
3447 for (int ir = 0; ir < obs->nr; ir++)
3448 if (mask[id * NR + ir])
3449 obs->rad[id][ir] = NAN;
3450
3451 /* Free... */
3452 free(mask);
3453}
void formod_rfm(const ctl_t *ctl, const atm_t *atm, obs_t *obs)
Interface routine for the Reference Forward Model (RFM).
Definition: jurassic.c:3693
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:3558
void formod_fov(const ctl_t *ctl, obs_t *obs)
Apply field-of-view (FOV) convolution to modeled radiances.
Definition: jurassic.c:3493
void hydrostatic(const ctl_t *ctl, atm_t *atm)
Adjust pressure profile using the hydrostatic equation.
Definition: jurassic.c:3871
#define BRIGHT(rad, nu)
Compute brightness temperature from radiance.
Definition: jurassic.h:413
#define ND
Maximum number of radiance channels.
Definition: jurassic.h:238
#define ALLOC(ptr, type, n)
Allocate memory for an array.
Definition: jurassic.h:383
#define NR
Maximum number of ray paths.
Definition: jurassic.h:253
double nu[ND]
Centroid wavenumber of each channel [cm^-1].
Definition: jurassic.h:1289
int formod
Forward model (0=CGA, 1=EGA, 2=RFM).
Definition: jurassic.h:1409
int write_bbt
Use brightness temperature instead of radiance (0=no, 1=yes).
Definition: jurassic.h:1403
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 3457 of file jurassic.c.

3461 {
3462
3463 /* Extinction... */
3464 for (int id = 0; id < ctl->nd; id++)
3465 beta[id] = los->k[ip][id];
3466
3467 /* CO2 continuum... */
3468 if (ctl->ctm_co2 && ctl->ig_co2 >= 0)
3469 for (int id = 0; id < ctl->nd; id++)
3470 beta[id] += ctmco2(ctl->nu[id], los->p[ip], los->t[ip],
3471 los->u[ip][ctl->ig_co2]) / los->ds[ip];
3472
3473 /* H2O continuum... */
3474 if (ctl->ctm_h2o && ctl->ig_h2o >= 0)
3475 for (int id = 0; id < ctl->nd; id++)
3476 beta[id] += ctmh2o(ctl->nu[id], los->p[ip], los->t[ip],
3477 los->q[ip][ctl->ig_h2o], los->u[ip][ctl->ig_h2o])
3478 / los->ds[ip];
3479
3480 /* N2 continuum... */
3481 if (ctl->ctm_n2)
3482 for (int id = 0; id < ctl->nd; id++)
3483 beta[id] += ctmn2(ctl->nu[id], los->p[ip], los->t[ip]);
3484
3485 /* O2 continuum... */
3486 if (ctl->ctm_o2)
3487 for (int id = 0; id < ctl->nd; id++)
3488 beta[id] += ctmo2(ctl->nu[id], los->p[ip], los->t[ip]);
3489}
double ctmo2(const double nu, const double p, const double t)
Compute O₂ collision-induced absorption coefficient.
Definition: jurassic.c:3194
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:2073
double ctmco2(const double nu, const double p, const double t, const double u)
Compute carbon dioxide continuum (optical depth).
Definition: jurassic.c:1210
double ctmn2(const double nu, const double p, const double t)
Compute N₂ collision-induced absorption coefficient.
Definition: jurassic.c:3125
int ctm_co2
Compute CO2 continuum (0=no, 1=yes).
Definition: jurassic.h:1331
int ctm_n2
Compute N2 continuum (0=no, 1=yes).
Definition: jurassic.h:1337
int ctm_h2o
Compute H2O continuum (0=no, 1=yes).
Definition: jurassic.h:1334
int ctm_o2
Compute O2 continuum (0=no, 1=yes).
Definition: jurassic.h:1340
int ig_h2o
Emitter index of H2O.
Definition: jurassic.h:1277
double q[NLOS][NG]
Volume mixing ratio [ppv].
Definition: jurassic.h:1450
double ds[NLOS]
Segment length [km].
Definition: jurassic.h:1462
double u[NLOS][NG]
Column density [molecules/cm^2].
Definition: jurassic.h:1465
double k[NLOS][ND]
Extinction [km^-1].
Definition: jurassic.h:1453
double t[NLOS]
Temperature [K].
Definition: jurassic.h:1447
double p[NLOS]
Pressure [hPa].
Definition: jurassic.h:1444
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 3493 of file jurassic.c.

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

3563 {
3564
3565 los_t *los;
3566
3567 double beta_ctm[ND], rad[ND], tau[ND], tau_refl[ND],
3568 tau_path[ND][NG], tau_gas[ND], x0[3], x1[3];
3569
3570 /* Allocate... */
3571 ALLOC(los, los_t, 1);
3572
3573 /* Initialize... */
3574 for (int id = 0; id < ctl->nd; id++) {
3575 rad[id] = 0;
3576 tau[id] = 1;
3577 for (int ig = 0; ig < ctl->ng; ig++)
3578 tau_path[id][ig] = 1;
3579 }
3580
3581 /* Raytracing... */
3582 raytrace(ctl, atm, obs, los, ir);
3583
3584 /* Loop over LOS points... */
3585 for (int ip = 0; ip < los->np; ip++) {
3586
3587 /* Get trace gas transmittance... */
3588 if (ctl->formod == 0)
3589 intpol_tbl_cga(ctl, tbl, los, ip, tau_path, tau_gas);
3590 else
3591 intpol_tbl_ega(ctl, tbl, los, ip, tau_path, tau_gas);
3592
3593 /* Get continuum absorption... */
3594 formod_continua(ctl, los, ip, beta_ctm);
3595
3596 /* Compute Planck function... */
3597 formod_srcfunc(ctl, tbl, los->t[ip], los->src[ip]);
3598
3599 /* Loop over channels... */
3600 for (int id = 0; id < ctl->nd; id++)
3601 if (tau_gas[id] > 0) {
3602
3603 /* Get segment emissivity... */
3604 los->eps[ip][id] = 1 - tau_gas[id] * exp(-beta_ctm[id] * los->ds[ip]);
3605
3606 /* Compute radiance... */
3607 rad[id] += los->src[ip][id] * los->eps[ip][id] * tau[id];
3608
3609 /* Compute path transmittance... */
3610 tau[id] *= (1 - los->eps[ip][id]);
3611 }
3612 }
3613
3614 /* Check whether LOS hit the ground... */
3615 if (ctl->sftype >= 1 && los->sft > 0) {
3616
3617 /* Add surface emissions... */
3618 double src_sf[ND];
3619 formod_srcfunc(ctl, tbl, los->sft, src_sf);
3620 for (int id = 0; id < ctl->nd; id++)
3621 rad[id] += los->sfeps[id] * src_sf[id] * tau[id];
3622
3623 /* Check reflectivity... */
3624 int refl = 0;
3625 if (ctl->sftype >= 2)
3626 for (int id = 0; id < ctl->nd; id++)
3627 if (los->sfeps[id] < 1) {
3628 refl = 1;
3629 break;
3630 }
3631
3632 /* Calculate reflection... */
3633 if (refl) {
3634
3635 /* Initialize... */
3636 for (int id = 0; id < ctl->nd; id++)
3637 tau_refl[id] = 1;
3638
3639 /* Add down-welling radiance... */
3640 for (int ip = los->np - 1; ip >= 0; ip--)
3641 for (int id = 0; id < ctl->nd; id++) {
3642 rad[id] += los->src[ip][id] * los->eps[ip][id] * tau_refl[id]
3643 * tau[id] * (1 - los->sfeps[id]);
3644 tau_refl[id] *= (1 - los->eps[ip][id]);
3645 }
3646
3647 /* Add solar term... */
3648 if (ctl->sftype >= 3) {
3649
3650 /* Get cosine of solar zenith angle... */
3651 double cos_sza_val;
3652 if (ctl->sfsza < 0)
3653 cos_sza_val = cos_sza(obs->time[ir],
3654 los->lon[los->np - 1], los->lat[los->np - 1]);
3655 else
3656 cos_sza_val = cos(DEG2RAD(ctl->sfsza));
3657
3658 /* Check validity (avoid division by zero)... */
3659 if (cos_sza_val > 1e-6) {
3660
3661 /* Compute incidence direction cosine... */
3662 geo2cart(los->z[los->np - 1], los->lon[los->np - 1],
3663 los->lat[los->np - 1], x0);
3664 geo2cart(los->z[0], los->lon[0], los->lat[0], x1);
3665 for (int i = 0; i < 3; i++)
3666 x1[i] -= x0[i];
3667 const double cosa = DOTP(x0, x1) / NORM(x0) / NORM(x1);
3668
3669 /* Ratio of incident direction to solar zenith direction... */
3670 const double rcos = cosa / cos_sza_val;
3671
3672 /* Add solar radiance contribution... */
3673 for (int id = 0; id < ctl->nd; id++)
3674 rad[id] += 6.764e-5 / (2. * M_PI) * PLANCK(TSUN, ctl->nu[id])
3675 * tau_refl[id] * (1 - los->sfeps[id]) * tau[id] * rcos;
3676 }
3677 }
3678 }
3679 }
3680
3681 /* Copy results... */
3682 for (int id = 0; id < ctl->nd; id++) {
3683 obs->rad[id][ir] = rad[id];
3684 obs->tau[id][ir] = tau[id];
3685 }
3686
3687 /* Free... */
3688 free(los);
3689}
double cos_sza(const double sec, const double lon, const double lat)
Calculates the cosine of the solar zenith angle.
Definition: jurassic.c:1138
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:4138
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:3457
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:4871
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:4049
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:3834
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:3851
#define DOTP(a, b)
Compute dot product of two 3D vectors.
Definition: jurassic.h:483
#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:953
double sfsza
Solar zenith angle at the surface [deg] (-999=auto).
Definition: jurassic.h:1313
int sftype
Surface treatment (0=none, 1=emissions, 2=downward, 3=solar).
Definition: jurassic.h:1310
Line-of-sight data.
Definition: jurassic.h:1429
double z[NLOS]
Altitude [km].
Definition: jurassic.h:1435
double eps[NLOS][ND]
Segment emissivity.
Definition: jurassic.h:1477
double sft
Surface temperature [K].
Definition: jurassic.h:1456
double lon[NLOS]
Longitude [deg].
Definition: jurassic.h:1438
int np
Number of LOS points.
Definition: jurassic.h:1432
double lat[NLOS]
Latitude [deg].
Definition: jurassic.h:1441
double src[NLOS][ND]
Segment source function [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1480
double sfeps[ND]
Surface emissivity.
Definition: jurassic.h:1459
Here is the call graph for this function:

◆ formod_rfm()

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

Interface routine for the Reference Forward Model (RFM).

Prepares input data, executes the RFM executable, and imports simulated radiances and transmittances into the observation structure. The routine converts the atmospheric and geometric configuration from internal JURASSIC data structures into RFM-compatible driver and atmosphere files, then reads the RFM output spectra.

Parameters
[in]ctlControl structure defining model configuration, RFM executable path, HITRAN database, and spectral setup.
[in]atmAtmospheric state structure containing pressure, temperature, and gas profiles.
[in,out]obsObservation geometry and radiance data to be populated with RFM-computed radiances and transmittances.
Note
The function assumes identical observer positions across all ray paths and no extinction data in atm. It automatically determines whether the geometry is limb, nadir, or observer-based.
Adds appropriate RFM flags (e.g., RAD, TRA, MIX, CTM) based on the control settings. Temporary files such as rfm.drv, rfm.atm, and rad_*.asc are created and removed automatically.
See also
ctl_t, atm_t, obs_t, raytrace, write_atm_rfm, read_shape, read_obs_rfm, geo2cart, NORM, DOTP
Exceptions
ERRMSGon inconsistent geometry, failed I/O, or system call errors.
Warning
Requires external RFM binary; ensure ctl_t::rfmbin is set.
Reference
Dudhia, A., "The Reference Forward Model (RFM)", JQSRT 186, 243–253 (2017)
Author
Lars Hoffmann

Definition at line 3693 of file jurassic.c.

3696 {
3697
3698 los_t *los;
3699
3700 FILE *out;
3701
3702 char cmd[2 * LEN], filename[2 * LEN],
3703 rfmflg[LEN] = { "RAD TRA MIX LIN SFC" };
3704
3705 double f[NSHAPE], nu[NSHAPE], nu0, nu1, obsz = -999, tsurf,
3706 xd[3], xo[3], xv[3], z[NR], zmin, zmax;
3707
3708 int n, nadir = 0;
3709
3710 /* Allocate... */
3711 ALLOC(los, los_t, 1);
3712
3713 /* Check observer positions... */
3714 for (int ir = 1; ir < obs->nr; ir++)
3715 if (obs->obsz[ir] != obs->obsz[0]
3716 || obs->obslon[ir] != obs->obslon[0]
3717 || obs->obslat[ir] != obs->obslat[0])
3718 ERRMSG("RFM interface requires identical observer positions!");
3719
3720 /* Check extinction data... */
3721 for (int iw = 0; iw < ctl->nw; iw++)
3722 for (int ip = 0; ip < atm->np; ip++)
3723 if (atm->k[iw][ip] != 0)
3724 ERRMSG("RFM interface cannot handle extinction data!");
3725
3726 /* Get altitude range of atmospheric data... */
3727 gsl_stats_minmax(&zmin, &zmax, atm->z, 1, (size_t) atm->np);
3728
3729 /* Observer within atmosphere? */
3730 if (obs->obsz[0] >= zmin && obs->obsz[0] <= zmax) {
3731 obsz = obs->obsz[0];
3732 strcat(rfmflg, " OBS");
3733 }
3734
3735 /* Determine tangent altitude or air mass factor... */
3736 for (int ir = 0; ir < obs->nr; ir++) {
3737
3738 /* Raytracing... */
3739 raytrace(ctl, atm, obs, los, ir);
3740
3741 /* Nadir? */
3742 if (obs->tpz[ir] <= zmin) {
3743 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xo);
3744 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xv);
3745 for (int i = 0; i < 3; i++)
3746 xd[i] = xo[i] - xv[i];
3747 z[ir] = NORM(xo) * NORM(xd) / DOTP(xo, xd);
3748 nadir++;
3749 } else
3750 z[ir] = obs->tpz[ir];
3751 }
3752 if (nadir > 0 && nadir < obs->nr)
3753 ERRMSG("Limb and nadir not simultaneously possible!");
3754
3755 /* Nadir? */
3756 if (nadir)
3757 strcat(rfmflg, " NAD");
3758
3759 /* Get surface temperature... */
3760 tsurf = atm->t[gsl_stats_min_index(atm->z, 1, (size_t) atm->np)];
3761
3762 /* Refraction? */
3763 if (!nadir && !ctl->refrac)
3764 strcat(rfmflg, " GEO");
3765
3766 /* Continua? */
3767 if (ctl->ctm_co2 || ctl->ctm_h2o || ctl->ctm_n2 || ctl->ctm_o2)
3768 strcat(rfmflg, " CTM");
3769
3770 /* Write atmospheric data file... */
3771 write_atm_rfm("rfm.atm", ctl, atm);
3772
3773 /* Loop over channels... */
3774 for (int id = 0; id < ctl->nd; id++) {
3775
3776 /* Read filter function... */
3777 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
3778 read_shape(filename, nu, f, &n);
3779
3780 /* Set spectral range... */
3781 nu0 = nu[0];
3782 nu1 = nu[n - 1];
3783
3784 /* Create RFM driver file... */
3785 if (!(out = fopen("rfm.drv", "w")))
3786 ERRMSG("Cannot create file!");
3787 fprintf(out, "*HDR\nRFM call by JURASSIC.\n");
3788 fprintf(out, "*FLG\n%s\n", rfmflg);
3789 fprintf(out, "*SPC\n%.4f %.4f 0.0005\n", nu0, nu1);
3790 fprintf(out, "*GAS\n");
3791 for (int ig = 0; ig < ctl->ng; ig++)
3792 fprintf(out, "%s\n", ctl->emitter[ig]);
3793 fprintf(out, "*ATM\nrfm.atm\n");
3794 fprintf(out, "*TAN\n");
3795 for (int ir = 0; ir < obs->nr; ir++)
3796 fprintf(out, "%g\n", z[ir]);
3797 fprintf(out, "*SFC\n%g 1.0\n", tsurf);
3798 if (obsz >= 0)
3799 fprintf(out, "*OBS\n%g\n", obsz);
3800 fprintf(out, "*HIT\n%s\n", ctl->rfmhit);
3801 fprintf(out, "*XSC\n");
3802 for (int ig = 0; ig < ctl->ng; ig++)
3803 if (ctl->rfmxsc[ig][0] != '-')
3804 fprintf(out, "%s\n", ctl->rfmxsc[ig]);
3805 fprintf(out, "*END\n");
3806 fclose(out);
3807
3808 /* Remove temporary files... */
3809 if (system("rm -f rfm.runlog rad_*.asc tra_*.asc"))
3810 ERRMSG("Cannot remove temporary files!");
3811
3812 /* Call RFM... */
3813 sprintf(cmd, "echo | %s", ctl->rfmbin);
3814 if (system(cmd))
3815 ERRMSG("Error while calling RFM!");
3816
3817 /* Read data... */
3818 for (int ir = 0; ir < obs->nr; ir++) {
3819 obs->rad[id][ir] = read_obs_rfm("rad", z[ir], nu, f, n) * 1e-5;
3820 obs->tau[id][ir] = read_obs_rfm("tra", z[ir], nu, f, n);
3821 }
3822 }
3823
3824 /* Remove temporary files... */
3825 if (system("rm -f rfm.drv rfm.atm rfm.runlog rad_*.asc tra_*.asc"))
3826 ERRMSG("Error while removing temporary files!");
3827
3828 /* Free... */
3829 free(los);
3830}
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:5875
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:7173
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:6047
#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:1415
char tblbase[LEN]
Basename for table files and filter function files.
Definition: jurassic.h:1316
char rfmbin[LEN]
Path to RFM binary.
Definition: jurassic.h:1412
char rfmxsc[NG][LEN]
Emitter cross-section files for RFM.
Definition: jurassic.h:1418
int refrac
Take into account refractivity (0=no, 1=yes).
Definition: jurassic.h:1343
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 3834 of file jurassic.c.

3838 {
3839
3840 /* Determine index in temperature array... */
3841 const int it = locate_reg(tbl->st, TBLNS, t);
3842
3843 /* Interpolate Planck function value... */
3844 for (int id = 0; id < ctl->nd; id++)
3845 src[id] = LIN(tbl->st[it], tbl->sr[it][id],
3846 tbl->st[it + 1], tbl->sr[it + 1][id], t);
3847}
#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:1652
double st[TBLNS]
Source function temperature [K].
Definition: jurassic.h:1649
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 3851 of file jurassic.c.

3855 {
3856
3857 const double radius = z + RE;
3858
3859 const double latrad = lat / 180. * M_PI;
3860 const double lonrad = lon / 180. * M_PI;
3861
3862 const double coslat = cos(latrad);
3863
3864 x[0] = radius * coslat * cos(lonrad);
3865 x[1] = radius * coslat * sin(lonrad);
3866 x[2] = radius * sin(latrad);
3867}

◆ 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 3871 of file jurassic.c.

3873 {
3874
3875 const double mmair = 28.96456e-3, mmh2o = 18.0153e-3;
3876
3877 const int ipts = 20;
3878
3879 double dzmin = 1e99, e = 0;
3880
3881 int ipref = 0;
3882
3883 /* Check reference height... */
3884 if (ctl->hydz < 0)
3885 return;
3886
3887 /* Find air parcel next to reference height... */
3888 for (int ip = 0; ip < atm->np; ip++)
3889 if (fabs(atm->z[ip] - ctl->hydz) < dzmin) {
3890 dzmin = fabs(atm->z[ip] - ctl->hydz);
3891 ipref = ip;
3892 }
3893
3894 /* Upper part of profile... */
3895 for (int ip = ipref + 1; ip < atm->np; ip++) {
3896 double mean = 0;
3897 for (int i = 0; i < ipts; i++) {
3898 if (ctl->ig_h2o >= 0)
3899 e = LIN(0.0, atm->q[ctl->ig_h2o][ip - 1],
3900 ipts - 1.0, atm->q[ctl->ig_h2o][ip], (double) i);
3901 mean += (e * mmh2o + (1 - e) * mmair)
3902 * G0 / RI
3903 / LIN(0.0, atm->t[ip - 1], ipts - 1.0, atm->t[ip], (double) i) / ipts;
3904 }
3905
3906 /* Compute p(z,T)... */
3907 atm->p[ip] =
3908 exp(log(atm->p[ip - 1]) - mean * 1000 * (atm->z[ip] - atm->z[ip - 1]));
3909 }
3910
3911 /* Lower part of profile... */
3912 for (int ip = ipref - 1; ip >= 0; ip--) {
3913 double mean = 0;
3914 for (int i = 0; i < ipts; i++) {
3915 if (ctl->ig_h2o >= 0)
3916 e = LIN(0.0, atm->q[ctl->ig_h2o][ip + 1],
3917 ipts - 1.0, atm->q[ctl->ig_h2o][ip], (double) i);
3918 mean += (e * mmh2o + (1 - e) * mmair)
3919 * G0 / RI
3920 / LIN(0.0, atm->t[ip + 1], ipts - 1.0, atm->t[ip], (double) i) / ipts;
3921 }
3922
3923 /* Compute p(z,T)... */
3924 atm->p[ip] =
3925 exp(log(atm->p[ip + 1]) - mean * 1000 * (atm->z[ip] - atm->z[ip + 1]));
3926 }
3927}
#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:1328

◆ 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 3931 of file jurassic.c.

3934 {
3935
3936 if (idx == IDXP)
3937 sprintf(quantity, "PRESSURE");
3938
3939 if (idx == IDXT)
3940 sprintf(quantity, "TEMPERATURE");
3941
3942 for (int ig = 0; ig < ctl->ng; ig++)
3943 if (idx == IDXQ(ig))
3944 sprintf(quantity, "%s", ctl->emitter[ig]);
3945
3946 for (int iw = 0; iw < ctl->nw; iw++)
3947 if (idx == IDXK(iw))
3948 sprintf(quantity, "EXTINCT_WINDOW_%d", iw);
3949
3950 if (idx == IDXCLZ)
3951 sprintf(quantity, "CLOUD_HEIGHT");
3952
3953 if (idx == IDXCLDZ)
3954 sprintf(quantity, "CLOUD_DEPTH");
3955
3956 for (int icl = 0; icl < ctl->ncl; icl++)
3957 if (idx == IDXCLK(icl))
3958 sprintf(quantity, "CLOUD_EXTINCT_%.4f", ctl->clnu[icl]);
3959
3960 if (idx == IDXSFT)
3961 sprintf(quantity, "SURFACE_TEMPERATURE");
3962
3963 for (int isf = 0; isf < ctl->nsf; isf++)
3964 if (idx == IDXSFEPS(isf))
3965 sprintf(quantity, "SURFACE_EMISSIVITY_%.4f", ctl->sfnu[isf]);
3966}
double sfnu[NSF]
Surface layer wavenumber [cm^-1].
Definition: jurassic.h:1307
double clnu[NCL]
Cloud layer wavenumber [cm^-1].
Definition: jurassic.h:1301

◆ init_srcfunc()

void init_srcfunc ( const ctl_t ctl,
tbl_t tbl 
)

Initialize the source-function (Planck radiance) lookup table.

Computes channel-averaged Planck radiances for a range of temperatures and stores them in the source-function table. For each spectral channel, the Planck function is integrated over the instrument filter function defined in the corresponding filter file (*.filt).

Parameters
[in]ctlControl structure defining spectral channels and table base name.
[out]tblEmissivity and source-function lookup table to populate.
Note
The source function is tabulated for TBLNS temperature levels uniformly distributed between TMIN and TMAX. Integration over the spectral response is performed using linear interpolation and uniform grid spacing.
See also
ctl_t, tbl_t, read_shape, locate_irr, LIN, PLANCK, TBLNS, TMIN, TMAX
Parallelization
Implemented with OpenMP to compute each temperature level concurrently.
Output
Writes diagnostic information via LOG at verbosity levels 1 and 2.
Warning
Requires valid filter files named <tblbase>_<wavenumber>.filt.
Author
Lars Hoffmann

Definition at line 3970 of file jurassic.c.

3972 {
3973
3974 char filename[2 * LEN];
3975
3976 double f[NSHAPE], nu[NSHAPE];
3977
3978 int n;
3979
3980 /* Write info... */
3981 LOG(1, "Initialize source function table...");
3982 LOG(2, "Number of data points: %d", TBLNS);
3983
3984 /* Loop over channels... */
3985 for (int id = 0; id < ctl->nd; id++) {
3986
3987 /* Read filter function... */
3988 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
3989 read_shape(filename, nu, f, &n);
3990
3991 /* Get minimum grid spacing... */
3992 double dnu = 1.0;
3993 for (int i = 1; i < n; i++)
3994 dnu = MIN(dnu, nu[i] - nu[i - 1]);
3995
3996 /* Compute source function table... */
3997#pragma omp parallel for default(none) shared(ctl,tbl,id,nu,f,n,dnu)
3998 for (int it = 0; it < TBLNS; it++) {
3999
4000 /* Set temperature... */
4001 tbl->st[it] = LIN(0.0, TMIN, TBLNS - 1.0, TMAX, (double) it);
4002
4003 /* Integrate Planck function... */
4004 double fsum = tbl->sr[it][id] = 0;
4005 for (double fnu = nu[0]; fnu <= nu[n - 1]; fnu += dnu) {
4006 const int i = locate_irr(nu, n, fnu);
4007 const double ff = LIN(nu[i], f[i], nu[i + 1], f[i + 1], fnu);
4008 fsum += ff;
4009 tbl->sr[it][id] += ff * PLANCK(tbl->st[it], fnu);
4010 }
4011 tbl->sr[it][id] /= fsum;
4012 }
4013
4014 /* Write info... */
4015 LOG(2,
4016 "channel= %.4f cm^-1 | T= %g ... %g K | B= %g ... %g W/(m^2 sr cm^-1)",
4017 ctl->nu[id], tbl->st[0], tbl->st[TBLNS - 1], tbl->sr[0][id],
4018 tbl->sr[TBLNS - 1][id]);
4019 }
4020}
#define LOG(level,...)
Print a log message with a specified logging level.
Definition: jurassic.h:1092
#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 4024 of file jurassic.c.

4031 {
4032
4033 /* Get array index... */
4034 const int ip = locate_irr(atm->z, atm->np, z);
4035
4036 /* Interpolate... */
4037 *p = LOGY(atm->z[ip], atm->p[ip], atm->z[ip + 1], atm->p[ip + 1], z);
4038 *t = LIN(atm->z[ip], atm->t[ip], atm->z[ip + 1], atm->t[ip + 1], z);
4039 for (int ig = 0; ig < ctl->ng; ig++)
4040 q[ig] =
4041 LIN(atm->z[ip], atm->q[ig][ip], atm->z[ip + 1], atm->q[ig][ip + 1], z);
4042 for (int iw = 0; iw < ctl->nw; iw++)
4043 k[iw] =
4044 LIN(atm->z[ip], atm->k[iw][ip], atm->z[ip + 1], atm->k[iw][ip + 1], z);
4045}
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 4049 of file jurassic.c.

4055 {
4056
4057 double eps;
4058
4059 /* Loop over channels... */
4060 for (int id = 0; id < ctl->nd; id++) {
4061
4062 /* Initialize... */
4063 tau_seg[id] = 1;
4064
4065 /* Loop over emitters.... */
4066 for (int ig = 0; ig < ctl->ng; ig++) {
4067
4068 /* Check size of table (pressure) and column density... */
4069 if (tbl->np[id][ig] < 30 || los->cgu[ip][ig] <= 0)
4070 eps = 0;
4071
4072 /* Check transmittance... */
4073 else if (tau_path[id][ig] < 1e-9)
4074 eps = 1;
4075
4076 /* Interpolate... */
4077 else {
4078
4079 /* Determine pressure and temperature indices... */
4080 const int ipr =
4081 locate_irr(tbl->p[id][ig], tbl->np[id][ig], los->cgp[ip][ig]);
4082 const int it0 = locate_reg(tbl->t[id][ig][ipr], tbl->nt[id][ig][ipr],
4083 los->cgt[ip][ig]);
4084 const int it1 =
4085 locate_reg(tbl->t[id][ig][ipr + 1], tbl->nt[id][ig][ipr + 1],
4086 los->cgt[ip][ig]);
4087
4088 /* Check size of table (temperature and column density)... */
4089 if (tbl->nt[id][ig][ipr] < 2 || tbl->nt[id][ig][ipr + 1] < 2
4090 || tbl->nu[id][ig][ipr][it0] < 2
4091 || tbl->nu[id][ig][ipr][it0 + 1] < 2
4092 || tbl->nu[id][ig][ipr + 1][it1] < 2
4093 || tbl->nu[id][ig][ipr + 1][it1 + 1] < 2)
4094 eps = 0;
4095
4096 else {
4097
4098 /* Get emissivities of extended path... */
4099 double eps00
4100 = intpol_tbl_eps(tbl, ig, id, ipr, it0, los->cgu[ip][ig]);
4101 double eps01 =
4102 intpol_tbl_eps(tbl, ig, id, ipr, it0 + 1, los->cgu[ip][ig]);
4103 double eps10 =
4104 intpol_tbl_eps(tbl, ig, id, ipr + 1, it1, los->cgu[ip][ig]);
4105 double eps11 =
4106 intpol_tbl_eps(tbl, ig, id, ipr + 1, it1 + 1, los->cgu[ip][ig]);
4107
4108 /* Interpolate with respect to temperature... */
4109 eps00 = LIN(tbl->t[id][ig][ipr][it0], eps00,
4110 tbl->t[id][ig][ipr][it0 + 1], eps01, los->cgt[ip][ig]);
4111 eps11 = LIN(tbl->t[id][ig][ipr + 1][it1], eps10,
4112 tbl->t[id][ig][ipr + 1][it1 + 1],
4113 eps11, los->cgt[ip][ig]);
4114
4115 /* Interpolate with respect to pressure... */
4116 eps00 = LOGX(tbl->p[id][ig][ipr], eps00,
4117 tbl->p[id][ig][ipr + 1], eps11, los->cgp[ip][ig]);
4118
4119 /* Check emissivity range... */
4120 eps00 = MAX(MIN(eps00, 1), 0);
4121
4122 /* Determine segment emissivity... */
4123 eps = 1 - (1 - eps00) / tau_path[id][ig];
4124 }
4125 }
4126
4127 /* Get transmittance of extended path... */
4128 tau_path[id][ig] *= (1 - eps);
4129
4130 /* Get segment transmittance... */
4131 tau_seg[id] *= (1 - eps);
4132 }
4133 }
4134}
double intpol_tbl_eps(const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double u)
Interpolate emissivity from lookup tables as a function of column density.
Definition: jurassic.c:4234
#define LOGX(x0, y0, x1, y1, x)
Compute logarithmic interpolation in x.
Definition: jurassic.h:570
double cgu[NLOS][NG]
Curtis-Godson column density [molecules/cm^2].
Definition: jurassic.h:1474
double cgt[NLOS][NG]
Curtis-Godson temperature [K].
Definition: jurassic.h:1471
double cgp[NLOS][NG]
Curtis-Godson pressure [hPa].
Definition: jurassic.h:1468
double p[ND][NG][TBLNP]
Pressure [hPa].
Definition: jurassic.h:1637
int nu[ND][NG][TBLNP][TBLNT]
Number of column densities.
Definition: jurassic.h:1634
int nt[ND][NG][TBLNP]
Number of temperatures.
Definition: jurassic.h:1631
double t[ND][NG][TBLNP][TBLNT]
Temperature [K].
Definition: jurassic.h:1640
int np[ND][NG]
Number of pressure levels.
Definition: jurassic.h:1628
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 4138 of file jurassic.c.

4144 {
4145
4146 double eps, u;
4147
4148 /* Loop over channels... */
4149 for (int id = 0; id < ctl->nd; id++) {
4150
4151 /* Initialize... */
4152 tau_seg[id] = 1;
4153
4154 /* Loop over emitters.... */
4155 for (int ig = 0; ig < ctl->ng; ig++) {
4156
4157 /* Check size of table (pressure) and column density... */
4158 if (tbl->np[id][ig] < 30 || los->cgu[ip][ig] <= 0)
4159 eps = 0;
4160
4161 /* Check transmittance... */
4162 else if (tau_path[id][ig] < 1e-9)
4163 eps = 1;
4164
4165 /* Interpolate... */
4166 else {
4167
4168 /* Determine pressure and temperature indices... */
4169 const int ipr =
4170 locate_irr(tbl->p[id][ig], tbl->np[id][ig], los->p[ip]);
4171 const int it0 =
4172 locate_reg(tbl->t[id][ig][ipr], tbl->nt[id][ig][ipr], los->t[ip]);
4173 const int it1 =
4174 locate_reg(tbl->t[id][ig][ipr + 1], tbl->nt[id][ig][ipr + 1],
4175 los->t[ip]);
4176
4177 /* Check size of table (temperature and column density)... */
4178 if (tbl->nt[id][ig][ipr] < 2 || tbl->nt[id][ig][ipr + 1] < 2
4179 || tbl->nu[id][ig][ipr][it0] < 2
4180 || tbl->nu[id][ig][ipr][it0 + 1] < 2
4181 || tbl->nu[id][ig][ipr + 1][it1] < 2
4182 || tbl->nu[id][ig][ipr + 1][it1 + 1] < 2)
4183 eps = 0;
4184
4185 else {
4186
4187 /* Get emissivities of extended path... */
4188 u = intpol_tbl_u(tbl, ig, id, ipr, it0, 1 - tau_path[id][ig]);
4189 double eps00
4190 = intpol_tbl_eps(tbl, ig, id, ipr, it0, u + los->u[ip][ig]);
4191
4192 u = intpol_tbl_u(tbl, ig, id, ipr, it0 + 1, 1 - tau_path[id][ig]);
4193 double eps01 =
4194 intpol_tbl_eps(tbl, ig, id, ipr, it0 + 1, u + los->u[ip][ig]);
4195
4196 u = intpol_tbl_u(tbl, ig, id, ipr + 1, it1, 1 - tau_path[id][ig]);
4197 double eps10 =
4198 intpol_tbl_eps(tbl, ig, id, ipr + 1, it1, u + los->u[ip][ig]);
4199
4200 u =
4201 intpol_tbl_u(tbl, ig, id, ipr + 1, it1 + 1, 1 - tau_path[id][ig]);
4202 double eps11 =
4203 intpol_tbl_eps(tbl, ig, id, ipr + 1, it1 + 1, u + los->u[ip][ig]);
4204
4205 /* Interpolate with respect to temperature... */
4206 eps00 = LIN(tbl->t[id][ig][ipr][it0], eps00,
4207 tbl->t[id][ig][ipr][it0 + 1], eps01, los->t[ip]);
4208 eps11 = LIN(tbl->t[id][ig][ipr + 1][it1], eps10,
4209 tbl->t[id][ig][ipr + 1][it1 + 1], eps11, los->t[ip]);
4210
4211 /* Interpolate with respect to pressure... */
4212 eps00 = LIN(tbl->p[id][ig][ipr], eps00,
4213 tbl->p[id][ig][ipr + 1], eps11, los->p[ip]);
4214
4215 /* Check emissivity range... */
4216 eps00 = MAX(MIN(eps00, 1), 0);
4217
4218 /* Determine segment emissivity... */
4219 eps = 1 - (1 - eps00) / tau_path[id][ig];
4220 }
4221 }
4222
4223 /* Get transmittance of extended path... */
4224 tau_path[id][ig] *= (1 - eps);
4225
4226 /* Get segment transmittance... */
4227 tau_seg[id] *= (1 - eps);
4228 }
4229 }
4230}
double intpol_tbl_u(const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double eps)
Interpolate column density from lookup tables as a function of emissivity.
Definition: jurassic.c:4266
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  u 
)
inline

Interpolate emissivity from lookup tables as a function of column density.

Retrieves the emissivity corresponding to a given column density u for a specific gas, channel, pressure level, and temperature index from the precomputed emissivity tables.

Parameters
[in]tblEmissivity lookup tables (tbl_t).
[in]igGas index.
[in]idChannel index.
[in]ipPressure level index.
[in]itTemperature level index.
[in]uColumn density [molecules/cm²].
Returns
Interpolated emissivity value in the range [0, 1].
  • Performs linear interpolation in column density between adjacent grid points using LIN.
  • Applies lower-bound extrapolation proportional to u for u < u_min.
  • Applies exponential upper-bound extrapolation ensuring asymptotic emissivity growth (eps → 1 as u → ∞).
  • The input arrays are taken from tbl->u and tbl->eps.
See also
tbl_t, LIN, locate_tbl
Note
Used by both the Curtis–Godson (CGA) and Emissivity Growth Approximation (EGA) interpolation schemes.
Author
Lars Hoffmann

Definition at line 4234 of file jurassic.c.

4240 {
4241
4242 const int nu = tbl->nu[id][ig][ip][it];
4243 const float *u_arr = tbl->u[id][ig][ip][it];
4244 const float *eps_arr = tbl->eps[id][ig][ip][it];
4245
4246 const double u_min = u_arr[0];
4247 const double u_max = u_arr[nu - 1];
4248
4249 /* Lower boundary extrapolation... */
4250 if (u < u_min)
4251 return eps_arr[0] * u / u_min;
4252
4253 /* Upper boundary extrapolation... */
4254 if (u > u_max) {
4255 const double a = log(1.0 - eps_arr[nu - 1]) / u_max;
4256 return 1.0 - exp(a * u);
4257 }
4258
4259 /* Interpolation... */
4260 const int idx = locate_tbl(u_arr, nu, u);
4261 return LIN(u_arr[idx], eps_arr[idx], u_arr[idx + 1], eps_arr[idx + 1], u);
4262}
int locate_tbl(const float *xx, const int n, const double x)
Locate index for interpolation within emissivity table grids.
Definition: jurassic.c:4475
float eps[ND][NG][TBLNP][TBLNT][TBLNU]
Emissivity.
Definition: jurassic.h:1646
float u[ND][NG][TBLNP][TBLNT][TBLNU]
Column density [molecules/cm^2].
Definition: jurassic.h:1643
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  eps 
)
inline

Interpolate column density from lookup tables as a function of emissivity.

Returns the column density corresponding to a given emissivity eps for a specific gas, channel, pressure level, and temperature index from the precomputed emissivity tables.

Parameters
[in]tblEmissivity lookup tables (tbl_t).
[in]igGas index.
[in]idChannel index.
[in]ipPressure level index.
[in]itTemperature level index.
[in]epsEmissivity value (0–1).
Returns
Interpolated column density [molecules/cm²].
  • Performs linear interpolation in emissivity between adjacent table entries using LIN.
  • For eps < eps_min, applies linear extrapolation proportional to emissivity.
  • For eps > eps_max, applies exponential extrapolation following the emissivity growth law.
  • The lookup is performed using tbl->eps and tbl->u.
See also
tbl_t, LIN, locate_tbl
Note
Used in the Emissivity Growth Approximation (EGA) to determine effective column density from transmittance.
Author
Lars Hoffmann

Definition at line 4266 of file jurassic.c.

4272 {
4273
4274 const int nu = tbl->nu[id][ig][ip][it];
4275 const float *eps_arr = tbl->eps[id][ig][ip][it];
4276 const float *u_arr = tbl->u[id][ig][ip][it];
4277
4278 const double eps_min = eps_arr[0];
4279 const double eps_max = eps_arr[nu - 1];
4280
4281 /* Lower boundary extrapolation... */
4282 if (eps < eps_min)
4283 return u_arr[0] * eps / eps_min;
4284
4285 /* Upper boundary extrapolation... */
4286 if (eps > eps_max) {
4287 const double a = log(1.0 - eps_max) / u_arr[nu - 1];
4288 return log(1.0 - eps) / a;
4289 }
4290
4291 /* Interpolation... */
4292 const int idx = locate_tbl(eps_arr, nu, eps);
4293 return LIN(eps_arr[idx], u_arr[idx], eps_arr[idx + 1], u_arr[idx + 1], eps);
4294}
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 4298 of file jurassic.c.

4306 {
4307
4308 struct tm t0, *t1;
4309
4310 t0.tm_year = 100;
4311 t0.tm_mon = 0;
4312 t0.tm_mday = 1;
4313 t0.tm_hour = 0;
4314 t0.tm_min = 0;
4315 t0.tm_sec = 0;
4316
4317 const time_t jsec0 = (time_t) jsec + timegm(&t0);
4318 t1 = gmtime(&jsec0);
4319
4320 *year = t1->tm_year + 1900;
4321 *mon = t1->tm_mon + 1;
4322 *day = t1->tm_mday;
4323 *hour = t1->tm_hour;
4324 *min = t1->tm_min;
4325 *sec = t1->tm_sec;
4326 *remain = jsec - floor(jsec);
4327}

◆ 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 4331 of file jurassic.c.

4336 {
4337
4338 int *iqa;
4339
4340 /* Get sizes... */
4341 const size_t m = k->size1;
4342 const size_t n = k->size2;
4343
4344 /* Allocate... */
4345 gsl_vector *x0 = gsl_vector_alloc(n);
4346 gsl_vector *yy0 = gsl_vector_alloc(m);
4347 ALLOC(iqa, int,
4348 N);
4349
4350 /* Compute radiance for undisturbed atmospheric data... */
4351 formod(ctl, tbl, atm, obs);
4352
4353 /* Compose vectors... */
4354 atm2x(ctl, atm, x0, iqa, NULL);
4355 obs2y(ctl, obs, yy0, NULL, NULL);
4356
4357 /* Initialize kernel matrix... */
4358 gsl_matrix_set_zero(k);
4359
4360 /* Loop over state vector elements... */
4361#pragma omp parallel for default(none) shared(ctl,tbl,atm,obs,k,x0,yy0,n,m,iqa)
4362 for (size_t j = 0; j < n; j++) {
4363
4364 /* Allocate... */
4365 atm_t *atm1;
4366 obs_t *obs1;
4367 ALLOC(atm1, atm_t, 1);
4368 ALLOC(obs1, obs_t, 1);
4369 gsl_vector *x1 = gsl_vector_alloc(n);
4370 gsl_vector *yy1 = gsl_vector_alloc(m);
4371
4372 /* Set perturbation size... */
4373 double h;
4374 if (iqa[j] == IDXP)
4375 h = MAX(fabs(0.01 * gsl_vector_get(x0, j)), 1e-7);
4376 else if (iqa[j] == IDXT)
4377 h = 1.0;
4378 else if (iqa[j] >= IDXQ(0) && iqa[j] < IDXQ(ctl->ng))
4379 h = MAX(fabs(0.01 * gsl_vector_get(x0, j)), 1e-15);
4380 else if (iqa[j] >= IDXK(0) && iqa[j] < IDXK(ctl->nw))
4381 h = 1e-4;
4382 else if (iqa[j] == IDXCLZ || iqa[j] == IDXCLDZ)
4383 h = 1.0;
4384 else if (iqa[j] >= IDXCLK(0) && iqa[j] < IDXCLK(ctl->ncl))
4385 h = 1e-4;
4386 else if (iqa[j] == IDXSFT)
4387 h = 1.0;
4388 else if (iqa[j] >= IDXSFEPS(0) && iqa[j] < IDXSFEPS(ctl->nsf))
4389 h = 1e-2;
4390 else
4391 ERRMSG("Cannot set perturbation size!");
4392
4393 /* Disturb state vector element... */
4394 gsl_vector_memcpy(x1, x0);
4395 gsl_vector_set(x1, j, gsl_vector_get(x1, j) + h);
4396 copy_atm(ctl, atm1, atm, 0);
4397 copy_obs(ctl, obs1, obs, 0);
4398 x2atm(ctl, x1, atm1);
4399
4400 /* Compute radiance for disturbed atmospheric data... */
4401 formod(ctl, tbl, atm1, obs1);
4402
4403 /* Compose measurement vector for disturbed radiance data... */
4404 obs2y(ctl, obs1, yy1, NULL, NULL);
4405
4406 /* Compute derivatives... */
4407 for (size_t i = 0; i < m; i++)
4408 gsl_matrix_set(k, i, j,
4409 (gsl_vector_get(yy1, i) - gsl_vector_get(yy0, i)) / h);
4410
4411 /* Free... */
4412 gsl_vector_free(x1);
4413 gsl_vector_free(yy1);
4414 free(atm1);
4415 free(obs1);
4416 }
4417
4418 /* Free... */
4419 gsl_vector_free(x0);
4420 gsl_vector_free(yy0);
4421 free(iqa);
4422}
void x2atm(const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
Map retrieval state vector back to atmospheric structure.
Definition: jurassic.c:8005
void formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
Execute the selected forward model.
Definition: jurassic.c:3407
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:4572
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:110
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 4426 of file jurassic.c.

4429 {
4430
4431 int ilo = 0;
4432 int ihi = n - 1;
4433 int i = (ihi + ilo) >> 1;
4434
4435 if (xx[i] < xx[i + 1])
4436 while (ihi > ilo + 1) {
4437 i = (ihi + ilo) >> 1;
4438 if (xx[i] > x)
4439 ihi = i;
4440 else
4441 ilo = i;
4442 } else
4443 while (ihi > ilo + 1) {
4444 i = (ihi + ilo) >> 1;
4445 if (xx[i] <= x)
4446 ihi = i;
4447 else
4448 ilo = i;
4449 }
4450
4451 return ilo;
4452}

◆ 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 4456 of file jurassic.c.

4459 {
4460
4461 /* Calculate index... */
4462 const int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
4463
4464 /* Check range... */
4465 if (i < 0)
4466 return 0;
4467 else if (i > n - 2)
4468 return n - 2;
4469 else
4470 return i;
4471}

◆ 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 4475 of file jurassic.c.

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

◆ 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 4497 of file jurassic.c.

4498 {
4499
4500 size_t diag = 1;
4501
4502 /* Get size... */
4503 const size_t n = a->size1;
4504
4505 /* Check if matrix is diagonal... */
4506 for (size_t i = 0; i < n && diag; i++)
4507 for (size_t j = i + 1; j < n; j++)
4508 if (gsl_matrix_get(a, i, j) != 0) {
4509 diag = 0;
4510 break;
4511 }
4512
4513 /* Quick inversion of diagonal matrix... */
4514 if (diag)
4515 for (size_t i = 0; i < n; i++)
4516 gsl_matrix_set(a, i, i, 1 / gsl_matrix_get(a, i, i));
4517
4518 /* Matrix inversion by means of Cholesky decomposition... */
4519 else {
4520 gsl_linalg_cholesky_decomp(a);
4521 gsl_linalg_cholesky_invert(a);
4522 }
4523}

◆ 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 4527 of file jurassic.c.

4531 {
4532
4533 /* Set sizes... */
4534 const size_t m = a->size1;
4535 const size_t n = a->size2;
4536
4537 /* Allocate... */
4538 gsl_matrix *aux = gsl_matrix_alloc(m, n);
4539
4540 /* Compute A^T B A... */
4541 if (transpose == 1) {
4542
4543 /* Compute B^1/2 A... */
4544 for (size_t i = 0; i < m; i++)
4545 for (size_t j = 0; j < n; j++)
4546 gsl_matrix_set(aux, i, j,
4547 gsl_vector_get(b, i) * gsl_matrix_get(a, i, j));
4548
4549 /* Compute A^T B A = (B^1/2 A)^T (B^1/2 A)... */
4550 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, aux, aux, 0.0, c);
4551 }
4552
4553 /* Compute A B A^T... */
4554 else if (transpose == 2) {
4555
4556 /* Compute A B^1/2... */
4557 for (size_t i = 0; i < m; i++)
4558 for (size_t j = 0; j < n; j++)
4559 gsl_matrix_set(aux, i, j,
4560 gsl_matrix_get(a, i, j) * gsl_vector_get(b, j));
4561
4562 /* Compute A B A^T = (A B^1/2) (A B^1/2)^T... */
4563 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, aux, aux, 0.0, c);
4564 }
4565
4566 /* Free... */
4567 gsl_matrix_free(aux);
4568}

◆ 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 4572 of file jurassic.c.

4577 {
4578
4579 size_t m = 0;
4580
4581 /* Determine measurement vector... */
4582 for (int ir = 0; ir < obs->nr; ir++)
4583 for (int id = 0; id < ctl->nd; id++)
4584 if (isfinite(obs->rad[id][ir])) {
4585 if (y != NULL)
4586 gsl_vector_set(y, m, obs->rad[id][ir]);
4587 if (ida != NULL)
4588 ida[m] = id;
4589 if (ira != NULL)
4590 ira[m] = ir;
4591 m++;
4592 }
4593
4594 return m;
4595}

◆ 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 4599 of file jurassic.c.

4607 {
4608
4609 static int ipa[N], iqa[N];
4610
4611 double disq = 0, lmpar = 0.001;
4612
4613 /* ------------------------------------------------------------
4614 Initialize...
4615 ------------------------------------------------------------ */
4616
4617 /* Get sizes... */
4618 const size_t m = obs2y(ctl, obs_meas, NULL, NULL, NULL);
4619 const size_t n = atm2x(ctl, atm_apr, NULL, iqa, ipa);
4620 if (m == 0 || n == 0) {
4621 WARN("Check problem definition (m = 0 or n = 0)!");
4622 *chisq = GSL_NAN;
4623 return;
4624 }
4625
4626 /* Allocate... */
4627 gsl_matrix *a = gsl_matrix_alloc(n, n);
4628 gsl_matrix *cov = gsl_matrix_alloc(n, n);
4629 gsl_matrix *k_i = gsl_matrix_alloc(m, n);
4630 gsl_matrix *s_a_inv = gsl_matrix_alloc(n, n);
4631
4632 gsl_vector *b = gsl_vector_alloc(n);
4633 gsl_vector *dx = gsl_vector_alloc(n);
4634 gsl_vector *dy = gsl_vector_alloc(m);
4635 gsl_vector *sig_eps_inv = gsl_vector_alloc(m);
4636 gsl_vector *sig_formod = gsl_vector_alloc(m);
4637 gsl_vector *sig_noise = gsl_vector_alloc(m);
4638 gsl_vector *x_a = gsl_vector_alloc(n);
4639 gsl_vector *x_i = gsl_vector_alloc(n);
4640 gsl_vector *x_step = gsl_vector_alloc(n);
4641 gsl_vector *y_aux = gsl_vector_alloc(m);
4642 gsl_vector *y_i = gsl_vector_alloc(m);
4643 gsl_vector *y_m = gsl_vector_alloc(m);
4644
4645 /* Set initial state... */
4646 copy_atm(ctl, atm_i, atm_apr, 0);
4647 copy_obs(ctl, obs_i, obs_meas, 0);
4648 formod(ctl, tbl, atm_i, obs_i);
4649
4650 /* Set state vectors and observation vectors... */
4651 atm2x(ctl, atm_apr, x_a, NULL, NULL);
4652 atm2x(ctl, atm_i, x_i, NULL, NULL);
4653 obs2y(ctl, obs_meas, y_m, NULL, NULL);
4654 obs2y(ctl, obs_i, y_i, NULL, NULL);
4655
4656 /* Set inverse a priori covariance S_a^-1... */
4657 set_cov_apr(ret, ctl, atm_apr, iqa, ipa, s_a_inv);
4658 write_matrix(ret->dir, "matrix_cov_apr.tab", ctl, s_a_inv,
4659 atm_i, obs_i, "x", "x", "r");
4660 matrix_invert(s_a_inv);
4661
4662 /* Get measurement errors... */
4663 set_cov_meas(ret, ctl, obs_meas, sig_noise, sig_formod, sig_eps_inv);
4664
4665 /* Determine dx = x_i - x_a and dy = y - F(x_i) ... */
4666 gsl_vector_memcpy(dx, x_i);
4667 gsl_vector_sub(dx, x_a);
4668 gsl_vector_memcpy(dy, y_m);
4669 gsl_vector_sub(dy, y_i);
4670
4671 /* Compute cost function... */
4672 *chisq = cost_function(dx, dy, s_a_inv, sig_eps_inv);
4673
4674 /* Write info... */
4675 LOG(2, "it= %d / chi^2/m= %g", 0, *chisq);
4676
4677 /* Compute initial kernel... */
4678 kernel(ctl, tbl, atm_i, obs_i, k_i);
4679
4680 /* ------------------------------------------------------------
4681 Levenberg-Marquardt minimization...
4682 ------------------------------------------------------------ */
4683
4684 /* Outer loop... */
4685 for (int it = 1; it <= ret->conv_itmax; it++) {
4686
4687 /* Store current cost function value... */
4688 double chisq_old = *chisq;
4689
4690 /* Compute kernel matrix K_i... */
4691 if (it > 1 && it % ret->kernel_recomp == 0)
4692 kernel(ctl, tbl, atm_i, obs_i, k_i);
4693
4694 /* Compute K_i^T * S_eps^{-1} * K_i ... */
4695 if (it == 1 || it % ret->kernel_recomp == 0)
4696 matrix_product(k_i, sig_eps_inv, 1, cov);
4697
4698 /* Determine b = K_i^T * S_eps^{-1} * dy - S_a^{-1} * dx ... */
4699 for (size_t i = 0; i < m; i++)
4700 gsl_vector_set(y_aux, i, gsl_vector_get(dy, i)
4701 * POW2(gsl_vector_get(sig_eps_inv, i)));
4702 gsl_blas_dgemv(CblasTrans, 1.0, k_i, y_aux, 0.0, b);
4703 gsl_blas_dgemv(CblasNoTrans, -1.0, s_a_inv, dx, 1.0, b);
4704
4705 /* Inner loop... */
4706 for (int it2 = 0; it2 < 20; it2++) {
4707
4708 /* Compute A = (1 + lmpar) * S_a^{-1} + K_i^T * S_eps^{-1} * K_i ... */
4709 gsl_matrix_memcpy(a, s_a_inv);
4710 gsl_matrix_scale(a, 1 + lmpar);
4711 gsl_matrix_add(a, cov);
4712
4713 /* Solve A * x_step = b by means of Cholesky decomposition... */
4714 gsl_linalg_cholesky_decomp(a);
4715 gsl_linalg_cholesky_solve(a, b, x_step);
4716
4717 /* Update atmospheric state... */
4718 gsl_vector_add(x_i, x_step);
4719 copy_atm(ctl, atm_i, atm_apr, 0);
4720 copy_obs(ctl, obs_i, obs_meas, 0);
4721 x2atm(ctl, x_i, atm_i);
4722
4723 /* Check atmospheric state... */
4724 for (int ip = 0; ip < atm_i->np; ip++) {
4725 atm_i->p[ip] = MIN(MAX(atm_i->p[ip], 5e-7), 5e4);
4726 atm_i->t[ip] = MIN(MAX(atm_i->t[ip], 100), 400);
4727 for (int ig = 0; ig < ctl->ng; ig++)
4728 atm_i->q[ig][ip] = MIN(MAX(atm_i->q[ig][ip], 0), 1);
4729 for (int iw = 0; iw < ctl->nw; iw++)
4730 atm_i->k[iw][ip] = MAX(atm_i->k[iw][ip], 0);
4731 }
4732 atm_i->clz = MAX(atm_i->clz, 0);
4733 atm_i->cldz = MAX(atm_i->cldz, 0.1);
4734 for (int icl = 0; icl < ctl->ncl; icl++)
4735 atm_i->clk[icl] = MAX(atm_i->clk[icl], 0);
4736 atm_i->sft = MIN(MAX(atm_i->sft, 100), 400);
4737 for (int isf = 0; isf < ctl->nsf; isf++)
4738 atm_i->sfeps[isf] = MIN(MAX(atm_i->sfeps[isf], 0), 1);
4739
4740 /* Forward calculation... */
4741 formod(ctl, tbl, atm_i, obs_i);
4742 obs2y(ctl, obs_i, y_i, NULL, NULL);
4743
4744 /* Determine dx = x_i - x_a and dy = y - F(x_i) ... */
4745 gsl_vector_memcpy(dx, x_i);
4746 gsl_vector_sub(dx, x_a);
4747 gsl_vector_memcpy(dy, y_m);
4748 gsl_vector_sub(dy, y_i);
4749
4750 /* Compute cost function... */
4751 *chisq = cost_function(dx, dy, s_a_inv, sig_eps_inv);
4752
4753 /* Modify Levenberg-Marquardt parameter... */
4754 if (*chisq > chisq_old) {
4755 lmpar *= 10;
4756 gsl_vector_sub(x_i, x_step);
4757 } else {
4758 lmpar /= 10;
4759 break;
4760 }
4761 }
4762
4763 /* Write info... */
4764 LOG(2, "it= %d / chi^2/m= %g", it, *chisq);
4765
4766 /* Get normalized step size in state space... */
4767 gsl_blas_ddot(x_step, b, &disq);
4768 disq /= (double) n;
4769
4770 /* Convergence test... */
4771 if ((it == 1 || it % ret->kernel_recomp == 0) && disq < ret->conv_dmin)
4772 break;
4773 }
4774
4775 /* ------------------------------------------------------------
4776 Analysis of retrieval results...
4777 ------------------------------------------------------------ */
4778
4779 /* Check if error analysis is requested... */
4780 if (ret->err_ana) {
4781
4782 /* Store results... */
4783 write_atm(ret->dir, "atm_final.tab", ctl, atm_i);
4784 write_obs(ret->dir, "obs_final.tab", ctl, obs_i);
4785 write_matrix(ret->dir, "matrix_kernel.tab", ctl, k_i,
4786 atm_i, obs_i, "y", "x", "r");
4787
4788 /* Allocate... */
4789 gsl_matrix *auxnm = gsl_matrix_alloc(n, m);
4790 gsl_matrix *corr = gsl_matrix_alloc(n, n);
4791 gsl_matrix *gain = gsl_matrix_alloc(n, m);
4792
4793 /* Compute inverse retrieval covariance...
4794 cov^{-1} = S_a^{-1} + K_i^T * S_eps^{-1} * K_i */
4795 matrix_product(k_i, sig_eps_inv, 1, cov);
4796 gsl_matrix_add(cov, s_a_inv);
4797
4798 /* Compute retrieval covariance... */
4799 matrix_invert(cov);
4800 write_matrix(ret->dir, "matrix_cov_ret.tab", ctl, cov,
4801 atm_i, obs_i, "x", "x", "r");
4802 write_stddev("total", ret, ctl, atm_i, cov);
4803
4804 /* Compute correlation matrix... */
4805 for (size_t i = 0; i < n; i++)
4806 for (size_t j = 0; j < n; j++)
4807 gsl_matrix_set(corr, i, j, gsl_matrix_get(cov, i, j)
4808 / sqrt(gsl_matrix_get(cov, i, i))
4809 / sqrt(gsl_matrix_get(cov, j, j)));
4810 write_matrix(ret->dir, "matrix_corr.tab", ctl, corr,
4811 atm_i, obs_i, "x", "x", "r");
4812
4813 /* Compute gain matrix...
4814 G = cov * K^T * S_eps^{-1} */
4815 for (size_t i = 0; i < n; i++)
4816 for (size_t j = 0; j < m; j++)
4817 gsl_matrix_set(auxnm, i, j, gsl_matrix_get(k_i, j, i)
4818 * POW2(gsl_vector_get(sig_eps_inv, j)));
4819 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, cov, auxnm, 0.0, gain);
4820 write_matrix(ret->dir, "matrix_gain.tab", ctl, gain,
4821 atm_i, obs_i, "x", "y", "c");
4822
4823 /* Compute retrieval error due to noise... */
4824 matrix_product(gain, sig_noise, 2, a);
4825 write_stddev("noise", ret, ctl, atm_i, a);
4826
4827 /* Compute retrieval error due to forward model errors... */
4828 matrix_product(gain, sig_formod, 2, a);
4829 write_stddev("formod", ret, ctl, atm_i, a);
4830
4831 /* Compute averaging kernel matrix
4832 A = G * K ... */
4833 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, gain, k_i, 0.0, a);
4834 write_matrix(ret->dir, "matrix_avk.tab", ctl, a,
4835 atm_i, obs_i, "x", "x", "r");
4836
4837 /* Analyze averaging kernel matrix... */
4838 analyze_avk(ret, ctl, atm_i, iqa, ipa, a);
4839
4840 /* Free... */
4841 gsl_matrix_free(auxnm);
4842 gsl_matrix_free(corr);
4843 gsl_matrix_free(gain);
4844 }
4845
4846 /* ------------------------------------------------------------
4847 Finalize...
4848 ------------------------------------------------------------ */
4849
4850 gsl_matrix_free(a);
4851 gsl_matrix_free(cov);
4852 gsl_matrix_free(k_i);
4853 gsl_matrix_free(s_a_inv);
4854
4855 gsl_vector_free(b);
4856 gsl_vector_free(dx);
4857 gsl_vector_free(dy);
4858 gsl_vector_free(sig_eps_inv);
4859 gsl_vector_free(sig_formod);
4860 gsl_vector_free(sig_noise);
4861 gsl_vector_free(x_a);
4862 gsl_vector_free(x_i);
4863 gsl_vector_free(x_step);
4864 gsl_vector_free(y_aux);
4865 gsl_vector_free(y_i);
4866 gsl_vector_free(y_m);
4867}
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:1179
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:4527
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:6506
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:7389
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:4331
void matrix_invert(gsl_matrix *a)
Invert a square matrix, optimized for diagonal or symmetric positive-definite matrices.
Definition: jurassic.c:4497
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:7211
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:6395
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:7795
#define WARN(...)
Print a warning message with contextual information.
Definition: jurassic.h:1129
int err_ana
Carry out error analysis (0=no, 1=yes).
Definition: jurassic.h:1558
double conv_dmin
Minimum normalized step size in state space.
Definition: jurassic.h:1555
int kernel_recomp
Re-computation of kernel matrix (number of iterations).
Definition: jurassic.h:1549
int conv_itmax
Maximum number of iterations.
Definition: jurassic.h:1552
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 4871 of file jurassic.c.

4876 {
4877
4878 const double h = 0.02, zrefrac = 60;
4879
4880 double ex0[3], ex1[3], k[NW], lat, lon, n, ng[3], norm, p, q[NG], t,
4881 x[3], xh[3], xobs[3], xvp[3], z = 1e99, zmax, zmin;
4882
4883 int stop = 0;
4884
4885 /* Initialize... */
4886 los->np = 0;
4887 los->sft = -999;
4888 obs->tpz[ir] = obs->vpz[ir];
4889 obs->tplon[ir] = obs->vplon[ir];
4890 obs->tplat[ir] = obs->vplat[ir];
4891
4892 /* Get altitude range of atmospheric data... */
4893 gsl_stats_minmax(&zmin, &zmax, atm->z, 1, (size_t) atm->np);
4894
4895 /* Ensure that altitude grid includes the local geometric surface... */
4896 if (zmin > 1e-3 || zmin < -1e-3)
4897 ERRMSG("Atmospheric profiles must include surface level (z = 0 km)!");
4898
4899 /* Check observer altitude... */
4900 if (obs->obsz[ir] < zmin)
4901 ERRMSG("Observer below surface!");
4902
4903 /* Check view point altitude... */
4904 if (obs->vpz[ir] > zmax)
4905 return;
4906
4907 /* Determine Cartesian coordinates for observer and view point... */
4908 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xobs);
4909 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xvp);
4910
4911 /* Determine initial tangent vector... */
4912 for (int i = 0; i < 3; i++)
4913 ex0[i] = xvp[i] - xobs[i];
4914 norm = NORM(ex0);
4915 for (int i = 0; i < 3; i++)
4916 ex0[i] /= norm;
4917
4918 /* Observer within atmosphere... */
4919 for (int i = 0; i < 3; i++)
4920 x[i] = xobs[i];
4921
4922 /* Observer above atmosphere (search entry point)... */
4923 if (obs->obsz[ir] > zmax) {
4924 double dmax = norm, dmin = 0;
4925 while (fabs(dmin - dmax) > 0.001) {
4926 const double d = (dmax + dmin) / 2;
4927 for (int i = 0; i < 3; i++)
4928 x[i] = xobs[i] + d * ex0[i];
4929 cart2geo(x, &z, &lon, &lat);
4930 if (z <= zmax && z > zmax - 0.001)
4931 break;
4932 if (z < zmax - 0.0005)
4933 dmax = d;
4934 else
4935 dmin = d;
4936 }
4937 }
4938
4939 /* Ray-tracing... */
4940 while (1) {
4941
4942 /* Set step length... */
4943 double ds = ctl->rayds;
4944 if (ctl->raydz > 0) {
4945 norm = NORM(x);
4946 for (int i = 0; i < 3; i++)
4947 xh[i] = x[i] / norm;
4948 const double cosa = fabs(DOTP(ex0, xh));
4949 if (cosa != 0)
4950 ds = MIN(ctl->rayds, ctl->raydz / cosa);
4951 }
4952
4953 /* Determine geolocation... */
4954 cart2geo(x, &z, &lon, &lat);
4955
4956 /* Check if LOS hits the ground or has left atmosphere... */
4957 if (z < zmin || z > zmax) {
4958 stop = (z < zmin ? 2 : 1);
4959 const double frac =
4960 ((z <
4961 zmin ? zmin : zmax) - los->z[los->np - 1]) / (z - los->z[los->np -
4962 1]);
4963 geo2cart(los->z[los->np - 1], los->lon[los->np - 1],
4964 los->lat[los->np - 1], xh);
4965 for (int i = 0; i < 3; i++)
4966 x[i] = xh[i] + frac * (x[i] - xh[i]);
4967 cart2geo(x, &z, &lon, &lat);
4968 los->ds[los->np - 1] = ds * frac;
4969 ds = 0;
4970 }
4971
4972 /* Interpolate atmospheric data... */
4973 intpol_atm(ctl, atm, z, &p, &t, q, k);
4974
4975 /* Save data... */
4976 los->lon[los->np] = lon;
4977 los->lat[los->np] = lat;
4978 los->z[los->np] = z;
4979 los->p[los->np] = p;
4980 los->t[los->np] = t;
4981 for (int ig = 0; ig < ctl->ng; ig++)
4982 los->q[los->np][ig] = q[ig];
4983 for (int id = 0; id < ctl->nd; id++)
4984 los->k[los->np][id] = k[ctl->window[id]];
4985 los->ds[los->np] = ds;
4986
4987 /* Add cloud extinction... */
4988 if (ctl->ncl > 0 && atm->cldz > 0) {
4989 const double aux = exp(-0.5 * POW2((z - atm->clz) / atm->cldz));
4990 for (int id = 0; id < ctl->nd; id++) {
4991 const int icl = locate_irr(ctl->clnu, ctl->ncl, ctl->nu[id]);
4992 los->k[los->np][id]
4993 += aux * LIN(ctl->clnu[icl], atm->clk[icl],
4994 ctl->clnu[icl + 1], atm->clk[icl + 1], ctl->nu[id]);
4995 }
4996 }
4997
4998 /* Increment and check number of LOS points... */
4999 if ((++los->np) > NLOS)
5000 ERRMSG("Too many LOS points!");
5001
5002 /* Check stop flag... */
5003 if (stop) {
5004
5005 /* Set surface temperature... */
5006 if (ctl->nsf > 0 && atm->sft > 0)
5007 t = atm->sft;
5008 los->sft = (stop == 2 ? t : -999);
5009
5010 /* Set surface emissivity... */
5011 for (int id = 0; id < ctl->nd; id++) {
5012 los->sfeps[id] = 1.0;
5013 if (ctl->nsf > 0) {
5014 const int isf = locate_irr(ctl->sfnu, ctl->nsf, ctl->nu[id]);
5015 los->sfeps[id] = LIN(ctl->sfnu[isf], atm->sfeps[isf],
5016 ctl->sfnu[isf + 1], atm->sfeps[isf + 1],
5017 ctl->nu[id]);
5018 }
5019 }
5020
5021 /* Leave raytracer... */
5022 break;
5023 }
5024
5025 /* Determine refractivity... */
5026 if (ctl->refrac && z <= zrefrac)
5027 n = 1 + REFRAC(p, t);
5028 else
5029 n = 1;
5030
5031 /* Construct new tangent vector (first term)... */
5032 for (int i = 0; i < 3; i++)
5033 ex1[i] = ex0[i] * n;
5034
5035 /* Compute gradient of refractivity... */
5036 if (ctl->refrac && z <= zrefrac) {
5037 for (int i = 0; i < 3; i++)
5038 xh[i] = x[i] + 0.5 * ds * ex0[i];
5039 cart2geo(xh, &z, &lon, &lat);
5040 intpol_atm(ctl, atm, z, &p, &t, q, k);
5041 n = REFRAC(p, t);
5042 for (int i = 0; i < 3; i++) {
5043 xh[i] += h;
5044 cart2geo(xh, &z, &lon, &lat);
5045 intpol_atm(ctl, atm, z, &p, &t, q, k);
5046 ng[i] = (REFRAC(p, t) - n) / h;
5047 xh[i] -= h;
5048 }
5049 } else
5050 for (int i = 0; i < 3; i++)
5051 ng[i] = 0;
5052
5053 /* Construct new tangent vector (second term)... */
5054 for (int i = 0; i < 3; i++)
5055 ex1[i] += ds * ng[i];
5056
5057 /* Normalize new tangent vector... */
5058 norm = NORM(ex1);
5059 for (int i = 0; i < 3; i++)
5060 ex1[i] /= norm;
5061
5062 /* Determine next point of LOS... */
5063 for (int i = 0; i < 3; i++)
5064 x[i] += 0.5 * ds * (ex0[i] + ex1[i]);
5065
5066 /* Copy tangent vector... */
5067 for (int i = 0; i < 3; i++)
5068 ex0[i] = ex1[i];
5069 }
5070
5071 /* Get tangent point (to be done before changing segment lengths!)... */
5072 tangent_point(los, &obs->tpz[ir], &obs->tplon[ir], &obs->tplat[ir]);
5073
5074 /* Change segment lengths according to trapezoid rule... */
5075 for (int ip = los->np - 1; ip >= 1; ip--)
5076 los->ds[ip] = 0.5 * (los->ds[ip - 1] + los->ds[ip]);
5077 los->ds[0] *= 0.5;
5078
5079 /* Compute column density... */
5080 for (int ip = 0; ip < los->np; ip++)
5081 for (int ig = 0; ig < ctl->ng; ig++)
5082 los->u[ip][ig] = 10 * los->q[ip][ig] * los->p[ip]
5083 / (KB * los->t[ip]) * los->ds[ip];
5084
5085 /* Compute Curtis-Godson means... */
5086 for (int ig = 0; ig < ctl->ng; ig++) {
5087 los->cgu[0][ig] = los->u[0][ig];
5088 los->cgp[0][ig] = los->u[0][ig] * los->p[0];
5089 los->cgt[0][ig] = los->u[0][ig] * los->t[0];
5090 }
5091 for (int ip = 1; ip < los->np; ip++)
5092 for (int ig = 0; ig < ctl->ng; ig++) {
5093 los->cgu[ip][ig] = los->cgu[ip - 1][ig] + los->u[ip][ig];
5094 los->cgp[ip][ig] = los->cgp[ip - 1][ig] + los->u[ip][ig] * los->p[ip];
5095 los->cgt[ip][ig] = los->cgt[ip - 1][ig] + los->u[ip][ig] * los->t[ip];
5096 }
5097 for (int ip = 0; ip < los->np; ip++)
5098 for (int ig = 0; ig < ctl->ng; ig++)
5099 if (los->cgu[ip][ig] != 0) {
5100 los->cgp[ip][ig] /= los->cgu[ip][ig];
5101 los->cgt[ip][ig] /= los->cgu[ip][ig];
5102 }
5103}
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:4024
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:6550
void cart2geo(const double *x, double *z, double *lon, double *lat)
Converts Cartesian coordinates to geographic coordinates.
Definition: jurassic.c:185
#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:1012
#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:1295
double rayds
Maximum step length for raytracing [km].
Definition: jurassic.h:1346
double raydz
Vertical step length for raytracing [km].
Definition: jurassic.h:1349
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 5107 of file jurassic.c.

5111 {
5112
5113 char file[LEN];
5114
5115 /* Init... */
5116 atm->np = 0;
5117
5118 /* Set filename... */
5119 if (dirname != NULL)
5120 sprintf(file, "%s/%s", dirname, filename);
5121 else
5122 sprintf(file, "%s", filename);
5123
5124 /* Write info... */
5125 LOG(1, "Read atmospheric data: %s", file);
5126
5127 /* Read ASCII data... */
5128 if (ctl->atmfmt == 1)
5129 read_atm_asc(file, ctl, atm);
5130
5131 /* Read binary data... */
5132 else if (ctl->atmfmt == 2)
5133 read_atm_bin(file, ctl, atm);
5134
5135 /* Read netCDF data... */
5136 else if (ctl->atmfmt == 3)
5137 read_atm_nc(file, ctl, atm, 0);
5138
5139 /* Error... */
5140 else
5141 ERRMSG("Unknown atmospheric data file format, check ATMFMT!");
5142
5143 /* Check number of points... */
5144 if (atm->np < 1)
5145 ERRMSG("Could not read any data!");
5146
5147 /* Write info... */
5148 double mini, maxi;
5149 LOG(2, "Number of data points: %d", atm->np);
5150 gsl_stats_minmax(&mini, &maxi, atm->time, 1, (size_t) atm->np);
5151 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
5152 gsl_stats_minmax(&mini, &maxi, atm->z, 1, (size_t) atm->np);
5153 LOG(2, "Altitude range: %g ... %g km", mini, maxi);
5154 gsl_stats_minmax(&mini, &maxi, atm->lon, 1, (size_t) atm->np);
5155 LOG(2, "Longitude range: %g ... %g deg", mini, maxi);
5156 gsl_stats_minmax(&mini, &maxi, atm->lat, 1, (size_t) atm->np);
5157 LOG(2, "Latitude range: %g ... %g deg", mini, maxi);
5158 gsl_stats_minmax(&mini, &maxi, atm->p, 1, (size_t) atm->np);
5159 LOG(2, "Pressure range: %g ... %g hPa", maxi, mini);
5160 gsl_stats_minmax(&mini, &maxi, atm->t, 1, (size_t) atm->np);
5161 LOG(2, "Temperature range: %g ... %g K", mini, maxi);
5162 for (int ig = 0; ig < ctl->ng; ig++) {
5163 gsl_stats_minmax(&mini, &maxi, atm->q[ig], 1, (size_t) atm->np);
5164 LOG(2, "Emitter %s range: %g ... %g ppv", ctl->emitter[ig], mini, maxi);
5165 }
5166 for (int iw = 0; iw < ctl->nw; iw++) {
5167 gsl_stats_minmax(&mini, &maxi, atm->k[iw], 1, (size_t) atm->np);
5168 LOG(2, "Extinction range (window %d): %g ... %g km^-1", iw, mini, maxi);
5169 }
5170 if (ctl->ncl > 0 && atm->np == 0) {
5171 LOG(2, "Cloud layer: z= %g km | dz= %g km | k= %g ... %g km^-1",
5172 atm->clz, atm->cldz, atm->clk[0], atm->clk[ctl->ncl - 1]);
5173 } else
5174 LOG(2, "Cloud layer: none");
5175 if (ctl->nsf > 0 && atm->np == 0) {
5176 LOG(2,
5177 "Surface: T_s = %g K | eps= %g ... %g",
5178 atm->sft, atm->sfeps[0], atm->sfeps[ctl->nsf - 1]);
5179 } else
5180 LOG(2, "Surface: none");
5181}
void read_atm_bin(const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric data in binary format.
Definition: jurassic.c:5237
void read_atm_asc(const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric data in ASCII format.
Definition: jurassic.c:5185
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:5331
int atmfmt
Atmospheric data file format (1=ASCII, 2=binary, 3=netCDF).
Definition: jurassic.h:1322
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 5185 of file jurassic.c.

5188 {
5189
5190 char line[LEN], *tok;
5191
5192 /* Init... */
5193 atm->np = 0;
5194
5195 /* Open file... */
5196 FILE *in;
5197 if (!(in = fopen(filename, "r")))
5198 ERRMSG("Cannot open file!");
5199
5200 /* Read line... */
5201 while (fgets(line, LEN, in)) {
5202
5203 /* Read data... */
5204 TOK(line, tok, "%lg", atm->time[atm->np]);
5205 TOK(NULL, tok, "%lg", atm->z[atm->np]);
5206 TOK(NULL, tok, "%lg", atm->lon[atm->np]);
5207 TOK(NULL, tok, "%lg", atm->lat[atm->np]);
5208 TOK(NULL, tok, "%lg", atm->p[atm->np]);
5209 TOK(NULL, tok, "%lg", atm->t[atm->np]);
5210 for (int ig = 0; ig < ctl->ng; ig++)
5211 TOK(NULL, tok, "%lg", atm->q[ig][atm->np]);
5212 for (int iw = 0; iw < ctl->nw; iw++)
5213 TOK(NULL, tok, "%lg", atm->k[iw][atm->np]);
5214 if (ctl->ncl > 0 && atm->np == 0) {
5215 TOK(NULL, tok, "%lg", atm->clz);
5216 TOK(NULL, tok, "%lg", atm->cldz);
5217 for (int icl = 0; icl < ctl->ncl; icl++)
5218 TOK(NULL, tok, "%lg", atm->clk[icl]);
5219 }
5220 if (ctl->nsf > 0 && atm->np == 0) {
5221 TOK(NULL, tok, "%lg", atm->sft);
5222 for (int isf = 0; isf < ctl->nsf; isf++)
5223 TOK(NULL, tok, "%lg", atm->sfeps[isf]);
5224 }
5225
5226 /* Increment data point counter... */
5227 if ((++atm->np) > NP)
5228 ERRMSG("Too many data points!");
5229 }
5230
5231 /* Close file... */
5232 fclose(in);
5233}
#define TOK(line, tok, format, var)
Tokenize a string and parse a variable.
Definition: jurassic.h:1048
#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 5237 of file jurassic.c.

5240 {
5241
5242 /* Open file... */
5243 FILE *in;
5244 if (!(in = fopen(filename, "r")))
5245 ERRMSG("Cannot open file!");
5246
5247 /* Read header... */
5248 char magic[4];
5249 FREAD(magic, char,
5250 4,
5251 in);
5252 if (memcmp(magic, "ATM1", 4) != 0)
5253 ERRMSG("Invalid magic string!");
5254
5255 int ng, nw, ncl, nsf;
5256 FREAD(&ng, int,
5257 1,
5258 in);
5259 FREAD(&nw, int,
5260 1,
5261 in);
5262 FREAD(&ncl, int,
5263 1,
5264 in);
5265 FREAD(&nsf, int,
5266 1,
5267 in);
5268 if (ng != ctl->ng || nw != ctl->nw || ncl != ctl->ncl || nsf != ctl->nsf)
5269 ERRMSG("Error reading file header!");
5270
5271 /* Read data... */
5272 size_t np;
5273 FREAD(&np, size_t,
5274 1,
5275 in);
5276 atm->np = (int) np;
5277 if (atm->np > NP)
5278 ERRMSG("Too many data points!");
5279 FREAD(atm->time, double,
5280 np,
5281 in);
5282 FREAD(atm->z, double,
5283 np,
5284 in);
5285 FREAD(atm->lon, double,
5286 np,
5287 in);
5288 FREAD(atm->lat, double,
5289 np,
5290 in);
5291 FREAD(atm->p, double,
5292 np,
5293 in);
5294 FREAD(atm->t, double,
5295 np,
5296 in);
5297 for (int ig = 0; ig < ctl->ng; ig++)
5298 FREAD(atm->q[ig], double,
5299 np,
5300 in);
5301 for (int iw = 0; iw < ctl->nw; iw++)
5302 FREAD(atm->k[iw], double,
5303 np,
5304 in);
5305 if (ctl->ncl > 0) {
5306 FREAD(&atm->clz, double,
5307 1,
5308 in);
5309 FREAD(&atm->cldz, double,
5310 1,
5311 in);
5312 FREAD(atm->clk, double,
5313 (size_t) ctl->ncl,
5314 in);
5315 }
5316 if (ctl->nsf) {
5317 FREAD(&atm->sft, double,
5318 1,
5319 in);
5320 FREAD(atm->sfeps, double,
5321 (size_t) ctl->nsf,
5322 in);
5323 }
5324
5325 /* Close file... */
5326 fclose(in);
5327}
#define FREAD(ptr, type, size, out)
Read binary data from a file.
Definition: jurassic.h:503

◆ 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 5331 of file jurassic.c.

5335 {
5336
5337 int ncid, var_time, var_z, var_lon, var_lat, var_p, var_t, var_q[NG],
5338 var_k[NW], var_cz = -1, var_cdz = -1, var_ck[NCL], var_sft =
5339 -1, var_sfe[NSF], var_nlev = -1;
5340
5341 char varname[LEN];
5342
5343 /* Open file... */
5344 NC(nc_open(filename, NC_NOWRITE, &ncid));
5345
5346 /* Initialize hyperslab... */
5347 size_t start[2] = { (size_t) profile, 0 };
5348 size_t count[2] = { 1, 0 };
5349
5350 /* Determine atm->np... */
5351 NC(nc_inq_varid(ncid, "nlev", &var_nlev));
5352 NC(nc_get_vara_int(ncid, var_nlev, start, count, &atm->np));
5353 if (atm->np < 1 || atm->np > NP)
5354 ERRMSG("Number of level out of range!");
5355
5356 /* Update hyperslab... */
5357 count[1] = (size_t) atm->np;
5358
5359 /* Inquire core variables... */
5360 NC(nc_inq_varid(ncid, "time", &var_time));
5361 NC(nc_inq_varid(ncid, "z", &var_z));
5362 NC(nc_inq_varid(ncid, "lon", &var_lon));
5363 NC(nc_inq_varid(ncid, "lat", &var_lat));
5364 NC(nc_inq_varid(ncid, "p", &var_p));
5365 NC(nc_inq_varid(ncid, "t", &var_t));
5366
5367 /* Inquire emiters... */
5368 for (int ig = 0; ig < ctl->ng; ig++)
5369 NC(nc_inq_varid(ncid, ctl->emitter[ig], &var_q[ig]));
5370
5371 /* Inquire extinctions... */
5372 for (int iw = 0; iw < ctl->nw; iw++) {
5373 sprintf(varname, "ext_win_%d", iw);
5374 NC(nc_inq_varid(ncid, varname, &var_k[iw]));
5375 }
5376
5377 /* Inquire cloud variables... */
5378 if (ctl->ncl > 0) {
5379 NC(nc_inq_varid(ncid, "cld_z", &var_cz));
5380 NC(nc_inq_varid(ncid, "cld_dz", &var_cdz));
5381 for (int icl = 0; icl < ctl->ncl; icl++) {
5382 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
5383 NC(nc_inq_varid(ncid, varname, &var_ck[icl]));
5384 }
5385 }
5386
5387 /* Inquire surface variables... */
5388 if (ctl->nsf > 0) {
5389 NC(nc_inq_varid(ncid, "srf_t", &var_sft));
5390 for (int isf = 0; isf < ctl->nsf; isf++) {
5391 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
5392 NC(nc_inq_varid(ncid, varname, &var_sfe[isf]));
5393 }
5394 }
5395
5396 /* Read core variables... */
5397 NC(nc_get_vara_double(ncid, var_time, start, count, atm->time));
5398 NC(nc_get_vara_double(ncid, var_z, start, count, atm->z));
5399 NC(nc_get_vara_double(ncid, var_lon, start, count, atm->lon));
5400 NC(nc_get_vara_double(ncid, var_lat, start, count, atm->lat));
5401 NC(nc_get_vara_double(ncid, var_p, start, count, atm->p));
5402 NC(nc_get_vara_double(ncid, var_t, start, count, atm->t));
5403
5404 /* Read emitters... */
5405 for (int ig = 0; ig < ctl->ng; ig++)
5406 NC(nc_get_vara_double(ncid, var_q[ig], start, count, atm->q[ig]));
5407
5408 /* Read extinctions... */
5409 for (int iw = 0; iw < ctl->nw; iw++)
5410 NC(nc_get_vara_double(ncid, var_k[iw], start, count, atm->k[iw]));
5411
5412 /* Read cloud variables... */
5413 if (ctl->ncl > 0) {
5414 NC(nc_get_vara_double(ncid, var_cz, start, count, &atm->clz));
5415 NC(nc_get_vara_double(ncid, var_cdz, start, count, &atm->cldz));
5416 for (int icl = 0; icl < ctl->ncl; icl++)
5417 NC(nc_get_vara_double(ncid, var_ck[icl], start, count, &atm->clk[icl]));
5418 }
5419
5420 /* Read surface variables... */
5421 if (ctl->nsf > 0) {
5422 NC(nc_get_vara_double(ncid, var_sft, start, count, &atm->sft));
5423
5424 for (int isf = 0; isf < ctl->nsf; isf++)
5425 NC(nc_get_vara_double
5426 (ncid, var_sfe[isf], start, count, &atm->sfeps[isf]));
5427 }
5428
5429 /* Close file... */
5430 NC(nc_close(ncid));
5431}
#define NC(cmd)
Execute a NetCDF command and check for errors.
Definition: jurassic.h:645
#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 5435 of file jurassic.c.

5438 {
5439
5440 /* Write info... */
5441 LOG(1, "\nJuelich Rapid Spectral Simulation Code (JURASSIC)\n"
5442 "(executable: %s | version: %s | compiled: %s, %s)\n",
5443 argv[0], VERSION, __DATE__, __TIME__);
5444
5445 /* Emitters... */
5446 ctl->ng = (int) scan_ctl(argc, argv, "NG", -1, "0", NULL);
5447 if (ctl->ng < 0 || ctl->ng > NG)
5448 ERRMSG("Set 0 <= NG <= MAX!");
5449 for (int ig = 0; ig < ctl->ng; ig++)
5450 scan_ctl(argc, argv, "EMITTER", ig, "", ctl->emitter[ig]);
5451 ctl->ig_co2 = find_emitter(ctl, "CO2");
5452 ctl->ig_h2o = find_emitter(ctl, "H2O");
5453 ctl->ig_n2 = find_emitter(ctl, "N2");
5454 ctl->ig_o2 = find_emitter(ctl, "O2");
5455
5456 /* Radiance channels... */
5457 ctl->nd = (int) scan_ctl(argc, argv, "ND", -1, "0", NULL);
5458 if (ctl->nd < 0 || ctl->nd > ND)
5459 ERRMSG("Set 0 <= ND <= MAX!");
5460 for (int id = 0; id < ctl->nd; id++)
5461 ctl->nu[id] = scan_ctl(argc, argv, "NU", id, "", NULL);
5462
5463 /* Spectral windows... */
5464 ctl->nw = (int) scan_ctl(argc, argv, "NW", -1, "1", NULL);
5465 if (ctl->nw < 0 || ctl->nw > NW)
5466 ERRMSG("Set 0 <= NW <= MAX!");
5467 for (int id = 0; id < ctl->nd; id++)
5468 ctl->window[id] = (int) scan_ctl(argc, argv, "WINDOW", id, "0", NULL);
5469
5470 /* Cloud data... */
5471 ctl->ncl = (int) scan_ctl(argc, argv, "NCL", -1, "0", NULL);
5472 if (ctl->ncl < 0 || ctl->ncl > NCL)
5473 ERRMSG("Set 0 <= NCL <= MAX!");
5474 if (ctl->ncl == 1)
5475 ERRMSG("Set NCL > 1!");
5476 for (int icl = 0; icl < ctl->ncl; icl++)
5477 ctl->clnu[icl] = scan_ctl(argc, argv, "CLNU", icl, "", NULL);
5478
5479 /* Surface data... */
5480 ctl->nsf = (int) scan_ctl(argc, argv, "NSF", -1, "0", NULL);
5481 if (ctl->nsf < 0 || ctl->nsf > NSF)
5482 ERRMSG("Set 0 <= NSF <= MAX!");
5483 if (ctl->nsf == 1)
5484 ERRMSG("Set NSF > 1!");
5485 for (int isf = 0; isf < ctl->nsf; isf++)
5486 ctl->sfnu[isf] = scan_ctl(argc, argv, "SFNU", isf, "", NULL);
5487 ctl->sftype = (int) scan_ctl(argc, argv, "SFTYPE", -1, "2", NULL);
5488 if (ctl->sftype < 0 || ctl->sftype > 3)
5489 ERRMSG("Set 0 <= SFTYPE <= 3!");
5490 ctl->sfsza = scan_ctl(argc, argv, "SFSZA", -1, "-999", NULL);
5491
5492 /* Emissivity look-up tables... */
5493 scan_ctl(argc, argv, "TBLBASE", -1, "-", ctl->tblbase);
5494 ctl->tblfmt = (int) scan_ctl(argc, argv, "TBLFMT", -1, "1", NULL);
5495
5496 /* File formats... */
5497 ctl->atmfmt = (int) scan_ctl(argc, argv, "ATMFMT", -1, "1", NULL);
5498 ctl->obsfmt = (int) scan_ctl(argc, argv, "OBSFMT", -1, "1", NULL);
5499
5500 /* Hydrostatic equilibrium... */
5501 ctl->hydz = scan_ctl(argc, argv, "HYDZ", -1, "-999", NULL);
5502
5503 /* Continua... */
5504 ctl->ctm_co2 = (int) scan_ctl(argc, argv, "CTM_CO2", -1, "1", NULL);
5505 ctl->ctm_h2o = (int) scan_ctl(argc, argv, "CTM_H2O", -1, "1", NULL);
5506 ctl->ctm_n2 = (int) scan_ctl(argc, argv, "CTM_N2", -1, "1", NULL);
5507 ctl->ctm_o2 = (int) scan_ctl(argc, argv, "CTM_O2", -1, "1", NULL);
5508
5509 /* Ray-tracing... */
5510 ctl->refrac = (int) scan_ctl(argc, argv, "REFRAC", -1, "1", NULL);
5511 ctl->rayds = scan_ctl(argc, argv, "RAYDS", -1, "10", NULL);
5512 ctl->raydz = scan_ctl(argc, argv, "RAYDZ", -1, "0.1", NULL);
5513
5514 /* Field of view... */
5515 scan_ctl(argc, argv, "FOV", -1, "-", ctl->fov);
5516 if (ctl->fov[0] != '-')
5517 read_shape(ctl->fov, ctl->fov_dz, ctl->fov_w, &ctl->fov_n);
5518
5519 /* Retrieval interface... */
5520 ctl->retp_zmin = scan_ctl(argc, argv, "RETP_ZMIN", -1, "-999", NULL);
5521 ctl->retp_zmax = scan_ctl(argc, argv, "RETP_ZMAX", -1, "-999", NULL);
5522 ctl->rett_zmin = scan_ctl(argc, argv, "RETT_ZMIN", -1, "-999", NULL);
5523 ctl->rett_zmax = scan_ctl(argc, argv, "RETT_ZMAX", -1, "-999", NULL);
5524 for (int ig = 0; ig < ctl->ng; ig++) {
5525 ctl->retq_zmin[ig] = scan_ctl(argc, argv, "RETQ_ZMIN", ig, "-999", NULL);
5526 ctl->retq_zmax[ig] = scan_ctl(argc, argv, "RETQ_ZMAX", ig, "-999", NULL);
5527 }
5528 for (int iw = 0; iw < ctl->nw; iw++) {
5529 ctl->retk_zmin[iw] = scan_ctl(argc, argv, "RETK_ZMIN", iw, "-999", NULL);
5530 ctl->retk_zmax[iw] = scan_ctl(argc, argv, "RETK_ZMAX", iw, "-999", NULL);
5531 }
5532 ctl->ret_clz = (int) scan_ctl(argc, argv, "RET_CLZ", -1, "0", NULL);
5533 ctl->ret_cldz = (int) scan_ctl(argc, argv, "RET_CLDZ", -1, "0", NULL);
5534 ctl->ret_clk = (int) scan_ctl(argc, argv, "RET_CLK", -1, "0", NULL);
5535 ctl->ret_sft = (int) scan_ctl(argc, argv, "RET_SFT", -1, "0", NULL);
5536 ctl->ret_sfeps = (int) scan_ctl(argc, argv, "RET_SFEPS", -1, "0", NULL);
5537
5538 /* Output flags... */
5539 ctl->write_bbt = (int) scan_ctl(argc, argv, "WRITE_BBT", -1, "0", NULL);
5540 ctl->write_matrix =
5541 (int) scan_ctl(argc, argv, "WRITE_MATRIX", -1, "0", NULL);
5542
5543 /* External forward models... */
5544 ctl->formod = (int) scan_ctl(argc, argv, "FORMOD", -1, "1", NULL);
5545 scan_ctl(argc, argv, "RFMBIN", -1, "-", ctl->rfmbin);
5546 scan_ctl(argc, argv, "RFMHIT", -1, "-", ctl->rfmhit);
5547 for (int ig = 0; ig < ctl->ng; ig++)
5548 scan_ctl(argc, argv, "RFMXSC", ig, "-", ctl->rfmxsc[ig]);
5549}
int find_emitter(const ctl_t *ctl, const char *emitter)
Find gas species index by name.
Definition: jurassic.c:3394
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:6326
int write_matrix
Write matrix file (0=no, 1=yes).
Definition: jurassic.h:1406
int obsfmt
Observation data file format (1=ASCII, 2=binary, 3=netCDF).
Definition: jurassic.h:1325
int tblfmt
Look-up table file format (1=ASCII, 2=binary, 3=netCDF).
Definition: jurassic.h:1319
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 5553 of file jurassic.c.

5556 {
5557
5558 FILE *in;
5559
5560 char dum[LEN], file[LEN], line[LEN];
5561
5562 double value;
5563
5564 int i, j;
5565
5566 /* Set filename... */
5567 if (dirname != NULL)
5568 sprintf(file, "%s/%s", dirname, filename);
5569 else
5570 sprintf(file, "%s", filename);
5571
5572 /* Write info... */
5573 LOG(1, "Read matrix: %s", file);
5574
5575 /* Open file... */
5576 if (!(in = fopen(file, "r")))
5577 ERRMSG("Cannot open file!");
5578
5579 /* Read data... */
5580 gsl_matrix_set_zero(matrix);
5581 while (fgets(line, LEN, in))
5582 if (sscanf(line, "%d %s %s %s %s %s %d %s %s %s %s %s %lg",
5583 &i, dum, dum, dum, dum, dum,
5584 &j, dum, dum, dum, dum, dum, &value) == 13)
5585 gsl_matrix_set(matrix, (size_t) i, (size_t) j, value);
5586
5587 /* Close file... */
5588 fclose(in);
5589}

◆ 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 5593 of file jurassic.c.

5597 {
5598
5599 char file[LEN];
5600
5601 /* Set filename... */
5602 if (dirname != NULL)
5603 sprintf(file, "%s/%s", dirname, filename);
5604 else
5605 sprintf(file, "%s", filename);
5606
5607 /* Write info... */
5608 LOG(1, "Read observation data: %s", file);
5609
5610 /* Read ASCII data... */
5611 if (ctl->obsfmt == 1)
5612 read_obs_asc(file, ctl, obs);
5613
5614 /* Read binary data... */
5615 else if (ctl->obsfmt == 2)
5616 read_obs_bin(file, ctl, obs);
5617
5618 /* Read netCDF data... */
5619 else if (ctl->obsfmt == 3)
5620 read_obs_nc(file, ctl, obs, 0);
5621
5622 /* Error... */
5623 else
5624 ERRMSG("Unknown observation file format!");
5625
5626 /* Check number of points... */
5627 if (obs->nr < 1)
5628 ERRMSG("Could not read any data!");
5629
5630 /* Write info... */
5631 double mini, maxi;
5632 LOG(2, "Number of ray paths: %d", obs->nr);
5633 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
5634 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
5635 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
5636 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
5637 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
5638 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
5639 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
5640 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
5641 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
5642 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
5643 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
5644 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
5645 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
5646 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
5647 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
5648 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
5649 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
5650 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
5651 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
5652 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
5653 for (int id = 0; id < ctl->nd; id++) {
5654 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
5655 if (ctl->write_bbt) {
5656 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
5657 ctl->nu[id], mini, maxi);
5658 } else {
5659 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
5660 ctl->nu[id], mini, maxi);
5661 }
5662 }
5663 for (int id = 0; id < ctl->nd; id++) {
5664 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
5665 if (ctl->write_bbt) {
5666 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
5667 ctl->nu[id], mini, maxi);
5668 }
5669 }
5670}
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:5719
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:5797
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:5674
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 5674 of file jurassic.c.

5677 {
5678
5679 char line[LEN], *tok;
5680
5681 /* Init... */
5682 obs->nr = 0;
5683
5684 /* Open file... */
5685 FILE *in;
5686 if (!(in = fopen(filename, "r")))
5687 ERRMSG("Cannot open file!");
5688
5689 /* Read line... */
5690 while (fgets(line, LEN, in)) {
5691
5692 /* Read data... */
5693 TOK(line, tok, "%lg", obs->time[obs->nr]);
5694 TOK(NULL, tok, "%lg", obs->obsz[obs->nr]);
5695 TOK(NULL, tok, "%lg", obs->obslon[obs->nr]);
5696 TOK(NULL, tok, "%lg", obs->obslat[obs->nr]);
5697 TOK(NULL, tok, "%lg", obs->vpz[obs->nr]);
5698 TOK(NULL, tok, "%lg", obs->vplon[obs->nr]);
5699 TOK(NULL, tok, "%lg", obs->vplat[obs->nr]);
5700 TOK(NULL, tok, "%lg", obs->tpz[obs->nr]);
5701 TOK(NULL, tok, "%lg", obs->tplon[obs->nr]);
5702 TOK(NULL, tok, "%lg", obs->tplat[obs->nr]);
5703 for (int id = 0; id < ctl->nd; id++)
5704 TOK(NULL, tok, "%lg", obs->rad[id][obs->nr]);
5705 for (int id = 0; id < ctl->nd; id++)
5706 TOK(NULL, tok, "%lg", obs->tau[id][obs->nr]);
5707
5708 /* Increment counter... */
5709 if ((++obs->nr) > NR)
5710 ERRMSG("Too many rays!");
5711 }
5712
5713 /* Close file... */
5714 fclose(in);
5715}

◆ 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 5719 of file jurassic.c.

5722 {
5723
5724 /* Open file... */
5725 FILE *in;
5726 if (!(in = fopen(filename, "r")))
5727 ERRMSG("Cannot open file!");
5728
5729 /* Read header... */
5730 char magic[4];
5731 FREAD(magic, char,
5732 4,
5733 in);
5734 if (memcmp(magic, "OBS1", 4) != 0)
5735 ERRMSG("Invalid magic string!");
5736
5737 int nd;
5738 FREAD(&nd, int,
5739 1,
5740 in);
5741 if (nd != ctl->nd)
5742 ERRMSG("Error reading file header!");
5743
5744 /* Read data... */
5745 size_t nr;
5746 FREAD(&nr, size_t,
5747 1,
5748 in);
5749 obs->nr = (int) nr;
5750 if (obs->nr > NR)
5751 ERRMSG("Too many ray paths!");
5752 FREAD(obs->time, double,
5753 nr,
5754 in);
5755 FREAD(obs->obsz, double,
5756 nr,
5757 in);
5758 FREAD(obs->obslon, double,
5759 nr,
5760 in);
5761 FREAD(obs->obslat, double,
5762 nr,
5763 in);
5764 FREAD(obs->vpz, double,
5765 nr,
5766 in);
5767 FREAD(obs->vplon, double,
5768 nr,
5769 in);
5770 FREAD(obs->vplat, double,
5771 nr,
5772 in);
5773 FREAD(obs->tpz, double,
5774 nr,
5775 in);
5776 FREAD(obs->tplon, double,
5777 nr,
5778 in);
5779 FREAD(obs->tplat, double,
5780 nr,
5781 in);
5782 for (int id = 0; id < ctl->nd; id++)
5783 FREAD(obs->rad[id], double,
5784 nr,
5785 in);
5786 for (int id = 0; id < ctl->nd; id++)
5787 FREAD(obs->tau[id], double,
5788 nr,
5789 in);
5790
5791 /* Close file... */
5792 fclose(in);
5793}

◆ 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 5797 of file jurassic.c.

5801 {
5802
5803 int ncid, var_nray = -1, var_time = -1, var_obsz = -1, var_obslon =
5804 -1, var_obslat = -1, var_vpz = -1, var_vplon = -1, var_vplat =
5805 -1, var_tpz = -1, var_tplon = -1, var_tplat =
5806 -1, var_rad[ND], var_tau[ND];
5807
5808 char varname[LEN];
5809
5810 /* Open file... */
5811 NC(nc_open(filename, NC_NOWRITE, &ncid));
5812
5813 /* Initialize hyperslab... */
5814 size_t start[2] = { (size_t) profile, 0 };
5815 size_t count[2] = { 1, 0 };
5816
5817 /* Read nray(profile) -> obs->nr */
5818 NC(nc_inq_varid(ncid, "nray", &var_nray));
5819 NC(nc_get_vara_int(ncid, var_nray, start, count, &obs->nr));
5820 if (obs->nr < 1 || obs->nr > NR)
5821 ERRMSG("Number of ray paths out of range!");
5822
5823 /* Update hyperslab... */
5824 count[1] = (size_t) obs->nr;
5825
5826 /* Inquire geometry variables... */
5827 NC(nc_inq_varid(ncid, "time", &var_time));
5828 NC(nc_inq_varid(ncid, "obs_z", &var_obsz));
5829 NC(nc_inq_varid(ncid, "obs_lon", &var_obslon));
5830 NC(nc_inq_varid(ncid, "obs_lat", &var_obslat));
5831
5832 NC(nc_inq_varid(ncid, "vp_z", &var_vpz));
5833 NC(nc_inq_varid(ncid, "vp_lon", &var_vplon));
5834 NC(nc_inq_varid(ncid, "vp_lat", &var_vplat));
5835
5836 NC(nc_inq_varid(ncid, "tp_z", &var_tpz));
5837 NC(nc_inq_varid(ncid, "tp_lon", &var_tplon));
5838 NC(nc_inq_varid(ncid, "tp_lat", &var_tplat));
5839
5840 /* Inquire spectral variables per channel... */
5841 for (int id = 0; id < ctl->nd; id++) {
5842 sprintf(varname, "rad_%.4f", ctl->nu[id]);
5843 NC(nc_inq_varid(ncid, varname, &var_rad[id]));
5844
5845 sprintf(varname, "tau_%.4f", ctl->nu[id]);
5846 NC(nc_inq_varid(ncid, varname, &var_tau[id]));
5847 }
5848
5849 /* Read geometry... */
5850 NC(nc_get_vara_double(ncid, var_time, start, count, obs->time));
5851 NC(nc_get_vara_double(ncid, var_obsz, start, count, obs->obsz));
5852 NC(nc_get_vara_double(ncid, var_obslon, start, count, obs->obslon));
5853 NC(nc_get_vara_double(ncid, var_obslat, start, count, obs->obslat));
5854
5855 NC(nc_get_vara_double(ncid, var_vpz, start, count, obs->vpz));
5856 NC(nc_get_vara_double(ncid, var_vplon, start, count, obs->vplon));
5857 NC(nc_get_vara_double(ncid, var_vplat, start, count, obs->vplat));
5858
5859 NC(nc_get_vara_double(ncid, var_tpz, start, count, obs->tpz));
5860 NC(nc_get_vara_double(ncid, var_tplon, start, count, obs->tplon));
5861 NC(nc_get_vara_double(ncid, var_tplat, start, count, obs->tplat));
5862
5863 /* Read radiance and transmittance... */
5864 for (int id = 0; id < ctl->nd; id++) {
5865 NC(nc_get_vara_double(ncid, var_rad[id], start, count, obs->rad[id]));
5866 NC(nc_get_vara_double(ncid, var_tau[id], start, count, obs->tau[id]));
5867 }
5868
5869 /* Close file... */
5870 NC(nc_close(ncid));
5871}

◆ 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 5875 of file jurassic.c.

5880 {
5881
5882 FILE *in;
5883
5884 char filename[LEN];
5885
5886 double filt, fsum = 0, nu2[NSHAPE], *nurfm, *rad, radsum = 0;
5887
5888 int npts;
5889
5890 /* Allocate... */
5891 ALLOC(nurfm, double,
5892 RFMNPTS);
5893 ALLOC(rad, double,
5894 RFMNPTS);
5895
5896 /* Search RFM spectrum... */
5897 sprintf(filename, "%s_%05d.asc", basename, (int) (z * 1000));
5898 if (!(in = fopen(filename, "r"))) {
5899 sprintf(filename, "%s_%05d.asc", basename, (int) (z * 1000) + 1);
5900 if (!(in = fopen(filename, "r")))
5901 ERRMSG("Cannot find RFM data file!");
5902 }
5903 fclose(in);
5904
5905 /* Read RFM spectrum... */
5906 read_rfm_spec(filename, nurfm, rad, &npts);
5907
5908 /* Set wavenumbers... */
5909 nu2[0] = nu[0];
5910 nu2[n - 1] = nu[n - 1];
5911 for (int i = 1; i < n - 1; i++)
5912 nu2[i] = LIN(0.0, nu2[0], n - 1.0, nu2[n - 1], i);
5913
5914 /* Convolute... */
5915 for (int ipts = 0; ipts < npts; ipts++)
5916 if (nurfm[ipts] >= nu2[0] && nurfm[ipts] <= nu2[n - 1]) {
5917 const int idx = locate_irr(nu2, n, nurfm[ipts]);
5918 filt = LIN(nu2[idx], f[idx], nu2[idx + 1], f[idx + 1], nurfm[ipts]);
5919 fsum += filt;
5920 radsum += filt * rad[ipts];
5921 }
5922
5923 /* Free... */
5924 free(nurfm);
5925 free(rad);
5926
5927 /* Return radiance... */
5928 return radsum / fsum;
5929}
void read_rfm_spec(const char *filename, double *nu, double *rad, int *npts)
Read a Reference Forward Model (RFM) ASCII spectrum.
Definition: jurassic.c:5986
#define RFMNPTS
Maximum number of RFM spectral grid points.
Definition: jurassic.h:328
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 5933 of file jurassic.c.

5937 {
5938
5939 /* Iteration control... */
5940 ret->kernel_recomp =
5941 (int) scan_ctl(argc, argv, "KERNEL_RECOMP", -1, "3", NULL);
5942 ret->conv_itmax = (int) scan_ctl(argc, argv, "CONV_ITMAX", -1, "30", NULL);
5943 ret->conv_dmin = scan_ctl(argc, argv, "CONV_DMIN", -1, "0.1", NULL);
5944
5945 /* Error analysis... */
5946 ret->err_ana = (int) scan_ctl(argc, argv, "ERR_ANA", -1, "0", NULL);
5947
5948 for (int id = 0; id < ctl->nd; id++)
5949 ret->err_formod[id] = scan_ctl(argc, argv, "ERR_FORMOD", id, "0", NULL);
5950
5951 for (int id = 0; id < ctl->nd; id++)
5952 ret->err_noise[id] = scan_ctl(argc, argv, "ERR_NOISE", id, "0", NULL);
5953
5954 ret->err_press = scan_ctl(argc, argv, "ERR_PRESS", -1, "0", NULL);
5955 ret->err_press_cz = scan_ctl(argc, argv, "ERR_PRESS_CZ", -1, "-999", NULL);
5956 ret->err_press_ch = scan_ctl(argc, argv, "ERR_PRESS_CH", -1, "-999", NULL);
5957
5958 ret->err_temp = scan_ctl(argc, argv, "ERR_TEMP", -1, "0", NULL);
5959 ret->err_temp_cz = scan_ctl(argc, argv, "ERR_TEMP_CZ", -1, "-999", NULL);
5960 ret->err_temp_ch = scan_ctl(argc, argv, "ERR_TEMP_CH", -1, "-999", NULL);
5961
5962 for (int ig = 0; ig < ctl->ng; ig++) {
5963 ret->err_q[ig] = scan_ctl(argc, argv, "ERR_Q", ig, "0", NULL);
5964 ret->err_q_cz[ig] = scan_ctl(argc, argv, "ERR_Q_CZ", ig, "-999", NULL);
5965 ret->err_q_ch[ig] = scan_ctl(argc, argv, "ERR_Q_CH", ig, "-999", NULL);
5966 }
5967
5968 for (int iw = 0; iw < ctl->nw; iw++) {
5969 ret->err_k[iw] = scan_ctl(argc, argv, "ERR_K", iw, "0", NULL);
5970 ret->err_k_cz[iw] = scan_ctl(argc, argv, "ERR_K_CZ", iw, "-999", NULL);
5971 ret->err_k_ch[iw] = scan_ctl(argc, argv, "ERR_K_CH", iw, "-999", NULL);
5972 }
5973
5974 ret->err_clz = scan_ctl(argc, argv, "ERR_CLZ", -1, "0", NULL);
5975 ret->err_cldz = scan_ctl(argc, argv, "ERR_CLDZ", -1, "0", NULL);
5976 for (int icl = 0; icl < ctl->ncl; icl++)
5977 ret->err_clk[icl] = scan_ctl(argc, argv, "ERR_CLK", icl, "0", NULL);
5978
5979 ret->err_sft = scan_ctl(argc, argv, "ERR_SFT", -1, "0", NULL);
5980 for (int isf = 0; isf < ctl->nsf; isf++)
5981 ret->err_sfeps[isf] = scan_ctl(argc, argv, "ERR_SFEPS", isf, "0", NULL);
5982}
double err_press_cz
Vertical correlation length for pressure error [km].
Definition: jurassic.h:1570
double err_press
Pressure error [%].
Definition: jurassic.h:1567
double err_k_cz[NW]
Vertical correlation length for extinction error [km].
Definition: jurassic.h:1597
double err_k_ch[NW]
Horizontal correlation length for extinction error [km].
Definition: jurassic.h:1600
double err_temp_cz
Vertical correlation length for temperature error [km].
Definition: jurassic.h:1579
double err_formod[ND]
Forward model error [%].
Definition: jurassic.h:1561
double err_temp
Temperature error [K].
Definition: jurassic.h:1576
double err_q_cz[NG]
Vertical correlation length for volume mixing ratio error [km].
Definition: jurassic.h:1588
double err_noise[ND]
Noise error [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1564
double err_clz
Cloud height error [km].
Definition: jurassic.h:1603
double err_sft
Surface temperature error [K].
Definition: jurassic.h:1612
double err_clk[NCL]
Cloud extinction error [km^-1].
Definition: jurassic.h:1609
double err_temp_ch
Horizontal correlation length for temperature error [km].
Definition: jurassic.h:1582
double err_cldz
Cloud depth error [km].
Definition: jurassic.h:1606
double err_press_ch
Horizontal correlation length for pressure error [km].
Definition: jurassic.h:1573
double err_q_ch[NG]
Horizontal correlation length for volume mixing ratio error [km].
Definition: jurassic.h:1591
double err_q[NG]
Volume mixing ratio error [%].
Definition: jurassic.h:1585
double err_sfeps[NSF]
Surface emissivity error.
Definition: jurassic.h:1615
double err_k[NW]
Extinction error [km^-1].
Definition: jurassic.h:1594
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 5986 of file jurassic.c.

5990 {
5991
5992 FILE *in;
5993
5994 char *line = NULL, *tok;
5995
5996 size_t line_buf_size = 0;
5997
5998 double dnu, nu0, nu1;
5999
6000 int ipts = 0;
6001
6002 /* Write info... */
6003 LOG(1, "Read RFM data: %s", filename);
6004
6005 /* Open file... */
6006 if (!(in = fopen(filename, "r")))
6007 ERRMSG("Cannot open file!");
6008
6009 /* Read header... */
6010 for (int i = 0; i < 4; i++)
6011 if (getline(&line, &line_buf_size, in) == -1)
6012 ERRMSG("Error while reading file header!");
6013 if (sscanf(line, "%d %lg %lg %lg", npts, &nu0, &dnu, &nu1) != 4)
6014 ERRMSG("Invalid spectrum header format!");
6015
6016 /* Check number of spectral grid points... */
6017 if (*npts > RFMNPTS)
6018 ERRMSG("Too many spectral grid points!");
6019
6020 /* Read radiance data... */
6021 while (getline(&line, &line_buf_size, in) != -1 && ipts < *npts) {
6022 tok = strtok(line, " \t\n");
6023 while (tok != NULL && ipts < *npts) {
6024 if (sscanf(tok, "%lg", &rad[ipts]) == 1)
6025 ipts++;
6026 tok = strtok(NULL, " \t\n");
6027 }
6028 }
6029
6030 /* Check number of spectral grid points... */
6031 if (ipts != *npts)
6032 ERRMSG("Error while reading RFM data!");
6033
6034 /* Compute wavenumbers... */
6035 for (ipts = 0; ipts < *npts; ipts++)
6036 nu[ipts] = LIN(0.0, nu0, (double) (*npts - 1), nu1, (double) ipts);
6037
6038 /* Close file... */
6039 fclose(in);
6040
6041 /* Free.. */
6042 free(line);
6043}

◆ 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 6047 of file jurassic.c.

6051 {
6052
6053 FILE *in;
6054
6055 char line[LEN];
6056
6057 /* Write info... */
6058 LOG(1, "Read shape function: %s", filename);
6059
6060 /* Open file... */
6061 if (!(in = fopen(filename, "r")))
6062 ERRMSG("Cannot open file!");
6063
6064 /* Read data... */
6065 *n = 0;
6066 while (fgets(line, LEN, in))
6067 if (sscanf(line, "%lg %lg", &x[*n], &y[*n]) == 2)
6068 if ((++(*n)) > NSHAPE)
6069 ERRMSG("Too many data points!");
6070
6071 /* Close file... */
6072 fclose(in);
6073
6074 /* Check number of data points... */
6075 if (*n < 2)
6076 ERRMSG("Could not read any data!");
6077
6078 /* Write info... */
6079 double mini, maxi;
6080 LOG(2, "Number of data points: %d", *n);
6081 gsl_stats_minmax(&mini, &maxi, x, 1, (size_t) *n);
6082 LOG(2, "Range of x values: %.4f ... %.4f", mini, maxi);
6083 gsl_stats_minmax(&mini, &maxi, y, 1, (size_t) *n);
6084 LOG(2, "Range of y values: %g ... %g", mini, maxi);
6085}

◆ read_tbl()

tbl_t * read_tbl ( const ctl_t ctl)

Read look-up tables for all trace gases and channels.

This function allocates and fills a tbl_t structure by reading look-up table data for every detector (id) and trace gas (ig) defined in the control structure. The actual reader used depends on the value of ctl->tblfmt:

  • 1: ASCII format
  • 2: Binary format
  • 3: netCDF format

For each (id, ig) pair, the corresponding look-up table is loaded and basic diagnostic information about pressure, temperature, absorber amount, and emissivity grids is logged.

After all tables are read, the source function tables are initialized via init_srcfunc().

Parameters
[in]ctlPointer to the control structure defining the number of detectors, trace gases, and the table format.
Returns
Pointer to a newly allocated and fully initialized look-up table structure.
Note
Memory for the returned tbl_t object is allocated inside this function. The caller is responsible for freeing it.
See also
read_tbl_asc()
read_tbl_bin()
read_tbl_nc()
init_srcfunc()
Author
Lars Hoffmann

Definition at line 6089 of file jurassic.c.

6090 {
6091
6092 /* Allocate... */
6093 tbl_t *tbl;
6094 ALLOC(tbl, tbl_t, 1);
6095
6096 /* Loop over trace gases and channels... */
6097 for (int id = 0; id < ctl->nd; id++)
6098 for (int ig = 0; ig < ctl->ng; ig++) {
6099
6100 /* Initialize... */
6101 tbl->np[id][ig] = -1;
6102
6103 /* Read ASCII look-up tables... */
6104 if (ctl->tblfmt == 1)
6105 read_tbl_asc(ctl, tbl, id, ig);
6106
6107 /* Read binary look-up tables... */
6108 else if (ctl->tblfmt == 2)
6109 read_tbl_bin(ctl, tbl, id, ig);
6110
6111 /* Read netCDF look-up tables... */
6112 else if (ctl->tblfmt == 3)
6113 read_tbl_nc(ctl, tbl, id, ig);
6114
6115 /* Error message... */
6116 else
6117 ERRMSG("Unknown look-up table format!");
6118
6119 /* Write info... */
6120 for (int ip = 0; ip < tbl->np[id][ig]; ip++)
6121 LOG(2,
6122 "p[%2d]= %.5e hPa | T[0:%2d]= %.2f ... %.2f K | u[0:%3d]= %.5e ... %.5e molec/cm^2 | eps[0:%3d]= %.5e ... %.5e",
6123 ip, tbl->p[id][ig][ip], tbl->nt[id][ig][ip] - 1,
6124 tbl->t[id][ig][ip][0],
6125 tbl->t[id][ig][ip][tbl->nt[id][ig][ip] - 1],
6126 tbl->nu[id][ig][ip][0] - 1, tbl->u[id][ig][ip][0][0],
6127 tbl->u[id][ig][ip][0][tbl->nu[id][ig][ip][0] - 1],
6128 tbl->nu[id][ig][ip][0] - 1, tbl->eps[id][ig][ip][0][0],
6129 tbl->eps[id][ig][ip][0][tbl->nu[id][ig][ip][0] - 1]);
6130 }
6131
6132 /* Initialize source function... */
6133 init_srcfunc(ctl, tbl);
6134
6135 /* Return pointer... */
6136 return tbl;
6137}
void read_tbl_bin(const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
Read a single binary emissivity lookup table.
Definition: jurassic.c:6239
void read_tbl_nc(const ctl_t *ctl, tbl_t *tbl, int id, int ig)
Read a packed lookup table from a NetCDF file.
Definition: jurassic.c:6285
void init_srcfunc(const ctl_t *ctl, tbl_t *tbl)
Initialize the source-function (Planck radiance) lookup table.
Definition: jurassic.c:3970
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:6141
Emissivity look-up tables.
Definition: jurassic.h:1625
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.

This reads one ASCII table corresponding to frequency index id and gas index ig. The table format is:

pressure   temperature   column_density   emissivity

The function automatically determines the pressure, temperature, and column-density indices based on new values appearing in the file.

Out-of-range values for u or eps are skipped and counted.

Parameters
ctlPointer to control structure specifying filenames and grids.
tblPointer to the table structure to be filled.
idFrequency index.
igGas index.
Warning
Aborts via ERRMSG() if table dimensions exceed TBLNP/TBLNT/TBLNU.
Author
Lars Hoffmann

Definition at line 6141 of file jurassic.c.

6145 {
6146
6147 /* Initialize... */
6148 double eps, eps_old = -999, press, press_old = -999, temp, temp_old =
6149 -999, u, u_old = -999;
6150 int nrange = 0;
6151
6152 /* Set filename... */
6153 char filename[2 * LEN];
6154 sprintf(filename, "%s_%.4f_%s.tab", ctl->tblbase,
6155 ctl->nu[id], ctl->emitter[ig]);
6156
6157 /* Write info... */
6158 LOG(1, "Read emissivity table: %s", filename);
6159
6160 /* Try to open file... */
6161 FILE *in;
6162 if (!(in = fopen(filename, "r"))) {
6163 WARN("Missing emissivity table: %s", filename);
6164 return;
6165 }
6166
6167 /* Read data... */
6168 char line[LEN];
6169 while (fgets(line, LEN, in)) {
6170
6171 /* Parse line... */
6172 if (sscanf(line, "%lg %lg %lg %lg", &press, &temp, &u, &eps) != 4)
6173 continue;
6174
6175 /* Check ranges... */
6176 if (u < UMIN || u > UMAX || eps < EPSMIN || eps > EPSMAX) {
6177 nrange++;
6178 continue;
6179 }
6180
6181 /* Determine pressure index... */
6182 if (press != press_old) {
6183 press_old = press;
6184 if ((++tbl->np[id][ig]) >= TBLNP)
6185 ERRMSG("Too many pressure levels!");
6186 tbl->nt[id][ig][tbl->np[id][ig]] = -1;
6187 }
6188
6189 /* Determine temperature index... */
6190 if (temp != temp_old) {
6191 temp_old = temp;
6192 if ((++tbl->nt[id][ig][tbl->np[id][ig]]) >= TBLNT)
6193 ERRMSG("Too many temperatures!");
6194 tbl->nu[id][ig][tbl->np[id][ig]]
6195 [tbl->nt[id][ig][tbl->np[id][ig]]] = -1;
6196 }
6197
6198 /* Determine column density index... */
6199 if ((eps > eps_old && u > u_old) || tbl->nu[id][ig][tbl->np[id][ig]]
6200 [tbl->nt[id][ig][tbl->np[id][ig]]] < 0) {
6201 eps_old = eps;
6202 u_old = u;
6203 if ((++tbl->nu[id][ig][tbl->np[id][ig]]
6204 [tbl->nt[id][ig][tbl->np[id][ig]]]) >= TBLNU)
6205 ERRMSG("Too many column densities!");
6206 }
6207
6208 /* Store data... */
6209 tbl->p[id][ig][tbl->np[id][ig]] = press;
6210 tbl->t[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
6211 = temp;
6212 tbl->u[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
6213 [tbl->nu[id][ig][tbl->np[id][ig]]
6214 [tbl->nt[id][ig][tbl->np[id][ig]]]] = (float) u;
6215 tbl->eps[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
6216 [tbl->nu[id][ig][tbl->np[id][ig]]
6217 [tbl->nt[id][ig][tbl->np[id][ig]]]] = (float) eps;
6218 }
6219
6220 /* Increment counters... */
6221 tbl->np[id][ig]++;
6222 for (int ip = 0; ip < tbl->np[id][ig]; ip++) {
6223 tbl->nt[id][ig][ip]++;
6224 for (int it = 0; it < tbl->nt[id][ig][ip]; it++)
6225 tbl->nu[id][ig][ip][it]++;
6226 }
6227
6228 /* Check ranges... */
6229 if (nrange > 0)
6230 WARN("Column density or emissivity out of range (%d data points)!",
6231 nrange);
6232
6233 /* Close file... */
6234 fclose(in);
6235}
#define UMAX
Maximum column density [molecules/cm^2].
Definition: jurassic.h:224
#define TBLNU
Maximum number of column densities in emissivity tables.
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 binary emissivity lookup table.

Reads the binary table stored as:

  • number of pressure levels
  • pressure grid
  • for each pressure:
    • number of temperatures
    • temperature grid
    • for each temperature:
      • number of column densities
      • u array
      • emissivity array

The function fills the corresponding entries of the tbl_t structure.

Parameters
ctlPointer to control structure specifying filenames and grids.
tblPointer to the table structure to be filled.
idFrequency index.
igGas index.
Warning
Aborts via ERRMSG() if table dimensions exceed TBLNP/TBLNT/TBLNU.
Author
Lars Hoffmann

Definition at line 6239 of file jurassic.c.

6243 {
6244
6245 /* Set filename... */
6246 char filename[2 * LEN];
6247 sprintf(filename, "%s_%.4f_%s.bin",
6248 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
6249
6250 /* Write info... */
6251 LOG(1, "Read emissivity table: %s", filename);
6252
6253 /* Open file... */
6254 FILE *in = fopen(filename, "rb");
6255 if (!in) {
6256 WARN("Missing emissivity table: %s", filename);
6257 return;
6258 }
6259
6260 /* Read length.. */
6261 size_t nbytes;
6262 FREAD(&nbytes, size_t,
6263 1,
6264 in);
6265 if (nbytes <= 0 || nbytes > TBLBUF)
6266 ERRMSG("Invalid packed table size!");
6267
6268 /* Read packed blob... */
6269 uint8_t *work = NULL;
6270 ALLOC(work, uint8_t, nbytes);
6271 FREAD(work, uint8_t, nbytes, in);
6272
6273 /* Unpack... */
6274 tbl_unpack(tbl, id, ig, work);
6275
6276 /* Close file... */
6277 fclose(in);
6278
6279 /* Free... */
6280 free(work);
6281}
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:6639
#define TBLBUF
Maximum buffer size for lookup tables...
Definition: jurassic.h:323
Here is the call graph for this function:

◆ read_tbl_nc()

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

Read a packed lookup table from a NetCDF file.

This function loads a previously stored lookup table for a specific emitter and detector from a NetCDF file created by write_tbl_nc(). The table is read as a packed binary blob and unpacked into the provided table structure using tbl_unpack().

The NetCDF filename is constructed as: <ctl->tblbase>_<ctl->emitter[ig]>.nc

Within that file, the variable name is derived from the detector frequency: tbl_XXXX (where XXXX is ctl->nu[id] formatted to four decimals)

The variable is stored as an NC_UBYTE vector whose length is read from its associated dimension.

Parameters
[in]ctlControl structure defining emitters, detectors, base filename, and detector frequencies.
[in,out]tblTable structure that will receive the unpacked data.
[in]idDetector index selecting ctl->nu[id].
[in]igEmitter index selecting ctl->emitter[ig].
Note
A temporary buffer is allocated to hold the packed table blob before unpacking.
Warning
The function terminates with an error if:
  • The NetCDF file or variable cannot be found.
  • The stored table size exceeds the maximum supported buffer.
See also
write_tbl_nc()
tbl_unpack()
Author
Lars Hoffmann

Definition at line 6285 of file jurassic.c.

6289 {
6290
6291 char filename[2 * LEN], varname[LEN];
6292
6293 int ncid, varid, dimid;
6294
6295 size_t nbytes;
6296
6297 /* Allocate... */
6298 uint8_t *work = NULL;
6299 ALLOC(work, uint8_t, TBLBUF);
6300
6301 /* Open file... */
6302 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
6303 NC(nc_open(filename, NC_NOWRITE, &ncid));
6304
6305 /* Read variable... */
6306 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
6307 NC(nc_inq_varid(ncid, varname, &varid));
6308 NC(nc_inq_vardimid(ncid, varid, &dimid));
6309 NC(nc_inq_dimlen(ncid, dimid, &nbytes));
6310 if (nbytes > TBLBUF)
6311 ERRMSG("Table blob exceeds buffer!");
6312 NC(nc_get_var_uchar(ncid, varid, (unsigned char *) work));
6313
6314 /* Unpack... */
6315 tbl_unpack(tbl, id, ig, work);
6316
6317 /* Close file... */
6318 NC(nc_close(ncid));
6319
6320 /* Free... */
6321 free(work);
6322}
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 6326 of file jurassic.c.

6332 {
6333
6334 FILE *in = NULL;
6335
6336 char dummy[LEN], fullname1[LEN], fullname2[LEN], line[LEN],
6337 rvarname[LEN], rval[LEN];
6338
6339 int contain = 0;
6340
6341 /* Open file... */
6342 if (argv[1][0] != '-')
6343 if (!(in = fopen(argv[1], "r")))
6344 ERRMSG("Cannot open file!");
6345
6346 /* Set full variable name... */
6347 if (arridx >= 0) {
6348 sprintf(fullname1, "%s[%d]", varname, arridx);
6349 sprintf(fullname2, "%s[*]", varname);
6350 } else {
6351 sprintf(fullname1, "%s", varname);
6352 sprintf(fullname2, "%s", varname);
6353 }
6354
6355 /* Read data... */
6356 if (in != NULL)
6357 while (fgets(line, LEN, in))
6358 if (sscanf(line, "%s %s %s", rvarname, dummy, rval) == 3)
6359 if (strcasecmp(rvarname, fullname1) == 0 ||
6360 strcasecmp(rvarname, fullname2) == 0) {
6361 contain = 1;
6362 break;
6363 }
6364 for (int i = 1; i < argc - 1; i++)
6365 if (strcasecmp(argv[i], fullname1) == 0 ||
6366 strcasecmp(argv[i], fullname2) == 0) {
6367 sprintf(rval, "%s", argv[i + 1]);
6368 contain = 1;
6369 break;
6370 }
6371
6372 /* Close file... */
6373 if (in != NULL)
6374 fclose(in);
6375
6376 /* Check for missing variables... */
6377 if (!contain) {
6378 if (strlen(defvalue) > 0)
6379 sprintf(rval, "%s", defvalue);
6380 else
6381 ERRMSG("Missing variable %s!\n", fullname1);
6382 }
6383
6384 /* Write info... */
6385 LOG(1, "%s = %s", fullname1, rval);
6386
6387 /* Return values... */
6388 if (value != NULL)
6389 sprintf(value, "%s", rval);
6390 return atof(rval);
6391}

◆ 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 6395 of file jurassic.c.

6401 {
6402
6403 /* Get sizes... */
6404 const size_t n = s_a->size1;
6405
6406 /* Allocate... */
6407 gsl_vector *x_a = gsl_vector_alloc(n);
6408
6409 /* Get sigma vector... */
6410 atm2x(ctl, atm, x_a, NULL, NULL);
6411 for (size_t i = 0; i < n; i++) {
6412 if (iqa[i] == IDXP)
6413 gsl_vector_set(x_a, i, ret->err_press / 100 * gsl_vector_get(x_a, i));
6414 if (iqa[i] == IDXT)
6415 gsl_vector_set(x_a, i, ret->err_temp);
6416 for (int ig = 0; ig < ctl->ng; ig++)
6417 if (iqa[i] == IDXQ(ig))
6418 gsl_vector_set(x_a, i, ret->err_q[ig] / 100 * gsl_vector_get(x_a, i));
6419 for (int iw = 0; iw < ctl->nw; iw++)
6420 if (iqa[i] == IDXK(iw))
6421 gsl_vector_set(x_a, i, ret->err_k[iw]);
6422 if (iqa[i] == IDXCLZ)
6423 gsl_vector_set(x_a, i, ret->err_clz);
6424 if (iqa[i] == IDXCLDZ)
6425 gsl_vector_set(x_a, i, ret->err_cldz);
6426 for (int icl = 0; icl < ctl->ncl; icl++)
6427 if (iqa[i] == IDXCLK(icl))
6428 gsl_vector_set(x_a, i, ret->err_clk[icl]);
6429 if (iqa[i] == IDXSFT)
6430 gsl_vector_set(x_a, i, ret->err_sft);
6431 for (int isf = 0; isf < ctl->nsf; isf++)
6432 if (iqa[i] == IDXSFEPS(isf))
6433 gsl_vector_set(x_a, i, ret->err_sfeps[isf]);
6434 }
6435
6436 /* Check standard deviations... */
6437 for (size_t i = 0; i < n; i++)
6438 if (POW2(gsl_vector_get(x_a, i)) <= 0)
6439 ERRMSG("Check a priori data (zero standard deviation)!");
6440
6441 /* Initialize diagonal covariance... */
6442 gsl_matrix_set_zero(s_a);
6443 for (size_t i = 0; i < n; i++)
6444 gsl_matrix_set(s_a, i, i, POW2(gsl_vector_get(x_a, i)));
6445
6446 /* Loop over matrix elements... */
6447 for (size_t i = 0; i < n; i++)
6448 for (size_t j = 0; j < n; j++)
6449 if (i != j && iqa[i] == iqa[j]) {
6450
6451 /* Initialize... */
6452 double cz = 0;
6453 double ch = 0;
6454
6455 /* Set correlation lengths for pressure... */
6456 if (iqa[i] == IDXP) {
6457 cz = ret->err_press_cz;
6458 ch = ret->err_press_ch;
6459 }
6460
6461 /* Set correlation lengths for temperature... */
6462 if (iqa[i] == IDXT) {
6463 cz = ret->err_temp_cz;
6464 ch = ret->err_temp_ch;
6465 }
6466
6467 /* Set correlation lengths for volume mixing ratios... */
6468 for (int ig = 0; ig < ctl->ng; ig++)
6469 if (iqa[i] == IDXQ(ig)) {
6470 cz = ret->err_q_cz[ig];
6471 ch = ret->err_q_ch[ig];
6472 }
6473
6474 /* Set correlation lengths for extinction... */
6475 for (int iw = 0; iw < ctl->nw; iw++)
6476 if (iqa[i] == IDXK(iw)) {
6477 cz = ret->err_k_cz[iw];
6478 ch = ret->err_k_ch[iw];
6479 }
6480
6481 /* Compute correlations... */
6482 if (cz > 0 && ch > 0) {
6483
6484 /* Get Cartesian coordinates... */
6485 double x0[3], x1[3];
6486 geo2cart(0, atm->lon[ipa[i]], atm->lat[ipa[i]], x0);
6487 geo2cart(0, atm->lon[ipa[j]], atm->lat[ipa[j]], x1);
6488
6489 /* Compute correlations... */
6490 const double rho =
6491 exp(-DIST(x0, x1) / ch -
6492 fabs(atm->z[ipa[i]] - atm->z[ipa[j]]) / cz);
6493
6494 /* Set covariance... */
6495 gsl_matrix_set(s_a, i, j, gsl_vector_get(x_a, i)
6496 * gsl_vector_get(x_a, j) * rho);
6497 }
6498 }
6499
6500 /* Free... */
6501 gsl_vector_free(x_a);
6502}
#define DIST(a, b)
Compute Cartesian distance between two 3D vectors.
Definition: jurassic.h:448
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 6506 of file jurassic.c.

6512 {
6513
6514 static obs_t obs_err;
6515
6516 /* Get size... */
6517 const size_t m = sig_eps_inv->size;
6518
6519 /* Noise error (always considered in retrieval fit)... */
6520 copy_obs(ctl, &obs_err, obs, 1);
6521 for (int ir = 0; ir < obs_err.nr; ir++)
6522 for (int id = 0; id < ctl->nd; id++)
6523 obs_err.rad[id][ir]
6524 = (isfinite(obs->rad[id][ir]) ? ret->err_noise[id] : NAN);
6525 obs2y(ctl, &obs_err, sig_noise, NULL, NULL);
6526
6527 /* Forward model error (always considered in retrieval fit)... */
6528 copy_obs(ctl, &obs_err, obs, 1);
6529 for (int ir = 0; ir < obs_err.nr; ir++)
6530 for (int id = 0; id < ctl->nd; id++)
6531 obs_err.rad[id][ir]
6532 = fabs(ret->err_formod[id] / 100 * obs->rad[id][ir]);
6533 obs2y(ctl, &obs_err, sig_formod, NULL, NULL);
6534
6535 /* Total error... */
6536 for (size_t i = 0; i < m; i++)
6537 gsl_vector_set(sig_eps_inv, i, 1 / sqrt(POW2(gsl_vector_get(sig_noise, i))
6538 +
6539 POW2(gsl_vector_get
6540 (sig_formod, i))));
6541
6542 /* Check standard deviations... */
6543 for (size_t i = 0; i < m; i++)
6544 if (gsl_vector_get(sig_eps_inv, i) <= 0)
6545 ERRMSG("Check measurement errors (zero standard deviation)!");
6546}
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 6550 of file jurassic.c.

6554 {
6555
6556 double dummy, v[3], v0[3], v2[3];
6557
6558 /* Find minimum altitude... */
6559 const size_t ip = gsl_stats_min_index(los->z, 1, (size_t) los->np);
6560
6561 /* Nadir or zenith... */
6562 if (ip <= 0 || ip >= (size_t) los->np - 1) {
6563 *tpz = los->z[los->np - 1];
6564 *tplon = los->lon[los->np - 1];
6565 *tplat = los->lat[los->np - 1];
6566 }
6567
6568 /* Limb... */
6569 else {
6570
6571 /* Determine interpolating polynomial y=a*x^2+b*x+c... */
6572 const double yy0 = los->z[ip - 1];
6573 const double yy1 = los->z[ip];
6574 const double yy2 = los->z[ip + 1];
6575 const double x1 = sqrt(POW2(los->ds[ip]) - POW2(yy1 - yy0));
6576 const double x2 = x1 + sqrt(POW2(los->ds[ip + 1]) - POW2(yy2 - yy1));
6577 const double a = 1 / (x1 - x2) * (-(yy0 - yy1) / x1 + (yy0 - yy2) / x2);
6578 const double b = -(yy0 - yy1) / x1 - a * x1;
6579 const double c = yy0;
6580
6581 /* Get tangent point location... */
6582 const double x = -b / (2 * a);
6583 *tpz = a * x * x + b * x + c;
6584 geo2cart(los->z[ip - 1], los->lon[ip - 1], los->lat[ip - 1], v0);
6585 geo2cart(los->z[ip + 1], los->lon[ip + 1], los->lat[ip + 1], v2);
6586 for (int i = 0; i < 3; i++)
6587 v[i] = LIN(0.0, v0[i], x2, v2[i], x);
6588 cart2geo(v, &dummy, tplon, tplat);
6589 }
6590}
Here is the call graph for this function:

◆ 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. No bounds checking is performed inside this function.
See also
tbl_unpack()
Author
Lars Hoffmann

Definition at line 6594 of file jurassic.c.

6599 {
6600
6601 uint8_t *cur = buf;
6602
6603 int np = tbl->np[id][ig];
6604 memcpy(cur, &np, sizeof(np));
6605 cur += sizeof(np);
6606
6607 memcpy(cur, tbl->p[id][ig], (size_t) np * sizeof(double));
6608 cur += ((size_t) np * sizeof(double));
6609
6610 for (int ip = 0; ip < np; ip++) {
6611 int nt = tbl->nt[id][ig][ip];
6612 memcpy(cur, &nt, sizeof(nt));
6613 cur += sizeof(nt);
6614
6615 memcpy(cur, tbl->t[id][ig][ip], (size_t) nt * sizeof(double));
6616 cur += ((size_t) nt * sizeof(double));
6617
6618 for (int it = 0; it < nt; it++) {
6619 int nu = tbl->nu[id][ig][ip][it];
6620 memcpy(cur, &nu, sizeof(nu));
6621 cur += sizeof(nu);
6622
6623 memcpy(cur, tbl->u[id][ig][ip][it], (size_t) nu * sizeof(float));
6624 cur += ((size_t) nu * sizeof(float));
6625
6626 memcpy(cur, tbl->eps[id][ig][ip][it], (size_t) nu * sizeof(float));
6627 cur += ((size_t) nu * sizeof(float));
6628 }
6629 }
6630
6631 *bytes_used = (size_t) (cur - buf);
6632
6633 if (*bytes_used > TBLBUF)
6634 ERRMSG("Packed table size exceeds buffer!");
6635}

◆ 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 6639 of file jurassic.c.

6643 {
6644
6645 const uint8_t *cur = buf;
6646
6647 int np;
6648 memcpy(&np, cur, sizeof(np));
6649 cur += sizeof(np);
6650
6651 if (np < 0 || np > TBLNP)
6652 ERRMSG("np out of range!");
6653
6654 tbl->np[id][ig] = np;
6655
6656 memcpy(tbl->p[id][ig], cur, (size_t) np * sizeof(double));
6657 cur += ((size_t) np * sizeof(double));
6658
6659 for (int ip = 0; ip < np; ip++) {
6660
6661 int nt;
6662 memcpy(&nt, cur, sizeof(nt));
6663 cur += sizeof(nt);
6664
6665 if (nt < 0 || nt > TBLNT)
6666 ERRMSG("nt out of range!");
6667
6668 tbl->nt[id][ig][ip] = nt;
6669
6670 memcpy(tbl->t[id][ig][ip], cur, (size_t) nt * sizeof(double));
6671 cur += ((size_t) nt * sizeof(double));
6672
6673 for (int it = 0; it < nt; it++) {
6674
6675 int nu;
6676 memcpy(&nu, cur, sizeof(nu));
6677 cur += sizeof(nu);
6678
6679 if (nu < 0 || nu > TBLNU)
6680 ERRMSG("nu out of range!");
6681
6682 tbl->nu[id][ig][ip][it] = nu;
6683
6684 memcpy(tbl->u[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
6685 cur += ((size_t) nu * sizeof(float));
6686
6687 memcpy(tbl->eps[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
6688 cur += ((size_t) nu * sizeof(float));
6689 }
6690 }
6691
6692 return (size_t) (cur - buf);
6693}

◆ 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 6697 of file jurassic.c.

6705 {
6706
6707 struct tm t0, t1;
6708
6709 t0.tm_year = 100;
6710 t0.tm_mon = 0;
6711 t0.tm_mday = 1;
6712 t0.tm_hour = 0;
6713 t0.tm_min = 0;
6714 t0.tm_sec = 0;
6715
6716 t1.tm_year = year - 1900;
6717 t1.tm_mon = mon - 1;
6718 t1.tm_mday = day;
6719 t1.tm_hour = hour;
6720 t1.tm_min = min;
6721 t1.tm_sec = sec;
6722
6723 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
6724}

◆ 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 6728 of file jurassic.c.

6733 {
6734
6735 static double w0[10];
6736
6737 static int l0[10], nt;
6738
6739 /* Start new timer... */
6740 if (mode == 1) {
6741 w0[nt] = omp_get_wtime();
6742 l0[nt] = line;
6743 if ((++nt) >= 10)
6744 ERRMSG("Too many timers!");
6745 }
6746
6747 /* Write elapsed time... */
6748 else {
6749
6750 /* Check timer index... */
6751 if (nt - 1 < 0)
6752 ERRMSG("Coding error!");
6753
6754 /* Write elapsed time... */
6755 LOG(1, "Timer '%s' (%s, %s, l%d-%d): %.3f sec",
6756 name, file, func, l0[nt - 1], line, omp_get_wtime() - w0[nt - 1]);
6757 }
6758
6759 /* Stop timer... */
6760 if (mode == 3)
6761 nt--;
6762}

◆ 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 6766 of file jurassic.c.

6770 {
6771
6772 char file[LEN];
6773
6774 /* Set filename... */
6775 if (dirname != NULL)
6776 sprintf(file, "%s/%s", dirname, filename);
6777 else
6778 sprintf(file, "%s", filename);
6779
6780 /* Write info... */
6781 LOG(1, "Write atmospheric data: %s", file);
6782
6783 /* Write ASCII data... */
6784 if (ctl->atmfmt == 1)
6785 write_atm_asc(file, ctl, atm);
6786
6787 /* Write binary data... */
6788 else if (ctl->atmfmt == 2)
6789 write_atm_bin(file, ctl, atm);
6790
6791 /* Write netCDF data... */
6792 else if (ctl->atmfmt == 3)
6793 write_atm_nc(file, ctl, atm, 0);
6794
6795 /* Error... */
6796 else
6797 ERRMSG("Unknown file format, check ATMFMT!");
6798
6799 /* Write info... */
6800 double mini, maxi;
6801 LOG(2, "Number of data points: %d", atm->np);
6802 gsl_stats_minmax(&mini, &maxi, atm->time, 1, (size_t) atm->np);
6803 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
6804 gsl_stats_minmax(&mini, &maxi, atm->z, 1, (size_t) atm->np);
6805 LOG(2, "Altitude range: %g ... %g km", mini, maxi);
6806 gsl_stats_minmax(&mini, &maxi, atm->lon, 1, (size_t) atm->np);
6807 LOG(2, "Longitude range: %g ... %g deg", mini, maxi);
6808 gsl_stats_minmax(&mini, &maxi, atm->lat, 1, (size_t) atm->np);
6809 LOG(2, "Latitude range: %g ... %g deg", mini, maxi);
6810 gsl_stats_minmax(&mini, &maxi, atm->p, 1, (size_t) atm->np);
6811 LOG(2, "Pressure range: %g ... %g hPa", maxi, mini);
6812 gsl_stats_minmax(&mini, &maxi, atm->t, 1, (size_t) atm->np);
6813 LOG(2, "Temperature range: %g ... %g K", mini, maxi);
6814 for (int ig = 0; ig < ctl->ng; ig++) {
6815 gsl_stats_minmax(&mini, &maxi, atm->q[ig], 1, (size_t) atm->np);
6816 LOG(2, "Emitter %s range: %g ... %g ppv", ctl->emitter[ig], mini, maxi);
6817 }
6818 for (int iw = 0; iw < ctl->nw; iw++) {
6819 gsl_stats_minmax(&mini, &maxi, atm->k[iw], 1, (size_t) atm->np);
6820 LOG(2, "Extinction range (window %d): %g ... %g km^-1", iw, mini, maxi);
6821 }
6822 if (ctl->ncl > 0 && atm->np == 0) {
6823 LOG(2, "Cloud layer: z= %g km | dz= %g km | k= %g ... %g km^-1",
6824 atm->clz, atm->cldz, atm->clk[0], atm->clk[ctl->ncl - 1]);
6825 } else
6826 LOG(2, "Cloud layer: none");
6827 if (ctl->nsf > 0 && atm->np == 0) {
6828 LOG(2,
6829 "Surface: T_s = %g K | eps= %g ... %g",
6830 atm->sft, atm->sfeps[0], atm->sfeps[ctl->nsf - 1]);
6831 } else
6832 LOG(2, "Surface: none");
6833}
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:6988
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:6837
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:6904
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 6837 of file jurassic.c.

6840 {
6841
6842 int n = 6;
6843
6844 /* Create file... */
6845 FILE *out;
6846 if (!(out = fopen(filename, "w")))
6847 ERRMSG("Cannot create file!");
6848
6849 /* Write header... */
6850 fprintf(out,
6851 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
6852 "# $2 = altitude [km]\n"
6853 "# $3 = longitude [deg]\n"
6854 "# $4 = latitude [deg]\n"
6855 "# $5 = pressure [hPa]\n" "# $6 = temperature [K]\n");
6856 for (int ig = 0; ig < ctl->ng; ig++)
6857 fprintf(out, "# $%d = %s volume mixing ratio [ppv]\n",
6858 ++n, ctl->emitter[ig]);
6859 for (int iw = 0; iw < ctl->nw; iw++)
6860 fprintf(out, "# $%d = extinction (window %d) [km^-1]\n", ++n, iw);
6861 if (ctl->ncl > 0) {
6862 fprintf(out, "# $%d = cloud layer height [km]\n", ++n);
6863 fprintf(out, "# $%d = cloud layer depth [km]\n", ++n);
6864 for (int icl = 0; icl < ctl->ncl; icl++)
6865 fprintf(out, "# $%d = cloud layer extinction (%.4f cm^-1) [km^-1]\n",
6866 ++n, ctl->clnu[icl]);
6867 }
6868 if (ctl->nsf > 0) {
6869 fprintf(out, "# $%d = surface temperature [K]\n", ++n);
6870 for (int isf = 0; isf < ctl->nsf; isf++)
6871 fprintf(out, "# $%d = surface emissivity (%.4f cm^-1)\n",
6872 ++n, ctl->sfnu[isf]);
6873 }
6874
6875 /* Write data... */
6876 for (int ip = 0; ip < atm->np; ip++) {
6877 if (ip == 0 || atm->time[ip] != atm->time[ip - 1])
6878 fprintf(out, "\n");
6879 fprintf(out, "%.2f %g %g %g %g %g", atm->time[ip], atm->z[ip],
6880 atm->lon[ip], atm->lat[ip], atm->p[ip], atm->t[ip]);
6881 for (int ig = 0; ig < ctl->ng; ig++)
6882 fprintf(out, " %g", atm->q[ig][ip]);
6883 for (int iw = 0; iw < ctl->nw; iw++)
6884 fprintf(out, " %g", atm->k[iw][ip]);
6885 if (ctl->ncl > 0) {
6886 fprintf(out, " %g %g", atm->clz, atm->cldz);
6887 for (int icl = 0; icl < ctl->ncl; icl++)
6888 fprintf(out, " %g", atm->clk[icl]);
6889 }
6890 if (ctl->nsf > 0) {
6891 fprintf(out, " %g", atm->sft);
6892 for (int isf = 0; isf < ctl->nsf; isf++)
6893 fprintf(out, " %g", atm->sfeps[isf]);
6894 }
6895 fprintf(out, "\n");
6896 }
6897
6898 /* Close file... */
6899 fclose(out);
6900}

◆ 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 6904 of file jurassic.c.

6907 {
6908
6909 /* Create file... */
6910 FILE *out;
6911 if (!(out = fopen(filename, "w")))
6912 ERRMSG("Cannot create file!");
6913
6914 /* Write header... */
6915 FWRITE("ATM1", char,
6916 4,
6917 out);
6918 FWRITE(&ctl->ng, int,
6919 1,
6920 out);
6921 FWRITE(&ctl->nw, int,
6922 1,
6923 out);
6924 FWRITE(&ctl->ncl, int,
6925 1,
6926 out);
6927 FWRITE(&ctl->nsf, int,
6928 1,
6929 out);
6930
6931 /* Write data... */
6932 size_t np = (size_t) atm->np;
6933 FWRITE(&np, size_t,
6934 1,
6935 out);
6936 FWRITE(atm->time, double,
6937 np,
6938 out);
6939 FWRITE(atm->z, double,
6940 np,
6941 out);
6942 FWRITE(atm->lon, double,
6943 np,
6944 out);
6945 FWRITE(atm->lat, double,
6946 np,
6947 out);
6948 FWRITE(atm->p, double,
6949 np,
6950 out);
6951 FWRITE(atm->t, double,
6952 np,
6953 out);
6954 for (int ig = 0; ig < ctl->ng; ig++)
6955 FWRITE(atm->q[ig], double,
6956 np,
6957 out);
6958 for (int iw = 0; iw < ctl->nw; iw++)
6959 FWRITE(atm->k[iw], double,
6960 np,
6961 out);
6962 if (ctl->ncl > 0) {
6963 FWRITE(&atm->clz, double,
6964 1,
6965 out);
6966 FWRITE(&atm->cldz, double,
6967 1,
6968 out);
6969 FWRITE(atm->clk, double,
6970 (size_t) ctl->ncl,
6971 out);
6972 }
6973 if (ctl->nsf > 0) {
6974 FWRITE(&atm->sft, double,
6975 1,
6976 out);
6977 FWRITE(atm->sfeps, double,
6978 (size_t) ctl->nsf,
6979 out);
6980 }
6981
6982 /* Close file... */
6983 fclose(out);
6984}
#define FWRITE(ptr, type, size, out)
Write binary data to a file.
Definition: jurassic.h:526

◆ 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 6988 of file jurassic.c.

6992 {
6993
6994 char longname[LEN], varname[LEN];
6995
6996 int ncid, varid, dim_profile, dim_level;
6997
6998 size_t level_max;
6999
7000 /* Open or create file... */
7001 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR)
7002 NC(nc_create(filename, NC_NETCDF4, &ncid));
7003
7004 /* Enter define mode... */
7005 int r = nc_redef(ncid);
7006 if (r != NC_NOERR && r != NC_EINDEFINE)
7007 NC(r);
7008
7009 /* Define profile dimension (unlimited)... */
7010 if (nc_inq_dimid(ncid, "profile", &dim_profile) != NC_NOERR)
7011 NC(nc_def_dim(ncid, "profile", NC_UNLIMITED, &dim_profile));
7012
7013 /* Define level dimension (fixed)... */
7014 if (nc_inq_dimid(ncid, "level", &dim_level) == NC_NOERR) {
7015 NC(nc_inq_dimlen(ncid, dim_level, &level_max));
7016 if (level_max < 1 || level_max > (size_t) NP)
7017 ERRMSG("netCDF dimension level is out of range!");
7018 if ((size_t) atm->np > level_max)
7019 ERRMSG("profile has too many levels!");
7020 } else {
7021 level_max = (size_t) atm->np;
7022 NC(nc_def_dim(ncid, "level", level_max, &dim_level));
7023 }
7024
7025 /* Set dimension IDs... */
7026 int dimids[2] = { dim_profile, dim_level };
7027
7028 /* Tunables for compression/quantization... */
7029 const int deflate_level = 0;
7030 const int quant_digits = 0;
7031
7032 /* Define nlev (1D)... */
7033 if (nc_inq_varid(ncid, "nlev", &varid) != NC_NOERR)
7034 NC_DEF_VAR("nlev", NC_INT, 1, dimids,
7035 "number of vertical levels", "1", 0, 0);
7036
7037 /* Define core variables (2D)... */
7038 if (nc_inq_varid(ncid, "time", &varid) != NC_NOERR)
7039 NC_DEF_VAR("time", NC_DOUBLE, 2, dimids,
7040 "time in seconds since 2000-01-01, 00:00 UTC", "s",
7041 deflate_level, 0);
7042
7043 if (nc_inq_varid(ncid, "z", &varid) != NC_NOERR)
7044 NC_DEF_VAR("z", NC_DOUBLE, 2, dimids, "altitude", "km", deflate_level, 0);
7045
7046 if (nc_inq_varid(ncid, "lon", &varid) != NC_NOERR)
7047 NC_DEF_VAR("lon", NC_DOUBLE, 2, dimids,
7048 "longitude", "degrees_east", deflate_level, 0);
7049
7050 if (nc_inq_varid(ncid, "lat", &varid) != NC_NOERR)
7051 NC_DEF_VAR("lat", NC_DOUBLE, 2, dimids,
7052 "latitude", "degrees_north", deflate_level, 0);
7053
7054 if (nc_inq_varid(ncid, "p", &varid) != NC_NOERR)
7055 NC_DEF_VAR("p", NC_DOUBLE, 2, dimids,
7056 "pressure", "hPa", deflate_level, quant_digits);
7057
7058 if (nc_inq_varid(ncid, "t", &varid) != NC_NOERR)
7059 NC_DEF_VAR("t", NC_DOUBLE, 2, dimids,
7060 "temperature", "K", deflate_level, quant_digits);
7061
7062 /* Write emitters (2D)... */
7063 for (int ig = 0; ig < ctl->ng; ig++)
7064 if (nc_inq_varid(ncid, ctl->emitter[ig], &varid) != NC_NOERR) {
7065 sprintf(longname, "%s volume mixing ratio", ctl->emitter[ig]);
7066 NC_DEF_VAR(ctl->emitter[ig], NC_DOUBLE, 2, dimids,
7067 longname, "ppv", deflate_level, quant_digits);
7068 }
7069
7070 /* Write extinction (2D)... */
7071 for (int iw = 0; iw < ctl->nw; iw++) {
7072 sprintf(varname, "ext_win_%d", iw);
7073 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7074 sprintf(longname, "extinction (window %d)", iw);
7075 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids,
7076 longname, "km**-1", deflate_level, quant_digits);
7077 }
7078 }
7079
7080 /* Write cloud variables (1D)... */
7081 if (ctl->ncl > 0) {
7082 if (nc_inq_varid(ncid, "cld_z", &varid) != NC_NOERR)
7083 NC_DEF_VAR("cld_z", NC_DOUBLE, 1, dimids,
7084 "cloud layer height", "km", deflate_level, quant_digits);
7085
7086 if (nc_inq_varid(ncid, "cld_dz", &varid) != NC_NOERR)
7087 NC_DEF_VAR("cld_dz", NC_DOUBLE, 1, dimids,
7088 "cloud layer depth", "km", deflate_level, quant_digits);
7089
7090 for (int icl = 0; icl < ctl->ncl; icl++) {
7091 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
7092 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7093 sprintf(longname, "cloud layer extinction (%.4f cm^-1)",
7094 ctl->clnu[icl]);
7095 NC_DEF_VAR(varname, NC_DOUBLE, 1, dimids, longname, "km**-1",
7096 deflate_level, quant_digits);
7097 }
7098 }
7099 }
7100
7101 /* Write surface variables (1D)... */
7102 if (ctl->nsf > 0) {
7103 if (nc_inq_varid(ncid, "srf_t", &varid) != NC_NOERR)
7104 NC_DEF_VAR("srf_t", NC_DOUBLE, 1, dimids,
7105 "surface temperature", "K", deflate_level, quant_digits);
7106
7107 for (int isf = 0; isf < ctl->nsf; isf++) {
7108 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
7109 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7110 sprintf(longname, "surface emissivity (%.4f cm^-1)", ctl->sfnu[isf]);
7111 NC_DEF_VAR(varname, NC_DOUBLE, 1, dimids, longname, "1",
7112 deflate_level, quant_digits);
7113 }
7114 }
7115 }
7116
7117 /* Leave define mode... */
7118 NC(nc_enddef(ncid));
7119
7120 /* Define hyperslabs... */
7121 size_t start[2] = { (size_t) profile, 0 };
7122 size_t count[2] = { 1, (size_t) atm->np };
7123
7124 /* Write nlev... */
7125 NC_PUT_INT("nlev", &atm->np, 1);
7126
7127 /* Write core variables... */
7128 NC_PUT_DOUBLE("time", atm->time, 1);
7129 NC_PUT_DOUBLE("z", atm->z, 1);
7130 NC_PUT_DOUBLE("lon", atm->lon, 1);
7131 NC_PUT_DOUBLE("lat", atm->lat, 1);
7132 NC_PUT_DOUBLE("p", atm->p, 1);
7133 NC_PUT_DOUBLE("t", atm->t, 1);
7134
7135 /* Write emitters... */
7136 for (int ig = 0; ig < ctl->ng; ig++)
7137 NC_PUT_DOUBLE(ctl->emitter[ig], atm->q[ig], 1);
7138
7139 /* Write extinction... */
7140 for (int iw = 0; iw < ctl->nw; iw++) {
7141 sprintf(varname, "ext_win_%d", iw);
7142 NC_PUT_DOUBLE(varname, atm->k[iw], 1);
7143 }
7144
7145 /* Write cloud variables... */
7146 if (ctl->ncl > 0) {
7147 NC_PUT_DOUBLE("cld_z", &atm->clz, 1);
7148 NC_PUT_DOUBLE("cld_dz", &atm->cldz, 1);
7149
7150 for (int icl = 0; icl < ctl->ncl; icl++) {
7151 sprintf(varname, "cld_k_%d", icl);
7152 NC_PUT_DOUBLE(varname, &atm->clk[icl], 1);
7153 }
7154 }
7155
7156 /* Write surface variables... */
7157 if (ctl->nsf > 0) {
7158 NC_PUT_DOUBLE("srf_t", &atm->sft, 1);
7159
7160 for (int isf = 0; isf < ctl->nsf; isf++) {
7161 sprintf(varname, "srf_eps_%d", isf);
7162 NC_PUT_DOUBLE(varname, &atm->sfeps[isf], 1);
7163 }
7164 }
7165
7166 /* Close file... */
7167 NC(nc_sync(ncid));
7168 NC(nc_close(ncid));
7169}
#define NC_PUT_INT(varname, ptr, hyperslab)
Write integer data to a NetCDF variable.
Definition: jurassic.h:805
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
Definition: jurassic.h:674
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
Definition: jurassic.h:758

◆ 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 7173 of file jurassic.c.

7176 {
7177
7178 FILE *out;
7179
7180 /* Write info... */
7181 LOG(1, "Write RFM data: %s", filename);
7182
7183 /* Create file... */
7184 if (!(out = fopen(filename, "w")))
7185 ERRMSG("Cannot create file!");
7186
7187 /* Write data... */
7188 fprintf(out, "%d\n", atm->np);
7189 fprintf(out, "*HGT [km]\n");
7190 for (int ip = 0; ip < atm->np; ip++)
7191 fprintf(out, "%g\n", atm->z[ip]);
7192 fprintf(out, "*PRE [mb]\n");
7193 for (int ip = 0; ip < atm->np; ip++)
7194 fprintf(out, "%g\n", atm->p[ip]);
7195 fprintf(out, "*TEM [K]\n");
7196 for (int ip = 0; ip < atm->np; ip++)
7197 fprintf(out, "%g\n", atm->t[ip]);
7198 for (int ig = 0; ig < ctl->ng; ig++) {
7199 fprintf(out, "*%s [ppmv]\n", ctl->emitter[ig]);
7200 for (int ip = 0; ip < atm->np; ip++)
7201 fprintf(out, "%g\n", atm->q[ig][ip] * 1e6);
7202 }
7203 fprintf(out, "*END\n");
7204
7205 /* Close file... */
7206 fclose(out);
7207}

◆ 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 7211 of file jurassic.c.

7220 {
7221
7222 FILE *out;
7223
7224 char file[LEN], quantity[LEN];
7225
7226 int *cida, *ciqa, *cipa, *cira, *rida, *riqa, *ripa, *rira;
7227
7228 size_t i, j, nc, nr;
7229
7230 /* Check output flag... */
7231 if (!ctl->write_matrix)
7232 return;
7233
7234 /* Allocate... */
7235 ALLOC(cida, int,
7236 M);
7237 ALLOC(ciqa, int,
7238 N);
7239 ALLOC(cipa, int,
7240 N);
7241 ALLOC(cira, int,
7242 M);
7243 ALLOC(rida, int,
7244 M);
7245 ALLOC(riqa, int,
7246 N);
7247 ALLOC(ripa, int,
7248 N);
7249 ALLOC(rira, int,
7250 M);
7251
7252 /* Set filename... */
7253 if (dirname != NULL)
7254 sprintf(file, "%s/%s", dirname, filename);
7255 else
7256 sprintf(file, "%s", filename);
7257
7258 /* Write info... */
7259 LOG(1, "Write matrix: %s", file);
7260
7261 /* Create file... */
7262 if (!(out = fopen(file, "w")))
7263 ERRMSG("Cannot create file!");
7264
7265 /* Write header (row space)... */
7266 if (rowspace[0] == 'y') {
7267
7268 fprintf(out,
7269 "# $1 = Row: index (measurement space)\n"
7270 "# $2 = Row: channel wavenumber [cm^-1]\n"
7271 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
7272 "# $4 = Row: view point altitude [km]\n"
7273 "# $5 = Row: view point longitude [deg]\n"
7274 "# $6 = Row: view point latitude [deg]\n");
7275
7276 /* Get number of rows... */
7277 nr = obs2y(ctl, obs, NULL, rida, rira);
7278
7279 } else {
7280
7281 fprintf(out,
7282 "# $1 = Row: index (state space)\n"
7283 "# $2 = Row: name of quantity\n"
7284 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
7285 "# $4 = Row: altitude [km]\n"
7286 "# $5 = Row: longitude [deg]\n" "# $6 = Row: latitude [deg]\n");
7287
7288 /* Get number of rows... */
7289 nr = atm2x(ctl, atm, NULL, riqa, ripa);
7290 }
7291
7292 /* Write header (column space)... */
7293 if (colspace[0] == 'y') {
7294
7295 fprintf(out,
7296 "# $7 = Col: index (measurement space)\n"
7297 "# $8 = Col: channel wavenumber [cm^-1]\n"
7298 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
7299 "# $10 = Col: view point altitude [km]\n"
7300 "# $11 = Col: view point longitude [deg]\n"
7301 "# $12 = Col: view point latitude [deg]\n");
7302
7303 /* Get number of columns... */
7304 nc = obs2y(ctl, obs, NULL, cida, cira);
7305
7306 } else {
7307
7308 fprintf(out,
7309 "# $7 = Col: index (state space)\n"
7310 "# $8 = Col: name of quantity\n"
7311 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
7312 "# $10 = Col: altitude [km]\n"
7313 "# $11 = Col: longitude [deg]\n" "# $12 = Col: latitude [deg]\n");
7314
7315 /* Get number of columns... */
7316 nc = atm2x(ctl, atm, NULL, ciqa, cipa);
7317 }
7318
7319 /* Write header entry... */
7320 fprintf(out, "# $13 = Matrix element\n\n");
7321
7322 /* Write matrix data... */
7323 i = j = 0;
7324 while (i < nr && j < nc) {
7325
7326 /* Write info about the row... */
7327 if (rowspace[0] == 'y')
7328 fprintf(out, "%d %.4f %.2f %g %g %g",
7329 (int) i, ctl->nu[rida[i]],
7330 obs->time[rira[i]], obs->vpz[rira[i]],
7331 obs->vplon[rira[i]], obs->vplat[rira[i]]);
7332 else {
7333 idx2name(ctl, riqa[i], quantity);
7334 fprintf(out, "%d %s %.2f %g %g %g", (int) i, quantity,
7335 atm->time[ripa[i]], atm->z[ripa[i]],
7336 atm->lon[ripa[i]], atm->lat[ripa[i]]);
7337 }
7338
7339 /* Write info about the column... */
7340 if (colspace[0] == 'y')
7341 fprintf(out, " %d %.4f %.2f %g %g %g",
7342 (int) j, ctl->nu[cida[j]],
7343 obs->time[cira[j]], obs->vpz[cira[j]],
7344 obs->vplon[cira[j]], obs->vplat[cira[j]]);
7345 else {
7346 idx2name(ctl, ciqa[j], quantity);
7347 fprintf(out, " %d %s %.2f %g %g %g", (int) j, quantity,
7348 atm->time[cipa[j]], atm->z[cipa[j]],
7349 atm->lon[cipa[j]], atm->lat[cipa[j]]);
7350 }
7351
7352 /* Write matrix entry... */
7353 fprintf(out, " %g\n", gsl_matrix_get(matrix, i, j));
7354
7355 /* Set matrix indices... */
7356 if (sort[0] == 'r') {
7357 j++;
7358 if (j >= nc) {
7359 j = 0;
7360 i++;
7361 fprintf(out, "\n");
7362 }
7363 } else {
7364 i++;
7365 if (i >= nr) {
7366 i = 0;
7367 j++;
7368 fprintf(out, "\n");
7369 }
7370 }
7371 }
7372
7373 /* Close file... */
7374 fclose(out);
7375
7376 /* Free... */
7377 free(cida);
7378 free(ciqa);
7379 free(cipa);
7380 free(cira);
7381 free(rida);
7382 free(riqa);
7383 free(ripa);
7384 free(rira);
7385}
void idx2name(const ctl_t *ctl, const int idx, char *quantity)
Convert a quantity index to a descriptive name string.
Definition: jurassic.c:3931
#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 7389 of file jurassic.c.

7393 {
7394
7395 char file[LEN];
7396
7397 /* Set filename... */
7398 if (dirname != NULL)
7399 sprintf(file, "%s/%s", dirname, filename);
7400 else
7401 sprintf(file, "%s", filename);
7402
7403 /* Write info... */
7404 LOG(1, "Write observation data: %s", file);
7405
7406 /* Write ASCII data... */
7407 if (ctl->obsfmt == 1)
7408 write_obs_asc(file, ctl, obs);
7409
7410 /* Write binary data... */
7411 else if (ctl->obsfmt == 2)
7412 write_obs_bin(file, ctl, obs);
7413
7414 /* Write netCDF data... */
7415 else if (ctl->obsfmt == 3)
7416 write_obs_nc(file, ctl, obs, 0);
7417
7418 /* Error... */
7419 else
7420 ERRMSG("Unknown observation file format, check OBSFMT!");
7421
7422 /* Write info... */
7423 double mini, maxi;
7424 LOG(2, "Number of ray paths: %d", obs->nr);
7425 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
7426 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
7427 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
7428 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
7429 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
7430 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
7431 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
7432 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
7433 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
7434 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
7435 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
7436 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
7437 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
7438 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
7439 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
7440 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
7441 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
7442 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
7443 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
7444 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
7445 for (int id = 0; id < ctl->nd; id++) {
7446 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
7447 if (ctl->write_bbt) {
7448 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
7449 ctl->nu[id], mini, maxi);
7450 } else {
7451 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
7452 ctl->nu[id], mini, maxi);
7453 }
7454 }
7455 for (int id = 0; id < ctl->nd; id++) {
7456 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
7457 if (ctl->write_bbt) {
7458 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
7459 ctl->nu[id], mini, maxi);
7460 }
7461 }
7462}
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:7466
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:7590
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:7522
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 7466 of file jurassic.c.

7469 {
7470
7471 int n = 10;
7472
7473 /* Create file... */
7474 FILE *out;
7475 if (!(out = fopen(filename, "w")))
7476 ERRMSG("Cannot create file!");
7477
7478 /* Write header... */
7479 fprintf(out,
7480 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
7481 "# $2 = observer altitude [km]\n"
7482 "# $3 = observer longitude [deg]\n"
7483 "# $4 = observer latitude [deg]\n"
7484 "# $5 = view point altitude [km]\n"
7485 "# $6 = view point longitude [deg]\n"
7486 "# $7 = view point latitude [deg]\n"
7487 "# $8 = tangent point altitude [km]\n"
7488 "# $9 = tangent point longitude [deg]\n"
7489 "# $10 = tangent point latitude [deg]\n");
7490 for (int id = 0; id < ctl->nd; id++)
7491 if (ctl->write_bbt)
7492 fprintf(out, "# $%d = brightness temperature (%.4f cm^-1) [K]\n",
7493 ++n, ctl->nu[id]);
7494 else
7495 fprintf(out, "# $%d = radiance (%.4f cm^-1) [W/(m^2 sr cm^-1)]\n",
7496 ++n, ctl->nu[id]);
7497 for (int id = 0; id < ctl->nd; id++)
7498 fprintf(out, "# $%d = transmittance (%.4f cm^-1) [-]\n", ++n,
7499 ctl->nu[id]);
7500
7501 /* Write data... */
7502 for (int ir = 0; ir < obs->nr; ir++) {
7503 if (ir == 0 || obs->time[ir] != obs->time[ir - 1])
7504 fprintf(out, "\n");
7505 fprintf(out, "%.2f %g %g %g %g %g %g %g %g %g", obs->time[ir],
7506 obs->obsz[ir], obs->obslon[ir], obs->obslat[ir],
7507 obs->vpz[ir], obs->vplon[ir], obs->vplat[ir],
7508 obs->tpz[ir], obs->tplon[ir], obs->tplat[ir]);
7509 for (int id = 0; id < ctl->nd; id++)
7510 fprintf(out, " %g", obs->rad[id][ir]);
7511 for (int id = 0; id < ctl->nd; id++)
7512 fprintf(out, " %g", obs->tau[id][ir]);
7513 fprintf(out, "\n");
7514 }
7515
7516 /* Close file... */
7517 fclose(out);
7518}

◆ 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 7522 of file jurassic.c.

7525 {
7526
7527 /* Create file... */
7528 FILE *out;
7529 if (!(out = fopen(filename, "w")))
7530 ERRMSG("Cannot create file!");
7531
7532 /* Write header... */
7533 FWRITE("OBS1", char,
7534 4,
7535 out);
7536 FWRITE(&ctl->nd, int,
7537 1,
7538 out);
7539
7540 /* Write data... */
7541 size_t nr = (size_t) obs->nr;
7542 FWRITE(&nr, size_t,
7543 1,
7544 out);
7545 FWRITE(obs->time, double,
7546 nr,
7547 out);
7548 FWRITE(obs->obsz, double,
7549 nr,
7550 out);
7551 FWRITE(obs->obslon, double,
7552 nr,
7553 out);
7554 FWRITE(obs->obslat, double,
7555 nr,
7556 out);
7557 FWRITE(obs->vpz, double,
7558 nr,
7559 out);
7560 FWRITE(obs->vplon, double,
7561 nr,
7562 out);
7563 FWRITE(obs->vplat, double,
7564 nr,
7565 out);
7566 FWRITE(obs->tpz, double,
7567 nr,
7568 out);
7569 FWRITE(obs->tplon, double,
7570 nr,
7571 out);
7572 FWRITE(obs->tplat, double,
7573 nr,
7574 out);
7575 for (int id = 0; id < ctl->nd; id++)
7576 FWRITE(obs->rad[id], double,
7577 nr,
7578 out);
7579 for (int id = 0; id < ctl->nd; id++)
7580 FWRITE(obs->tau[id], double,
7581 nr,
7582 out);
7583
7584 /* Close file... */
7585 fclose(out);
7586}

◆ 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 7590 of file jurassic.c.

7594 {
7595
7596 char longname[LEN], varname[LEN];
7597
7598 int ncid, varid, dim_profile, dim_ray;
7599
7600 size_t ray_max;
7601
7602 /* Open or create file... */
7603 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR)
7604 NC(nc_create(filename, NC_NETCDF4, &ncid));
7605
7606 /* Enter define mode... */
7607 int r = nc_redef(ncid);
7608 if (r != NC_NOERR && r != NC_EINDEFINE)
7609 NC(r);
7610
7611 /* Define profile dimension (unlimited)... */
7612 if (nc_inq_dimid(ncid, "profile", &dim_profile) != NC_NOERR)
7613 NC(nc_def_dim(ncid, "profile", NC_UNLIMITED, &dim_profile));
7614
7615 /* Define ray dimension (fixed)... */
7616 if (nc_inq_dimid(ncid, "ray", &dim_ray) == NC_NOERR) {
7617 NC(nc_inq_dimlen(ncid, dim_ray, &ray_max));
7618 if (ray_max < 1 || ray_max > (size_t) NR)
7619 ERRMSG("netCDF dimension ray is out of range!");
7620 if ((size_t) obs->nr > ray_max)
7621 ERRMSG("profile has too many rays!");
7622 } else {
7623 ray_max = (size_t) obs->nr;
7624 NC(nc_def_dim(ncid, "ray", ray_max, &dim_ray));
7625 }
7626
7627 /* Dimension ID array... */
7628 int dimids[2] = { dim_profile, dim_ray };
7629
7630 /* Tunables for compression/quantization... */
7631 const int deflate_level = 0;
7632 const int quant_digits = 0;
7633
7634 /* Define nray (1D over profile)... */
7635 if (nc_inq_varid(ncid, "nray", &varid) != NC_NOERR)
7636 NC_DEF_VAR("nray", NC_INT, 1, dimids, "number of ray paths", "1", 0, 0);
7637
7638 /* Define geometry variables (2D over profile, ray)... */
7639 if (nc_inq_varid(ncid, "time", &varid) != NC_NOERR)
7640 NC_DEF_VAR("time", NC_DOUBLE, 2, dimids,
7641 "time in seconds since 2000-01-01, 00:00 UTC", "s",
7642 deflate_level, 0);
7643
7644 if (nc_inq_varid(ncid, "obs_z", &varid) != NC_NOERR)
7645 NC_DEF_VAR("obs_z", NC_DOUBLE, 2, dimids,
7646 "observer altitude", "km", deflate_level, 0);
7647
7648 if (nc_inq_varid(ncid, "obs_lon", &varid) != NC_NOERR)
7649 NC_DEF_VAR("obs_lon", NC_DOUBLE, 2, dimids,
7650 "observer longitude", "degrees_east", deflate_level, 0);
7651
7652 if (nc_inq_varid(ncid, "obs_lat", &varid) != NC_NOERR)
7653 NC_DEF_VAR("obs_lat", NC_DOUBLE, 2, dimids,
7654 "observer latitude", "degrees_north", deflate_level, 0);
7655
7656 if (nc_inq_varid(ncid, "vp_z", &varid) != NC_NOERR)
7657 NC_DEF_VAR("vp_z", NC_DOUBLE, 2, dimids,
7658 "view point altitude", "km", deflate_level, 0);
7659
7660 if (nc_inq_varid(ncid, "vp_lon", &varid) != NC_NOERR)
7661 NC_DEF_VAR("vp_lon", NC_DOUBLE, 2, dimids,
7662 "view point longitude", "degrees_east", deflate_level, 0);
7663
7664 if (nc_inq_varid(ncid, "vp_lat", &varid) != NC_NOERR)
7665 NC_DEF_VAR("vp_lat", NC_DOUBLE, 2, dimids,
7666 "view point latitude", "degrees_north", deflate_level, 0);
7667
7668 if (nc_inq_varid(ncid, "tp_z", &varid) != NC_NOERR)
7669 NC_DEF_VAR("tp_z", NC_DOUBLE, 2, dimids,
7670 "tangent point altitude", "km", deflate_level, 0);
7671
7672 if (nc_inq_varid(ncid, "tp_lon", &varid) != NC_NOERR)
7673 NC_DEF_VAR("tp_lon", NC_DOUBLE, 2, dimids,
7674 "tangent point longitude", "degrees_east", deflate_level, 0);
7675
7676 if (nc_inq_varid(ncid, "tp_lat", &varid) != NC_NOERR)
7677 NC_DEF_VAR("tp_lat", NC_DOUBLE, 2, dimids,
7678 "tangent point latitude", "degrees_north", deflate_level, 0);
7679
7680 /* Define radiance/transmittance per channel (2D profile,ray)... */
7681 for (int id = 0; id < ctl->nd; id++) {
7682
7683 sprintf(varname, "rad_%.4f", ctl->nu[id]);
7684 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7685 if (ctl->write_bbt) {
7686 sprintf(longname, "brightness temperature (%.4f cm^-1)", ctl->nu[id]);
7687 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname, "K",
7688 deflate_level, quant_digits);
7689 } else {
7690 sprintf(longname, "radiance (%.4f cm^-1)", ctl->nu[id]);
7691 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname,
7692 "W/(m^2 sr cm^-1)", deflate_level, quant_digits);
7693 }
7694 }
7695
7696 sprintf(varname, "tau_%.4f", ctl->nu[id]);
7697 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7698 sprintf(longname, "transmittance (%.4f cm^-1)", ctl->nu[id]);
7699 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname, "1",
7700 deflate_level, quant_digits);
7701 }
7702 }
7703
7704 /* Leave define mode... */
7705 NC(nc_enddef(ncid));
7706
7707 /* Hyperslabs... */
7708 size_t start[2] = { (size_t) profile, 0 };
7709 size_t count[2] = { 1, (size_t) obs->nr };
7710
7711 /* Write nray(profile)... */
7712 int nr = obs->nr;
7713 NC(nc_inq_varid(ncid, "nray", &varid));
7714 NC(nc_put_vara_int(ncid, varid, start, count, &nr));
7715
7716 /* Write geometry... */
7717 NC(nc_inq_varid(ncid, "time", &varid));
7718 NC(nc_put_vara_double(ncid, varid, start, count, obs->time));
7719
7720 NC(nc_inq_varid(ncid, "obs_z", &varid));
7721 NC(nc_put_vara_double(ncid, varid, start, count, obs->obsz));
7722
7723 NC(nc_inq_varid(ncid, "obs_lon", &varid));
7724 NC(nc_put_vara_double(ncid, varid, start, count, obs->obslon));
7725
7726 NC(nc_inq_varid(ncid, "obs_lat", &varid));
7727 NC(nc_put_vara_double(ncid, varid, start, count, obs->obslat));
7728
7729 NC(nc_inq_varid(ncid, "vp_z", &varid));
7730 NC(nc_put_vara_double(ncid, varid, start, count, obs->vpz));
7731
7732 NC(nc_inq_varid(ncid, "vp_lon", &varid));
7733 NC(nc_put_vara_double(ncid, varid, start, count, obs->vplon));
7734
7735 NC(nc_inq_varid(ncid, "vp_lat", &varid));
7736 NC(nc_put_vara_double(ncid, varid, start, count, obs->vplat));
7737
7738 NC(nc_inq_varid(ncid, "tp_z", &varid));
7739 NC(nc_put_vara_double(ncid, varid, start, count, obs->tpz));
7740
7741 NC(nc_inq_varid(ncid, "tp_lon", &varid));
7742 NC(nc_put_vara_double(ncid, varid, start, count, obs->tplon));
7743
7744 NC(nc_inq_varid(ncid, "tp_lat", &varid));
7745 NC(nc_put_vara_double(ncid, varid, start, count, obs->tplat));
7746
7747 /* Write spectral variables per channel... */
7748 for (int id = 0; id < ctl->nd; id++) {
7749 sprintf(varname, "rad_%.4f", ctl->nu[id]);
7750 NC(nc_inq_varid(ncid, varname, &varid));
7751 NC(nc_put_vara_double(ncid, varid, start, count, obs->rad[id]));
7752
7753 sprintf(varname, "tau_%.4f", ctl->nu[id]);
7754 NC(nc_inq_varid(ncid, varname, &varid));
7755 NC(nc_put_vara_double(ncid, varid, start, count, obs->tau[id]));
7756 }
7757
7758 /* Close file... */
7759 NC(nc_sync(ncid));
7760 NC(nc_close(ncid));
7761}

◆ 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 7765 of file jurassic.c.

7769 {
7770
7771 FILE *out;
7772
7773 /* Write info... */
7774 LOG(1, "Write shape function: %s", filename);
7775
7776 /* Create file... */
7777 if (!(out = fopen(filename, "w")))
7778 ERRMSG("Cannot create file!");
7779
7780 /* Write header... */
7781 fprintf(out,
7782 "# $1 = shape function x-value [-]\n"
7783 "# $2 = shape function y-value [-]\n\n");
7784
7785 /* Write data... */
7786 for (int i = 0; i < n; i++)
7787 fprintf(out, "%.10g %.10g\n", x[i], y[i]);
7788
7789 /* Close file... */
7790 fclose(out);
7791}

◆ 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 7795 of file jurassic.c.

7800 {
7801
7802 static atm_t atm_aux;
7803
7804 char filename[LEN];
7805
7806 /* Get sizes... */
7807 const size_t n = s->size1;
7808
7809 /* Allocate... */
7810 gsl_vector *x_aux = gsl_vector_alloc(n);
7811
7812 /* Compute standard deviation... */
7813 for (size_t i = 0; i < n; i++)
7814 gsl_vector_set(x_aux, i, sqrt(gsl_matrix_get(s, i, i)));
7815
7816 /* Write to disk... */
7817 copy_atm(ctl, &atm_aux, atm, 1);
7818 x2atm(ctl, x_aux, &atm_aux);
7819 sprintf(filename, "atm_err_%s.tab", quantity);
7820 write_atm(ret->dir, filename, ctl, &atm_aux);
7821
7822 /* Free... */
7823 gsl_vector_free(x_aux);
7824}
Here is the call graph for this function:

◆ write_tbl()

void write_tbl ( const ctl_t ctl,
const tbl_t tbl 
)

Write look-up tables in the format specified by the control structure.

This function dispatches the look-up table output to the appropriate writer based on the value of ctl->tblfmt:

  • 1: ASCII format
  • 2: Binary format
  • 3: netCDF format

If an unsupported format is specified, an error is raised.

Parameters
[in]ctlPointer to the control structure defining output format and other configuration options.
[in]tblPointer to the look-up table data to be written.
Note
This function does not return a value. Errors are reported via the ERRMSG mechanism.
See also
write_tbl_asc()
write_tbl_bin()
write_tbl_nc()
Author
Lars Hoffmann

Definition at line 7828 of file jurassic.c.

7830 {
7831
7832 /* Write ASCII look-up tables... */
7833 if (ctl->tblfmt == 1)
7834 write_tbl_asc(ctl, tbl);
7835
7836 /* Write binary look-up tables... */
7837 else if (ctl->tblfmt == 2)
7838 write_tbl_bin(ctl, tbl);
7839
7840 /* Write netCDF look-up tables... */
7841 else if (ctl->tblfmt == 3)
7842 write_tbl_nc(ctl, tbl);
7843
7844 /* Error message... */
7845 else
7846 ERRMSG("Unknown look-up table format!");
7847}
void write_tbl_nc(const ctl_t *ctl, const tbl_t *tbl)
Write packed lookup tables to NetCDF files.
Definition: jurassic.c:7941
void write_tbl_asc(const ctl_t *ctl, const tbl_t *tbl)
Write all lookup tables in human-readable ASCII format.
Definition: jurassic.c:7851
void write_tbl_bin(const ctl_t *ctl, const tbl_t *tbl)
Write all lookup tables in compact binary format.
Definition: jurassic.c:7896
Here is the call graph for this function:

◆ write_tbl_asc()

void write_tbl_asc ( const ctl_t ctl,
const tbl_t tbl 
)

Write all lookup tables in human-readable ASCII format.

For every gas index (ig) and frequency index (id), the function generates a file of the form:

<base>_<nu[id]>_<emitter[ig]>.tab

The ASCII file contains four columns:

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

Table dimensions are taken from the tbl_t structure.
Missing files cause the program to abort via ERRMSG().

Parameters
ctlControl structure providing grid metadata and filename base.
tblTable data to be written.
Author
Lars Hoffmann

Definition at line 7851 of file jurassic.c.

7853 {
7854
7855 /* Loop over emitters and detectors... */
7856 for (int ig = 0; ig < ctl->ng; ig++)
7857 for (int id = 0; id < ctl->nd; id++) {
7858
7859 /* Set filename... */
7860 char filename[2 * LEN];
7861 sprintf(filename, "%s_%.4f_%s.tab", ctl->tblbase,
7862 ctl->nu[id], ctl->emitter[ig]);
7863
7864 /* Write info... */
7865 LOG(1, "Write emissivity table: %s", filename);
7866
7867 /* Create file... */
7868 FILE *out;
7869 if (!(out = fopen(filename, "w")))
7870 ERRMSG("Cannot create file!");
7871
7872 /* Write header... */
7873 fprintf(out,
7874 "# $1 = pressure [hPa]\n"
7875 "# $2 = temperature [K]\n"
7876 "# $3 = column density [molecules/cm^2]\n"
7877 "# $4 = emissivity [-]\n");
7878
7879 /* Save table file... */
7880 for (int ip = 0; ip < tbl->np[id][ig]; ip++)
7881 for (int it = 0; it < tbl->nt[id][ig][ip]; it++) {
7882 fprintf(out, "\n");
7883 for (int iu = 0; iu < tbl->nu[id][ig][ip][it]; iu++)
7884 fprintf(out, "%g %g %e %e\n",
7885 tbl->p[id][ig][ip], tbl->t[id][ig][ip][it],
7886 tbl->u[id][ig][ip][it][iu], tbl->eps[id][ig][ip][it][iu]);
7887 }
7888
7889 /* Close file... */
7890 fclose(out);
7891 }
7892}

◆ write_tbl_bin()

void write_tbl_bin ( const ctl_t ctl,
const tbl_t tbl 
)

Write all lookup tables in compact binary format.

For each gas index (ig) and frequency index (id), a binary file named

<base>_<nu[id]>_<emitter[ig]>.bin

is created. The format is:

  • int np (number of pressure levels)
  • double p[np]
  • for each pressure:
    • int nt (number of temperature levels)
    • double t[nt]
    • for each temperature:
      • int nu (number of column-density points)
      • float u[nu]
      • float eps[nu]
Parameters
ctlControl structure containing filename base and spectral grid.
tblTable data to be serialized.
Author
Lars Hoffmann

Definition at line 7896 of file jurassic.c.

7898 {
7899
7900 /* Allocate... */
7901 uint8_t *work = NULL;
7902 ALLOC(work, uint8_t, TBLBUF);
7903
7904 /* Loop over emitters and detectors... */
7905 for (int ig = 0; ig < ctl->ng; ig++)
7906 for (int id = 0; id < ctl->nd; id++) {
7907
7908 /* Set filename... */
7909 char filename[2 * LEN];
7910 sprintf(filename, "%s_%.4f_%s.bin",
7911 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
7912
7913 /* Write info... */
7914 LOG(1, "Write emissivity table: %s", filename);
7915
7916 /* Create file... */
7917 FILE *out = fopen(filename, "wb");
7918 if (!out)
7919 ERRMSG("Cannot create file!");
7920
7921 /* Pack... */
7922 size_t used = 0;
7923 tbl_pack(tbl, id, ig, work, &used);
7924
7925 /* Write length and packed blob... */
7926 FWRITE(&used, size_t,
7927 1,
7928 out);
7929 FWRITE(work, uint8_t, used, out);
7930
7931 /* Close file... */
7932 fclose(out);
7933 }
7934
7935 /* Free... */
7936 free(work);
7937}
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:6594
Here is the call graph for this function:

◆ write_tbl_nc()

void write_tbl_nc ( const ctl_t ctl,
const tbl_t tbl 
)

Write packed lookup tables to NetCDF files.

This function serializes and stores lookup tables for all combinations of emitters and detectors into NetCDF4 files. One file is created (or opened) per emitter, and each detector’s table is written as a separate variable within that file.

The output filename for each emitter is: <ctl->tblbase>_<ctl->emitter[ig]>.nc

For each detector frequency ctl->nu[id], a variable named tbl_XXXX and a corresponding dimension len_XXXX (where XXXX is the formatted frequency) are created. Each variable contains a packed binary blob produced by tbl_pack(), stored as NC_UBYTE.

If a file does not already exist, it is created and initialized with global attributes:

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

If a variable for a given detector already exists in the file, the function aborts to prevent overwriting existing data.

Parameters
[in]ctlControl structure defining emitters, detectors, base filename, and frequencies.
[in]tblTable data structure containing the lookup tables to be packed and written.
Note
A single temporary buffer is allocated to hold the packed table data. Its size is computed to be large enough for the largest possible packed table.
Warning
The function terminates with an error if:
  • A packed table exceeds the allocated buffer size.
  • A table variable already exists in the target NetCDF file.
See also
tbl_pack()
Author
Lars Hoffmann

Definition at line 7941 of file jurassic.c.

7943 {
7944
7945 /* Allocate... */
7946 uint8_t *work = NULL;
7947 ALLOC(work, uint8_t, TBLBUF);
7948
7949 /* Loop over emitters... */
7950 for (int ig = 0; ig < ctl->ng; ig++) {
7951
7952 /* Set filename... */
7953 char filename[2 * LEN];
7954 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
7955
7956 /* Open or create file... */
7957 int ncid;
7958 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
7959 NC(nc_create(filename, NC_NETCDF4 | NC_CLOBBER, &ncid));
7960 NC_PUT_ATT_GLOBAL("format_version", "1");
7961 NC_PUT_ATT_GLOBAL("emitter", ctl->emitter[ig]);
7962 NC(nc_enddef(ncid));
7963 }
7964
7965 /* Loop over detectors... */
7966 for (int id = 0; id < ctl->nd; id++) {
7967
7968 /* Set variable and dimension name... */
7969 char varname[LEN], dimname[LEN];
7970 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
7971 sprintf(dimname, "len_%.4f", ctl->nu[id]);
7972
7973 /* Pack table... */
7974 size_t used = 0;
7975 tbl_pack(tbl, id, ig, work, &used);
7976
7977 /* Prevent overwrite... */
7978 int tmp;
7979 if (nc_inq_varid(ncid, varname, &tmp) == NC_NOERR)
7980 ERRMSG("Table already present!");
7981
7982 /* Add dimension and variable... */
7983 int dimid, varid;
7984 NC(nc_redef(ncid));
7985 NC(nc_def_dim(ncid, dimname, used, &dimid));
7986 int dimids[1] = { dimid };
7987 NC_DEF_VAR(varname, NC_UBYTE, 1, dimids,
7988 "Packed lookup table blob", "1", 0, 0);
7989 NC(nc_enddef(ncid));
7990
7991 /* Write data... */
7992 NC(nc_put_var_uchar(ncid, varid, (const unsigned char *) work));
7993 }
7994
7995 /* Close file... */
7996 NC(nc_close(ncid));
7997 }
7998
7999 /* Free... */
8000 free(work);
8001}
#define NC_PUT_ATT_GLOBAL(attname, text)
Add a global text attribute to a NetCDF file.
Definition: jurassic.h:844
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 8005 of file jurassic.c.

8008 {
8009
8010 size_t n = 0;
8011
8012 /* Get pressure... */
8013 for (int ip = 0; ip < atm->np; ip++)
8014 if (atm->z[ip] >= ctl->retp_zmin && atm->z[ip] <= ctl->retp_zmax)
8015 x2atm_help(&atm->p[ip], x, &n);
8016
8017 /* Get temperature... */
8018 for (int ip = 0; ip < atm->np; ip++)
8019 if (atm->z[ip] >= ctl->rett_zmin && atm->z[ip] <= ctl->rett_zmax)
8020 x2atm_help(&atm->t[ip], x, &n);
8021
8022 /* Get volume mixing ratio... */
8023 for (int ig = 0; ig < ctl->ng; ig++)
8024 for (int ip = 0; ip < atm->np; ip++)
8025 if (atm->z[ip] >= ctl->retq_zmin[ig]
8026 && atm->z[ip] <= ctl->retq_zmax[ig])
8027 x2atm_help(&atm->q[ig][ip], x, &n);
8028
8029 /* Get extinction... */
8030 for (int iw = 0; iw < ctl->nw; iw++)
8031 for (int ip = 0; ip < atm->np; ip++)
8032 if (atm->z[ip] >= ctl->retk_zmin[iw]
8033 && atm->z[ip] <= ctl->retk_zmax[iw])
8034 x2atm_help(&atm->k[iw][ip], x, &n);
8035
8036 /* Get cloud data... */
8037 if (ctl->ret_clz)
8038 x2atm_help(&atm->clz, x, &n);
8039 if (ctl->ret_cldz)
8040 x2atm_help(&atm->cldz, x, &n);
8041 if (ctl->ret_clk)
8042 for (int icl = 0; icl < ctl->ncl; icl++)
8043 x2atm_help(&atm->clk[icl], x, &n);
8044
8045 /* Get surface data... */
8046 if (ctl->ret_sft)
8047 x2atm_help(&atm->sft, x, &n);
8048 if (ctl->ret_sfeps)
8049 for (int isf = 0; isf < ctl->nsf; isf++)
8050 x2atm_help(&atm->sfeps[isf], x, &n);
8051}
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:8055
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 8055 of file jurassic.c.

8058 {
8059
8060 /* Get state vector element... */
8061 *value = gsl_vector_get(x, *n);
8062 (*n)++;
8063}

◆ 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 8067 of file jurassic.c.

8070 {
8071
8072 size_t m = 0;
8073
8074 /* Decompose measurement vector... */
8075 for (int ir = 0; ir < obs->nr; ir++)
8076 for (int id = 0; id < ctl->nd; id++)
8077 if (isfinite(obs->rad[id][ir])) {
8078 obs->rad[id][ir] = gsl_vector_get(y, m);
8079 m++;
8080 }
8081}