108#include <gsl/gsl_math.h>
109#include <gsl/gsl_blas.h>
110#include <gsl/gsl_linalg.h>
111#include <gsl/gsl_randist.h>
112#include <gsl/gsl_rng.h>
113#include <gsl/gsl_statistics.h>
128#define C1 1.19104259e-8
158#define KB 1.3806504e-23
168#define NA 6.02214199e23
277#define N ((2 + NG + NW) * NP + NCL + NSF + 3)
282#define NQ (5 + NG + NW + NCL + NSF)
322#define MAX_TABLES 10000
327#define RFMNPTS 10000000
341#define IDXQ(ig) (2 + (ig))
344#define IDXK(iw) (2 + (ctl->ng) + (iw))
347#define IDXCLZ (2 + (ctl->ng) + (ctl->nw))
350#define IDXCLDZ (3 + (ctl->ng) + (ctl->nw))
353#define IDXCLK(icl) (4 + (ctl->ng) + (ctl->nw) + (icl))
356#define IDXSFT (4 + (ctl->ng) + (ctl->nw) + (ctl->ncl))
359#define IDXSFEPS(isf) (5 + (ctl->ng) + (ctl->nw) + (ctl->ncl) + (isf))
382#define ALLOC(ptr, type, n) \
383 if((ptr=calloc((size_t)(n), sizeof(type)))==NULL) \
384 ERRMSG("Out of memory!");
412#define BRIGHT(rad, nu) \
413 (C2 * (nu) / gsl_log1p(C1 * POW3(nu) / (rad)))
429#define DEG2RAD(deg) ((deg) * (M_PI / 180.0))
447#define DIST(a, b) sqrt(DIST2(a, b))
465 ((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])+(a[2]-b[2])*(a[2]-b[2]))
482#define DOTP(a, b) (a[0]*b[0]+a[1]*b[1]+a[2]*b[2])
502#define FREAD(ptr, type, size, out) { \
503 if(fread(ptr, sizeof(type), size, out)!=size) \
504 ERRMSG("Error while reading!"); \
525#define FWRITE(ptr, type, size, out) { \
526 if(fwrite(ptr, sizeof(type), size, out)!=size) \
527 ERRMSG("Error while writing!"); \
548#define LIN(x0, y0, x1, y1, x) \
549 ((y0)+((y1)-(y0))/((x1)-(x0))*((x)-(x0)))
569#define LOGX(x0, y0, x1, y1, x) \
570 (((x)/(x0)>0 && (x1)/(x0)>0) \
571 ? ((y0)+((y1)-(y0))*log((x)/(x0))/log((x1)/(x0))) \
572 : LIN(x0, y0, x1, y1, x))
592#define LOGY(x0, y0, x1, y1, x) \
594 ? ((y0)*exp(log((y1)/(y0))/((x1)-(x0))*((x)-(x0)))) \
595 : LIN(x0, y0, x1, y1, x))
613#define MAX(a,b) (((a)>(b))?(a):(b))
631#define MIN(a,b) (((a)<(b))?(a):(b))
662#define NEDT(t_bg, nesr, nu) \
663 (BRIGHT(PLANCK((t_bg), (nu)) + (nesr), (nu)) - (t_bg))
691#define NESR(t_bg, nedt, nu) \
692 (PLANCK((t_bg) + (nedt), (nu)) - PLANCK((t_bg), (nu)))
708#define NORM(a) sqrt(DOTP(a, a))
739#define PLANCK(T, nu) \
740 (C1 * POW3(nu) / gsl_expm1(C2 * (nu) / (T)))
753#define POW2(x) ((x)*(x))
766#define POW3(x) ((x)*(x)*(x))
782#define RAD2DEG(rad) ((rad) * (180.0 / M_PI))
798#define REFRAC(p, T) (7.753e-05 * (p) / (T))
813#define TIMER(name, mode) \
814 {timer(name, __FILE__, __func__, __LINE__, mode);}
834#define TOK(line, tok, format, var) { \
835 if(((tok)=strtok((line), " \t"))) { \
836 if(sscanf(tok, format, &(var))!=1) continue; \
837 } else ERRMSG("Error while reading!"); \
878#define LOG(level, ...) { \
881 if(level <= LOGLEV) { \
882 printf(__VA_ARGS__); \
916 printf("\nWarning (%s, %s, l%d): ", __FILE__, __func__, __LINE__); \
917 LOG(0, __VA_ARGS__); \
948#define ERRMSG(...) { \
949 printf("\nError (%s, %s, l%d): ", __FILE__, __func__, __LINE__); \
950 LOG(0, __VA_ARGS__); \
951 exit(EXIT_FAILURE); \
983#define PRINT(format, var) \
984 printf("Print (%s, %s, l%d): %s= "format"\n", \
985 __FILE__, __func__, __LINE__, #var, var);
1539 const gsl_matrix * avk);
1597 const gsl_matrix * avk,
1661 const int value_iqa,
1776 const gsl_vector * dx,
1777 const gsl_vector * dy,
1778 const gsl_matrix * s_a_inv,
1779 const gsl_vector * sig_eps_inv);
1899 const atm_t * atm_src,
1929 const obs_t * obs_src,
1953 const char *emitter);
2345 double tau_path[
ND][
NG],
2346 double tau_seg[
ND]);
2391 double tau_path[
ND][
NG],
2392 double tau_seg[
ND]);
2736 const gsl_matrix * a,
2737 const gsl_vector * b,
2738 const int transpose,
2858 const char *dirname,
2859 const char *filename,
2940 const char *dirname,
2941 const char *filename,
2942 gsl_matrix * matrix);
2981 const char *dirname,
2982 const char *filename,
3026 const char *basename,
3143 const char *filename,
3182 const char *filename,
3431 const char *varname,
3433 const char *defvalue,
3556 gsl_vector * sig_noise,
3557 gsl_vector * sig_formod,
3558 gsl_vector * sig_eps_inv);
3678 const double remain,
3773 const char *dirname,
3774 const char *filename,
3831 const char *filename,
3884 const char *dirname,
3885 const char *filename,
3887 const gsl_matrix * matrix,
3890 const char *rowspace,
3891 const char *colspace,
3952 const char *dirname,
3953 const char *filename,
3993 const char *filename,
4045 const char *quantity,
4049 const gsl_matrix * s);
4277 const gsl_vector * x,
4311 const gsl_vector * x,
4349 const gsl_vector * y,
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.
void read_tbl_bin(const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
Read a single binary emissivity lookup table.
#define LEN
Maximum length of ASCII data lines.
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.
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.
void read_matrix(const char *dirname, const char *filename, gsl_matrix *matrix)
Read a numerical matrix from an ASCII file.
void timer(const char *name, const char *file, const char *func, int line, int mode)
Simple wall-clock timer for runtime diagnostics.
void read_rfm_spec(const char *filename, double *nu, double *rad, int *npts)
Read a Reference Forward Model (RFM) ASCII spectrum.
double cos_sza(const double sec, const double lon, const double lat)
Calculates the cosine of the solar zenith angle.
void write_atm(const char *dirname, const char *filename, const ctl_t *ctl, const atm_t *atm)
Write atmospheric profile data to a text file.
int locate_reg(const double *xx, const int n, const double x)
Locate index for interpolation on a regular (uniform) grid.
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).
void formod_rfm(const ctl_t *ctl, const atm_t *atm, obs_t *obs)
Interface routine for the Reference Forward Model (RFM).
double ctmo2(const double nu, const double p, const double t)
Compute O₂ collision-induced absorption coefficient.
int write_tbl_gas_single(tbl_gas_t *g, const double freq, const tbl_t *tbl, const int id, const int ig)
Append or overwrite a single frequency-table block in a per-gas file.
void idx2name(const ctl_t *ctl, const int idx, char *quantity)
Convert a quantity index to a descriptive name string.
int read_tbl_gas_single(const tbl_gas_t *g, const double freq, tbl_t *tbl, const int id, const int ig)
Read one emissivity table block from a per-gas table file.
void read_ctl(int argc, char *argv[], ctl_t *ctl)
Read model control parameters from command-line and configuration input.
void formod_continua(const ctl_t *ctl, const los_t *los, const int ip, double *beta)
Compute total extinction including gaseous continua.
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.
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 .
int locate_irr(const double *xx, const int n, const double x)
Locate index for interpolation on an irregular grid.
void write_tbl_asc(const ctl_t *ctl, const tbl_t *tbl)
Write all lookup tables in human-readable ASCII format.
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.
void x2atm(const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
Map retrieval state vector back to atmospheric structure.
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.
double ctmh2o(const double nu, const double p, const double t, const double q, const double u)
Compute water vapor continuum (optical depth).
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).
void write_tbl_bin(const ctl_t *ctl, const tbl_t *tbl)
Write all lookup tables in compact binary format.
void write_atm_rfm(const char *filename, const ctl_t *ctl, const atm_t *atm)
Write atmospheric profile in RFM-compatible format.
#define ND
Maximum number of radiance channels.
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.
double intpol_tbl_u(const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double eps)
Interpolate column density from lookup tables as a function of emissivity.
double intpol_tbl_eps(const tbl_t *tbl, const int ig, const int id, const int ip, const int it, const double u)
Interpolate emissivity from lookup tables as a function of column density.
#define NSHAPE
Maximum number of shape function grid points.
void write_tbl(const ctl_t *ctl, const tbl_t *tbl)
Write all emissivity lookup tables in the format specified by the control structure.
void write_tbl_gas(const ctl_t *ctl, const tbl_t *tbl)
Write lookup tables into per-gas binary table files with indexed blocks.
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.
void read_tbl_gas(const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
Read one frequency block from a per-gas binary table file.
int find_emitter(const ctl_t *ctl, const char *emitter)
Find gas species index by name.
void tangent_point(const los_t *los, double *tpz, double *tplon, double *tplat)
Determine the tangent point along a line of sight (LOS).
#define TBLNU
Maximum number of column densities in emissivity tables.
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.
double ctmco2(const double nu, const double p, const double t, const double u)
Compute carbon dioxide continuum (optical depth).
void read_atm(const char *dirname, const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric profile data from an ASCII file.
void copy_obs(const ctl_t *ctl, obs_t *obs_dest, const obs_t *obs_src, const int init)
Copy or initialize observation geometry and radiance data.
void read_obs(const char *dirname, const char *filename, const ctl_t *ctl, obs_t *obs)
Read observation geometry and radiance data from an ASCII file.
void write_obs(const char *dirname, const char *filename, const ctl_t *ctl, const obs_t *obs)
Write observation geometry and radiance data to a text file.
#define TBLNT
Maximum number of temperatures in emissivity tables.
void x2atm_help(double *value, const gsl_vector *x, size_t *n)
Helper function to extract a single value from the retrieval state vector.
void cart2geo(const double *x, double *z, double *lon, double *lat)
Converts Cartesian coordinates to geographic coordinates.
#define NP
Maximum number of atmospheric data points.
void formod_fov(const ctl_t *ctl, obs_t *obs)
Apply field-of-view (FOV) convolution to modeled radiances.
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.
void init_srcfunc(const ctl_t *ctl, tbl_t *tbl)
Initialize the source-function (Planck radiance) lookup table.
void matrix_invert(gsl_matrix *a)
Invert a square matrix, optimized for diagonal or symmetric positive-definite matrices.
void read_ret(int argc, char *argv[], const ctl_t *ctl, ret_t *ret)
Read retrieval configuration and error parameters.
double scan_ctl(int argc, char *argv[], const char *varname, const int arridx, const char *defvalue, char *value)
Scan control file or command-line arguments for a configuration variable.
void write_shape(const char *filename, const double *x, const double *y, const int n)
Write tabulated shape function data to a text file.
void formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
Execute the selected forward model.
#define NG
Maximum number of emitters.
void read_tbl_asc(const ctl_t *ctl, tbl_t *tbl, const int id, const int ig)
Read a single ASCII emissivity lookup table.
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.
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.
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.
#define TBLNS
Maximum number of source function temperature levels.
tbl_t * read_tbl(const ctl_t *ctl)
Read all emissivity lookup tables for all gases and frequencies.
double sza(double sec, double lon, double lat)
Compute the solar zenith angle for a given time and location.
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.
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.
void y2obs(const ctl_t *ctl, const gsl_vector *y, obs_t *obs)
Copy elements from the measurement vector y into the observation structure.
void hydrostatic(const ctl_t *ctl, atm_t *atm)
Adjust pressure profile using the hydrostatic equation.
void read_shape(const char *filename, double *x, double *y, int *n)
Read a two-column shape function from an ASCII file.
double ctmn2(const double nu, const double p, const double t)
Compute N₂ collision-induced absorption coefficient.
int read_tbl_gas_close(tbl_gas_t *g)
Close a per-gas binary table file and optionally rewrite metadata.
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.
int read_tbl_gas_open(const char *path, tbl_gas_t *g)
Open a per-gas binary table file for reading and writing.
#define TBLNP
Maximum number of pressure levels in emissivity tables.
void climatology(const ctl_t *ctl, atm_t *atm)
Initializes atmospheric climatology profiles.
void geo2cart(const double z, const double lon, const double lat, double *x)
Converts geographic coordinates (longitude, latitude, altitude) to Cartesian coordinates.
#define NSF
Maximum number of surface layer spectral grid points.
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.
#define NCL
Maximum number of cloud layer spectral grid points.
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.
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.
#define NLOS
Maximum number of LOS points.
#define NR
Maximum number of ray paths.
int locate_tbl(const float *xx, const int n, const double x)
Locate index for interpolation within emissivity table grids.
#define NW
Maximum number of spectral windows.
int write_tbl_gas_create(const char *path)
Create a new per-gas table file with an empty index.
Atmospheric profile data.
double clz
Cloud layer height [km].
int np
Number of data points.
double cldz
Cloud layer depth [km].
double sft
Surface temperature [K].
int write_matrix
Write matrix file (0=no, 1=yes).
int nw
Number of spectral windows.
double retp_zmin
Minimum altitude for pressure retrieval [km].
int ig_co2
Emitter index of CO2.
double hydz
Reference height for hydrostatic pressure profile (-999 to skip) [km].
int ctm_co2
Compute CO2 continuum (0=no, 1=yes).
double rett_zmax
Maximum altitude for temperature retrieval [km].
int ret_sfeps
Retrieve surface layer emissivity (0=no, 1=yes).
int ret_sft
Retrieve surface layer temperature (0=no, 1=yes).
int ret_clz
Retrieve cloud layer height (0=no, 1=yes).
int ctm_n2
Compute N2 continuum (0=no, 1=yes).
int ctm_h2o
Compute H2O continuum (0=no, 1=yes).
int formod
Forward model (0=CGA, 1=EGA, 2=RFM).
int ng
Number of emitters.
int refrac
Take into account refractivity (0=no, 1=yes).
int ig_o2
Emitter index of O2.
double rett_zmin
Minimum altitude for temperature retrieval [km].
double sfsza
Solar zenith angle at the surface [deg] (-999=auto).
int nd
Number of radiance channels.
int fov_n
Field-of-view number of data points.
int sftype
Surface treatment (0=none, 1=emissions, 2=downward, 3=solar).
int ncl
Number of cloud layer spectral grid points.
int ig_n2
Emitter index of N2.
int ctm_o2
Compute O2 continuum (0=no, 1=yes).
int ret_clk
Retrieve cloud layer extinction (0=no, 1=yes).
int nsf
Number of surface layer spectral grid points.
double rayds
Maximum step length for raytracing [km].
int ret_cldz
Retrieve cloud layer depth (0=no, 1=yes).
int ig_h2o
Emitter index of H2O.
int tblfmt
Look-up table file format (1=ASCII, 2=binary).
double raydz
Vertical step length for raytracing [km].
int write_bbt
Use brightness temperature instead of radiance (0=no, 1=yes).
double retp_zmax
Maximum altitude for pressure retrieval [km].
double sft
Surface temperature [K].
int np
Number of LOS points.
Observation geometry and radiance data.
int nr
Number of ray paths.
Retrieval control parameters.
double err_press_cz
Vertical correlation length for pressure error [km].
double err_press
Pressure error [%].
int err_ana
Carry out error analysis (0=no, 1=yes).
double err_temp_cz
Vertical correlation length for temperature error [km].
double conv_dmin
Minimum normalized step size in state space.
double err_temp
Temperature error [K].
double err_clz
Cloud height error [km].
double err_sft
Surface temperature error [K].
double err_temp_ch
Horizontal correlation length for temperature error [km].
int kernel_recomp
Re-computation of kernel matrix (number of iterations).
int conv_itmax
Maximum number of iterations.
double err_cldz
Cloud depth error [km].
double err_press_ch
Horizontal correlation length for pressure error [km].
On-disk index entry describing one frequency table block in a gas file.
int64_t offset
Byte offset in file where the serialized block begins.
int64_t size
Size of the serialized block (in bytes).
double freq
Frequency identifier ν_j for this table block.
In-memory representation of an open per-gas lookup-table file.
FILE * fp
Open file handle ("rb+"), NULL if not open.
int32_t ntables
Number of index entries currently in use.
tbl_gas_index_t * index
In-memory index table of length MAX_TABLES.
Emissivity look-up tables.