JURASSIC
Data Structures | Macros | Functions
jurassic.h File Reference

JURASSIC library declarations. More...

#include <errno.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_statistics.h>
#include <math.h>
#include <netcdf.h>
#include <omp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

Go to the source code of this file.

Data Structures

struct  atm_t
 Atmospheric profile data. More...
 
struct  ctl_t
 Control parameters. More...
 
struct  los_t
 Line-of-sight data. More...
 
struct  obs_t
 Observation geometry and radiance data. More...
 
struct  ret_t
 Retrieval control parameters. More...
 
struct  tbl_t
 Emissivity look-up tables. More...
 

Macros

#define C1   1.19104259e-8
 First spectroscopic constant (c_1 = 2 h c^2) [W/(m^2 sr cm^-4)]. More...
 
#define C2   1.43877506
 Second spectroscopic constant (c_2 = h c / k) [K/cm^-1]. More...
 
#define EPSMIN   0
 Minimum emissivity. More...
 
#define EPSMAX   1
 Maximum emissivity. More...
 
#define G0   9.80665
 Standard gravity [m/s^2]. More...
 
#define H0   7.0
 Standard scale height [km]. More...
 
#define KB   1.3806504e-23
 Boltzmann constant [kg m^2/(K s^2)]. More...
 
#define ME   5.976e24
 Mass of Earth [kg]. More...
 
#define NA   6.02214199e23
 Avogadro's number. More...
 
#define N2   0.78084
 Nitrogen concentration. More...
 
#define O2   0.20946
 Oxygen concentration. More...
 
#define P0   1013.25
 Standard pressure [hPa]. More...
 
#define RE   6367.421
 Mean radius of Earth [km]. More...
 
#define RI   8.3144598
 Ideal gas constant [J/(mol K)]. More...
 
#define T0   273.15
 Standard temperature [K]. More...
 
#define TMIN   100.
 Minimum temperature for source function [K]. More...
 
#define TMAX   400.
 Maximum temperature for source function [K]. More...
 
#define TSUN   5780.
 Effective temperature of the sun [K]. More...
 
#define UMIN   0
 Minimum column density [molecules/cm^2]. More...
 
#define UMAX   1e30
 Maximum column density [molecules/cm^2]. More...
 
#define NCL   8
 Maximum number of cloud layer spectral grid points. More...
 
#define ND   128
 Maximum number of radiance channels. More...
 
#define NG   8
 Maximum number of emitters. More...
 
#define NP   256
 Maximum number of atmospheric data points. More...
 
#define NR   256
 Maximum number of ray paths. More...
 
#define NSF   8
 Maximum number of surface layer spectral grid points. More...
 
#define NW   4
 Maximum number of spectral windows. More...
 
#define LEN   10000
 Maximum length of ASCII data lines. More...
 
#define M   (NR*ND)
 Maximum size of measurement vector. More...
 
#define N   ((2 + NG + NW) * NP + NCL + NSF + 3)
 Maximum size of state vector. More...
 
#define NQ   (5 + NG + NW + NCL + NSF)
 Maximum number of quantities. More...
 
#define NLOS   4096
 Maximum number of LOS points. More...
 
#define NSHAPE   20000
 Maximum number of shape function grid points. More...
 
#define NFOV   5
 Number of ray paths used for FOV calculations. More...
 
#define TBLNP   41
 Maximum number of pressure levels in emissivity tables. More...
 
#define TBLNT   30
 Maximum number of temperatures in emissivity tables. More...
 
#define TBLNU   512
 Maximum number of column densities per emissivity curve. More...
 
#define TBLNS   1200
 Maximum number of source function temperature levels. More...
 
#define RFMNPTS   10000000
 Maximum number of RFM spectral grid points. More...
 
#define IDXP   0
 Index for pressure. More...
 
#define IDXT   1
 Index for temperature. More...
 
#define IDXQ(ig)   (2 + (ig))
 Indices for volume mixing ratios. More...
 
#define IDXK(iw)   (2 + (ctl->ng) + (iw))
 Indices for extinction. More...
 
#define IDXCLZ   (2 + (ctl->ng) + (ctl->nw))
 Index for cloud layer height. More...
 
#define IDXCLDZ   (3 + (ctl->ng) + (ctl->nw))
 Index for cloud layer depth. More...
 
#define IDXCLK(icl)   (4 + (ctl->ng) + (ctl->nw) + (icl))
 Indices for cloud layer extinction. More...
 
#define IDXSFT   (4 + (ctl->ng) + (ctl->nw) + (ctl->ncl))
 Index for surface layer temperature. More...
 
#define IDXSFEPS(isf)   (5 + (ctl->ng) + (ctl->nw) + (ctl->ncl) + (isf))
 Indices for surface layer emissivity. More...
 
#define ALLOC(ptr, type, n)
 Allocate memory for an array. More...
 
#define BRIGHT(rad, nu)    (C2 * (nu) / gsl_log1p(C1 * POW3(nu) / (rad)))
 Compute brightness temperature from radiance. More...
 
#define DEG2RAD(deg)   ((deg) * (M_PI / 180.0))
 Convert degrees to radians. More...
 
#define DIST(a, b)   sqrt(DIST2(a, b))
 Compute Cartesian distance between two 3D vectors. More...
 
#define DIST2(a, b)    ((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])+(a[2]-b[2])*(a[2]-b[2]))
 Compute squared distance between two 3D vectors. More...
 
#define DOTP(a, b)   (a[0]*b[0]+a[1]*b[1]+a[2]*b[2])
 Compute dot product of two 3D vectors. More...
 
#define FREAD(ptr, type, size, out)
 Read binary data from a file. More...
 
#define FWRITE(ptr, type, size, out)
 Write binary data to a file. More...
 
#define LIN(x0, y0, x1, y1, x)    ((y0)+((y1)-(y0))/((x1)-(x0))*((x)-(x0)))
 Compute linear interpolation. More...
 
#define LOGX(x0, y0, x1, y1, x)
 Compute logarithmic interpolation in x. More...
 
#define LOGY(x0, y0, x1, y1, x)
 Compute logarithmic interpolation in y. More...
 
#define MAX(a, b)   (((a)>(b))?(a):(b))
 Determine the maximum of two values. More...
 
#define MIN(a, b)   (((a)<(b))?(a):(b))
 Determine the minimum of two values. More...
 
#define NC(cmd)
 Execute a NetCDF command and check for errors. More...
 
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
 Define a NetCDF variable with attributes. More...
 
#define NC_GET_DOUBLE(varname, ptr, force)
 Retrieve a double-precision variable from a NetCDF file. More...
 
#define NC_INQ_DIM(dimname, ptr, min, max, check)
 Inquire the length of a dimension in a NetCDF file. More...
 
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
 Write double precision data to a NetCDF variable. More...
 
#define NC_PUT_FLOAT(varname, ptr, hyperslab)
 Write a float array to a NetCDF file. More...
 
#define NC_PUT_INT(varname, ptr, hyperslab)
 Write integer data to a NetCDF variable. More...
 
#define NC_PUT_ATT(varname, attname, text)
 Add a text attribute to a NetCDF variable. More...
 
#define NC_PUT_ATT_GLOBAL(attname, text)    NC(nc_put_att_text(ncid, NC_GLOBAL, attname, strnlen(text, LEN), text));
 Add a global text attribute to a NetCDF file. More...
 
#define NEDT(t_bg, nesr, nu)    (BRIGHT(PLANCK((t_bg), (nu)) + (nesr), (nu)) - (t_bg))
 Convert noise-equivalent spectral radiance (NESR) to noise-equivalent delta temperature (NEDT). More...
 
#define NESR(t_bg, nedt, nu)    (PLANCK((t_bg) + (nedt), (nu)) - PLANCK((t_bg), (nu)))
 Convert noise-equivalent delta temperature (NEDT) to noise-equivalent spectral radiance (NESR). More...
 
#define NORM(a)   sqrt(DOTP(a, a))
 Compute the norm (magnitude) of a 3D vector. More...
 
#define PLANCK(T, nu)    (C1 * POW3(nu) / gsl_expm1(C2 * (nu) / (T)))
 Compute spectral radiance using Planck’s law. More...
 
#define POW2(x)   ((x)*(x))
 Compute the square of a value. More...
 
#define POW3(x)   ((x)*(x)*(x))
 Compute the cube of a value. More...
 
#define RAD2DEG(rad)   ((rad) * (180.0 / M_PI))
 Convert radians to degrees. More...
 
#define REFRAC(p, T)   (7.753e-05 * (p) / (T))
 Compute air refractivity (n - 1). More...
 
#define TBL_LOG(tbl, id, ig)
 Log detailed statistics of an emissivity look-up table. More...
 
#define TIMER(name, mode)    {timer(name, __FILE__, __func__, __LINE__, mode);}
 Start or stop a named timer. More...
 
#define TOK(line, tok, format, var)
 Tokenize a string and parse a variable. More...
 
#define LOGLEV   2
 Level of log messages (0=none, 1=basic, 2=detailed, 3=debug). More...
 
#define LOG(level, ...)
 Print a log message with a specified logging level. More...
 
#define WARN(...)
 Print a warning message with contextual information. More...
 
#define ERRMSG(...)
 Print an error message with contextual information and terminate the program. More...
 
#define PRINT(format, var)
 Print the value of a variable with contextual information. More...
 

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 source function lookup tables from emissivity data. More...
 
void intpol_atm (const ctl_t *ctl, const atm_t *atm, const double z, double *p, double *t, double *q, double *k)
 Interpolate atmospheric state variables at a given altitude. More...
 
void intpol_tbl_cga (const ctl_t *ctl, const tbl_t *tbl, const los_t *los, const int ip, double tau_path[ND][NG], double tau_seg[ND])
 Interpolate emissivities and transmittances using the Curtis–Godson approximation (CGA). More...
 
void intpol_tbl_ega (const ctl_t *ctl, const tbl_t *tbl, const los_t *los, const int ip, double tau_path[ND][NG], double tau_seg[ND])
 Interpolate emissivities and transmittances using the Emissivity Growth Approximation (EGA). More...
 
double intpol_tbl_eps (const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double logu)
 Interpolate gas emissivity as a function of column amount. More...
 
double intpol_tbl_u (const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double logeps)
 Interpolate column amount as a function of emissivity. More...
 
void jsec2time (const double jsec, int *year, int *mon, int *day, int *hour, int *min, int *sec, double *remain)
 Converts Julian seconds to calendar date and time components. More...
 
void kernel (const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs, gsl_matrix *k)
 Compute the Jacobian (kernel) matrix by finite differences. More...
 
int locate_irr (const double *xx, const int n, const double x)
 Locate index for interpolation on an irregular grid. More...
 
int locate_reg (const double *xx, const int n, const double x)
 Locate index for interpolation on a regular (uniform) grid. More...
 
int locate_tbl (const float *xx, const int n, const double x)
 Locate index for interpolation within emissivity table grids. More...
 
void matrix_invert (gsl_matrix *a)
 Invert a square matrix, optimized for diagonal or symmetric positive-definite matrices. More...
 
void matrix_product (const gsl_matrix *a, const gsl_vector *b, const int transpose, gsl_matrix *c)
 Compute structured matrix products of the form \(A^T B A\) or \(A B A^T\). More...
 
size_t obs2y (const ctl_t *ctl, const obs_t *obs, gsl_vector *y, int *ida, int *ira)
 Convert observation radiances into a measurement vector. More...
 
void optimal_estimation (ret_t *ret, ctl_t *ctl, tbl_t *tbl, obs_t *obs_meas, obs_t *obs_i, atm_t *atm_apr, atm_t *atm_i, double *chisq)
 Perform optimal estimation retrieval using Levenberg–Marquardt minimization. More...
 
void raytrace (const ctl_t *ctl, const atm_t *atm, obs_t *obs, los_t *los, const int ir)
 Perform line-of-sight (LOS) ray tracing through the atmosphere. More...
 
void read_atm (const char *dirname, const char *filename, const ctl_t *ctl, atm_t *atm)
 Read atmospheric input data from a file. More...
 
void read_atm_asc (const char *filename, const ctl_t *ctl, atm_t *atm)
 Read atmospheric data in ASCII format. More...
 
void read_atm_bin (const char *filename, const ctl_t *ctl, atm_t *atm)
 Read atmospheric data in binary format. More...
 
void read_atm_nc (const char *filename, const ctl_t *ctl, atm_t *atm, int profile)
 Read one atmospheric profile from a netCDF file. More...
 
void read_ctl (int argc, char *argv[], ctl_t *ctl)
 Read model control parameters from command-line and configuration input. More...
 
void read_matrix (const char *dirname, const char *filename, gsl_matrix *matrix)
 Read a numerical matrix from an ASCII file. More...
 
void read_obs (const char *dirname, const char *filename, const ctl_t *ctl, obs_t *obs)
 Read observation data from an input file. More...
 
void read_obs_asc (const char *filename, const ctl_t *ctl, obs_t *obs)
 Read ASCII-formatted observation data from a file. More...
 
void read_obs_bin (const char *filename, const ctl_t *ctl, obs_t *obs)
 Read binary-formatted observation data from a file. More...
 
void read_obs_nc (const char *filename, const ctl_t *ctl, obs_t *obs, const int profile)
 Read one observation profile from a NetCDF file. More...
 
double read_obs_rfm (const char *basename, const double z, const double *nu, const double *f, const int n)
 Read and spectrally convolve an RFM output spectrum. More...
 
void read_ret (int argc, char *argv[], const ctl_t *ctl, ret_t *ret)
 Read retrieval configuration and error parameters. More...
 
void read_rfm_spec (const char *filename, double *nu, double *rad, int *npts)
 Read a Reference Forward Model (RFM) ASCII spectrum. More...
 
void read_shape (const char *filename, double *x, double *y, int *n)
 Read a two-column shape function from an ASCII file. More...
 
tbl_tread_tbl (const ctl_t *ctl)
 Read emissivity lookup tables from disk. More...
 
