49 static atm_t atm_i, atm_apr;
51 static obs_t obs_i, obs_meas;
58 ERRMSG(
"Give parameters: <ctl> <dirlist>");
71 if (!(dirlist = fopen(argv[2],
"r")))
72 ERRMSG(
"Cannot open directory list!");
75 while (fscanf(dirlist,
"%4999s", ret.
dir) != EOF) {
78 LOG(1,
"\nRetrieve in directory %s...\n", ret.
dir);
94 LOG(1,
"\nRetrieval done...");
116 static int ipa[
N], iqa[
N];
120 char filename[2 *
LEN];
122 double chisq, disq = 0, lmpar = 0.001;
131 const size_t m =
obs2y(ctl, obs_meas, NULL, NULL, NULL);
132 const size_t n =
atm2x(ctl, atm_apr, NULL, iqa, ipa);
133 if (m == 0 || n == 0)
134 ERRMSG(
"Check problem definition!");
137 LOG(1,
"Problem size: m= %d / n= %d "
138 "(alloc= %.4g MB / stat= %.4g MB)",
140 (
double) (3 * m * n + 4 * n * n + 8 * m +
141 8 * n) *
sizeof(
double) / 1024. / 1024.,
142 (
double) (5 *
sizeof(
atm_t) + 3 *
sizeof(
obs_t)
143 + 2 *
N *
sizeof(
int)) / 1024. / 1024.);
146 gsl_matrix *a = gsl_matrix_alloc(n, n);
147 gsl_matrix *cov = gsl_matrix_alloc(n, n);
148 gsl_matrix *k_i = gsl_matrix_alloc(m, n);
149 gsl_matrix *s_a_inv = gsl_matrix_alloc(n, n);
151 gsl_vector *b = gsl_vector_alloc(n);
152 gsl_vector *dx = gsl_vector_alloc(n);
153 gsl_vector *dy = gsl_vector_alloc(m);
154 gsl_vector *sig_eps_inv = gsl_vector_alloc(m);
155 gsl_vector *sig_formod = gsl_vector_alloc(m);
156 gsl_vector *sig_noise = gsl_vector_alloc(m);
157 gsl_vector *x_a = gsl_vector_alloc(n);
158 gsl_vector *x_i = gsl_vector_alloc(n);
159 gsl_vector *x_step = gsl_vector_alloc(n);
160 gsl_vector *y_aux = gsl_vector_alloc(m);
161 gsl_vector *y_i = gsl_vector_alloc(m);
162 gsl_vector *y_m = gsl_vector_alloc(m);
167 formod(ctl, tbl, atm_i, obs_i);
170 atm2x(ctl, atm_apr, x_a, NULL, NULL);
171 atm2x(ctl, atm_i, x_i, NULL, NULL);
172 obs2y(ctl, obs_meas, y_m, NULL, NULL);
173 obs2y(ctl, obs_i, y_i, NULL, NULL);
178 atm_i, obs_i,
"x",
"x",
"r");
182 set_cov_meas(ret, ctl, obs_meas, sig_noise, sig_formod, sig_eps_inv);
185 sprintf(filename,
"%s/costs.tab", ret->
dir);
186 if (!(out = fopen(filename,
"w")))
187 ERRMSG(
"Cannot create cost function file!");
191 "# $1 = iteration number\n"
192 "# $2 = normalized cost function\n"
193 "# $3 = number of measurements\n"
194 "# $4 = number of state vector elements\n\n");
197 gsl_vector_memcpy(dx, x_i);
198 gsl_vector_sub(dx, x_a);
199 gsl_vector_memcpy(dy, y_m);
200 gsl_vector_sub(dy, y_i);
206 LOG(1,
"it= %d / chi^2/m= %g", it, chisq);
209 fprintf(out,
"%d %g %d %d\n", it, chisq, (
int) m, (
int) n);
212 kernel(ctl, tbl, atm_i, obs_i, k_i);
222 double chisq_old = chisq;
226 kernel(ctl, tbl, atm_i, obs_i, k_i);
233 for (
size_t i = 0; i < m; i++)
234 gsl_vector_set(y_aux, i, gsl_vector_get(dy, i)
235 *
POW2(gsl_vector_get(sig_eps_inv, i)));
236 gsl_blas_dgemv(CblasTrans, 1.0, k_i, y_aux, 0.0, b);
237 gsl_blas_dgemv(CblasNoTrans, -1.0, s_a_inv, dx, 1.0, b);
240 for (
int it2 = 0; it2 < 20; it2++) {
243 gsl_matrix_memcpy(a, s_a_inv);
244 gsl_matrix_scale(a, 1 + lmpar);
245 gsl_matrix_add(a, cov);
248 gsl_linalg_cholesky_decomp(a);
249 gsl_linalg_cholesky_solve(a, b, x_step);
252 gsl_vector_add(x_i, x_step);
255 x2atm(ctl, x_i, atm_i);
258 for (
int ip = 0; ip < atm_i->
np; ip++) {
259 atm_i->
p[ip] =
MIN(
MAX(atm_i->
p[ip], 5e-7), 5e4);
260 atm_i->
t[ip] =
MIN(
MAX(atm_i->
t[ip], 100), 400);
261 for (
int ig = 0; ig < ctl->
ng; ig++)
262 atm_i->
q[ig][ip] =
MIN(
MAX(atm_i->
q[ig][ip], 0), 1);
263 for (
int iw = 0; iw < ctl->
nw; iw++)
264 atm_i->
k[iw][ip] =
MAX(atm_i->
k[iw][ip], 0);
268 for (
int icl = 0; icl < ctl->
ncl; icl++)
269 atm_i->
clk[icl] =
MAX(atm_i->
clk[icl], 0);
271 for (
int isf = 0; isf < ctl->
nsf; isf++)
275 formod(ctl, tbl, atm_i, obs_i);
276 obs2y(ctl, obs_i, y_i, NULL, NULL);
279 gsl_vector_memcpy(dx, x_i);
280 gsl_vector_sub(dx, x_a);
281 gsl_vector_memcpy(dy, y_m);
282 gsl_vector_sub(dy, y_i);
288 if (chisq > chisq_old) {
290 gsl_vector_sub(x_i, x_step);
298 LOG(1,
"it= %d / chi^2/m= %g", it, chisq);
301 fprintf(out,
"%d %g %d %d\n", it, chisq, (
int) m, (
int) n);
304 gsl_blas_ddot(x_step, b, &disq);
319 atm_i, obs_i,
"y",
"x",
"r");
329 gsl_matrix *auxnm = gsl_matrix_alloc(n, m);
330 gsl_matrix *corr = gsl_matrix_alloc(n, n);
331 gsl_matrix *gain = gsl_matrix_alloc(n, m);
336 gsl_matrix_add(cov, s_a_inv);
341 atm_i, obs_i,
"x",
"x",
"r");
345 for (
size_t i = 0; i < n; i++)
346 for (
size_t j = 0; j < n; j++)
347 gsl_matrix_set(corr, i, j, gsl_matrix_get(cov, i, j)
348 / sqrt(gsl_matrix_get(cov, i, i))
349 / sqrt(gsl_matrix_get(cov, j, j)));
351 atm_i, obs_i,
"x",
"x",
"r");
355 for (
size_t i = 0; i < n; i++)
356 for (
size_t j = 0; j < m; j++)
357 gsl_matrix_set(auxnm, i, j, gsl_matrix_get(k_i, j, i)
358 *
POW2(gsl_vector_get(sig_eps_inv, j)));
359 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, cov, auxnm, 0.0, gain);
361 atm_i, obs_i,
"x",
"y",
"c");
373 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, gain, k_i, 0.0, a);
375 atm_i, obs_i,
"x",
"x",
"r");
381 gsl_matrix_free(auxnm);
382 gsl_matrix_free(corr);
383 gsl_matrix_free(gain);
391 gsl_matrix_free(cov);
392 gsl_matrix_free(k_i);
393 gsl_matrix_free(s_a_inv);
398 gsl_vector_free(sig_eps_inv);
399 gsl_vector_free(sig_formod);
400 gsl_vector_free(sig_noise);
401 gsl_vector_free(x_a);
402 gsl_vector_free(x_i);
403 gsl_vector_free(x_step);
404 gsl_vector_free(y_aux);
405 gsl_vector_free(y_i);
406 gsl_vector_free(y_m);
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.
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.
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.
void read_ctl(int argc, char *argv[], ctl_t *ctl)
Read model control parameters from command-line and configuration input.
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 .
void x2atm(const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
Map retrieval state vector back to atmospheric structure.
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.
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.
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 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.
void formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs)
Execute the selected forward model.
tbl_t * read_tbl(const ctl_t *ctl)
Read all emissivity lookup tables for all gases and frequencies.
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.
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 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.
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.
JURASSIC library declarations.
#define N
Maximum size of state vector.
#define LEN
Maximum length of ASCII data lines.
#define POW2(x)
Compute the square of a value.
#define MIN(a, b)
Determine the minimum of two values.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
#define TIMER(name, mode)
Start or stop a named timer.
#define LOG(level,...)
Print a log message with a specified logging level.
#define MAX(a, b)
Determine the maximum of two values.
int main(int argc, char *argv[])
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)
Carry out optimal estimation retrieval.
Atmospheric profile data.
double sfeps[NSF]
Surface emissivity.
double k[NW][NP]
Extinction [km^-1].
double t[NP]
Temperature [K].
double clz
Cloud layer height [km].
int np
Number of data points.
double cldz
Cloud layer depth [km].
double sft
Surface temperature [K].
double clk[NCL]
Cloud layer extinction [km^-1].
double q[NG][NP]
Volume mixing ratio [ppv].
double p[NP]
Pressure [hPa].
int nw
Number of spectral windows.
int ng
Number of emitters.
int ncl
Number of cloud layer spectral grid points.
int nsf
Number of surface layer spectral grid points.
Observation geometry and radiance data.
Retrieval control parameters.
int err_ana
Carry out error analysis (0=no, 1=yes).
double conv_dmin
Minimum normalized step size in state space.
int kernel_recomp
Re-computation of kernel matrix (number of iterations).
int conv_itmax
Maximum number of iterations.
char dir[LEN]
Working directory.
Emissivity look-up tables.