Analyze averaging kernel (AVK) matrix for retrieval diagnostics.
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.
The averaging kernel matrix \(\mathbf{A}\) describes the sensitivity of the retrieved state \(\hat{x}\) to the true state \(x\):
where \(x_a\) is the a priori state.
This function separates and evaluates:
@references Rodgers, C. D. (2000). Inverse Methods for Atmospheric Sounding: Theory and Practice. World Scientific.
#ifndef JURASSIC_H
#define JURASSIC_H
#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 <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifndef C1
#define C1 1.19104259e-8
#endif
#ifndef C2
#define C2 1.43877506
#endif
#ifndef EPSMIN
#define EPSMIN 0
#endif
#ifndef EPSMAX
#define EPSMAX 1
#endif
#ifndef G0
#define G0 9.80665
#endif
#ifndef H0
#define H0 7.0
#endif
#ifndef KB
#define KB 1.3806504e-23
#endif
#ifndef ME
#define ME 5.976e24
#endif
#ifndef NA
#define NA 6.02214199e23
#endif
#ifndef N2
#define N2 0.78084
#endif
#ifndef O2
#define O2 0.20946
#endif
#ifndef P0
#define P0 1013.25
#endif
#ifndef RE
#define RE 6367.421
#endif
#ifndef RI
#define RI 8.3144598
#endif
#ifndef T0
#define T0 273.15
#endif
#ifndef TMIN
#define TMIN 100.
#endif
#ifndef TMAX
#define TMAX 400.
#endif
#ifndef TSUN
#define TSUN 5780.
#endif
#ifndef UMIN
#define UMIN 0
#endif
#ifndef UMAX
#define UMAX 1e30
#endif
#ifndef NCL
#define NCL 8
#endif
#ifndef ND
#define ND 128
#endif
#ifndef NG
#define NG 8
#endif
#ifndef NP
#define NP 256
#endif
#ifndef NR
#define NR 256
#endif
#ifndef NSF
#define NSF 8
#endif
#ifndef NW
#define NW 4
#endif
#ifndef LEN
#define LEN 10000
#endif
#ifndef M
#define M (NR*ND)
#endif
#ifndef N
#define N ((2 + NG + NW) * NP + NCL + NSF + 3)
#endif
#ifndef NQ
#define NQ (5 + NG + NW + NCL + NSF)
#endif
#ifndef NLOS
#define NLOS 4096
#endif
#ifndef NSHAPE
#define NSHAPE 20000
#endif
#ifndef NFOV
#define NFOV 5
#endif
#ifndef TBLNP
#define TBLNP 41
#endif
#ifndef TBLNT
#define TBLNT 30
#endif
#ifndef TBLNU
#define TBLNU 320
#endif
#ifndef TBLNS
#define TBLNS 1200
#endif
#ifndef RFMNPTS
#define RFMNPTS 10000000
#endif
#define IDXP 0
#define IDXT 1
#define IDXQ(ig) (2 + (ig))
#define IDXK(iw) (2 + (ctl->ng) + (iw))
#define IDXCLZ (2 + (ctl->ng) + (ctl->nw))
#define IDXCLDZ (3 + (ctl->ng) + (ctl->nw))
#define IDXCLK(icl) (4 + (ctl->ng) + (ctl->nw) + (icl))
#define IDXSFT (4 + (ctl->ng) + (ctl->nw) + (ctl->ncl))
#define IDXSFEPS(isf) (5 + (ctl->ng) + (ctl->nw) + (ctl->ncl) + (isf))
#define ALLOC(ptr, type, n) \
if((ptr=malloc((size_t)(n)*sizeof(type)))==NULL) \
ERRMSG("Out of memory!");
#define BRIGHT(rad, nu) \
(C2 * (nu) / gsl_log1p(C1 * POW3(nu) / (rad)))
#define DEG2RAD(deg) ((deg) * (M_PI / 180.0))
#define DIST(a, b) sqrt(DIST2(a, b))
#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]))
#define DOTP(a, b) (a[0]*b[0]+a[1]*b[1]+a[2]*b[2])
#define FREAD(ptr, type, size, out) { \
if(fread(ptr, sizeof(type), size, out)!=size) \
ERRMSG("Error while reading!"); \
}
#define FWRITE(ptr, type, size, out) { \
if(fwrite(ptr, sizeof(type), size, out)!=size) \
ERRMSG("Error while writing!"); \
}
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define LIN(x0, y0, x1, y1, x) \
((y0)+((y1)-(y0))/((x1)-(x0))*((x)-(x0)))
#define LOGX(x0, y0, x1, y1, x) \
(((x)/(x0)>0 && (x1)/(x0)>0) \
? ((y0)+((y1)-(y0))*log((x)/(x0))/log((x1)/(x0))) \
: LIN(x0, y0, x1, y1, x))
#define LOGY(x0, y0, x1, y1, x) \
(((y1)/(y0)>0) \
? ((y0)*exp(log((y1)/(y0))/((x1)-(x0))*((x)-(x0)))) \
: LIN(x0, y0, x1, y1, x))
#define NORM(a) sqrt(DOTP(a, a))
#define PLANCK(T, nu) \
(C1 * POW3(nu) / gsl_expm1(C2 * (nu) / (T)))
#define POW2(x) ((x)*(x))
#define POW3(x) ((x)*(x)*(x))
#define RAD2DEG(rad) ((rad) * (180.0 / M_PI))
#define REFRAC(p, T) (7.753e-05 * (p) / (T))
#define TIMER(name, mode) \
{timer(name, __FILE__, __func__, __LINE__, mode);}
#define TOK(line, tok, format, var) { \
if(((tok)=strtok((line), " \t"))) { \
if(sscanf(tok, format, &(var))!=1) continue; \
} else ERRMSG("Error while reading!"); \
}
#ifndef LOGLEV
#define LOGLEV 2
#endif
#define LOG(level, ...) { \
if(level >= 2) \
printf(" "); \
if(level <= LOGLEV) { \
printf(__VA_ARGS__); \
printf("\n"); \
} \
}
#define WARN(...) { \
printf("\nWarning (%s, %s, l%d): ", __FILE__, __func__, __LINE__); \
LOG(0, __VA_ARGS__); \
}
#define ERRMSG(...) { \
printf("\nError (%s, %s, l%d): ", __FILE__, __func__, __LINE__); \
LOG(0, __VA_ARGS__); \
exit(EXIT_FAILURE); \
}
#define PRINT(format, var) \
printf("Print (%s, %s, l%d): %s= "format"\n", \
__FILE__, __func__, __LINE__, #var, var);
typedef struct {
int np;
double clz;
double cldz;
double sft;
typedef struct {
int ng;
int ig_co2;
int ig_h2o;
int ig_n2;
int ig_o2;
int nd;
int nw;
int ncl;
int nsf;
int sftype;
double sfsza;
int tblfmt;
double hydz;
int ctm_co2;
int ctm_h2o;
int ctm_n2;
int ctm_o2;
int refrac;
double rayds;
double raydz;
int fov_n;
double retp_zmin;
double retp_zmax;
double rett_zmin;
double rett_zmax;
int ret_clz;
int ret_cldz;
int ret_clk;
int ret_sft;
int ret_sfeps;
int write_bbt;
typedef struct {
int np;
double sft;
typedef struct {
int nr;
typedef struct {
int kernel_recomp;
int conv_itmax;
double conv_dmin;
int err_ana;
double err_press;
double err_press_cz;
double err_press_ch;
double err_temp;
double err_temp_cz;
double err_temp_ch;
double err_clz;
double err_cldz;
double err_sft;
typedef struct {
int *iqa,
int *ipa,
gsl_matrix * avk);
gsl_matrix * avk,
int iq,
int *ipa,
size_t *n0,
size_t *n1,
double *cont,
double *res);
gsl_vector * x,
int *iqa,
int *ipa);
const double value,
const int value_iqa,
const int value_ip,
gsl_vector * x,
int *iqa,
int *ipa,
size_t *n);
const double *x,
double *z,
double *lon,
double *lat);
gsl_vector * dx,
gsl_vector * dy,
gsl_matrix * s_a_inv,
gsl_vector * sig_eps_inv);
const double nu,
const double p,
const double t,
const double u);
const double nu,
const double p,
const double t,
const double q,
const double u);
const double nu,
const double p,
const double t);
const double nu,
const double p,
const double t);
const int init);
const int init);
const char *emitter);
const int ip,
double *beta);
const int ir);
const double t,
double *src);
const double z,
const double lon,
const double lat,
double *x);
const int idx,
char *quantity);
const double z,
double *p,
double *t,
double *q,
double *k);
const int ip,
const int ip,
const int ig,
const int id,
const int ip,
const int it,
const double u);
const int ig,
const int id,
const int ip,
const int it,
const double eps);
const double jsec,
int *year,
int *mon,
int *day,
int *hour,
int *min,
int *sec,
double *remain);
gsl_matrix * k);
const double *xx,
const int n,
const double x);
const double *xx,
const int n,
const double x);
const float *xx,
const int n,
const double x);
gsl_matrix * a);
gsl_matrix * a,
gsl_vector * b,
int transpose,
gsl_matrix * c);
gsl_vector * y,
int *ida,
int *ira);
const int ir);
const char *dirname,
const char *filename,
int argc,
char *argv[],
const char *dirname,
const char *filename,
gsl_matrix * matrix);
const char *dirname,
const char *filename,
const char *basename,
const double z,
double *nu,
double *f,
int n);
int argc,
char *argv[],
const char *filename,
double *nu,
double *rad,
int *npts);
const char *filename,
double *x,
double *y,
int *n);
int argc,
char *argv[],
const char *varname,
const int arridx,
const char *defvalue,
char *value);
int *iqa,
int *ipa,
gsl_matrix * s_a);
gsl_vector * sig_noise,
gsl_vector * sig_formod,
gsl_vector * sig_eps_inv);
double sec,
double lon,
double lat);
double *tpz,
double *tplon,
double *tplat);
const int year,
const int mon,
const int day,
const int hour,
const int min,
const int sec,
const double remain,
double *jsec);
const char *name,
const char *file,
const char *func,
int line,
int mode);
const char *dirname,
const char *filename,
const char *filename,
const char *dirname,
const char *filename,
const gsl_matrix * matrix,
const char *rowspace,
const char *colspace,
const char *sort);
const char *dirname,
const char *filename,
const char *filename,
const double *x,
const double *y,
const int n);
const char *quantity,
gsl_matrix * s);
const gsl_vector * x,
double *value,
const gsl_vector * x,
size_t *n);
const gsl_vector * y,
#endif
void matrix_product(gsl_matrix *a, gsl_vector *b, int transpose, gsl_matrix *c)
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)
void read_rfm_spec(const char *filename, double *nu, double *rad, int *npts)
Read a Reference Forward Model (RFM) ASCII spectrum.
void write_atm(const char *dirname, const char *filename, const ctl_t *ctl, const atm_t *atm)
void set_cov_apr(ret_t *ret, ctl_t *ctl, atm_t *atm, int *iqa, int *ipa, gsl_matrix *s_a)
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).
double read_obs_rfm(const char *basename, const double z, double *nu, double *f, int n)
Read and spectrally convolve an RFM output spectrum.
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.
void idx2name(const ctl_t *ctl, const int idx, char *quantity)
Convert a quantity index to a descriptive name string.
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.
int locate_irr(const double *xx, const int n, const double x)
Locate index for interpolation on an irregular grid.
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)
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_atm_rfm(const char *filename, const ctl_t *ctl, const atm_t *atm)
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.
void write_tbl(const ctl_t *ctl, const tbl_t *tbl)
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.
int find_emitter(const ctl_t *ctl, const char *emitter)
Find gas species index by name.
double sza(const double sec, const double lon, const double lat)
Compute the solar zenith angle for a given time and location.
void tangent_point(const los_t *los, double *tpz, double *tplon, double *tplat)
Determine the tangent point along a line of sight (LOS).
void read_ret(int argc, char *argv[], ctl_t *ctl, ret_t *ret)
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.
void set_cov_meas(ret_t *ret, ctl_t *ctl, obs_t *obs, gsl_vector *sig_noise, gsl_vector *sig_formod, gsl_vector *sig_eps_inv)
double ctmco2(const double nu, const double p, const double t, const double u)
Compute carbon dioxide continuum (optical depth).
void write_stddev(const char *quantity, ret_t *ret, ctl_t *ctl, atm_t *atm, gsl_matrix *s)
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)
void x2atm_help(double *value, const gsl_vector *x, size_t *n)
void cart2geo(const double *x, double *z, double *lon, double *lat)
Converts Cartesian coordinates to geographic coordinates.
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)
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)
void formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
Execute the selected forward model.
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 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.
tbl_t * read_tbl(const ctl_t *ctl)
Read gas emissivity look-up tables for all channels and emitters.
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)
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.
double cost_function(gsl_vector *dx, gsl_vector *dy, gsl_matrix *s_a_inv, gsl_vector *sig_eps_inv)
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.
void analyze_avk_quantity(gsl_matrix *avk, int iq, int *ipa, size_t *n0, size_t *n1, double *cont, double *res)
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.
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)
int locate_tbl(const float *xx, const int n, const double x)
Locate index for interpolation within emissivity table grids.
#define LEN
Maximum length of ASCII data lines.
#define ND
Maximum number of radiance channels.
#define NSHAPE
Maximum number of shape function grid points.
#define TBLNU
Maximum number of column densities in emissivity tables.
#define TBLNT
Maximum number of temperatures in emissivity tables.
#define NP
Maximum number of atmospheric data points.
#define NG
Maximum number of emitters.
#define TBLNS
Maximum number of source function temperature levels.
#define TBLNP
Maximum number of pressure levels in emissivity tables.
#define NSF
Maximum number of surface layer spectral grid points.
#define NCL
Maximum number of cloud layer spectral grid points.
#define NLOS
Maximum number of LOS points.
#define NR
Maximum number of ray paths.
#define NW
Maximum number of spectral windows.
Atmospheric profile data.
Observation geometry and radiance data.
Retrieval control parameters.
Emissivity look-up tables.