void read_tbl_asc (const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
 Read a single ASCII emissivity lookup table. More...
 
void read_tbl_bin (const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
 Read a single compact binary emissivity lookup table. More...
 
void read_tbl_nc_channel (const ctl_t *ctl, tbl_t *tbl, int id, int ig, int ncid)
 Read one packed emissivity lookup table from an open NetCDF file. More...
 
double scan_ctl (int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
 Scan control file or command-line arguments for a configuration variable. More...
 
void set_cov_apr (const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const int *iqa, const int *ipa, gsl_matrix *s_a)
 Construct the a priori covariance matrix \(\mathbf{S_a}\) for retrieval parameters. More...
 
void set_cov_meas (const ret_t *ret, const ctl_t *ctl, const obs_t *obs, gsl_vector *sig_noise, gsl_vector *sig_formod, gsl_vector *sig_eps_inv)
 Construct measurement error standard deviations and their inverse. More...
 
double sza (double sec, double lon, double lat)
 Compute the solar zenith angle for a given time and location. More...
 
void tangent_point (const los_t *los, double *tpz, double *tplon, double *tplat)
 Determine the tangent point along a line of sight (LOS). More...
 
void tbl_free (const ctl_t *ctl, tbl_t *tbl)
 Free lookup table and all internally allocated memory. More...
 
void tbl_pack (const tbl_t *tbl, int id, int ig, uint8_t *buf, size_t *bytes_used)
 Pack a lookup table into a contiguous binary buffer. More...
 
size_t tbl_packed_size (const tbl_t *tbl, int id, int ig)
 Compute required buffer size (in bytes) for tbl_pack(). More...
 
size_t tbl_unpack (tbl_t *tbl, int id, int ig, const uint8_t *buf)
 Unpack a lookup table from a contiguous binary buffer. More...
 
void time2jsec (const int year, const int mon, const int day, const int hour, const int min, const int sec, const double remain, double *jsec)
 Converts time components to seconds since January 1, 2000, 12:00:00 UTC. More...
 
void timer (const char *name, const char *file, const char *func, int line, int mode)
 Simple wall-clock timer for runtime diagnostics. More...
 
void write_atm (const char *dirname, const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric data to a file. More...
 
void write_atm_asc (const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric data to an ASCII file. More...
 
void write_atm_bin (const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric data to a binary file. More...
 
void write_atm_nc (const char *filename, const ctl_t *ctl, const atm_t *atm, int profile)
 Write one atmospheric profile to a netCDF file. More...
 
void write_atm_rfm (const char *filename, const ctl_t *ctl, const atm_t *atm)
 Write atmospheric profile in RFM-compatible format. More...
 
void write_matrix (const char *dirname, const char *filename, const ctl_t *ctl, const gsl_matrix *matrix, const atm_t *atm, const obs_t *obs, const char *rowspace, const char *colspace, const char *sort)
 Write a fully annotated matrix (e.g., Jacobian or gain matrix) to file. More...
 
void write_obs (const char *dirname, const char *filename, const ctl_t *ctl, const obs_t *obs)
 Write observation data to an output file in ASCII or binary format. More...
 
void write_obs_asc (const char *filename, const ctl_t *ctl, const obs_t *obs)
 Write observation data to an ASCII text file. More...
 
void write_obs_bin (const char *filename, const ctl_t *ctl, const obs_t *obs)
 Write observation data in binary format to a file. More...
 
void write_obs_nc (const char *filename, const ctl_t *ctl, const obs_t *obs, const int profile)
 Write one observation profile to a NetCDF file. More...
 
void write_shape (const char *filename, const double *x, const double *y, const int n)
 Write tabulated shape function data to a text file. More...
 
void write_stddev (const char *quantity, const ret_t *ret, const ctl_t *ctl, const atm_t *atm, const gsl_matrix *s)
 Write retrieval standard deviation profiles to disk. More...
 
void write_tbl (const ctl_t *ctl, const tbl_t *tbl)
 Write emissivity lookup tables to disk. More...
 
void write_tbl_asc (const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
 Write one emissivity lookup table in human-readable ASCII format. More...
 
void write_tbl_bin (const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
 Write one emissivity lookup table in compact binary format. More...
 
void write_tbl_nc (const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
 Write one packed lookup table to a NetCDF file. More...
 
void x2atm (const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
 Map retrieval state vector back to atmospheric structure. More...
 
void x2atm_help (double *value, const gsl_vector *x, size_t *n)
 Helper function to extract a single value from the retrieval state vector. More...
 
void y2obs (const ctl_t *ctl, const gsl_vector *y, obs_t *obs)
 Copy elements from the measurement vector y into the observation structure. More...
 

Detailed Description

JURASSIC library declarations.

Definition in file jurassic.h.

Macro Definition Documentation

◆ C1

#define C1   1.19104259e-8

First spectroscopic constant (c_1 = 2 h c^2) [W/(m^2 sr cm^-4)].

Definition at line 129 of file jurassic.h.

◆ C2

#define C2   1.43877506

Second spectroscopic constant (c_2 = h c / k) [K/cm^-1].

Definition at line 134 of file jurassic.h.

◆ EPSMIN

#define EPSMIN   0

Minimum emissivity.

Definition at line 139 of file jurassic.h.

◆ EPSMAX

#define EPSMAX   1

Maximum emissivity.

Definition at line 144 of file jurassic.h.

◆ G0

#define G0   9.80665

Standard gravity [m/s^2].

Definition at line 149 of file jurassic.h.

◆ H0

#define H0   7.0

Standard scale height [km].

Definition at line 154 of file jurassic.h.

◆ KB

#define KB   1.3806504e-23

Boltzmann constant [kg m^2/(K s^2)].

Definition at line 159 of file jurassic.h.

◆ ME

#define ME   5.976e24

Mass of Earth [kg].

Definition at line 164 of file jurassic.h.

◆ NA

#define NA   6.02214199e23

Avogadro's number.

Definition at line 169 of file jurassic.h.

◆ N2

#define N2   0.78084

Nitrogen concentration.

Definition at line 174 of file jurassic.h.

◆ O2

#define O2   0.20946

Oxygen concentration.

Definition at line 179 of file jurassic.h.

◆ P0

#define P0   1013.25

Standard pressure [hPa].

Definition at line 184 of file jurassic.h.

◆ RE

#define RE   6367.421

Mean radius of Earth [km].

Definition at line 189 of file jurassic.h.

◆ RI

#define RI   8.3144598

Ideal gas constant [J/(mol K)].

Definition at line 194 of file jurassic.h.

◆ T0

#define T0   273.15

Standard temperature [K].

Definition at line 199 of file jurassic.h.

◆ TMIN

#define TMIN   100.

Minimum temperature for source function [K].

Definition at line 204 of file jurassic.h.

◆ TMAX

#define TMAX   400.

Maximum temperature for source function [K].

Definition at line 209 of file jurassic.h.

◆ TSUN

#define TSUN   5780.

Effective temperature of the sun [K].

Definition at line 214 of file jurassic.h.

◆ UMIN

#define UMIN   0

Minimum column density [molecules/cm^2].

Definition at line 219 of file jurassic.h.

◆ UMAX

#define UMAX   1e30

Maximum column density [molecules/cm^2].

Definition at line 224 of file jurassic.h.

◆ NCL

#define NCL   8

Maximum number of cloud layer spectral grid points.

Definition at line 233 of file jurassic.h.

◆ ND

#define ND   128

Maximum number of radiance channels.

Definition at line 238 of file jurassic.h.

◆ NG

#define NG   8

Maximum number of emitters.

Definition at line 243 of file jurassic.h.

◆ NP

#define NP   256

Maximum number of atmospheric data points.

Definition at line 248 of file jurassic.h.

◆ NR

#define NR   256

Maximum number of ray paths.

Definition at line 253 of file jurassic.h.

◆ NSF

#define NSF   8

Maximum number of surface layer spectral grid points.

Definition at line 258 of file jurassic.h.

◆ NW

#define NW   4

Maximum number of spectral windows.

Definition at line 263 of file jurassic.h.

◆ LEN

#define LEN   10000

Maximum length of ASCII data lines.

Definition at line 268 of file jurassic.h.

◆ M

#define M   (NR*ND)

Maximum size of measurement vector.

Definition at line 273 of file jurassic.h.

◆ N

#define N   ((2 + NG + NW) * NP + NCL + NSF + 3)

Maximum size of state vector.

Definition at line 278 of file jurassic.h.

◆ NQ

#define NQ   (5 + NG + NW + NCL + NSF)

Maximum number of quantities.

Definition at line 283 of file jurassic.h.

◆ NLOS

#define NLOS   4096

Maximum number of LOS points.

Definition at line 288 of file jurassic.h.

◆ NSHAPE

#define NSHAPE   20000

Maximum number of shape function grid points.

Definition at line 293 of file jurassic.h.

◆ NFOV

#define NFOV   5

Number of ray paths used for FOV calculations.

Definition at line 298 of file jurassic.h.

◆ TBLNP

#define TBLNP   41

Maximum number of pressure levels in emissivity tables.

Definition at line 303 of file jurassic.h.

◆ TBLNT

#define TBLNT   30

Maximum number of temperatures in emissivity tables.

Definition at line 308 of file jurassic.h.

◆ TBLNU

#define TBLNU   512

Maximum number of column densities per emissivity curve.

Definition at line 313 of file jurassic.h.

◆ TBLNS

#define TBLNS   1200

Maximum number of source function temperature levels.

Definition at line 318 of file jurassic.h.

◆ RFMNPTS

#define RFMNPTS   10000000

Maximum number of RFM spectral grid points.

Definition at line 323 of file jurassic.h.

◆ IDXP

#define IDXP   0

Index for pressure.

Definition at line 331 of file jurassic.h.

◆ IDXT

#define IDXT   1

Index for temperature.

Definition at line 334 of file jurassic.h.

◆ IDXQ

#define IDXQ (   ig)    (2 + (ig))

Indices for volume mixing ratios.

Definition at line 337 of file jurassic.h.

◆ IDXK

#define IDXK (   iw)    (2 + (ctl->ng) + (iw))

Indices for extinction.

Definition at line 340 of file jurassic.h.

◆ IDXCLZ

#define IDXCLZ   (2 + (ctl->ng) + (ctl->nw))

Index for cloud layer height.

Definition at line 343 of file jurassic.h.

◆ IDXCLDZ

#define IDXCLDZ   (3 + (ctl->ng) + (ctl->nw))

Index for cloud layer depth.

Definition at line 346 of file jurassic.h.

◆ IDXCLK

#define IDXCLK (   icl)    (4 + (ctl->ng) + (ctl->nw) + (icl))

Indices for cloud layer extinction.

Definition at line 349 of file jurassic.h.

◆ IDXSFT

#define IDXSFT   (4 + (ctl->ng) + (ctl->nw) + (ctl->ncl))

Index for surface layer temperature.

Definition at line 352 of file jurassic.h.

◆ IDXSFEPS

#define IDXSFEPS (   isf)    (5 + (ctl->ng) + (ctl->nw) + (ctl->ncl) + (isf))

Indices for surface layer emissivity.

Definition at line 355 of file jurassic.h.

◆ ALLOC

#define ALLOC (   ptr,
  type,
 
)
Value:
if((ptr=calloc((size_t)(n), sizeof(type)))==NULL) \
ERRMSG("Out of memory!");

Allocate memory for an array.

Allocates a contiguous block of memory for an array of n elements of type type and assigns the pointer to ptr. If allocation fails, the program prints an error message and terminates.

Parameters
[out]ptrPointer to be allocated.
[in]typeData type of the elements to allocate.
[in]nNumber of elements to allocate.
Note
Wraps malloc() with built-in error handling.
See also
FREAD, FWRITE
Author
Lars Hoffmann

Definition at line 378 of file jurassic.h.

◆ BRIGHT

#define BRIGHT (   rad,
  nu 
)     (C2 * (nu) / gsl_log1p(C1 * POW3(nu) / (rad)))

Compute brightness temperature from radiance.

Computes the equivalent blackbody (brightness) temperature corresponding to a given spectral radiance and wavenumber, using the inverse Planck function. This form assumes the spectroscopic constants C1 and C2 are defined for wavenumber units (cm⁻¹).

Parameters
[in]radSpectral radiance [W·m⁻²·sr⁻¹·(cm⁻¹)⁻¹].
[in]nuWavenumber [cm⁻¹].
Returns
Brightness temperature [K].
See also
PLANCK, C1, C2
Note
Based on Planck’s law in wavenumber form: \( T_b = \frac{c_2 \nu}{\ln\!\left(1 + \frac{c_1 \nu^3}{L_\nu}\right)} \) where \(L_\nu\) is the radiance. The ν³ dependence reflects the definition of C1 for radiance per unit wavenumber in cm⁻¹.
Warning
The radiance MUST be in W·m⁻²·sr⁻¹·(cm⁻¹)⁻¹. Using radiance per meter will produce brightness temperatures incorrect by six orders of magnitude.
Author
Lars Hoffmann

Definition at line 408 of file jurassic.h.

◆ DEG2RAD

#define DEG2RAD (   deg)    ((deg) * (M_PI / 180.0))

Convert degrees to radians.

Converts an angle measured in degrees to radians using: \( \text{radians} = \text{degrees} \times \frac{\pi}{180} \).

Parameters
[in]degAngle in degrees.
Returns
Angle in radians.
See also
RAD2DEG
Author
Lars Hoffmann

Definition at line 425 of file jurassic.h.

◆ DIST

#define DIST (   a,
 
)    sqrt(DIST2(a, b))

Compute Cartesian distance between two 3D vectors.

Computes the Euclidean distance between two 3D vectors or points.

Parameters
[in]aFirst vector (array of length 3).
[in]bSecond vector (array of length 3).
Returns
Euclidean distance between a and b.
See also
DIST2
Note
Equivalent to \( \sqrt{(x_1-x_2)^2 + (y_1-y_2)^2 + (z_1-z_2)^2} \).
Author
Lars Hoffmann

Definition at line 443 of file jurassic.h.

◆ DIST2

#define DIST2 (   a,
 
)     ((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])+(a[2]-b[2])*(a[2]-b[2]))

Compute squared distance between two 3D vectors.

Computes the square of the Euclidean distance between two 3D vectors. Useful when only relative distances are needed (avoids square root).

Parameters
[in]aFirst vector (array of length 3).
[in]bSecond vector (array of length 3).
Returns
Squared distance between a and b.
See also
DIST
Author
Lars Hoffmann

Definition at line 460 of file jurassic.h.

◆ DOTP

#define DOTP (   a,
 
)    (a[0]*b[0]+a[1]*b[1]+a[2]*b[2])

Compute dot product of two 3D vectors.

Computes the scalar (dot) product between two 3-element vectors: \( a \cdot b = a_x b_x + a_y b_y + a_z b_z \).

Parameters
[in]aFirst vector (array of length 3).
[in]bSecond vector (array of length 3).
Returns
Scalar dot product of a and b.
See also
NORM
Author
Lars Hoffmann

Definition at line 478 of file jurassic.h.

◆ FREAD

#define FREAD (   ptr,
  type,
  size,
  out 
)
Value:
{ \
if(fread(ptr, sizeof(type), size, out)!=size) \
ERRMSG("Error while reading!"); \
}

Read binary data from a file.

Reads size elements of type type from the file stream out into the memory pointed to by ptr. If the number of elements read differs from size, an error message is printed and the program terminates.

Parameters
[out]ptrPointer to destination memory buffer.
[in]typeType of each element to read.
[in]sizeNumber of elements to read.
[in,out]outFile stream opened for reading.
See also
FWRITE, ALLOC
Note
Wraps fread() with error handling.
Author
Lars Hoffmann

Definition at line 498 of file jurassic.h.

◆ FWRITE

#define FWRITE (   ptr,
  type,
  size,
  out 
)
Value:
{ \
if(fwrite(ptr, sizeof(type), size, out)!=size) \
ERRMSG("Error while writing!"); \
}

Write binary data to a file.

Writes size elements of type type from the memory pointed to by ptr to the file stream out. If the number of elements written differs from size, an error message is printed and the program terminates.

Parameters
[in]ptrPointer to memory buffer containing data to write.
[in]typeType of each element to write.
[in]sizeNumber of elements to write.
[in,out]outFile stream opened for writing.
See also
FREAD
Note
Wraps fwrite() with error handling.
Author
Lars Hoffmann

Definition at line 521 of file jurassic.h.

◆ LIN

#define LIN (   x0,
  y0,
  x1,
  y1,
 
)     ((y0)+((y1)-(y0))/((x1)-(x0))*((x)-(x0)))

Compute linear interpolation.

Performs simple linear interpolation between two known points (x₀, y₀) and (x₁, y₁) to estimate the value of y at a given x.

Parameters
[in]x0Lower x-value.
[in]y0Function value at x₀.
[in]x1Upper x-value.
[in]y1Function value at x₁.
[in]xInterpolation point.
Returns
Linearly interpolated y-value at x.
See also
LOGX, LOGY
Author
Lars Hoffmann

Definition at line 544 of file jurassic.h.

◆ LOGX

#define LOGX (   x0,
  y0,
  x1,
  y1,
 
)
Value:
(((x)/(x0)>0 && (x1)/(x0)>0) \
? ((y0)+((y1)-(y0))*log((x)/(x0))/log((x1)/(x0))) \
: LIN(x0, y0, x1, y1, x))
#define LIN(x0, y0, x1, y1, x)
Compute linear interpolation.
Definition: jurassic.h:544

Compute logarithmic interpolation in x.

Performs interpolation assuming logarithmic variation in the x-axis. If either x/x₀ or x₁/x₀ is nonpositive, reverts to linear interpolation.

Parameters
[in]x0Lower x-value.
[in]y0Function value at x₀.
[in]x1Upper x-value.
[in]y1Function value at x₁.
[in]xInterpolation point.
Returns
Interpolated y-value at x.
See also
LIN, LOGY
Author
Lars Hoffmann

Definition at line 565 of file jurassic.h.

◆ LOGY

#define LOGY (   x0,
  y0,
  x1,
  y1,
 
)
Value:
(((y1)/(y0)>0) \
? ((y0)*exp(log((y1)/(y0))/((x1)-(x0))*((x)-(x0)))) \
: LIN(x0, y0, x1, y1, x))

Compute logarithmic interpolation in y.

Performs interpolation assuming exponential variation in the y-axis (logarithmic in y). If y₁/y₀ is nonpositive, reverts to linear interpolation.

Parameters
[in]x0Lower x-value.
[in]y0Function value at x₀.
[in]x1Upper x-value.
[in]y1Function value at x₁.
[in]xInterpolation point.
Returns
Interpolated y-value at x.
See also
LIN, LOGX
Author
Lars Hoffmann

Definition at line 588 of file jurassic.h.

◆ MAX

#define MAX (   a,
 
)    (((a)>(b))?(a):(b))

Determine the maximum of two values.

Returns the greater of two scalar values.

Parameters
[in]aFirst value.
[in]bSecond value.
Returns
Maximum of a and b.
See also
MIN
Note
Both arguments are evaluated multiple times; avoid side effects.
Author
Lars Hoffmann

Definition at line 609 of file jurassic.h.

◆ MIN

#define MIN (   a,
 
)    (((a)<(b))?(a):(b))

Determine the minimum of two values.

Returns the smaller of two scalar values.

Parameters
[in]aFirst value.
[in]bSecond value.
Returns
Minimum of a and b.
See also
MAX
Note
Both arguments are evaluated multiple times; avoid side effects.
Author
Lars Hoffmann

Definition at line 627 of file jurassic.h.

◆ NC

#define NC (   cmd)
Value:
{ \
int nc_result=(cmd); \
if(nc_result!=NC_NOERR) \
ERRMSG("%s", nc_strerror(nc_result)); \
}

Execute a NetCDF command and check for errors.

This macro executes a NetCDF command and checks the result. If the result indicates an error, it prints the error message using ERRMSG.

Parameters
cmdNetCDF command to execute.
Author
Lars Hoffmann

Definition at line 640 of file jurassic.h.

◆ NC_DEF_VAR

#define NC_DEF_VAR (   varname,
  type,
  ndims,
  dims,
  long_name,
  units,
  level,
  quant 
)
Value:
{ \
NC(nc_def_var(ncid, varname, type, ndims, dims, &varid)); \
NC(nc_put_att_text(ncid, varid, "long_name", strnlen(long_name, LEN), long_name)); \
NC(nc_put_att_text(ncid, varid, "units", strnlen(units, LEN), units)); \
if((quant) > 0) \
NC(nc_def_var_quantize(ncid, varid, NC_QUANTIZE_GRANULARBR, quant)); \
if((level) != 0) { \
NC(nc_def_var_deflate(ncid, varid, 1, 1, level)); \
/* unsigned int ulevel = (unsigned int)level; */ \
/* NC(nc_def_var_filter(ncid, varid, 32015, 1, (unsigned int[]){ulevel})); */ \
} \
}
#define LEN
Maximum length of ASCII data lines.
Definition: jurassic.h:268

Define a NetCDF variable with attributes.

This macro defines a NetCDF variable with the specified name, data type, dimensions, long name, and units. It also sets the long_name and units attributes for the variable. It enables compression and quantizatio of the data.

Parameters
varnameName of the variable.
typeData type of the variable.
ndimsNumber of dimensions for the variable.
dimsArray of dimension IDs.
long_nameLong name of the variable.
unitsUnits of the variable.
levelzlib compression level (0 = off).
quantNumber of digits for quantization (0 = off).
Note
To enable ZSTD compression, replace nc_def_var_deflate() by nc_def_var_filter() below. Use dynamic linking, static linking does not work. Set environment variable HDF5_PLUGIN_PATH to ./libs/build/share/netcdf-plugins/.
Author
Lars Hoffmann

Definition at line 669 of file jurassic.h.

◆ NC_GET_DOUBLE

#define NC_GET_DOUBLE (   varname,
  ptr,
  force 
)
Value:
{ \
if(force) { \
NC(nc_inq_varid(ncid, varname, &varid)); \
NC(nc_get_var_double(ncid, varid, ptr)); \
} else { \
if(nc_inq_varid(ncid, varname, &varid) == NC_NOERR) { \
NC(nc_get_var_double(ncid, varid, ptr)); \
WARN("netCDF variable %s is missing!", varname); \
} \
}
#define WARN(...)
Print a warning message with contextual information.
Definition: jurassic.h:1161

Retrieve a double-precision variable from a NetCDF file.

This macro retrieves a double-precision variable from a NetCDF file. It first checks if the variable exists in the file and then reads its data into the specified pointer. If the force parameter is set to true, it forces the retrieval of the variable, raising an error if the variable does not exist. If force is false, it retrieves the variable if it exists and issues a warning if it does not.

Parameters
varnameName of the variable to retrieve.
ptrPointer to the memory location where the data will be stored.
forceBoolean flag indicating whether to force retrieval (true) or not (false).
Author
Lars Hoffmann

Definition at line 699 of file jurassic.h.

◆ NC_INQ_DIM

#define NC_INQ_DIM (   dimname,
  ptr,
  min,
  max,
  check 
)
Value:
{ \
int dimid; size_t naux; \
NC(nc_inq_dimid(ncid, dimname, &dimid)); \
NC(nc_inq_dimlen(ncid, dimid, &naux)); \
*ptr = (int)naux; \
if (check) \
if ((*ptr) < (min) || (*ptr) > (max)) \
ERRMSG("Dimension %s is out of range!", dimname); \
}

Inquire the length of a dimension in a NetCDF file.

This macro retrieves the length of a specified dimension from a NetCDF file. It checks if the length of the dimension is within a specified range and assigns the length to the provided pointer. If the length is outside the specified range, an error message is raised.

Parameters
dimnameName of the dimension to inquire.
ptrPointer to an integer where the dimension length will be stored.
minMinimum acceptable length for the dimension.
maxMaximum acceptable length for the dimension.
checkFlag to check bounds. Set to 1 for bounds check.
Author
Lars Hoffmann
Jan Clemens

Definition at line 729 of file jurassic.h.

◆ NC_PUT_DOUBLE

#define NC_PUT_DOUBLE (   varname,
  ptr,
  hyperslab 
)
Value:
{ \
NC(nc_inq_varid(ncid, varname, &varid)); \
if(hyperslab) { \
NC(nc_put_vara_double(ncid, varid, start, count, ptr)); \
} else { \
NC(nc_put_var_double(ncid, varid, ptr)); \
} \
}

Write double precision data to a NetCDF variable.

This macro writes data to a specified NetCDF variable. It can handle both full variable writes and hyperslab writes depending on the hyperslab parameter. If hyperslab is true, the data is written as a hyperslab; otherwise, the entire variable is written.

Parameters
varnameName of the NetCDF variable to write to.
ptrPointer to the data to be written.
hyperslabBoolean indicating whether to write the data as a hyperslab.
Author
Lars Hoffmann

Definition at line 753 of file jurassic.h.

◆ NC_PUT_FLOAT

#define NC_PUT_FLOAT (   varname,
  ptr,
  hyperslab 
)
Value:
{ \
NC(nc_inq_varid(ncid, varname, &varid)); \
if(hyperslab) { \
NC(nc_put_vara_float(ncid, varid, start, count, ptr)); \
} else { \
NC(nc_put_var_float(ncid, varid, ptr)); \
} \
}

Write a float array to a NetCDF file.

This macro writes a float array to a specified variable in a NetCDF file. Depending on the value of the hyperslab parameter, the data can be written as a hyperslab or as a whole variable.

Parameters
varnameName of the variable to which the float array will be written.
ptrPointer to the float array to be written.
hyperslabBoolean flag indicating if the data should be written as a hyperslab.
  • If true, the data will be written as a hyperslab using the start and count arrays.
  • If false, the data will be written to the entire variable.
Author
Lars Hoffmann

Definition at line 777 of file jurassic.h.

◆ NC_PUT_INT

#define NC_PUT_INT (   varname,
  ptr,
  hyperslab 
)
Value:
{ \
NC(nc_inq_varid(ncid, varname, &varid)); \
if(hyperslab) { \
NC(nc_put_vara_int(ncid, varid, start, count, ptr)); \
} else { \
NC(nc_put_var_int(ncid, varid, ptr)); \
} \
}

Write integer data to a NetCDF variable.

This macro writes data to a specified NetCDF variable. It can handle both full variable writes and hyperslab writes depending on the hyperslab parameter. If hyperslab is true, the data is written as a hyperslab; otherwise, the entire variable is written.

Parameters
varnameName of the NetCDF variable to write to.
ptrPointer to the data to be written.
hyperslabBoolean indicating whether to write the data as a hyperslab.
Author
Lars Hoffmann

Definition at line 800 of file jurassic.h.

◆ NC_PUT_ATT

#define NC_PUT_ATT (   varname,
  attname,
  text 
)
Value:
{ \
NC(nc_inq_varid(ncid, varname, &varid)); \
NC(nc_put_att_text(ncid, varid, attname, strnlen(text, LEN), text)); \
}

Add a text attribute to a NetCDF variable.

This macro adds a text attribute to a specified NetCDF variable. It first retrieves the variable ID using its name, then it attaches the text attribute to the variable.

Parameters
varnameName of the NetCDF variable to which the attribute will be added.
attnameName of the attribute to be added.
textText of the attribute to be added.
Author
Lars Hoffmann

Definition at line 822 of file jurassic.h.

◆ NC_PUT_ATT_GLOBAL

#define NC_PUT_ATT_GLOBAL (   attname,
  text 
)     NC(nc_put_att_text(ncid, NC_GLOBAL, attname, strnlen(text, LEN), text));

Add a global text attribute to a NetCDF file.

This macro adds a text attribute to the global attributes of a NetCDF file. It directly attaches the attribute to the file, rather than to a specific variable.

Parameters
attnameName of the global attribute to be added.
textText of the attribute to be added.
Author
Lars Hoffmann

Definition at line 839 of file jurassic.h.

◆ NEDT

#define NEDT (   t_bg,
  nesr,
  nu 
)     (BRIGHT(PLANCK((t_bg), (nu)) + (nesr), (nu)) - (t_bg))

Convert noise-equivalent spectral radiance (NESR) to noise-equivalent delta temperature (NEDT).

Computes the temperature noise level corresponding to a given NESR at a background radiance, using the inverse Planck function. The NEDT expresses radiometric sensitivity in temperature units, assuming blackbody emission.

Parameters
[in]t_bgBackground (scene) brightness temperature [K].
[in]nesrNoise-equivalent spectral radiance [W·m⁻²·sr⁻¹·(cm⁻¹)⁻¹].
[in]nuWavenumber [cm⁻¹].
Returns
Noise-equivalent delta temperature [K].
Note
This macro computes

\[ \mathrm{NEDT} = T_b(L_\nu(T_\mathrm{bg}) + \mathrm{NESR}) - T_\mathrm{bg} \]

where \(T_b\) is the brightness temperature from the inverse Planck function.
Warning
All units must be consistent with PLANCK and BRIGHT. Mixing radiance units per meter instead of per cm⁻¹ will yield incorrect results by orders of magnitude.
See also
NESR, PLANCK, BRIGHT, C1, C2

Definition at line 871 of file jurassic.h.

◆ NESR

#define NESR (   t_bg,
  nedt,
  nu 
)     (PLANCK((t_bg) + (nedt), (nu)) - PLANCK((t_bg), (nu)))

Convert noise-equivalent delta temperature (NEDT) to noise-equivalent spectral radiance (NESR).

Computes the radiance difference corresponding to a temperature noise level at a given background temperature and wavenumber, using Planck’s law. The NESR quantifies the radiometric sensitivity in spectral radiance units.

Parameters
[in]t_bgBackground (scene) brightness temperature [K].
[in]nedtNoise-equivalent delta temperature [K].
[in]nuWavenumber [cm⁻¹].
Returns
Noise-equivalent spectral radiance [W·m⁻²·sr⁻¹·(cm⁻¹)⁻¹].
Note
This macro computes

\[ \mathrm{NESR} = L_\nu(T_\mathrm{bg} + \mathrm{NEDT}) - L_\nu(T_\mathrm{bg}) \]

where \(L_\nu\) is spectral radiance from Planck’s law.
Warning
All units must be consistent with PLANCK. In particular, nu must be given in cm⁻¹.
See also
PLANCK, NEDT, BRIGHT

Definition at line 900 of file jurassic.h.

◆ NORM

#define NORM (   a)    sqrt(DOTP(a, a))

Compute the norm (magnitude) of a 3D vector.

Computes the Euclidean norm using the dot product: \( |a| = \sqrt{a \cdot a} \).

Parameters
[in]aInput vector (array of length 3).
Returns
Magnitude (norm) of vector a.
See also
DOTP
Author
Lars Hoffmann

Definition at line 917 of file jurassic.h.

◆ PLANCK

#define PLANCK (   T,
  nu 
)     (C1 * POW3(nu) / gsl_expm1(C2 * (nu) / (T)))

Compute spectral radiance using Planck’s law.

Evaluates Planck’s blackbody spectral radiance for a given temperature and wavenumber. The expression is formulated in wavenumber space (cm⁻¹) and uses the spectroscopic constants C1 and C2 in wavenumber units.

Parameters
[in]nuWavenumber [cm⁻¹].
[in]TTemperature [K].
Returns
Spectral radiance \(L_\nu\) in [W·m⁻²·sr⁻¹·(cm⁻¹)⁻¹].
Note
The Planck law implemented here is

\[ L_\nu = \frac{C_{1}\,\nu^{3}} {\exp\!\left(\frac{C_{2}\,\nu}{T}\right) - 1} \]

with \(\nu\) in cm⁻¹. The \(\nu^{3}\) dependence follows from the definition of C1 for radiance per wavenumber in cm⁻¹.
Warning
The units of all inputs MUST be consistent: nu in cm⁻¹ and T in kelvin. Mixing wavenumber and frequency formulations, or using radiance per meter instead of per cm⁻¹, will produce results off by orders of magnitude.
See also
BRIGHT, C1, C2

Definition at line 948 of file jurassic.h.

◆ POW2

#define POW2 (   x)    ((x)*(x))

Compute the square of a value.

Returns x². Inline alternative to pow(x,2).

Parameters
[in]xInput value.
Returns
x squared.
Author
Lars Hoffmann

Definition at line 962 of file jurassic.h.

◆ POW3

#define POW3 (   x)    ((x)*(x)*(x))

Compute the cube of a value.

Returns x³. Inline alternative to pow(x,3).

Parameters
[in]xInput value.
Returns
x cubed.
Author
Lars Hoffmann

Definition at line 975 of file jurassic.h.

◆ RAD2DEG

#define RAD2DEG (   rad)    ((rad) * (180.0 / M_PI))

Convert radians to degrees.

Converts an angle measured in radians to degrees using: \( \text{degrees} = \text{radians} \times \frac{180}{\pi} \).

Parameters
[in]radAngle in radians.
Returns
Angle in degrees.
See also
DEG2RAD
Author
Lars Hoffmann

Definition at line 991 of file jurassic.h.

◆ REFRAC

#define REFRAC (   p,
 
)    (7.753e-05 * (p) / (T))

Compute air refractivity (n - 1).

Approximates the refractivity of air under standard conditions using: \( n - 1 = 7.753\times10^{-5} \frac{p}{T} \), where p is pressure (hPa) and T is temperature (K).

Parameters
[in]pPressure [hPa].
[in]TTemperature [K].
Returns
Refractivity (dimensionless, n - 1).
Author
Lars Hoffmann

Definition at line 1007 of file jurassic.h.

◆ TBL_LOG

#define TBL_LOG (   tbl,
  id,
  ig 
)
Value:
do { \
for (int ip = 0; ip < (tbl)->np[(id)][(ig)]; ip++) \
LOG(2, \
"p[%2d]= %.5e hPa | T[0:%2d]= %.2f ... %.2f K | " \
"u[0:%3d]= %.5e ... %.5e molec/cm^2 | " \
"eps[0:%3d]= %.5e ... %.5e", \
(ip), \
(tbl)->p[(id)][(ig)][(ip)], \
(tbl)->nt[(id)][(ig)][(ip)] - 1, \
(tbl)->t[(id)][(ig)][(ip)][0], \
(tbl)->t[(id)][(ig)][(ip)] \
[(tbl)->nt[(id)][(ig)][(ip)] - 1], \
(tbl)->nu[(id)][(ig)][(ip)][0] - 1, \
exp((tbl)->logu[(id)][(ig)][(ip)][0][0]), \
exp((tbl)->logu[(id)][(ig)][(ip)][0] \
[(tbl)->nu[(id)][(ig)][(ip)][0] - 1]), \
(tbl)->nu[(id)][(ig)][(ip)][0] - 1, \
exp((tbl)->logeps[(id)][(ig)][(ip)][0][0]), \
exp((tbl)->logeps[(id)][(ig)][(ip)][0] \
[(tbl)->nu[(id)][(ig)][(ip)][0] - 1])); \
} while (0)
#define LOG(level,...)
Print a log message with a specified logging level.
Definition: jurassic.h:1124

Log detailed statistics of an emissivity look-up table.

This macro logs pressure, temperature, absorber column, and emissivity ranges for all pressure levels of a given (channel, emitter) table. Output is written at verbosity level 2 and is intended for diagnostics and debugging.

Parameters
tblPointer to the look-up table structure.
idChannel (detector) index.
igEmitter (trace gas) index.
Author
Lars Hoffmann

Definition at line 1023 of file jurassic.h.

◆ TIMER

#define TIMER (   name,
  mode 
)     {timer(name, __FILE__, __func__, __LINE__, mode);}

Start or stop a named timer.

Calls the timer() function with contextual information (file name, function name, and line number) to start or stop timing. Useful for performance profiling.

Parameters
[in]nameName or label of the timer.
[in]modeOperation mode (e.g., start or stop).
Note
Relies on a user-defined timer() function.
Author
Lars Hoffmann

Definition at line 1059 of file jurassic.h.

◆ TOK

#define TOK (   line,
  tok,
  format,
  var 
)
Value:
{ \
if(((tok)=strtok((line), " \t"))) { \
if(sscanf(tok, format, &(var))!=1) continue; \
} else ERRMSG("Error while reading!"); \
}
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: jurassic.h:1194

Tokenize a string and parse a variable.

Splits a text line into tokens separated by spaces or tabs, and reads a value from the first token using sscanf() and the provided format. If tokenization or parsing fails, an error message is printed.

Parameters
[in,out]lineInput string buffer to tokenize (modified by strtok()).
[out]tokPointer to token string.
[in]formatFormat string for sscanf().
[out]varVariable to store parsed value.
Note
Uses strtok() internally and modifies the input buffer.
See also
FREAD, FWRITE
Author
Lars Hoffmann

Definition at line 1080 of file jurassic.h.

◆ LOGLEV

#define LOGLEV   2

Level of log messages (0=none, 1=basic, 2=detailed, 3=debug).

Definition at line 1092 of file jurassic.h.

◆ LOG

#define LOG (   level,
  ... 
)
Value:
{ \
if(level >= 2) \
printf(" "); \
if(level <= LOGLEV) { \
printf(__VA_ARGS__); \
printf("\n"); \
} \
}
#define LOGLEV
Level of log messages (0=none, 1=basic, 2=detailed, 3=debug).
Definition: jurassic.h:1092

Print a log message with a specified logging level.

This macro prints a formatted log message to the standard output if the specified logging level meets certain conditions. The message will be indented if the logging level is greater than or equal to 2.

Parameters
levelThe logging level of the message. This should be an integer value.
...The formatted message string and its arguments, similar to printf.

The LOG macro provides a simple way to log messages with different levels of importance. The message is only printed if the specified level is less than or equal to the pre-defined LOGLEV macro. If the level is greater than or equal to 2, the message is preceded by two spaces for indentation.

The macro expands to a block of code that:

  • Checks if the level is greater than or equal to 2, and if so, prints two spaces.
  • Checks if the level is less than or equal to LOGLEV, and if so, prints the formatted message followed by a newline.
Note
The LOGLEV macro must be defined with an appropriate logging level before using the LOG macro.
Author
Lars Hoffmann

Definition at line 1124 of file jurassic.h.

◆ WARN

#define WARN (   ...)
Value:
{ \
printf("\nWarning (%s, %s, l%d): ", __FILE__, __func__, __LINE__); \
LOG(0, __VA_ARGS__); \
}

Print a warning message with contextual information.

This macro prints a formatted warning message to the standard output, including the file name, function name, and line number where the warning occurred. The message is then passed to the LOG macro with a logging level of 0.

Parameters
...The formatted warning message string and its arguments, similar to printf.

The WARN macro is used to print warning messages with additional context about where the warning was triggered. The message includes the following contextual information:

  • The name of the source file where the macro is called (__FILE__).
  • The name of the function where the macro is called (__func__).
  • The line number in the source file where the macro is called (__LINE__).

After printing this contextual information, the macro uses the LOG macro with a logging level of 0 to print the actual warning message. This ensures that warning messages are always logged, regardless of the value of LOGLEV.

Note
The LOG macro must be defined before using the WARN macro.
Author
Lars Hoffmann

Definition at line 1161 of file jurassic.h.

◆ ERRMSG

#define ERRMSG (   ...)
Value:
{ \
printf("\nError (%s, %s, l%d): ", __FILE__, __func__, __LINE__); \
LOG(0, __VA_ARGS__); \
exit(EXIT_FAILURE); \
}

Print an error message with contextual information and terminate the program.

This macro prints a formatted error message to the standard output, including the file name, function name, and line number where the error occurred. After printing the message, the program is terminated with an exit status indicating failure.

Parameters
...The formatted error message string and its arguments, similar to printf.

The ERRMSG macro is used to report critical errors that require the program to terminate immediately. The message includes the following contextual information:

  • The name of the source file where the macro is called (__FILE__).
  • The name of the function where the macro is called (__func__).
  • The line number in the source file where the macro is called (__LINE__).

After printing this contextual information, the macro uses the LOG macro with a logging level of 0 to print the actual error message. Finally, the program exits with a failure status (EXIT_FAILURE).

Note
The LOG macro must be defined before using the ERRMSG macro.
Author
Lars Hoffmann

Definition at line 1194 of file jurassic.h.

◆ PRINT

#define PRINT (   format,
  var 
)
Value:
printf("Print (%s, %s, l%d): %s= "format"\n", \
__FILE__, __func__, __LINE__, #var, var);

Print the value of a variable with contextual information.

This macro prints the value of a variable to the standard output, including the file name, function name, and line number where the macro is called. The output also includes the variable's name and value in a formatted string.

Parameters
formatThe format string used to print the variable's value, similar to printf.
varThe variable to be printed.

The PRINT macro is used to output the value of a variable along with additional context about where the macro is called. The message includes:

  • The name of the source file where the macro is called (__FILE__).
  • The name of the function where the macro is called (__func__).
  • The line number in the source file where the macro is called (__LINE__).
  • The name of the variable being printed (#var).
  • The value of the variable, formatted according to the provided format string (format).

This macro is particularly useful for debugging purposes, providing a convenient way to trace variable values and their locations in the code.

Note
The format string must be compatible with the type of the variable being printed.
Author
Lars Hoffmann

Definition at line 1229 of file jurassic.h.

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:6920
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:343
#define IDXCLDZ
Index for cloud layer depth.
Definition: jurassic.h:346
#define IDXK(iw)
Indices for extinction.
Definition: jurassic.h:340
#define NQ
Maximum number of quantities.
Definition: jurassic.h:283
#define IDXSFT
Index for surface layer temperature.
Definition: jurassic.h:352
#define IDXSFEPS(isf)
Indices for surface layer emissivity.
Definition: jurassic.h:355
#define IDXCLK(icl)
Indices for cloud layer extinction.
Definition: jurassic.h:349
#define IDXP
Index for pressure.
Definition: jurassic.h:331
#define IDXQ(ig)
Indices for volume mixing ratios.
Definition: jurassic.h:337
#define IDXT
Index for temperature.
Definition: jurassic.h:334
Atmospheric profile data.
Definition: jurassic.h:1244
double sfeps[NSF]
Surface emissivity.
Definition: jurassic.h:1286
double k[NW][NP]
Extinction [km^-1].
Definition: jurassic.h:1271
double t[NP]
Temperature [K].
Definition: jurassic.h:1265
double clz
Cloud layer height [km].
Definition: jurassic.h:1274
double cldz
Cloud layer depth [km].
Definition: jurassic.h:1277
double sft
Surface temperature [K].
Definition: jurassic.h:1283
double clk[NCL]
Cloud layer extinction [km^-1].
Definition: jurassic.h:1280
double q[NG][NP]
Volume mixing ratio [ppv].
Definition: jurassic.h:1268
double p[NP]
Pressure [hPa].
Definition: jurassic.h:1262
int nw
Number of spectral windows.
Definition: jurassic.h:1324
int ng
Number of emitters.
Definition: jurassic.h:1300
int ncl
Number of cloud layer spectral grid points.
Definition: jurassic.h:1330
int nsf
Number of surface layer spectral grid points.
Definition: jurassic.h:1336
char dir[LEN]
Working directory.
Definition: jurassic.h:1578
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:1247
double z[NP]
Altitude [km].
Definition: jurassic.h:1253
double retp_zmin
Minimum altitude for pressure retrieval [km].
Definition: jurassic.h:1396
double retk_zmax[NW]
Maximum altitude for extinction retrieval [km].
Definition: jurassic.h:1417
double rett_zmax
Maximum altitude for temperature retrieval [km].
Definition: jurassic.h:1405
int ret_sfeps
Retrieve surface layer emissivity (0=no, 1=yes).
Definition: jurassic.h:1432
int ret_sft
Retrieve surface layer temperature (0=no, 1=yes).
Definition: jurassic.h:1429
int ret_clz
Retrieve cloud layer height (0=no, 1=yes).
Definition: jurassic.h:1420
double retq_zmax[NG]
Maximum altitude for volume mixing ratio retrieval [km].
Definition: jurassic.h:1411
double retq_zmin[NG]
Minimum altitude for volume mixing ratio retrieval [km].
Definition: jurassic.h:1408
double rett_zmin
Minimum altitude for temperature retrieval [km].
Definition: jurassic.h:1402
double retk_zmin[NW]
Minimum altitude for extinction retrieval [km].
Definition: jurassic.h:1414
int ret_clk
Retrieve cloud layer extinction (0=no, 1=yes).
Definition: jurassic.h:1426
int ret_cldz
Retrieve cloud layer depth (0=no, 1=yes).
Definition: jurassic.h:1423
double retp_zmax
Maximum altitude for pressure retrieval [km].
Definition: jurassic.h:1399
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:917
#define RAD2DEG(rad)
Convert radians to degrees.
Definition: jurassic.h:991

◆ 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:4474
#define O2
Oxygen concentration.
Definition: jurassic.h:179
#define LOGY(x0, y0, x1, y1, x)
Compute logarithmic interpolation in y.
Definition: jurassic.h:588
#define NG
Maximum number of emitters.
Definition: jurassic.h:243
#define N2
Nitrogen concentration.
Definition: jurassic.h:174
double time[NP]
Time (seconds since 2000-01-01T00:00Z).
Definition: jurassic.h:1250
int ig_co2
Emitter index of CO2.
Definition: jurassic.h:1306
int ig_o2
Emitter index of O2.
Definition: jurassic.h:1315
int ig_n2
Emitter index of N2.
Definition: jurassic.h:1312
char emitter[NG][LEN]
Name of each emitter.
Definition: jurassic.h:1303
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:962
#define DEG2RAD(deg)
Convert degrees to radians.
Definition: jurassic.h:425

◆ 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:975

◆ 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:1259
double lon[NP]
Longitude [deg].
Definition: jurassic.h:1256

◆ 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:1318
double tau[ND][NR]
Transmittance of ray path.
Definition: jurassic.h:1559
double rad[ND][NR]
Radiance [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1562
double tplon[NR]
Tangent point longitude [deg].
Definition: jurassic.h:1553
double vpz[NR]
View point altitude [km].
Definition: jurassic.h:1541
double vplat[NR]
View point latitude [deg].
Definition: jurassic.h:1547
double obslon[NR]
Observer longitude [deg].
Definition: jurassic.h:1535
double obslat[NR]
Observer latitude [deg].
Definition: jurassic.h:1538
double obsz[NR]
Observer altitude [km].
Definition: jurassic.h:1532
double tplat[NR]
Tangent point latitude [deg].
Definition: jurassic.h:1556
double vplon[NR]
View point longitude [deg].
Definition: jurassic.h:1544
double time[NR]
Time (seconds since 2000-01-01T00:00Z).
Definition: jurassic.h:1529
double tpz[NR]
Tangent point altitude [km].
Definition: jurassic.h:1550
int nr
Number of ray paths.
Definition: jurassic.h:1526

◆ 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:408
#define ND
Maximum number of radiance channels.
Definition: jurassic.h:238
#define ALLOC(ptr, type, n)
Allocate memory for an array.
Definition: jurassic.h:378
#define NR
Maximum number of ray paths.
Definition: jurassic.h:253
double nu[ND]
Centroid wavenumber of each channel [cm^-1].
Definition: jurassic.h:1321
int formod
Forward model (0=CGA, 1=EGA, 2=RFM).
Definition: jurassic.h:1441
int write_bbt
Use brightness temperature instead of radiance (0=no, 1=yes).
Definition: jurassic.h:1435
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:1363
int ctm_n2
Compute N2 continuum (0=no, 1=yes).
Definition: jurassic.h:1369
int ctm_h2o
Compute H2O continuum (0=no, 1=yes).
Definition: jurassic.h:1366
int ctm_o2
Compute O2 continuum (0=no, 1=yes).
Definition: jurassic.h:1372
int ig_h2o
Emitter index of H2O.
Definition: jurassic.h:1309
double q[NLOS][NG]
Volume mixing ratio [ppv].
Definition: jurassic.h:1482
double ds[NLOS]
Segment length [km].
Definition: jurassic.h:1494
double u[NLOS][NG]
Column density [molecules/cm^2].
Definition: jurassic.h:1497
double k[NLOS][ND]
Extinction [km^-1].
Definition: jurassic.h:1485
double t[NLOS]
Temperature [K].
Definition: jurassic.h:1479
double p[NLOS]
Pressure [hPa].
Definition: jurassic.h:1476
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:4444
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:627
#define MAX(a, b)
Determine the maximum of two values.
Definition: jurassic.h:609
char fov[LEN]
Field-of-view data file.
Definition: jurassic.h:1384
int fov_n
Field-of-view number of data points.
Definition: jurassic.h:1393
double fov_dz[NSHAPE]
Field-of-view vertical distance [km].
Definition: jurassic.h:1387
double fov_w[NSHAPE]
Field-of-view weighting factor.
Definition: jurassic.h:1390
Observation geometry and radiance data.
Definition: jurassic.h:1523
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:4128
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:4889
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:4042
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:478
#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:948
double sfsza
Solar zenith angle at the surface [deg] (-999=auto).
Definition: jurassic.h:1345
int sftype
Surface treatment (0=none, 1=emissions, 2=downward, 3=solar).
Definition: jurassic.h:1342
Line-of-sight data.
Definition: jurassic.h:1461
double z[NLOS]
Altitude [km].
Definition: jurassic.h:1467
double eps[NLOS][ND]
Segment emissivity.
Definition: jurassic.h:1509
double sft
Surface temperature [K].
Definition: jurassic.h:1488
double lon[NLOS]
Longitude [deg].
Definition: jurassic.h:1470
int np
Number of LOS points.
Definition: jurassic.h:1464
double lat[NLOS]
Latitude [deg].
Definition: jurassic.h:1473
double src[NLOS][ND]
Segment source function [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1512
double sfeps[ND]
Surface emissivity.
Definition: jurassic.h:1491
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:5892
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:7325
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:6064
#define NSHAPE
Maximum number of shape function grid points.
Definition: jurassic.h:293
char rfmhit[LEN]
HITRAN file for RFM.
Definition: jurassic.h:1447
char tblbase[LEN]
Basename for table files and filter function files.
Definition: jurassic.h:1348
char rfmbin[LEN]
Path to RFM binary.
Definition: jurassic.h:1444
char rfmxsc[NG][LEN]
Emitter cross-section files for RFM.
Definition: jurassic.h:1450
int refrac
Take into account refractivity (0=no, 1=yes).
Definition: jurassic.h:1375
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:1693
double st[TBLNS]
Source function temperature [K].
Definition: jurassic.h:1690
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:1360

◆ 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:1339
double clnu[NCL]
Cloud layer wavenumber [cm^-1].
Definition: jurassic.h:1333

◆ init_srcfunc()

void init_srcfunc ( const ctl_t ctl,
tbl_t tbl 
)

Initialize source function lookup tables from emissivity data.

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

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

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

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

Definition at line 3970 of file jurassic.c.

3972 {
3973
3974 /* Write info... */
3975 LOG(1, "Initialize source function table...");
3976 LOG(2, "Number of data points: %d", TBLNS);
3977
3978 /* Loop over channels... */
3979 for (int id = 0; id < ctl->nd; id++) {
3980
3981 /* Get minimum grid spacing... */
3982 double dnu = 1.0;
3983 for (int i = 1; i < tbl->filt_n[id]; i++)
3984 dnu = MIN(dnu, tbl->filt_nu[id][i] - tbl->filt_nu[id][i - 1]);
3985
3986 /* Compute source function table... */
3987#pragma omp parallel for default(none) shared(ctl,tbl,id,dnu)
3988 for (int it = 0; it < TBLNS; it++) {
3989
3990 /* Set temperature... */
3991 tbl->st[it] = LIN(0.0, TMIN, TBLNS - 1.0, TMAX, (double) it);
3992
3993 /* Integrate Planck function... */
3994 double fsum = tbl->sr[it][id] = 0;
3995 for (double fnu = tbl->filt_nu[id][0];
3996 fnu <= tbl->filt_nu[id][tbl->filt_n[id] - 1]; fnu += dnu) {
3997 const int i = locate_irr(tbl->filt_nu[id], tbl->filt_n[id], fnu);
3998 const double ff = LIN(tbl->filt_nu[id][i], tbl->filt_f[id][i],
3999 tbl->filt_nu[id][i + 1], tbl->filt_f[id][i + 1],
4000 fnu);
4001 fsum += ff;
4002 tbl->sr[it][id] += ff * PLANCK(tbl->st[it], fnu);
4003 }
4004 tbl->sr[it][id] /= fsum;
4005 }
4006
4007 /* Write info... */
4008 LOG(2,
4009 "channel= %.4f cm^-1 | T= %g ... %g K | B= %g ... %g W/(m^2 sr cm^-1)",
4010 ctl->nu[id], tbl->st[0], tbl->st[TBLNS - 1], tbl->sr[0][id],
4011 tbl->sr[TBLNS - 1][id]);
4012 }
4013}
#define TMAX
Maximum temperature for source function [K].
Definition: jurassic.h:209
#define TMIN
Minimum temperature for source function [K].
Definition: jurassic.h:204
int filt_n[ND]
Filter function number of spectral grid points.
Definition: jurassic.h:1681
double filt_f[ND][NSHAPE]
Filter function values.
Definition: jurassic.h:1687
double filt_nu[ND][NSHAPE]
Filter function spectral grid points [cm^-1].
Definition: jurassic.h:1684
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 4017 of file jurassic.c.

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

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

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

◆ intpol_tbl_eps()

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

Interpolate gas emissivity as a function of column amount.

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

Behavior:

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

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

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

Definition at line 4225 of file jurassic.c.

4231 {
4232
4233 const int nu = tbl->nu[id][ig][ip][it];
4234 const float *logu_arr = tbl->logu[id][ig][ip][it];
4235 const float *logeps_arr = tbl->logeps[id][ig][ip][it];
4236
4237 /* Work in log-space and only convert back when needed... */
4238 const double logu_min = (double) logu_arr[0];
4239 const double logu_max = (double) logu_arr[nu - 1];
4240
4241 /* Lower boundary extrapolation (u < u_min)...
4242 eps ~ eps_min * u/u_min => log(eps) = logeps_min + log(u) - log(u_min) */
4243 if (logu < logu_min) {
4244 const double logeps_min = (double) logeps_arr[0];
4245 return exp(logeps_min + logu - logu_min);
4246 }
4247
4248 /* Upper boundary extrapolation (u > u_max)...
4249 * Assume eps(u) approaches 1 exponentially:
4250 * eps(u) = 1 - exp(a * u), a < 0
4251 * Continuity at (u_max, eps_max) gives
4252 * a = log(1 - eps_max) / u_max.
4253 * Use log1p/expm1 and u/u_max = exp(log(u) - log(u_max)) for stability.
4254 */
4255 if (logu > logu_max) {
4256 const double eps_max = exp((double) logeps_arr[nu - 1]);
4257 const double l1m_eps_max = log1p(-eps_max);
4258 const double r = exp(logu - logu_max);
4259 return -expm1(l1m_eps_max * r);
4260 }
4261
4262 /* Interpolation (log-log using precomputed logs)... */
4263 const int idx = locate_tbl(logu_arr, nu, logu);
4264 return exp(LIN(logu_arr[idx], logeps_arr[idx],
4265 logu_arr[idx + 1], logeps_arr[idx + 1], logu));
4266}
int locate_tbl(const float *xx, const int n, const double x)
Locate index for interpolation within emissivity table grids.
Definition: jurassic.c:4493
float * logu[ND][NG][TBLNP][TBLNT]
Logarithm of column density [molecules/cm^2].
Definition: jurassic.h:1675
float * logeps[ND][NG][TBLNP][TBLNT]
Logarithm of emissivity.
Definition: jurassic.h:1678
Here is the call graph for this function:

◆ intpol_tbl_u()

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

Interpolate column amount as a function of emissivity.

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

Behavior:

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

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

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

Definition at line 4270 of file jurassic.c.

4276 {
4277
4278 const int nu = tbl->nu[id][ig][ip][it];
4279 const float *logeps_arr = tbl->logeps[id][ig][ip][it];
4280 const float *logu_arr = tbl->logu[id][ig][ip][it];
4281
4282 /* Work in log-space and only convert back when needed.... */
4283 const double logeps_min = (double) logeps_arr[0];
4284 const double logeps_max = (double) logeps_arr[nu - 1];
4285
4286 /* Lower boundary extrapolation (eps < eps_min)...
4287 u ~ u_min * eps/eps_min => log(u) = log(u_min) + log(eps) - log(eps_min) */
4288 if (logeps < logeps_min) {
4289 const double logu_min = (double) logu_arr[0];
4290 return exp(logu_min + logeps - logeps_min);
4291 }
4292
4293 /* Upper boundary extrapolation (eps > eps_max):
4294 * Invert the exponential tail used for eps(u):
4295 * u = log(1 - eps) / a,
4296 * with a = log(1 - eps_max) / u_max.
4297 * Rewritten as
4298 * u = u_max * log(tau) / log(1 - eps_max)
4299 * for numerical stability (log1p).
4300 */
4301 if (logeps > logeps_max) {
4302 const double u_max = exp((double) logu_arr[nu - 1]);
4303 const double l1m_eps_max = log1p(-exp(logeps_max));
4304 const double logtau = log1p(-exp(logeps));
4305 return u_max * (logtau / l1m_eps_max);
4306 }
4307
4308 /* Interpolation (log-log using precomputed logs)... */
4309 const int idx = locate_tbl(logeps_arr, nu, logeps);
4310 return exp(LIN(logeps_arr[idx], logu_arr[idx],
4311 logeps_arr[idx + 1], logu_arr[idx + 1], logeps));
4312}
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 4316 of file jurassic.c.

4324 {
4325
4326 struct tm t0, *t1;
4327
4328 t0.tm_year = 100;
4329 t0.tm_mon = 0;
4330 t0.tm_mday = 1;
4331 t0.tm_hour = 0;
4332 t0.tm_min = 0;
4333 t0.tm_sec = 0;
4334
4335 const time_t jsec0 = (time_t) jsec + timegm(&t0);
4336 t1 = gmtime(&jsec0);
4337
4338 *year = t1->tm_year + 1900;
4339 *mon = t1->tm_mon + 1;
4340 *day = t1->tm_mday;
4341 *hour = t1->tm_hour;
4342 *min = t1->tm_min;
4343 *sec = t1->tm_sec;
4344 *remain = jsec - floor(jsec);
4345}

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

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

4447 {
4448
4449 int ilo = 0;
4450 int ihi = n - 1;
4451 int i = (ihi + ilo) >> 1;
4452
4453 if (xx[i] < xx[i + 1])
4454 while (ihi > ilo + 1) {
4455 i = (ihi + ilo) >> 1;
4456 if (xx[i] > x)
4457 ihi = i;
4458 else
4459 ilo = i;
4460 } else
4461 while (ihi > ilo + 1) {
4462 i = (ihi + ilo) >> 1;
4463 if (xx[i] <= x)
4464 ihi = i;
4465 else
4466 ilo = i;
4467 }
4468
4469 return ilo;
4470}

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

4477 {
4478
4479 /* Calculate index... */
4480 const int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
4481
4482 /* Check range... */
4483 if (i < 0)
4484 return 0;
4485 else if (i > n - 2)
4486 return n - 2;
4487 else
4488 return i;
4489}

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

4496 {
4497
4498 int ilo = 0;
4499 int ihi = n - 1;
4500 int i = (ihi + ilo) >> 1;
4501
4502 while (ihi > ilo + 1) {
4503 i = (ihi + ilo) >> 1;
4504 if (xx[i] > x)
4505 ihi = i;
4506 else
4507 ilo = i;
4508 }
4509
4510 return ilo;
4511}

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

4516 {
4517
4518 size_t diag = 1;
4519
4520 /* Get size... */
4521 const size_t n = a->size1;
4522
4523 /* Check if matrix is diagonal... */
4524 for (size_t i = 0; i < n && diag; i++)
4525 for (size_t j = i + 1; j < n; j++)
4526 if (gsl_matrix_get(a, i, j) != 0) {
4527 diag = 0;
4528 break;
4529 }
4530
4531 /* Quick inversion of diagonal matrix... */
4532 if (diag)
4533 for (size_t i = 0; i < n; i++)
4534 gsl_matrix_set(a, i, i, 1 / gsl_matrix_get(a, i, i));
4535
4536 /* Matrix inversion by means of Cholesky decomposition... */
4537 else {
4538 gsl_linalg_cholesky_decomp(a);
4539 gsl_linalg_cholesky_invert(a);
4540 }
4541}

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

4549 {
4550
4551 /* Set sizes... */
4552 const size_t m = a->size1;
4553 const size_t n = a->size2;
4554
4555 /* Allocate... */
4556 gsl_matrix *aux = gsl_matrix_alloc(m, n);
4557
4558 /* Compute A^T B A... */
4559 if (transpose == 1) {
4560
4561 /* Compute B^1/2 A... */
4562 for (size_t i = 0; i < m; i++)
4563 for (size_t j = 0; j < n; j++)
4564 gsl_matrix_set(aux, i, j,
4565 gsl_vector_get(b, i) * gsl_matrix_get(a, i, j));
4566
4567 /* Compute A^T B A = (B^1/2 A)^T (B^1/2 A)... */
4568 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, aux, aux, 0.0, c);
4569 }
4570
4571 /* Compute A B A^T... */
4572 else if (transpose == 2) {
4573
4574 /* Compute A B^1/2... */
4575 for (size_t i = 0; i < m; i++)
4576 for (size_t j = 0; j < n; j++)
4577 gsl_matrix_set(aux, i, j,
4578 gsl_matrix_get(a, i, j) * gsl_vector_get(b, j));
4579
4580 /* Compute A B A^T = (A B^1/2) (A B^1/2)^T... */
4581 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, aux, aux, 0.0, c);
4582 }
4583
4584 /* Free... */
4585 gsl_matrix_free(aux);
4586}

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

4595 {
4596
4597 size_t m = 0;
4598
4599 /* Determine measurement vector... */
4600 for (int ir = 0; ir < obs->nr; ir++)
4601 for (int id = 0; id < ctl->nd; id++)
4602 if (isfinite(obs->rad[id][ir])) {
4603 if (y != NULL)
4604 gsl_vector_set(y, m, obs->rad[id][ir]);
4605 if (ida != NULL)
4606 ida[m] = id;
4607 if (ira != NULL)
4608 ira[m] = ir;
4609 m++;
4610 }
4611
4612 return m;
4613}

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

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

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

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

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

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

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

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

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

5577 {
5578
5579 FILE *in;
5580
5581 char dum[LEN], file[LEN], line[LEN];
5582
5583 double value;
5584
5585 int i, j;
5586
5587 /* Set filename... */
5588 if (dirname != NULL)
5589 sprintf(file, "%s/%s", dirname, filename);
5590 else
5591 sprintf(file, "%s", filename);
5592
5593 /* Write info... */
5594 LOG(1, "Read matrix: %s", file);
5595
5596 /* Open file... */
5597 if (!(in = fopen(file, "r")))
5598 ERRMSG("Cannot open file!");
5599
5600 /* Read data... */
5601 gsl_matrix_set_zero(matrix);
5602 while (fgets(line, LEN, in))
5603 if (sscanf(line, "%d %s %s %s %s %s %d %s %s %s %s %s %lg",
5604 &i, dum, dum, dum, dum, dum,
5605 &j, dum, dum, dum, dum, dum, &value) == 13)
5606 gsl_matrix_set(matrix, (size_t) i, (size_t) j, value);
5607
5608 /* Close file... */
5609 fclose(in);
5610}

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

5618 {
5619
5620 char file[LEN];
5621
5622 /* Set filename... */
5623 if (dirname != NULL)
5624 sprintf(file, "%s/%s", dirname, filename);
5625 else
5626 sprintf(file, "%s", filename);
5627
5628 /* Write info... */
5629 LOG(1, "Read observation data: %s", file);
5630
5631 /* Read ASCII data... */
5632 if (ctl->obsfmt == 1)
5633 read_obs_asc(file, ctl, obs);
5634
5635 /* Read binary data... */
5636 else if (ctl->obsfmt == 2)
5637 read_obs_bin(file, ctl, obs);
5638
5639 /* Read netCDF data... */
5640 else if (ctl->obsfmt == 3)
5641 read_obs_nc(file, ctl, obs, 0);
5642
5643 /* Check number of points... */
5644 if (obs->nr < 1)
5645 ERRMSG("Could not read any data!");
5646
5647 /* Write info... */
5648 double mini, maxi;
5649 LOG(2, "Number of ray paths: %d", obs->nr);
5650 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
5651 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
5652 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
5653 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
5654 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
5655 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
5656 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
5657 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
5658 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
5659 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
5660 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
5661 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
5662 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
5663 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
5664 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
5665 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
5666 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
5667 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
5668 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
5669 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
5670 for (int id = 0; id < ctl->nd; id++) {
5671 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
5672 if (ctl->write_bbt) {
5673 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
5674 ctl->nu[id], mini, maxi);
5675 } else {
5676 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
5677 ctl->nu[id], mini, maxi);
5678 }
5679 }
5680 for (int id = 0; id < ctl->nd; id++) {
5681 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
5682 if (ctl->write_bbt) {
5683 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
5684 ctl->nu[id], mini, maxi);
5685 }
5686 }
5687}
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:5736
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:5814
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:5691
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 5691 of file jurassic.c.

5694 {
5695
5696 char line[LEN], *tok;
5697
5698 /* Init... */
5699 obs->nr = 0;
5700
5701 /* Open file... */
5702 FILE *in;
5703 if (!(in = fopen(filename, "r")))
5704 ERRMSG("Cannot open file!");
5705
5706 /* Read line... */
5707 while (fgets(line, LEN, in)) {
5708
5709 /* Read data... */
5710 TOK(line, tok, "%lg", obs->time[obs->nr]);
5711 TOK(NULL, tok, "%lg", obs->obsz[obs->nr]);
5712 TOK(NULL, tok, "%lg", obs->obslon[obs->nr]);
5713 TOK(NULL, tok, "%lg", obs->obslat[obs->nr]);
5714 TOK(NULL, tok, "%lg", obs->vpz[obs->nr]);
5715 TOK(NULL, tok, "%lg", obs->vplon[obs->nr]);
5716 TOK(NULL, tok, "%lg", obs->vplat[obs->nr]);
5717 TOK(NULL, tok, "%lg", obs->tpz[obs->nr]);
5718 TOK(NULL, tok, "%lg", obs->tplon[obs->nr]);
5719 TOK(NULL, tok, "%lg", obs->tplat[obs->nr]);
5720 for (int id = 0; id < ctl->nd; id++)
5721 TOK(NULL, tok, "%lg", obs->rad[id][obs->nr]);
5722 for (int id = 0; id < ctl->nd; id++)
5723 TOK(NULL, tok, "%lg", obs->tau[id][obs->nr]);
5724
5725 /* Increment counter... */
5726 if ((++obs->nr) > NR)
5727 ERRMSG("Too many rays!");
5728 }
5729
5730 /* Close file... */
5731 fclose(in);
5732}

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

5739 {
5740
5741 /* Open file... */
5742 FILE *in;
5743 if (!(in = fopen(filename, "r")))
5744 ERRMSG("Cannot open file!");
5745
5746 /* Read header... */
5747 char magic[4];
5748 FREAD(magic, char,
5749 4,
5750 in);
5751 if (memcmp(magic, "OBS1", 4) != 0)
5752 ERRMSG("Invalid magic string!");
5753
5754 int nd;
5755 FREAD(&nd, int,
5756 1,
5757 in);
5758 if (nd != ctl->nd)
5759 ERRMSG("Error reading file header!");
5760
5761 /* Read data... */
5762 size_t nr;
5763 FREAD(&nr, size_t,
5764 1,
5765 in);
5766 obs->nr = (int) nr;
5767 if (obs->nr > NR)
5768 ERRMSG("Too many ray paths!");
5769 FREAD(obs->time, double,
5770 nr,
5771 in);
5772 FREAD(obs->obsz, double,
5773 nr,
5774 in);
5775 FREAD(obs->obslon, double,
5776 nr,
5777 in);
5778 FREAD(obs->obslat, double,
5779 nr,
5780 in);
5781 FREAD(obs->vpz, double,
5782 nr,
5783 in);
5784 FREAD(obs->vplon, double,
5785 nr,
5786 in);
5787 FREAD(obs->vplat, double,
5788 nr,
5789 in);
5790 FREAD(obs->tpz, double,
5791 nr,
5792 in);
5793 FREAD(obs->tplon, double,
5794 nr,
5795 in);
5796 FREAD(obs->tplat, double,
5797 nr,
5798 in);
5799 for (int id = 0; id < ctl->nd; id++)
5800 FREAD(obs->rad[id], double,
5801 nr,
5802 in);
5803 for (int id = 0; id < ctl->nd; id++)
5804 FREAD(obs->tau[id], double,
5805 nr,
5806 in);
5807
5808 /* Close file... */
5809 fclose(in);
5810}

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

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

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

5897 {
5898
5899 FILE *in;
5900
5901 char filename[LEN];
5902
5903 double filt, fsum = 0, nu2[NSHAPE], *nurfm, *rad, radsum = 0;
5904
5905 int npts;
5906
5907 /* Allocate... */
5908 ALLOC(nurfm, double,
5909 RFMNPTS);
5910 ALLOC(rad, double,
5911 RFMNPTS);
5912
5913 /* Search RFM spectrum... */
5914 sprintf(filename, "%s_%05d.asc", basename, (int) (z * 1000));
5915 if (!(in = fopen(filename, "r"))) {
5916 sprintf(filename, "%s_%05d.asc", basename, (int) (z * 1000) + 1);
5917 if (!(in = fopen(filename, "r")))
5918 ERRMSG("Cannot find RFM data file!");
5919 }
5920 fclose(in);
5921
5922 /* Read RFM spectrum... */
5923 read_rfm_spec(filename, nurfm, rad, &npts);
5924
5925 /* Set wavenumbers... */
5926 nu2[0] = nu[0];
5927 nu2[n - 1] = nu[n - 1];
5928 for (int i = 1; i < n - 1; i++)
5929 nu2[i] = LIN(0.0, nu2[0], n - 1.0, nu2[n - 1], i);
5930
5931 /* Convolute... */
5932 for (int ipts = 0; ipts < npts; ipts++)
5933 if (nurfm[ipts] >= nu2[0] && nurfm[ipts] <= nu2[n - 1]) {
5934 const int idx = locate_irr(nu2, n, nurfm[ipts]);
5935 filt = LIN(nu2[idx], f[idx], nu2[idx + 1], f[idx + 1], nurfm[ipts]);
5936 fsum += filt;
5937 radsum += filt * rad[ipts];
5938 }
5939
5940 /* Free... */
5941 free(nurfm);
5942 free(rad);
5943
5944 /* Return radiance... */
5945 return radsum / fsum;
5946}
void read_rfm_spec(const char *filename, double *nu, double *rad, int *npts)
Read a Reference Forward Model (RFM) ASCII spectrum.
Definition: jurassic.c:6003
#define RFMNPTS
Maximum number of RFM spectral grid points.
Definition: jurassic.h:323
Here is the call graph for this function:

◆ read_ret()

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

Read retrieval configuration and error parameters.

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

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

The function performs the following initialization steps:

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

Definition at line 5950 of file jurassic.c.

5954 {
5955
5956 /* Iteration control... */
5957 ret->kernel_recomp =
5958 (int) scan_ctl(argc, argv, "KERNEL_RECOMP", -1, "3", NULL);
5959 ret->conv_itmax = (int) scan_ctl(argc, argv, "CONV_ITMAX", -1, "30", NULL);
5960 ret->conv_dmin = scan_ctl(argc, argv, "CONV_DMIN", -1, "0.1", NULL);
5961
5962 /* Error analysis... */
5963 ret->err_ana = (int) scan_ctl(argc, argv, "ERR_ANA", -1, "0", NULL);
5964
5965 for (int id = 0; id < ctl->nd; id++)
5966 ret->err_formod[id] = scan_ctl(argc, argv, "ERR_FORMOD", id, "0", NULL);
5967
5968 for (int id = 0; id < ctl->nd; id++)
5969 ret->err_noise[id] = scan_ctl(argc, argv, "ERR_NOISE", id, "0", NULL);
5970
5971 ret->err_press = scan_ctl(argc, argv, "ERR_PRESS", -1, "0", NULL);
5972 ret->err_press_cz = scan_ctl(argc, argv, "ERR_PRESS_CZ", -1, "-999", NULL);
5973 ret->err_press_ch = scan_ctl(argc, argv, "ERR_PRESS_CH", -1, "-999", NULL);
5974
5975 ret->err_temp = scan_ctl(argc, argv, "ERR_TEMP", -1, "0", NULL);
5976 ret->err_temp_cz = scan_ctl(argc, argv, "ERR_TEMP_CZ", -1, "-999", NULL);
5977 ret->err_temp_ch = scan_ctl(argc, argv, "ERR_TEMP_CH", -1, "-999", NULL);
5978
5979 for (int ig = 0; ig < ctl->ng; ig++) {
5980 ret->err_q[ig] = scan_ctl(argc, argv, "ERR_Q", ig, "0", NULL);
5981 ret->err_q_cz[ig] = scan_ctl(argc, argv, "ERR_Q_CZ", ig, "-999", NULL);
5982 ret->err_q_ch[ig] = scan_ctl(argc, argv, "ERR_Q_CH", ig, "-999", NULL);
5983 }
5984
5985 for (int iw = 0; iw < ctl->nw; iw++) {
5986 ret->err_k[iw] = scan_ctl(argc, argv, "ERR_K", iw, "0", NULL);
5987 ret->err_k_cz[iw] = scan_ctl(argc, argv, "ERR_K_CZ", iw, "-999", NULL);
5988 ret->err_k_ch[iw] = scan_ctl(argc, argv, "ERR_K_CH", iw, "-999", NULL);
5989 }
5990
5991 ret->err_clz = scan_ctl(argc, argv, "ERR_CLZ", -1, "0", NULL);
5992 ret->err_cldz = scan_ctl(argc, argv, "ERR_CLDZ", -1, "0", NULL);
5993 for (int icl = 0; icl < ctl->ncl; icl++)
5994 ret->err_clk[icl] = scan_ctl(argc, argv, "ERR_CLK", icl, "0", NULL);
5995
5996 ret->err_sft = scan_ctl(argc, argv, "ERR_SFT", -1, "0", NULL);
5997 for (int isf = 0; isf < ctl->nsf; isf++)
5998 ret->err_sfeps[isf] = scan_ctl(argc, argv, "ERR_SFEPS", isf, "0", NULL);
5999}
double err_press_cz
Vertical correlation length for pressure error [km].
Definition: jurassic.h:1602
double err_press
Pressure error [%].
Definition: jurassic.h:1599
double err_k_cz[NW]
Vertical correlation length for extinction error [km].
Definition: jurassic.h:1629
double err_k_ch[NW]
Horizontal correlation length for extinction error [km].
Definition: jurassic.h:1632
double err_temp_cz
Vertical correlation length for temperature error [km].
Definition: jurassic.h:1611
double err_formod[ND]
Forward model error [%].
Definition: jurassic.h:1593
double err_temp
Temperature error [K].
Definition: jurassic.h:1608
double err_q_cz[NG]
Vertical correlation length for volume mixing ratio error [km].
Definition: jurassic.h:1620
double err_noise[ND]
Noise error [W/(m^2 sr cm^-1)].
Definition: jurassic.h:1596
double err_clz
Cloud height error [km].
Definition: jurassic.h:1635
double err_sft
Surface temperature error [K].
Definition: jurassic.h:1644
double err_clk[NCL]
Cloud extinction error [km^-1].
Definition: jurassic.h:1641
double err_temp_ch
Horizontal correlation length for temperature error [km].
Definition: jurassic.h:1614
double err_cldz
Cloud depth error [km].
Definition: jurassic.h:1638
double err_press_ch
Horizontal correlation length for pressure error [km].
Definition: jurassic.h:1605
double err_q_ch[NG]
Horizontal correlation length for volume mixing ratio error [km].
Definition: jurassic.h:1623
double err_q[NG]
Volume mixing ratio error [%].
Definition: jurassic.h:1617
double err_sfeps[NSF]
Surface emissivity error.
Definition: jurassic.h:1647
double err_k[NW]
Extinction error [km^-1].
Definition: jurassic.h:1626
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 6003 of file jurassic.c.

6007 {
6008
6009 FILE *in;
6010
6011 char *line = NULL, *tok;
6012
6013 size_t line_buf_size = 0;
6014
6015 double dnu, nu0, nu1;
6016
6017 int ipts = 0;
6018
6019 /* Write info... */
6020 LOG(1, "Read RFM data: %s", filename);
6021
6022 /* Open file... */
6023 if (!(in = fopen(filename, "r")))
6024 ERRMSG("Cannot open file!");
6025
6026 /* Read header... */
6027 for (int i = 0; i < 4; i++)
6028 if (getline(&line, &line_buf_size, in) == -1)
6029 ERRMSG("Error while reading file header!");
6030 if (sscanf(line, "%d %lg %lg %lg", npts, &nu0, &dnu, &nu1) != 4)
6031 ERRMSG("Invalid spectrum header format!");
6032
6033 /* Check number of spectral grid points... */
6034 if (*npts > RFMNPTS)
6035 ERRMSG("Too many spectral grid points!");
6036
6037 /* Read radiance data... */
6038 while (getline(&line, &line_buf_size, in) != -1 && ipts < *npts) {
6039 tok = strtok(line, " \t\n");
6040 while (tok != NULL && ipts < *npts) {
6041 if (sscanf(tok, "%lg", &rad[ipts]) == 1)
6042 ipts++;
6043 tok = strtok(NULL, " \t\n");
6044 }
6045 }
6046
6047 /* Check number of spectral grid points... */
6048 if (ipts != *npts)
6049 ERRMSG("Error while reading RFM data!");
6050
6051 /* Compute wavenumbers... */
6052 for (ipts = 0; ipts < *npts; ipts++)
6053 nu[ipts] = LIN(0.0, nu0, (double) (*npts - 1), nu1, (double) ipts);
6054
6055 /* Close file... */
6056 fclose(in);
6057
6058 /* Free.. */
6059 free(line);
6060}

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

6068 {
6069
6070 FILE *in;
6071
6072 char line[LEN];
6073
6074 /* Write info... */
6075 LOG(1, "Read shape function: %s", filename);
6076
6077 /* Open file... */
6078 if (!(in = fopen(filename, "r")))
6079 ERRMSG("Cannot open file!");
6080
6081 /* Read data... */
6082 *n = 0;
6083 while (fgets(line, LEN, in))
6084 if (sscanf(line, "%lg %lg", &x[*n], &y[*n]) == 2)
6085 if ((++(*n)) > NSHAPE)
6086 ERRMSG("Too many data points!");
6087
6088 /* Close file... */
6089 fclose(in);
6090
6091 /* Check number of data points... */
6092 if (*n < 2)
6093 ERRMSG("Could not read any data!");
6094
6095 /* Write info... */
6096 double mini, maxi;
6097 LOG(2, "Number of data points: %d", *n);
6098 gsl_stats_minmax(&mini, &maxi, x, 1, (size_t) *n);
6099 LOG(2, "Range of x values: %.4f ... %.4f", mini, maxi);
6100 gsl_stats_minmax(&mini, &maxi, y, 1, (size_t) *n);
6101 LOG(2, "Range of y values: %g ... %g", mini, maxi);
6102}

◆ read_tbl()

tbl_t * read_tbl ( const ctl_t ctl)

Read emissivity lookup tables from disk.

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

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

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

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

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

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

Definition at line 6106 of file jurassic.c.

6107 {
6108
6109 /* Allocate... */
6110 tbl_t *tbl;
6111 ALLOC(tbl, tbl_t, 1);
6112
6113 /* Initialize filter function sizes... */
6114 for (int id = 0; id < ctl->nd; id++)
6115 tbl->filt_n[id] = 0;
6116
6117 /* Loop over trace gases... */
6118 for (int ig = 0; ig < ctl->ng; ig++) {
6119
6120 /* Read ASCII look-up tables... */
6121 if (ctl->tblfmt == 1)
6122 for (int id = 0; id < ctl->nd; id++) {
6123 read_tbl_asc(ctl, tbl, id, ig);
6124 TBL_LOG(tbl, id, ig);
6125 }
6126
6127 /* Read binary look-up tables... */
6128 else if (ctl->tblfmt == 2)
6129 for (int id = 0; id < ctl->nd; id++) {
6130 read_tbl_bin(ctl, tbl, id, ig);
6131 TBL_LOG(tbl, id, ig);
6132 }
6133
6134 /* Read netCDF look-up tables... */
6135 else if (ctl->tblfmt == 3) {
6136
6137 /* Open file... */
6138 int ncid;
6139 char filename[2 * LEN];
6140 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
6141 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
6142 WARN("Missing emissivity table: %s", filename);
6143 continue;
6144 } else
6145 LOG(1, "Read emissivity table: %s", filename);
6146
6147 /* Read channels... */
6148 for (int id = 0; id < ctl->nd; id++) {
6149 read_tbl_nc_channel(ctl, tbl, id, ig, ncid);
6150 TBL_LOG(tbl, id, ig);
6151 }
6152
6153 /* Close file... */
6154 NC(nc_close(ncid));
6155 }
6156 }
6157
6158 /* Read filter functions... */
6159 if (ctl->tblfmt == 1)
6160 for (int id = 0; id < ctl->nd; id++) {
6161 char filename[2 * LEN];
6162 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
6163 read_shape(filename, tbl->filt_nu[id], tbl->filt_f[id],
6164 &tbl->filt_n[id]);
6165 }
6166
6167 /* Initialize source function lookup tables... */
6168 init_srcfunc(ctl, tbl);
6169
6170 /* Return pointer... */
6171 return tbl;
6172}
void read_tbl_bin(const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
Read a single compact binary emissivity lookup table.
Definition: jurassic.c:6299
void init_srcfunc(const ctl_t *ctl, tbl_t *tbl)
Initialize source function lookup tables from emissivity data.
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:6176
void read_tbl_nc_channel(const ctl_t *ctl, tbl_t *tbl, int id, int ig, int ncid)
Read one packed emissivity lookup table from an open NetCDF file.
Definition: jurassic.c:6343
#define TBL_LOG(tbl, id, ig)
Log detailed statistics of an emissivity look-up table.
Definition: jurassic.h:1023
Emissivity look-up tables.
Definition: jurassic.h:1657
Here is the call graph for this function:

◆ read_tbl_asc()

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

Read a single ASCII emissivity lookup table.

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

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

The table file contains four columns:

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

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

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

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

Definition at line 6176 of file jurassic.c.

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

◆ read_tbl_bin()

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

Read a single compact binary emissivity lookup table.

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

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

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

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

The blob is unpacked into tbl using tbl_unpack().

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

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

Definition at line 6299 of file jurassic.c.

6303 {
6304
6305 /* Set filename... */
6306 char filename[2 * LEN];
6307 sprintf(filename, "%s_%.4f_%s.bin",
6308 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
6309
6310 /* Open file... */
6311 FILE *in = fopen(filename, "rb");
6312 if (!in) {
6313 WARN("Missing emissivity table: %s", filename);
6314 return;
6315 } else
6316 LOG(1, "Read emissivity table: %s", filename);
6317
6318 /* Read length.. */
6319 size_t nbytes;
6320 FREAD(&nbytes, size_t,
6321 1,
6322 in);
6323 if (nbytes <= 0)
6324 ERRMSG("Invalid packed table size!");
6325
6326 /* Read packed blob... */
6327 uint8_t *work = NULL;
6328 ALLOC(work, uint8_t, nbytes);
6329 FREAD(work, uint8_t, nbytes, in);
6330
6331 /* Unpack... */
6332 tbl_unpack(tbl, id, ig, work);
6333
6334 /* Close file... */
6335 fclose(in);
6336
6337 /* Free... */
6338 free(work);
6339}
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:6775
Here is the call graph for this function:

◆ read_tbl_nc_channel()

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

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

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

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

tbl_XXXX

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

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

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

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

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

Definition at line 6343 of file jurassic.c.

6348 {
6349
6350 char varname[LEN];
6351
6352 int varid, dimid;
6353
6354 size_t nbytes;
6355
6356 /* Inquire variable... */
6357 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
6358 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
6359 WARN("Missing emissivity table: %s", varname);
6360 return;
6361 } else
6362 LOG(1, "Read emissivity table: %s", varname);
6363 NC(nc_inq_vardimid(ncid, varid, &dimid));
6364 NC(nc_inq_dimlen(ncid, dimid, &nbytes));
6365
6366 /* Read variable... */
6367 uint8_t *work = NULL;
6368 ALLOC(work, uint8_t, nbytes);
6369 NC(nc_get_var_uchar(ncid, varid, (unsigned char *) work));
6370
6371 /* Unpack... */
6372 tbl_unpack(tbl, id, ig, work);
6373
6374 /* Free... */
6375 free(work);
6376}
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 6380 of file jurassic.c.

6386 {
6387
6388 FILE *in = NULL;
6389
6390 char dummy[LEN], fullname1[LEN], fullname2[LEN], line[LEN],
6391 rvarname[LEN], rval[LEN];
6392
6393 int contain = 0;
6394
6395 /* Open file... */
6396 if (argv[1][0] != '-')
6397 if (!(in = fopen(argv[1], "r")))
6398 ERRMSG("Cannot open file!");
6399
6400 /* Set full variable name... */
6401 if (arridx >= 0) {
6402 sprintf(fullname1, "%s[%d]", varname, arridx);
6403 sprintf(fullname2, "%s[*]", varname);
6404 } else {
6405 sprintf(fullname1, "%s", varname);
6406 sprintf(fullname2, "%s", varname);
6407 }
6408
6409 /* Read data... */
6410 if (in != NULL)
6411 while (fgets(line, LEN, in))
6412 if (sscanf(line, "%s %s %s", rvarname, dummy, rval) == 3)
6413 if (strcasecmp(rvarname, fullname1) == 0 ||
6414 strcasecmp(rvarname, fullname2) == 0) {
6415 contain = 1;
6416 break;
6417 }
6418 for (int i = 1; i < argc - 1; i++)
6419 if (strcasecmp(argv[i], fullname1) == 0 ||
6420 strcasecmp(argv[i], fullname2) == 0) {
6421 sprintf(rval, "%s", argv[i + 1]);
6422 contain = 1;
6423 break;
6424 }
6425
6426 /* Close file... */
6427 if (in != NULL)
6428 fclose(in);
6429
6430 /* Check for missing variables... */
6431 if (!contain) {
6432 if (strlen(defvalue) > 0)
6433 sprintf(rval, "%s", defvalue);
6434 else
6435 ERRMSG("Missing variable %s!\n", fullname1);
6436 }
6437
6438 /* Write info... */
6439 LOG(1, "%s = %s", fullname1, rval);
6440
6441 /* Return values... */
6442 if (value != NULL)
6443 sprintf(value, "%s", rval);
6444 return atof(rval);
6445}

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

6455 {
6456
6457 /* Get sizes... */
6458 const size_t n = s_a->size1;
6459
6460 /* Allocate... */
6461 gsl_vector *x_a = gsl_vector_alloc(n);
6462
6463 /* Get sigma vector... */
6464 atm2x(ctl, atm, x_a, NULL, NULL);
6465 for (size_t i = 0; i < n; i++) {
6466 if (iqa[i] == IDXP)
6467 gsl_vector_set(x_a, i, ret->err_press / 100 * gsl_vector_get(x_a, i));
6468 if (iqa[i] == IDXT)
6469 gsl_vector_set(x_a, i, ret->err_temp);
6470 for (int ig = 0; ig < ctl->ng; ig++)
6471 if (iqa[i] == IDXQ(ig))
6472 gsl_vector_set(x_a, i, ret->err_q[ig] / 100 * gsl_vector_get(x_a, i));
6473 for (int iw = 0; iw < ctl->nw; iw++)
6474 if (iqa[i] == IDXK(iw))
6475 gsl_vector_set(x_a, i, ret->err_k[iw]);
6476 if (iqa[i] == IDXCLZ)
6477 gsl_vector_set(x_a, i, ret->err_clz);
6478 if (iqa[i] == IDXCLDZ)
6479 gsl_vector_set(x_a, i, ret->err_cldz);
6480 for (int icl = 0; icl < ctl->ncl; icl++)
6481 if (iqa[i] == IDXCLK(icl))
6482 gsl_vector_set(x_a, i, ret->err_clk[icl]);
6483 if (iqa[i] == IDXSFT)
6484 gsl_vector_set(x_a, i, ret->err_sft);
6485 for (int isf = 0; isf < ctl->nsf; isf++)
6486 if (iqa[i] == IDXSFEPS(isf))
6487 gsl_vector_set(x_a, i, ret->err_sfeps[isf]);
6488 }
6489
6490 /* Check standard deviations... */
6491 for (size_t i = 0; i < n; i++)
6492 if (POW2(gsl_vector_get(x_a, i)) <= 0)
6493 ERRMSG("Check a priori data (zero standard deviation)!");
6494
6495 /* Initialize diagonal covariance... */
6496 gsl_matrix_set_zero(s_a);
6497 for (size_t i = 0; i < n; i++)
6498 gsl_matrix_set(s_a, i, i, POW2(gsl_vector_get(x_a, i)));
6499
6500 /* Loop over matrix elements... */
6501 for (size_t i = 0; i < n; i++)
6502 for (size_t j = 0; j < n; j++)
6503 if (i != j && iqa[i] == iqa[j]) {
6504
6505 /* Initialize... */
6506 double cz = 0;
6507 double ch = 0;
6508
6509 /* Set correlation lengths for pressure... */
6510 if (iqa[i] == IDXP) {
6511 cz = ret->err_press_cz;
6512 ch = ret->err_press_ch;
6513 }
6514
6515 /* Set correlation lengths for temperature... */
6516 if (iqa[i] == IDXT) {
6517 cz = ret->err_temp_cz;
6518 ch = ret->err_temp_ch;
6519 }
6520
6521 /* Set correlation lengths for volume mixing ratios... */
6522 for (int ig = 0; ig < ctl->ng; ig++)
6523 if (iqa[i] == IDXQ(ig)) {
6524 cz = ret->err_q_cz[ig];
6525 ch = ret->err_q_ch[ig];
6526 }
6527
6528 /* Set correlation lengths for extinction... */
6529 for (int iw = 0; iw < ctl->nw; iw++)
6530 if (iqa[i] == IDXK(iw)) {
6531 cz = ret->err_k_cz[iw];
6532 ch = ret->err_k_ch[iw];
6533 }
6534
6535 /* Compute correlations... */
6536 if (cz > 0 && ch > 0) {
6537
6538 /* Get Cartesian coordinates... */
6539 double x0[3], x1[3];
6540 geo2cart(0, atm->lon[ipa[i]], atm->lat[ipa[i]], x0);
6541 geo2cart(0, atm->lon[ipa[j]], atm->lat[ipa[j]], x1);
6542
6543 /* Compute correlations... */
6544 const double rho =
6545 exp(-DIST(x0, x1) / ch -
6546 fabs(atm->z[ipa[i]] - atm->z[ipa[j]]) / cz);
6547
6548 /* Set covariance... */
6549 gsl_matrix_set(s_a, i, j, gsl_vector_get(x_a, i)
6550 * gsl_vector_get(x_a, j) * rho);
6551 }
6552 }
6553
6554 /* Free... */
6555 gsl_vector_free(x_a);
6556}
#define DIST(a, b)
Compute Cartesian distance between two 3D vectors.
Definition: jurassic.h:443
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 6560 of file jurassic.c.

6566 {
6567
6568 static obs_t obs_err;
6569
6570 /* Get size... */
6571 const size_t m = sig_eps_inv->size;
6572
6573 /* Noise error (always considered in retrieval fit)... */
6574 copy_obs(ctl, &obs_err, obs, 1);
6575 for (int ir = 0; ir < obs_err.nr; ir++)
6576 for (int id = 0; id < ctl->nd; id++)
6577 obs_err.rad[id][ir]
6578 = (isfinite(obs->rad[id][ir]) ? ret->err_noise[id] : NAN);
6579 obs2y(ctl, &obs_err, sig_noise, NULL, NULL);
6580
6581 /* Forward model error (always considered in retrieval fit)... */
6582 copy_obs(ctl, &obs_err, obs, 1);
6583 for (int ir = 0; ir < obs_err.nr; ir++)
6584 for (int id = 0; id < ctl->nd; id++)
6585 obs_err.rad[id][ir]
6586 = fabs(ret->err_formod[id] / 100 * obs->rad[id][ir]);
6587 obs2y(ctl, &obs_err, sig_formod, NULL, NULL);
6588
6589 /* Total error... */
6590 for (size_t i = 0; i < m; i++)
6591 gsl_vector_set(sig_eps_inv, i, 1 / sqrt(POW2(gsl_vector_get(sig_noise, i))
6592 +
6593 POW2(gsl_vector_get
6594 (sig_formod, i))));
6595
6596 /* Check standard deviations... */
6597 for (size_t i = 0; i < m; i++)
6598 if (gsl_vector_get(sig_eps_inv, i) <= 0)
6599 ERRMSG("Check measurement errors (zero standard deviation)!");
6600}
Here is the call graph for this function:

◆ sza()

double sza ( double  sec,
double  lon,
double  lat 
)

Compute the solar zenith angle for a given time and location.

Calculates the apparent solar zenith angle (SZA) [deg] based on the observer’s longitude, latitude, and time since 2000-01-01 T00:00 Z.

Parameters
[in]secSeconds since 2000-01-01 T00:00 Z.
[in]lonObserver longitude [deg].
[in]latObserver latitude [deg].
Returns
Solar zenith angle [deg].
  • Implements a simplified astronomical model based on the Sun’s apparent ecliptic longitude and the Earth’s mean obliquity.
  • Uses the following steps:
    1. Compute the number of days since J2000 noon epoch.
    2. Determine the Sun’s apparent ecliptic longitude and declination.
    3. Compute the local hour angle from Greenwich Mean Sidereal Time.
    4. Derive the solar zenith angle via spherical trigonometry:

      \[ \cos(\theta) = \sin(\varphi)\sin(\delta) + \cos(\varphi)\cos(\delta)\cos(h) \]

      where \(\varphi\) = latitude, \(\delta\) = declination, \(h\) = hour angle.
See also
formod_pencil, ctl_t::sfsza
Note
  • Neglects atmospheric refraction and seasonal perturbations.
  • Accuracy is sufficient for radiative transfer applications (<0.1°).
  • Longitude positive eastward, latitude positive northward.
Author
Lars Hoffmann

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

6608 {
6609
6610 double dummy, v[3], v0[3], v2[3];
6611
6612 /* Find minimum altitude... */
6613 const size_t ip = gsl_stats_min_index(los->z, 1, (size_t) los->np);
6614
6615 /* Nadir or zenith... */
6616 if (ip <= 0 || ip >= (size_t) los->np - 1) {
6617 *tpz = los->z[los->np - 1];
6618 *tplon = los->lon[los->np - 1];
6619 *tplat = los->lat[los->np - 1];
6620 }
6621
6622 /* Limb... */
6623 else {
6624
6625 /* Determine interpolating polynomial y=a*x^2+b*x+c... */
6626 const double yy0 = los->z[ip - 1];
6627 const double yy1 = los->z[ip];
6628 const double yy2 = los->z[ip + 1];
6629 const double x1 = sqrt(POW2(los->ds[ip]) - POW2(yy1 - yy0));
6630 const double x2 = x1 + sqrt(POW2(los->ds[ip + 1]) - POW2(yy2 - yy1));
6631 const double a = 1 / (x1 - x2) * (-(yy0 - yy1) / x1 + (yy0 - yy2) / x2);
6632 const double b = -(yy0 - yy1) / x1 - a * x1;
6633 const double c = yy0;
6634
6635 /* Get tangent point location... */
6636 const double x = -b / (2 * a);
6637 *tpz = a * x * x + b * x + c;
6638 geo2cart(los->z[ip - 1], los->lon[ip - 1], los->lat[ip - 1], v0);
6639 geo2cart(los->z[ip + 1], los->lon[ip + 1], los->lat[ip + 1], v2);
6640 for (int i = 0; i < 3; i++)
6641 v[i] = LIN(0.0, v0[i], x2, v2[i], x);
6642 cart2geo(v, &dummy, tplon, tplat);
6643 }
6644}
Here is the call graph for this function:

◆ tbl_free()

void tbl_free ( const ctl_t ctl,
tbl_t tbl 
)

Free lookup table and all internally allocated memory.

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

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

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

Definition at line 6648 of file jurassic.c.

6650 {
6651
6652 /* Check pointer... */
6653 if (!tbl)
6654 return;
6655
6656 /* Loop over channels and emitters... */
6657 for (int id = 0; id < ctl->nd; id++)
6658 for (int ig = 0; ig < ctl->ng; ig++) {
6659
6660 /* Check number of pressure levels... */
6661 const int np = tbl->np[id][ig];
6662 if (np < 0)
6663 continue;
6664
6665 /* Loop over pressure levels... */
6666 for (int ip = 0; ip < np; ip++) {
6667
6668 /* Loop over temperature levels... */
6669 const int nt = tbl->nt[id][ig][ip];
6670 for (int it = 0; it < nt; it++) {
6671
6672 /* Free... */
6673 free(tbl->logu[id][ig][ip][it]);
6674 free(tbl->logeps[id][ig][ip][it]);
6675 tbl->logu[id][ig][ip][it] = NULL;
6676 tbl->logeps[id][ig][ip][it] = NULL;
6677 }
6678 }
6679 }
6680
6681 /* Free... */
6682 free(tbl);
6683}

◆ tbl_pack()

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

Pack a lookup table into a contiguous binary buffer.

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

The packed layout in buf is, in order:

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

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

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

Definition at line 6687 of file jurassic.c.

6692 {
6693
6694 uint8_t *cur = buf;
6695
6696 /* Pack lookup table... */
6697 int np = tbl->np[id][ig];
6698 memcpy(cur, &np, sizeof(np));
6699 cur += sizeof(np);
6700
6701 memcpy(cur, tbl->p[id][ig], (size_t) np * sizeof(double));
6702 cur += ((size_t) np * sizeof(double));
6703
6704 for (int ip = 0; ip < np; ip++) {
6705 int nt = tbl->nt[id][ig][ip];
6706 memcpy(cur, &nt, sizeof(nt));
6707 cur += sizeof(nt);
6708
6709 memcpy(cur, tbl->t[id][ig][ip], (size_t) nt * sizeof(double));
6710 cur += ((size_t) nt * sizeof(double));
6711
6712 for (int it = 0; it < nt; it++) {
6713 int nu = tbl->nu[id][ig][ip][it];
6714 memcpy(cur, &nu, sizeof(nu));
6715 cur += sizeof(nu);
6716
6717 memcpy(cur, tbl->logu[id][ig][ip][it], (size_t) nu * sizeof(float));
6718 cur += ((size_t) nu * sizeof(float));
6719
6720 memcpy(cur, tbl->logeps[id][ig][ip][it], (size_t) nu * sizeof(float));
6721 cur += ((size_t) nu * sizeof(float));
6722 }
6723 }
6724
6725 /* Pack filter function... */
6726 const int n = tbl->filt_n[id];
6727 memcpy(cur, &n, sizeof(n));
6728 cur += sizeof(n);
6729
6730 memcpy(cur, tbl->filt_nu[id], (size_t) n * sizeof(double));
6731 cur += ((size_t) n * sizeof(double));
6732
6733 memcpy(cur, tbl->filt_f[id], (size_t) n * sizeof(double));
6734 cur += ((size_t) n * sizeof(double));
6735
6736 *bytes_used = (size_t) (cur - buf);
6737}

◆ tbl_packed_size()

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

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

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

See also
tbl_pack()
Author
Lars Hoffmann

Definition at line 6741 of file jurassic.c.

6744 {
6745
6746 size_t bytes = 0;
6747
6748 /* Size of lookup table... */
6749 const int np = tbl->np[id][ig];
6750 bytes += sizeof(int);
6751 bytes += ((size_t) np * sizeof(double));
6752
6753 for (int ip = 0; ip < np; ip++) {
6754 const int nt = tbl->nt[id][ig][ip];
6755 bytes += sizeof(int);
6756 bytes += ((size_t) nt * sizeof(double));
6757
6758 for (int it = 0; it < nt; it++) {
6759 const int nu = tbl->nu[id][ig][ip][it];
6760 bytes += sizeof(int);
6761 bytes += (2 * (size_t) nu * sizeof(float));
6762 }
6763 }
6764
6765 /* Size of filter function... */
6766 const int n = tbl->filt_n[id];
6767 bytes += sizeof(int);
6768 bytes += (2 * (size_t) n * sizeof(double));
6769
6770 return bytes;
6771}

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

6779 {
6780
6781 const uint8_t *cur = buf;
6782
6783 /* Unpack lookup table... */
6784 int np;
6785 memcpy(&np, cur, sizeof(np));
6786 cur += sizeof(np);
6787
6788 if (np < 0 || np > TBLNP)
6789 ERRMSG("np out of range!");
6790 tbl->np[id][ig] = np;
6791
6792 memcpy(tbl->p[id][ig], cur, (size_t) np * sizeof(double));
6793 cur += ((size_t) np * sizeof(double));
6794
6795 for (int ip = 0; ip < np; ip++) {
6796
6797 int nt;
6798 memcpy(&nt, cur, sizeof(nt));
6799 cur += sizeof(nt);
6800
6801 if (nt < 0 || nt > TBLNT)
6802 ERRMSG("nt out of range!");
6803 tbl->nt[id][ig][ip] = nt;
6804
6805 memcpy(tbl->t[id][ig][ip], cur, (size_t) nt * sizeof(double));
6806 cur += ((size_t) nt * sizeof(double));
6807
6808 for (int it = 0; it < nt; it++) {
6809
6810 int nu;
6811 memcpy(&nu, cur, sizeof(nu));
6812 cur += sizeof(nu);
6813
6814 if (nu < 0 || nu > TBLNU)
6815 ERRMSG("nu out of range!");
6816 tbl->nu[id][ig][ip][it] = nu;
6817
6818 ALLOC(tbl->logu[id][ig][ip][it], float,
6819 nu);
6820 ALLOC(tbl->logeps[id][ig][ip][it], float,
6821 nu);
6822
6823 memcpy(tbl->logu[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
6824 cur += ((size_t) nu * sizeof(float));
6825
6826 memcpy(tbl->logeps[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
6827 cur += ((size_t) nu * sizeof(float));
6828 }
6829 }
6830
6831 /* Unpack filter function... */
6832 int n;
6833 memcpy(&n, cur, sizeof(n));
6834 cur += sizeof(n);
6835
6836 if (n < 2 || n > NSHAPE)
6837 ERRMSG("Missing or invalid filter function (filt_n) in packed table!");
6838 tbl->filt_n[id] = n;
6839
6840 memcpy(tbl->filt_nu[id], cur, (size_t) n * sizeof(double));
6841 cur += ((size_t) n * sizeof(double));
6842
6843 memcpy(tbl->filt_f[id], cur, (size_t) n * sizeof(double));
6844 cur += ((size_t) n * sizeof(double));
6845
6846 return (size_t) (cur - buf);
6847}

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

6859 {
6860
6861 struct tm t0, t1;
6862
6863 t0.tm_year = 100;
6864 t0.tm_mon = 0;
6865 t0.tm_mday = 1;
6866 t0.tm_hour = 0;
6867 t0.tm_min = 0;
6868 t0.tm_sec = 0;
6869
6870 t1.tm_year = year - 1900;
6871 t1.tm_mon = mon - 1;
6872 t1.tm_mday = day;
6873 t1.tm_hour = hour;
6874 t1.tm_min = min;
6875 t1.tm_sec = sec;
6876
6877 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
6878}

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

6887 {
6888
6889 static double w0[10];
6890
6891 static int l0[10], nt;
6892
6893 /* Start new timer... */
6894 if (mode == 1) {
6895 w0[nt] = omp_get_wtime();
6896 l0[nt] = line;
6897 if ((++nt) >= 10)
6898 ERRMSG("Too many timers!");
6899 }
6900
6901 /* Write elapsed time... */
6902 else {
6903
6904 /* Check timer index... */
6905 if (nt - 1 < 0)
6906 ERRMSG("Coding error!");
6907
6908 /* Write elapsed time... */
6909 LOG(1, "Timer '%s' (%s, %s, l%d-%d): %.3f sec",
6910 name, file, func, l0[nt - 1], line, omp_get_wtime() - w0[nt - 1]);
6911 }
6912
6913 /* Stop timer... */
6914 if (mode == 3)
6915 nt--;
6916}

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

6924 {
6925
6926 char file[LEN];
6927
6928 /* Set filename... */
6929 if (dirname != NULL)
6930 sprintf(file, "%s/%s", dirname, filename);
6931 else
6932 sprintf(file, "%s", filename);
6933
6934 /* Write info... */
6935 LOG(1, "Write atmospheric data: %s", file);
6936
6937 /* Write ASCII data... */
6938 if (ctl->atmfmt == 1)
6939 write_atm_asc(file, ctl, atm);
6940
6941 /* Write binary data... */
6942 else if (ctl->atmfmt == 2)
6943 write_atm_bin(file, ctl, atm);
6944
6945 /* Write netCDF data... */
6946 else if (ctl->atmfmt == 3)
6947 write_atm_nc(file, ctl, atm, 0);
6948
6949 /* Error... */
6950 else
6951 ERRMSG("Unknown file format, check ATMFMT!");
6952
6953 /* Write info... */
6954 double mini, maxi;
6955 LOG(2, "Number of data points: %d", atm->np);
6956 gsl_stats_minmax(&mini, &maxi, atm->time, 1, (size_t) atm->np);
6957 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
6958 gsl_stats_minmax(&mini, &maxi, atm->z, 1, (size_t) atm->np);
6959 LOG(2, "Altitude range: %g ... %g km", mini, maxi);
6960 gsl_stats_minmax(&mini, &maxi, atm->lon, 1, (size_t) atm->np);
6961 LOG(2, "Longitude range: %g ... %g deg", mini, maxi);
6962 gsl_stats_minmax(&mini, &maxi, atm->lat, 1, (size_t) atm->np);
6963 LOG(2, "Latitude range: %g ... %g deg", mini, maxi);
6964 gsl_stats_minmax(&mini, &maxi, atm->p, 1, (size_t) atm->np);
6965 LOG(2, "Pressure range: %g ... %g hPa", maxi, mini);
6966 gsl_stats_minmax(&mini, &maxi, atm->t, 1, (size_t) atm->np);
6967 LOG(2, "Temperature range: %g ... %g K", mini, maxi);
6968 for (int ig = 0; ig < ctl->ng; ig++) {
6969 gsl_stats_minmax(&mini, &maxi, atm->q[ig], 1, (size_t) atm->np);
6970 LOG(2, "Emitter %s range: %g ... %g ppv", ctl->emitter[ig], mini, maxi);
6971 }
6972 for (int iw = 0; iw < ctl->nw; iw++) {
6973 gsl_stats_minmax(&mini, &maxi, atm->k[iw], 1, (size_t) atm->np);
6974 LOG(2, "Extinction range (window %d): %g ... %g km^-1", iw, mini, maxi);
6975 }
6976 if (ctl->ncl > 0) {
6977 LOG(2, "Cloud layer: z= %g km | dz= %g km | k= %g ... %g km^-1",
6978 atm->clz, atm->cldz, atm->clk[0], atm->clk[ctl->ncl - 1]);
6979 } else
6980 LOG(2, "Cloud layer: none");
6981 if (ctl->nsf > 0) {
6982 LOG(2,
6983 "Surface: T_s = %g K | eps= %g ... %g",
6984 atm->sft, atm->sfeps[0], atm->sfeps[ctl->nsf - 1]);
6985 } else
6986 LOG(2, "Surface: none");
6987}
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:7142
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:6991
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:7058
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 6991 of file jurassic.c.

6994 {
6995
6996 int n = 6;
6997
6998 /* Create file... */
6999 FILE *out;
7000 if (!(out = fopen(filename, "w")))
7001 ERRMSG("Cannot create file!");
7002
7003 /* Write header... */
7004 fprintf(out,
7005 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
7006 "# $2 = altitude [km]\n"
7007 "# $3 = longitude [deg]\n"
7008 "# $4 = latitude [deg]\n"
7009 "# $5 = pressure [hPa]\n" "# $6 = temperature [K]\n");
7010 for (int ig = 0; ig < ctl->ng; ig++)
7011 fprintf(out, "# $%d = %s volume mixing ratio [ppv]\n",
7012 ++n, ctl->emitter[ig]);
7013 for (int iw = 0; iw < ctl->nw; iw++)
7014 fprintf(out, "# $%d = extinction (window %d) [km^-1]\n", ++n, iw);
7015 if (ctl->ncl > 0) {
7016 fprintf(out, "# $%d = cloud layer height [km]\n", ++n);
7017 fprintf(out, "# $%d = cloud layer depth [km]\n", ++n);
7018 for (int icl = 0; icl < ctl->ncl; icl++)
7019 fprintf(out, "# $%d = cloud layer extinction (%.4f cm^-1) [km^-1]\n",
7020 ++n, ctl->clnu[icl]);
7021 }
7022 if (ctl->nsf > 0) {
7023 fprintf(out, "# $%d = surface temperature [K]\n", ++n);
7024 for (int isf = 0; isf < ctl->nsf; isf++)
7025 fprintf(out, "# $%d = surface emissivity (%.4f cm^-1)\n",
7026 ++n, ctl->sfnu[isf]);
7027 }
7028
7029 /* Write data... */
7030 for (int ip = 0; ip < atm->np; ip++) {
7031 if (ip == 0 || atm->time[ip] != atm->time[ip - 1])
7032 fprintf(out, "\n");
7033 fprintf(out, "%.2f %g %g %g %g %g", atm->time[ip], atm->z[ip],
7034 atm->lon[ip], atm->lat[ip], atm->p[ip], atm->t[ip]);
7035 for (int ig = 0; ig < ctl->ng; ig++)
7036 fprintf(out, " %g", atm->q[ig][ip]);
7037 for (int iw = 0; iw < ctl->nw; iw++)
7038 fprintf(out, " %g", atm->k[iw][ip]);
7039 if (ctl->ncl > 0) {
7040 fprintf(out, " %g %g", atm->clz, atm->cldz);
7041 for (int icl = 0; icl < ctl->ncl; icl++)
7042 fprintf(out, " %g", atm->clk[icl]);
7043 }
7044 if (ctl->nsf > 0) {
7045 fprintf(out, " %g", atm->sft);
7046 for (int isf = 0; isf < ctl->nsf; isf++)
7047 fprintf(out, " %g", atm->sfeps[isf]);
7048 }
7049 fprintf(out, "\n");
7050 }
7051
7052 /* Close file... */
7053 fclose(out);
7054}

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

7061 {
7062
7063 /* Create file... */
7064 FILE *out;
7065 if (!(out = fopen(filename, "w")))
7066 ERRMSG("Cannot create file!");
7067
7068 /* Write header... */
7069 FWRITE("ATM1", char,
7070 4,
7071 out);
7072 FWRITE(&ctl->ng, int,
7073 1,
7074 out);
7075 FWRITE(&ctl->nw, int,
7076 1,
7077 out);
7078 FWRITE(&ctl->ncl, int,
7079 1,
7080 out);
7081 FWRITE(&ctl->nsf, int,
7082 1,
7083 out);
7084
7085 /* Write data... */
7086 size_t np = (size_t) atm->np;
7087 FWRITE(&np, size_t,
7088 1,
7089 out);
7090 FWRITE(atm->time, double,
7091 np,
7092 out);
7093 FWRITE(atm->z, double,
7094 np,
7095 out);
7096 FWRITE(atm->lon, double,
7097 np,
7098 out);
7099 FWRITE(atm->lat, double,
7100 np,
7101 out);
7102 FWRITE(atm->p, double,
7103 np,
7104 out);
7105 FWRITE(atm->t, double,
7106 np,
7107 out);
7108 for (int ig = 0; ig < ctl->ng; ig++)
7109 FWRITE(atm->q[ig], double,
7110 np,
7111 out);
7112 for (int iw = 0; iw < ctl->nw; iw++)
7113 FWRITE(atm->k[iw], double,
7114 np,
7115 out);
7116 if (ctl->ncl > 0) {
7117 FWRITE(&atm->clz, double,
7118 1,
7119 out);
7120 FWRITE(&atm->cldz, double,
7121 1,
7122 out);
7123 FWRITE(atm->clk, double,
7124 (size_t) ctl->ncl,
7125 out);
7126 }
7127 if (ctl->nsf > 0) {
7128 FWRITE(&atm->sft, double,
7129 1,
7130 out);
7131 FWRITE(atm->sfeps, double,
7132 (size_t) ctl->nsf,
7133 out);
7134 }
7135
7136 /* Close file... */
7137 fclose(out);
7138}
#define FWRITE(ptr, type, size, out)
Write binary data to a file.
Definition: jurassic.h:521

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

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

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

7328 {
7329
7330 FILE *out;
7331
7332 /* Write info... */
7333 LOG(1, "Write RFM data: %s", filename);
7334
7335 /* Create file... */
7336 if (!(out = fopen(filename, "w")))
7337 ERRMSG("Cannot create file!");
7338
7339 /* Write data... */
7340 fprintf(out, "%d\n", atm->np);
7341 fprintf(out, "*HGT [km]\n");
7342 for (int ip = 0; ip < atm->np; ip++)
7343 fprintf(out, "%g\n", atm->z[ip]);
7344 fprintf(out, "*PRE [mb]\n");
7345 for (int ip = 0; ip < atm->np; ip++)
7346 fprintf(out, "%g\n", atm->p[ip]);
7347 fprintf(out, "*TEM [K]\n");
7348 for (int ip = 0; ip < atm->np; ip++)
7349 fprintf(out, "%g\n", atm->t[ip]);
7350 for (int ig = 0; ig < ctl->ng; ig++) {
7351 fprintf(out, "*%s [ppmv]\n", ctl->emitter[ig]);
7352 for (int ip = 0; ip < atm->np; ip++)
7353 fprintf(out, "%g\n", atm->q[ig][ip] * 1e6);
7354 }
7355 fprintf(out, "*END\n");
7356
7357 /* Close file... */
7358 fclose(out);
7359}

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

7372 {
7373
7374 FILE *out;
7375
7376 char file[LEN], quantity[LEN];
7377
7378 int *cida, *ciqa, *cipa, *cira, *rida, *riqa, *ripa, *rira;
7379
7380 size_t i, j, nc, nr;
7381
7382 /* Check output flag... */
7383 if (!ctl->write_matrix)
7384 return;
7385
7386 /* Allocate... */
7387 ALLOC(cida, int,
7388 M);
7389 ALLOC(ciqa, int,
7390 N);
7391 ALLOC(cipa, int,
7392 N);
7393 ALLOC(cira, int,
7394 M);
7395 ALLOC(rida, int,
7396 M);
7397 ALLOC(riqa, int,
7398 N);
7399 ALLOC(ripa, int,
7400 N);
7401 ALLOC(rira, int,
7402 M);
7403
7404 /* Set filename... */
7405 if (dirname != NULL)
7406 sprintf(file, "%s/%s", dirname, filename);
7407 else
7408 sprintf(file, "%s", filename);
7409
7410 /* Write info... */
7411 LOG(1, "Write matrix: %s", file);
7412
7413 /* Create file... */
7414 if (!(out = fopen(file, "w")))
7415 ERRMSG("Cannot create file!");
7416
7417 /* Write header (row space)... */
7418 if (rowspace[0] == 'y') {
7419
7420 fprintf(out,
7421 "# $1 = Row: index (measurement space)\n"
7422 "# $2 = Row: channel wavenumber [cm^-1]\n"
7423 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
7424 "# $4 = Row: view point altitude [km]\n"
7425 "# $5 = Row: view point longitude [deg]\n"
7426 "# $6 = Row: view point latitude [deg]\n");
7427
7428 /* Get number of rows... */
7429 nr = obs2y(ctl, obs, NULL, rida, rira);
7430
7431 } else {
7432
7433 fprintf(out,
7434 "# $1 = Row: index (state space)\n"
7435 "# $2 = Row: name of quantity\n"
7436 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
7437 "# $4 = Row: altitude [km]\n"
7438 "# $5 = Row: longitude [deg]\n" "# $6 = Row: latitude [deg]\n");
7439
7440 /* Get number of rows... */
7441 nr = atm2x(ctl, atm, NULL, riqa, ripa);
7442 }
7443
7444 /* Write header (column space)... */
7445 if (colspace[0] == 'y') {
7446
7447 fprintf(out,
7448 "# $7 = Col: index (measurement space)\n"
7449 "# $8 = Col: channel wavenumber [cm^-1]\n"
7450 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
7451 "# $10 = Col: view point altitude [km]\n"
7452 "# $11 = Col: view point longitude [deg]\n"
7453 "# $12 = Col: view point latitude [deg]\n");
7454
7455 /* Get number of columns... */
7456 nc = obs2y(ctl, obs, NULL, cida, cira);
7457
7458 } else {
7459
7460 fprintf(out,
7461 "# $7 = Col: index (state space)\n"
7462 "# $8 = Col: name of quantity\n"
7463 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
7464 "# $10 = Col: altitude [km]\n"
7465 "# $11 = Col: longitude [deg]\n" "# $12 = Col: latitude [deg]\n");
7466
7467 /* Get number of columns... */
7468 nc = atm2x(ctl, atm, NULL, ciqa, cipa);
7469 }
7470
7471 /* Write header entry... */
7472 fprintf(out, "# $13 = Matrix element\n\n");
7473
7474 /* Write matrix data... */
7475 i = j = 0;
7476 while (i < nr && j < nc) {
7477
7478 /* Write info about the row... */
7479 if (rowspace[0] == 'y')
7480 fprintf(out, "%d %.4f %.2f %g %g %g",
7481 (int) i, ctl->nu[rida[i]],
7482 obs->time[rira[i]], obs->vpz[rira[i]],
7483 obs->vplon[rira[i]], obs->vplat[rira[i]]);
7484 else {
7485 idx2name(ctl, riqa[i], quantity);
7486 fprintf(out, "%d %s %.2f %g %g %g", (int) i, quantity,
7487 atm->time[ripa[i]], atm->z[ripa[i]],
7488 atm->lon[ripa[i]], atm->lat[ripa[i]]);
7489 }
7490
7491 /* Write info about the column... */
7492 if (colspace[0] == 'y')
7493 fprintf(out, " %d %.4f %.2f %g %g %g",
7494 (int) j, ctl->nu[cida[j]],
7495 obs->time[cira[j]], obs->vpz[cira[j]],
7496 obs->vplon[cira[j]], obs->vplat[cira[j]]);
7497 else {
7498 idx2name(ctl, ciqa[j], quantity);
7499 fprintf(out, " %d %s %.2f %g %g %g", (int) j, quantity,
7500 atm->time[cipa[j]], atm->z[cipa[j]],
7501 atm->lon[cipa[j]], atm->lat[cipa[j]]);
7502 }
7503
7504 /* Write matrix entry... */
7505 fprintf(out, " %g\n", gsl_matrix_get(matrix, i, j));
7506
7507 /* Set matrix indices... */
7508 if (sort[0] == 'r') {
7509 j++;
7510 if (j >= nc) {
7511 j = 0;
7512 i++;
7513 fprintf(out, "\n");
7514 }
7515 } else {
7516 i++;
7517 if (i >= nr) {
7518 i = 0;
7519 j++;
7520 fprintf(out, "\n");
7521 }
7522 }
7523 }
7524
7525 /* Close file... */
7526 fclose(out);
7527
7528 /* Free... */
7529 free(cida);
7530 free(ciqa);
7531 free(cipa);
7532 free(cira);
7533 free(rida);
7534 free(riqa);
7535 free(ripa);
7536 free(rira);
7537}
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 7541 of file jurassic.c.

7545 {
7546
7547 char file[LEN];
7548
7549 /* Set filename... */
7550 if (dirname != NULL)
7551 sprintf(file, "%s/%s", dirname, filename);
7552 else
7553 sprintf(file, "%s", filename);
7554
7555 /* Write info... */
7556 LOG(1, "Write observation data: %s", file);
7557
7558 /* Write ASCII data... */
7559 if (ctl->obsfmt == 1)
7560 write_obs_asc(file, ctl, obs);
7561
7562 /* Write binary data... */
7563 else if (ctl->obsfmt == 2)
7564 write_obs_bin(file, ctl, obs);
7565
7566 /* Write netCDF data... */
7567 else if (ctl->obsfmt == 3)
7568 write_obs_nc(file, ctl, obs, 0);
7569
7570 /* Write info... */
7571 double mini, maxi;
7572 LOG(2, "Number of ray paths: %d", obs->nr);
7573 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
7574 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
7575 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
7576 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
7577 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
7578 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
7579 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
7580 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
7581 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
7582 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
7583 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
7584 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
7585 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
7586 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
7587 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
7588 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
7589 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
7590 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
7591 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
7592 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
7593 for (int id = 0; id < ctl->nd; id++) {
7594 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
7595 if (ctl->write_bbt) {
7596 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
7597 ctl->nu[id], mini, maxi);
7598 } else {
7599 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
7600 ctl->nu[id], mini, maxi);
7601 }
7602 }
7603 for (int id = 0; id < ctl->nd; id++) {
7604 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
7605 if (ctl->write_bbt) {
7606 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
7607 ctl->nu[id], mini, maxi);
7608 }
7609 }
7610}
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:7614
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:7738
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:7670
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 7614 of file jurassic.c.

7617 {
7618
7619 int n = 10;
7620
7621 /* Create file... */
7622 FILE *out;
7623 if (!(out = fopen(filename, "w")))
7624 ERRMSG("Cannot create file!");
7625
7626 /* Write header... */
7627 fprintf(out,
7628 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
7629 "# $2 = observer altitude [km]\n"
7630 "# $3 = observer longitude [deg]\n"
7631 "# $4 = observer latitude [deg]\n"
7632 "# $5 = view point altitude [km]\n"
7633 "# $6 = view point longitude [deg]\n"
7634 "# $7 = view point latitude [deg]\n"
7635 "# $8 = tangent point altitude [km]\n"
7636 "# $9 = tangent point longitude [deg]\n"
7637 "# $10 = tangent point latitude [deg]\n");
7638 for (int id = 0; id < ctl->nd; id++)
7639 if (ctl->write_bbt)
7640 fprintf(out, "# $%d = brightness temperature (%.4f cm^-1) [K]\n",
7641 ++n, ctl->nu[id]);
7642 else
7643 fprintf(out, "# $%d = radiance (%.4f cm^-1) [W/(m^2 sr cm^-1)]\n",
7644 ++n, ctl->nu[id]);
7645 for (int id = 0; id < ctl->nd; id++)
7646 fprintf(out, "# $%d = transmittance (%.4f cm^-1) [-]\n", ++n,
7647 ctl->nu[id]);
7648
7649 /* Write data... */
7650 for (int ir = 0; ir < obs->nr; ir++) {
7651 if (ir == 0 || obs->time[ir] != obs->time[ir - 1])
7652 fprintf(out, "\n");
7653 fprintf(out, "%.2f %g %g %g %g %g %g %g %g %g", obs->time[ir],
7654 obs->obsz[ir], obs->obslon[ir], obs->obslat[ir],
7655 obs->vpz[ir], obs->vplon[ir], obs->vplat[ir],
7656 obs->tpz[ir], obs->tplon[ir], obs->tplat[ir]);
7657 for (int id = 0; id < ctl->nd; id++)
7658 fprintf(out, " %g", obs->rad[id][ir]);
7659 for (int id = 0; id < ctl->nd; id++)
7660 fprintf(out, " %g", obs->tau[id][ir]);
7661 fprintf(out, "\n");
7662 }
7663
7664 /* Close file... */
7665 fclose(out);
7666}

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

7673 {
7674
7675 /* Create file... */
7676 FILE *out;
7677 if (!(out = fopen(filename, "w")))
7678 ERRMSG("Cannot create file!");
7679
7680 /* Write header... */
7681 FWRITE("OBS1", char,
7682 4,
7683 out);
7684 FWRITE(&ctl->nd, int,
7685 1,
7686 out);
7687
7688 /* Write data... */
7689 size_t nr = (size_t) obs->nr;
7690 FWRITE(&nr, size_t,
7691 1,
7692 out);
7693 FWRITE(obs->time, double,
7694 nr,
7695 out);
7696 FWRITE(obs->obsz, double,
7697 nr,
7698 out);
7699 FWRITE(obs->obslon, double,
7700 nr,
7701 out);
7702 FWRITE(obs->obslat, double,
7703 nr,
7704 out);
7705 FWRITE(obs->vpz, double,
7706 nr,
7707 out);
7708 FWRITE(obs->vplon, double,
7709 nr,
7710 out);
7711 FWRITE(obs->vplat, double,
7712 nr,
7713 out);
7714 FWRITE(obs->tpz, double,
7715 nr,
7716 out);
7717 FWRITE(obs->tplon, double,
7718 nr,
7719 out);
7720 FWRITE(obs->tplat, double,
7721 nr,
7722 out);
7723 for (int id = 0; id < ctl->nd; id++)
7724 FWRITE(obs->rad[id], double,
7725 nr,
7726 out);
7727 for (int id = 0; id < ctl->nd; id++)
7728 FWRITE(obs->tau[id], double,
7729 nr,
7730 out);
7731
7732 /* Close file... */
7733 fclose(out);
7734}

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

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

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

7917 {
7918
7919 FILE *out;
7920
7921 /* Write info... */
7922 LOG(1, "Write shape function: %s", filename);
7923
7924 /* Create file... */
7925 if (!(out = fopen(filename, "w")))
7926 ERRMSG("Cannot create file!");
7927
7928 /* Write header... */
7929 fprintf(out,
7930 "# $1 = shape function x-value [-]\n"
7931 "# $2 = shape function y-value [-]\n\n");
7932
7933 /* Write data... */
7934 for (int i = 0; i < n; i++)
7935 fprintf(out, "%.10g %.10g\n", x[i], y[i]);
7936
7937 /* Close file... */
7938 fclose(out);
7939}

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

7948 {
7949
7950 static atm_t atm_aux;
7951
7952 char filename[LEN];
7953
7954 /* Get sizes... */
7955 const size_t n = s->size1;
7956
7957 /* Allocate... */
7958 gsl_vector *x_aux = gsl_vector_alloc(n);
7959
7960 /* Compute standard deviation... */
7961 for (size_t i = 0; i < n; i++)
7962 gsl_vector_set(x_aux, i, sqrt(gsl_matrix_get(s, i, i)));
7963
7964 /* Write to disk... */
7965 copy_atm(ctl, &atm_aux, atm, 1);
7966 x2atm(ctl, x_aux, &atm_aux);
7967 sprintf(filename, "atm_err_%s.tab", quantity);
7968 write_atm(ret->dir, filename, ctl, &atm_aux);
7969
7970 /* Free... */
7971 gsl_vector_free(x_aux);
7972}
Here is the call graph for this function:

◆ write_tbl()

void write_tbl ( const ctl_t ctl,
const tbl_t tbl 
)

Write emissivity lookup tables to disk.

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

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

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

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

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

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

Definition at line 7976 of file jurassic.c.

7978 {
7979
7980 /* Loop over emitters and detectors... */
7981 for (int ig = 0; ig < ctl->ng; ig++)
7982 for (int id = 0; id < ctl->nd; id++) {
7983
7984 /* Skip empty tables... */
7985 if (tbl->np[id][ig] <= 0) {
7986 WARN("Skip writing empty emissivity table: emitter=%s, nu=%.4f",
7987 ctl->emitter[ig], ctl->nu[id]);
7988 continue;
7989 }
7990
7991 /* Write ASCII look-up tables... */
7992 if (ctl->tblfmt == 1)
7993 write_tbl_asc(ctl, tbl, id, ig);
7994
7995 /* Write binary look-up tables... */
7996 else if (ctl->tblfmt == 2)
7997 write_tbl_bin(ctl, tbl, id, ig);
7998
7999 /* Write netCDF look-up tables... */
8000 else if (ctl->tblfmt == 3)
8001 write_tbl_nc(ctl, tbl, id, ig);
8002
8003 /* Write info... */
8004 TBL_LOG(tbl, id, ig);
8005 }
8006
8007 /* Write filter functions... */
8008 if (ctl->tblfmt == 1)
8009 for (int id = 0; id < ctl->nd; id++) {
8010 char filename[2 * LEN];
8011 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
8012 write_shape(filename, tbl->filt_nu[id], tbl->filt_f[id],
8013 tbl->filt_n[id]);
8014 }
8015}
void write_tbl_asc(const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
Write one emissivity lookup table in human-readable ASCII format.
Definition: jurassic.c:8019
void write_tbl_nc(const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
Write one packed lookup table to a NetCDF file.
Definition: jurassic.c:8103
void write_tbl_bin(const ctl_t *ctl, const tbl_t *tbl, const int id, const int ig)
Write one emissivity lookup table in compact binary format.
Definition: jurassic.c:8061
void write_shape(const char *filename, const double *x, const double *y, const int n)
Write tabulated shape function data to a text file.
Definition: jurassic.c:7913
Here is the call graph for this function:

◆ write_tbl_asc()

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

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

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

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

The ASCII file contains four columns:

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

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

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

Definition at line 8019 of file jurassic.c.

8023 {
8024
8025 /* Set filename... */
8026 char filename[2 * LEN];
8027 sprintf(filename, "%s_%.4f_%s.tab", ctl->tblbase,
8028 ctl->nu[id], ctl->emitter[ig]);
8029
8030 /* Create file... */
8031 FILE *out;
8032 if (!(out = fopen(filename, "w"))) {
8033 ERRMSG("Cannot create emissivity table: %s", filename);
8034 } else
8035 LOG(1, "Write emissivity table: %s", filename);
8036
8037 /* Write header... */
8038 fprintf(out,
8039 "# $1 = pressure [hPa]\n"
8040 "# $2 = temperature [K]\n"
8041 "# $3 = column density [molecules/cm^2]\n"
8042 "# $4 = emissivity [-]\n");
8043
8044 /* Save table file... */
8045 for (int ip = 0; ip < tbl->np[id][ig]; ip++)
8046 for (int it = 0; it < tbl->nt[id][ig][ip]; it++) {
8047 fprintf(out, "\n");
8048 for (int iu = 0; iu < tbl->nu[id][ig][ip][it]; iu++)
8049 fprintf(out, "%g %g %e %e\n",
8050 tbl->p[id][ig][ip], tbl->t[id][ig][ip][it],
8051 exp(tbl->logu[id][ig][ip][it][iu]),
8052 exp(tbl->logeps[id][ig][ip][it][iu]));
8053 }
8054
8055 /* Close file... */
8056 fclose(out);
8057}

◆ write_tbl_bin()

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

Write one emissivity lookup table in compact binary format.

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

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

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

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

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

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

Definition at line 8061 of file jurassic.c.

8065 {
8066
8067 /* Set filename... */
8068 char filename[2 * LEN];
8069 sprintf(filename, "%s_%.4f_%s.bin",
8070 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
8071
8072 /* Create file... */
8073 FILE *out;
8074 if (!(out = fopen(filename, "w"))) {
8075 ERRMSG("Cannot create emissivity table: %s", filename);
8076 } else
8077 LOG(1, "Write emissivity table: %s", filename);
8078
8079 /* Pack... */
8080 size_t used = 0;
8081 const size_t need = tbl_packed_size(tbl, id, ig);
8082 uint8_t *work = NULL;
8083 ALLOC(work, uint8_t, need);
8084 tbl_pack(tbl, id, ig, work, &used);
8085 if (used != need)
8086 ERRMSG("Internal error: packed size mismatch!");
8087
8088 /* Write length and packed blob... */
8089 FWRITE(&used, size_t,
8090 1,
8091 out);
8092 FWRITE(work, uint8_t, used, out);
8093
8094 /* Close file... */
8095 fclose(out);
8096
8097 /* Free... */
8098 free(work);
8099}
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:6687
size_t tbl_packed_size(const tbl_t *tbl, int id, int ig)
Compute required buffer size (in bytes) for tbl_pack().
Definition: jurassic.c:6741
Here is the call graph for this function:

◆ write_tbl_nc()

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

Write one packed lookup table to a NetCDF file.

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

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

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

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

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

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

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

Definition at line 8103 of file jurassic.c.

8107 {
8108
8109 /* Set filename... */
8110 char filename[2 * LEN];
8111 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
8112
8113 /* Open or create file... */
8114 int ncid;
8115 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
8116 if (nc_create(filename, NC_NETCDF4 | NC_CLOBBER, &ncid) != NC_NOERR)
8117 ERRMSG("Cannot open or create emissivity table: %s", filename);
8118 NC_PUT_ATT_GLOBAL("format_version", "1");
8119 NC_PUT_ATT_GLOBAL("emitter", ctl->emitter[ig]);
8120 NC(nc_enddef(ncid));
8121 }
8122
8123 /* Set variable and dimension name... */
8124 char varname[LEN], dimname[LEN];
8125 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
8126 sprintf(dimname, "len_%.4f", ctl->nu[id]);
8127
8128 /* Write info... */
8129 LOG(1, "Write emissivity table: %s in %s", varname, filename);
8130
8131 /* Allocate work space... */
8132 size_t used = 0;
8133 const size_t need = tbl_packed_size(tbl, id, ig);
8134 uint8_t *work = NULL;
8135 ALLOC(work, uint8_t, need);
8136
8137 /* Pack table... */
8138 tbl_pack(tbl, id, ig, work, &used);
8139 if (used != need)
8140 ERRMSG("Internal error: packed size mismatch!");
8141
8142 /* Prevent overwrite... */
8143 int tmp;
8144 if (nc_inq_varid(ncid, varname, &tmp) == NC_NOERR)
8145 ERRMSG("Table already present!");
8146
8147 /* Add dimension and variable... */
8148 int dimid, varid;
8149 NC(nc_redef(ncid));
8150 NC(nc_def_dim(ncid, dimname, used, &dimid));
8151 int dimids[1] = { dimid };
8152 NC_DEF_VAR(varname, NC_UBYTE, 1, dimids,
8153 "Packed lookup table blob", "1", 0, 0);
8154 NC(nc_enddef(ncid));
8155
8156 /* Write data... */
8157 NC(nc_put_var_uchar(ncid, varid, (const unsigned char *) work));
8158
8159 /* Free... */
8160 free(work);
8161
8162 /* Close file... */
8163 NC(nc_close(ncid));
8164}
#define NC_PUT_ATT_GLOBAL(attname, text)
Add a global text attribute to a NetCDF file.
Definition: jurassic.h:839
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 8168 of file jurassic.c.

8171 {
8172
8173 size_t n = 0;
8174
8175 /* Get pressure... */
8176 for (int ip = 0; ip < atm->np; ip++)
8177 if (atm->z[ip] >= ctl->retp_zmin && atm->z[ip] <= ctl->retp_zmax)
8178 x2atm_help(&atm->p[ip], x, &n);
8179
8180 /* Get temperature... */
8181 for (int ip = 0; ip < atm->np; ip++)
8182 if (atm->z[ip] >= ctl->rett_zmin && atm->z[ip] <= ctl->rett_zmax)
8183 x2atm_help(&atm->t[ip], x, &n);
8184
8185 /* Get volume mixing ratio... */
8186 for (int ig = 0; ig < ctl->ng; ig++)
8187 for (int ip = 0; ip < atm->np; ip++)
8188 if (atm->z[ip] >= ctl->retq_zmin[ig]
8189 && atm->z[ip] <= ctl->retq_zmax[ig])
8190 x2atm_help(&atm->q[ig][ip], x, &n);
8191
8192 /* Get extinction... */
8193 for (int iw = 0; iw < ctl->nw; iw++)
8194 for (int ip = 0; ip < atm->np; ip++)
8195 if (atm->z[ip] >= ctl->retk_zmin[iw]
8196 && atm->z[ip] <= ctl->retk_zmax[iw])
8197 x2atm_help(&atm->k[iw][ip], x, &n);
8198
8199 /* Get cloud data... */
8200 if (ctl->ret_clz)
8201 x2atm_help(&atm->clz, x, &n);
8202 if (ctl->ret_cldz)
8203 x2atm_help(&atm->cldz, x, &n);
8204 if (ctl->ret_clk)
8205 for (int icl = 0; icl < ctl->ncl; icl++)
8206 x2atm_help(&atm->clk[icl], x, &n);
8207
8208 /* Get surface data... */
8209 if (ctl->ret_sft)
8210 x2atm_help(&atm->sft, x, &n);
8211 if (ctl->ret_sfeps)
8212 for (int isf = 0; isf < ctl->nsf; isf++)
8213 x2atm_help(&atm->sfeps[isf], x, &n);
8214}
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:8218
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 8218 of file jurassic.c.

8221 {
8222
8223 /* Get state vector element... */
8224 *value = gsl_vector_get(x, *n);
8225 (*n)++;
8226}

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

8233 {
8234
8235 size_t m = 0;
8236
8237 /* Decompose measurement vector... */
8238 for (int ir = 0; ir < obs->nr; ir++)
8239 for (int id = 0; id < ctl->nd; id++)
8240 if (isfinite(obs->rad[id][ir])) {
8241 obs->rad[id][ir] = gsl_vector_get(y, m);
8242 m++;
8243 }
8244}