JURASSIC
Loading...
Searching...
No Matches
jurassic.c
Go to the documentation of this file.
1/*
2 This file is part of JURASSIC.
3
4 JURASSIC is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 JURASSIC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with JURASSIC. If not, see <http://www.gnu.org/licenses/>.
16
17 Copyright (C) 2003-2026 Forschungszentrum Juelich GmbH
18*/
19
25#include "jurassic.h"
26#include <dirent.h>
27#include <sys/wait.h>
28
29/*****************************************************************************/
30
32 const ret_t *ret,
33 const ctl_t *ctl,
34 const atm_t *atm,
35 const int *iqa,
36 const int *ipa,
37 const gsl_matrix *avk) {
38
39 /* Allocate... */
40 atm_t *atm_cont, *atm_res;
41 ALLOC(atm_cont, atm_t, 1);
42 ALLOC(atm_res, atm_t, 1);
43
44 /* Get sizes... */
45 const size_t n = avk->size1;
46
47 /* Find sub-matrices for different quantities... */
48 size_t n0[NQ], n1[NQ];
49 for (int iq = 0; iq < NQ; iq++) {
50 n0[iq] = N;
51 for (size_t i = 0; i < n; i++) {
52 if (iqa[i] == iq && n0[iq] == N)
53 n0[iq] = i;
54 if (iqa[i] == iq)
55 n1[iq] = i - n0[iq] + 1;
56 }
57 }
58
59 /* Initialize... */
60 copy_atm(ctl, atm_cont, atm, 1);
61 copy_atm(ctl, atm_res, atm, 1);
62
63 /* Analyze quantities... */
64 analyze_avk_quantity(avk, IDXP, ipa, n0, n1, atm_cont->p, atm_res->p);
65 analyze_avk_quantity(avk, IDXT, ipa, n0, n1, atm_cont->t, atm_res->t);
66 for (int ig = 0; ig < ctl->ng; ig++)
67 analyze_avk_quantity(avk, IDXQ(ig), ipa, n0, n1,
68 atm_cont->q[ig], atm_res->q[ig]);
69 for (int iw = 0; iw < ctl->nw; iw++)
70 analyze_avk_quantity(avk, IDXK(iw), ipa, n0, n1,
71 atm_cont->k[iw], atm_res->k[iw]);
72 analyze_avk_quantity(avk, IDXCLZ, ipa, n0, n1, &atm_cont->clz,
73 &atm_res->clz);
74 analyze_avk_quantity(avk, IDXCLDZ, ipa, n0, n1, &atm_cont->cldz,
75 &atm_res->cldz);
76 for (int icl = 0; icl < ctl->ncl; icl++)
77 analyze_avk_quantity(avk, IDXCLK(icl), ipa, n0, n1,
78 &atm_cont->clk[icl], &atm_res->clk[icl]);
79 analyze_avk_quantity(avk, IDXSFT, ipa, n0, n1, &atm_cont->sft,
80 &atm_res->sft);
81 for (int isf = 0; isf < ctl->nsf; isf++)
82 analyze_avk_quantity(avk, IDXSFEPS(isf), ipa, n0, n1,
83 &atm_cont->sfeps[isf], &atm_res->sfeps[isf]);
84
85 /* Write results to disk... */
86 const char *dirname;
87 int profile;
88 const char *filename =
89 shared_io_output_target(ret, ret->shared_io_atm_cont_file, "atm_cont.tab",
90 &dirname, &profile);
91 write_atm(dirname, filename, ctl, atm_cont, profile);
93 "atm_res.tab", &dirname, &profile);
94 write_atm(dirname, filename, ctl, atm_res, profile);
95
96 /* Free... */
97 free(atm_cont);
98 free(atm_res);
99}
100
101/*****************************************************************************/
102
104 const gsl_matrix *avk,
105 const int iq,
106 const int *ipa,
107 const size_t *n0,
108 const size_t *n1,
109 double *cont,
110 double *res) {
111
112 /* Loop over state vector elements... */
113 if (n0[iq] < N)
114 for (size_t i = 0; i < n1[iq]; i++) {
115
116 /* Get area of averaging kernel... */
117 for (size_t j = 0; j < n1[iq]; j++)
118 cont[ipa[n0[iq] + i]] += gsl_matrix_get(avk, n0[iq] + i, n0[iq] + j);
119
120 /* Get information density... */
121 res[ipa[n0[iq] + i]] = 1 / gsl_matrix_get(avk, n0[iq] + i, n0[iq] + i);
122 }
123}
124
125/*****************************************************************************/
126
127size_t atm2x(
128 const ctl_t *ctl,
129 const atm_t *atm,
130 gsl_vector *x,
131 int *iqa,
132 int *ipa) {
133
134 size_t n = 0;
135
136 /* Add pressure... */
137 for (int ip = 0; ip < atm->np; ip++)
138 if (atm->z[ip] >= ctl->retp_zmin && atm->z[ip] <= ctl->retp_zmax)
139 atm2x_help(atm->p[ip], IDXP, ip, x, iqa, ipa, &n);
140
141 /* Add temperature... */
142 for (int ip = 0; ip < atm->np; ip++)
143 if (atm->z[ip] >= ctl->rett_zmin && atm->z[ip] <= ctl->rett_zmax)
144 atm2x_help(atm->t[ip], IDXT, ip, x, iqa, ipa, &n);
145
146 /* Add volume mixing ratios... */
147 for (int ig = 0; ig < ctl->ng; ig++)
148 for (int ip = 0; ip < atm->np; ip++)
149 if (atm->z[ip] >= ctl->retq_zmin[ig]
150 && atm->z[ip] <= ctl->retq_zmax[ig])
151 atm2x_help(atm->q[ig][ip], IDXQ(ig), ip, x, iqa, ipa, &n);
152
153 /* Add extinction... */
154 for (int iw = 0; iw < ctl->nw; iw++)
155 for (int ip = 0; ip < atm->np; ip++)
156 if (atm->z[ip] >= ctl->retk_zmin[iw]
157 && atm->z[ip] <= ctl->retk_zmax[iw])
158 atm2x_help(atm->k[iw][ip], IDXK(iw), ip, x, iqa, ipa, &n);
159
160 /* Add cloud variables... */
161 if (ctl->ret_clz)
162 atm2x_help(atm->clz, IDXCLZ, 0, x, iqa, ipa, &n);
163 if (ctl->ret_cldz)
164 atm2x_help(atm->cldz, IDXCLDZ, 0, x, iqa, ipa, &n);
165 if (ctl->ret_clk)
166 for (int icl = 0; icl < ctl->ncl; icl++)
167 atm2x_help(atm->clk[icl], IDXCLK(icl), 0, x, iqa, ipa, &n);
168
169 /* Add surface variables... */
170 if (ctl->ret_sft)
171 atm2x_help(atm->sft, IDXSFT, 0, x, iqa, ipa, &n);
172 if (ctl->ret_sfeps)
173 for (int isf = 0; isf < ctl->nsf; isf++)
174 atm2x_help(atm->sfeps[isf], IDXSFEPS(isf), 0, x, iqa, ipa, &n);
175
176 return n;
177}
178
179/*****************************************************************************/
180
182 const double value,
183 const int value_iqa,
184 const int value_ip,
185 gsl_vector *x,
186 int *iqa,
187 int *ipa,
188 size_t *n) {
189
190 /* Add element to state vector... */
191 if (x != NULL)
192 gsl_vector_set(x, *n, value);
193 if (iqa != NULL)
194 iqa[*n] = value_iqa;
195 if (ipa != NULL)
196 ipa[*n] = value_ip;
197 (*n)++;
198}
199
200/*****************************************************************************/
201
203 const double *x,
204 double *z,
205 double *lon,
206 double *lat) {
207
208 const double radius = NORM(x);
209
210 *lat = RAD2DEG(asin(x[2] / radius));
211 *lon = RAD2DEG(atan2(x[1], x[0]));
212 *z = radius - RE;
213}
214
215/*****************************************************************************/
216
218 const ctl_t *ctl,
219 const clim_t *clim,
220 atm_t *atm) {
221
222 static const double z[121] = {
223 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
224 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
225 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
226 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
227 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
228 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
229 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120
230 };
231
232 static const double pre[121] = {
233 1017, 901.083, 796.45, 702.227, 617.614, 541.644, 473.437, 412.288,
234 357.603, 308.96, 265.994, 228.348, 195.619, 167.351, 143.039, 122.198,
235 104.369, 89.141, 76.1528, 65.0804, 55.641, 47.591, 40.7233, 34.8637,
236 29.8633, 25.5956, 21.9534, 18.8445, 16.1909, 13.9258, 11.9913,
237 10.34, 8.92988, 7.72454, 6.6924, 5.80701, 5.04654, 4.39238, 3.82902,
238 3.34337, 2.92413, 2.56128, 2.2464, 1.97258, 1.73384, 1.52519, 1.34242,
239 1.18197, 1.04086, 0.916546, 0.806832, 0.709875, 0.624101, 0.548176,
240 0.480974, 0.421507, 0.368904, 0.322408, 0.281386, 0.245249, 0.213465,
241 0.185549, 0.161072, 0.139644, 0.120913, 0.104568, 0.0903249, 0.0779269,
242 0.0671493, 0.0577962, 0.0496902, 0.0426736, 0.0366093, 0.0313743,
243 0.0268598, 0.0229699, 0.0196206, 0.0167399, 0.0142646, 0.0121397,
244 0.0103181, 0.00875775, 0.00742226, 0.00628076, 0.00530519, 0.00447183,
245 0.00376124, 0.00315632, 0.00264248, 0.00220738, 0.00184003, 0.00153095,
246 0.00127204, 0.00105608, 0.000876652, 0.00072798, 0.00060492,
247 0.000503201, 0.000419226, 0.000349896, 0.000292659, 0.000245421,
248 0.000206394, 0.000174125, 0.000147441, 0.000125333, 0.000106985,
249 9.173e-05, 7.90172e-05, 6.84172e-05, 5.95574e-05, 5.21183e-05,
250 4.58348e-05, 4.05127e-05, 3.59987e-05, 3.21583e-05, 2.88718e-05,
251 2.60322e-05, 2.35687e-05, 2.14263e-05, 1.95489e-05
252 };
253
254 static const double tem[121] = {
255 285.14, 279.34, 273.91, 268.3, 263.24, 256.55, 250.2, 242.82, 236.17,
256 229.87, 225.04, 221.19, 218.85, 217.19, 216.2, 215.68, 215.42, 215.55,
257 215.92, 216.4, 216.93, 217.45, 218, 218.68, 219.39, 220.25, 221.3,
258 222.41, 223.88, 225.42, 227.2, 229.52, 231.89, 234.51, 236.85, 239.42,
259 241.94, 244.57, 247.36, 250.32, 253.34, 255.82, 258.27, 260.39,
260 262.03, 263.45, 264.2, 264.78, 264.67, 264.38, 263.24, 262.03, 260.02,
261 258.09, 255.63, 253.28, 250.43, 247.81, 245.26, 242.77, 240.38,
262 237.94, 235.79, 233.53, 231.5, 229.53, 227.6, 225.62, 223.77, 222.06,
263 220.33, 218.69, 217.18, 215.64, 214.13, 212.52, 210.86, 209.25,
264 207.49, 205.81, 204.11, 202.22, 200.32, 198.39, 195.92, 193.46,
265 190.94, 188.31, 185.82, 183.57, 181.43, 179.74, 178.64, 178.1, 178.25,
266 178.7, 179.41, 180.67, 182.31, 184.18, 186.6, 189.53, 192.66, 196.54,
267 201.13, 205.93, 211.73, 217.86, 225, 233.53, 242.57, 252.14, 261.48,
268 272.97, 285.26, 299.12, 312.2, 324.17, 338.34, 352.56, 365.28
269 };
270
271 static const double c2h2[121] = {
272 1.352e-09, 2.83e-10, 1.269e-10, 6.926e-11, 4.346e-11, 2.909e-11,
273 2.014e-11, 1.363e-11, 8.71e-12, 5.237e-12, 2.718e-12, 1.375e-12,
274 5.786e-13, 2.16e-13, 7.317e-14, 2.551e-14, 1.055e-14, 4.758e-15,
275 2.056e-15, 7.703e-16, 2.82e-16, 1.035e-16, 4.382e-17, 1.946e-17,
276 9.638e-18, 5.2e-18, 2.811e-18, 1.494e-18, 7.925e-19, 4.213e-19,
277 1.998e-19, 8.78e-20, 3.877e-20, 1.728e-20, 7.743e-21, 3.536e-21,
278 1.623e-21, 7.508e-22, 3.508e-22, 1.65e-22, 7.837e-23, 3.733e-23,
279 1.808e-23, 8.77e-24, 4.285e-24, 2.095e-24, 1.032e-24, 5.082e-25,
280 2.506e-25, 1.236e-25, 6.088e-26, 2.996e-26, 1.465e-26, 0, 0, 0,
281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
284 };
285
286 static const double c2h6[121] = {
287 2.667e-09, 2.02e-09, 1.658e-09, 1.404e-09, 1.234e-09, 1.109e-09,
288 1.012e-09, 9.262e-10, 8.472e-10, 7.71e-10, 6.932e-10, 6.216e-10,
289 5.503e-10, 4.87e-10, 4.342e-10, 3.861e-10, 3.347e-10, 2.772e-10,
290 2.209e-10, 1.672e-10, 1.197e-10, 8.536e-11, 5.783e-11, 3.846e-11,
291 2.495e-11, 1.592e-11, 1.017e-11, 6.327e-12, 3.895e-12, 2.403e-12,
292 1.416e-12, 8.101e-13, 4.649e-13, 2.686e-13, 1.557e-13, 9.14e-14,
293 5.386e-14, 3.19e-14, 1.903e-14, 1.14e-14, 6.875e-15, 4.154e-15,
294 2.538e-15, 1.553e-15, 9.548e-16, 5.872e-16, 3.63e-16, 2.244e-16,
295 1.388e-16, 8.587e-17, 5.308e-17, 3.279e-17, 2.017e-17, 1.238e-17,
296 7.542e-18, 4.585e-18, 2.776e-18, 1.671e-18, 9.985e-19, 5.937e-19,
297 3.518e-19, 2.07e-19, 1.215e-19, 7.06e-20, 4.097e-20, 2.37e-20,
298 1.363e-20, 7.802e-21, 4.441e-21, 2.523e-21, 1.424e-21, 8.015e-22,
299 4.497e-22, 2.505e-22, 1.391e-22, 7.691e-23, 4.238e-23, 2.331e-23,
300 1.274e-23, 6.929e-24, 3.752e-24, 2.02e-24, 1.083e-24, 5.774e-25,
301 3.041e-25, 1.593e-25, 8.308e-26, 4.299e-26, 2.195e-26, 1.112e-26,
302 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
303 0, 0, 0, 0, 0, 0, 0, 0, 0
304 };
305
306 static const double ccl4[121] = {
307 1.075e-10, 1.075e-10, 1.075e-10, 1.075e-10, 1.075e-10, 1.075e-10,
308 1.075e-10, 1.075e-10, 1.075e-10, 1.06e-10, 1.024e-10, 9.69e-11,
309 8.93e-11, 8.078e-11, 7.213e-11, 6.307e-11, 5.383e-11, 4.49e-11,
310 3.609e-11, 2.705e-11, 1.935e-11, 1.385e-11, 8.35e-12, 5.485e-12,
311 3.853e-12, 2.22e-12, 5.875e-13, 3.445e-13, 1.015e-13, 6.075e-14,
312 4.383e-14, 2.692e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
313 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
314 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
315 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
316 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
317 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
318 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
319 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
320 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14, 1e-14,
321 1e-14, 1e-14, 1e-14
322 };
323
324 static const double ch3oh[121] = {
325 5.01099e-10, 5.01099e-10, 5.01099e-10, 5.01099e-10, 5.01099e-10,
326 5.01099e-10, 5.50999e-10, 5.7313e-10, 5.75638e-10, 5.4086e-10,
327 4.77601e-10, 4.12907e-10, 3.6274e-10, 3.26448e-10, 2.9706e-10,
328 2.27698e-10, 1.96999e-10, 1.66212e-10, 1.17941e-10, 1.19844e-10,
329 1.11211e-10, 1.02714e-10, 9.86138e-11, 9.45133e-11, 9.04127e-11,
330 8.05243e-11, 6.3678e-11, 4.68317e-11, 4.00618e-11, 3.95786e-11,
331 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
332 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
333 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
334 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
335 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
336 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
337 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
338 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
339 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
340 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
341 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
342 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
343 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
344 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
345 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
346 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
347 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
348 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11, 3.95786e-11,
349 3.95786e-11
350 };
351
352 static const double ch4[121] = {
353 1.864e-06, 1.835e-06, 1.819e-06, 1.805e-06, 1.796e-06, 1.788e-06,
354 1.782e-06, 1.776e-06, 1.769e-06, 1.761e-06, 1.749e-06, 1.734e-06,
355 1.716e-06, 1.692e-06, 1.654e-06, 1.61e-06, 1.567e-06, 1.502e-06,
356 1.433e-06, 1.371e-06, 1.323e-06, 1.277e-06, 1.232e-06, 1.188e-06,
357 1.147e-06, 1.108e-06, 1.07e-06, 1.027e-06, 9.854e-07, 9.416e-07,
358 8.933e-07, 8.478e-07, 7.988e-07, 7.515e-07, 7.07e-07, 6.64e-07,
359 6.239e-07, 5.864e-07, 5.512e-07, 5.184e-07, 4.87e-07, 4.571e-07,
360 4.296e-07, 4.04e-07, 3.802e-07, 3.578e-07, 3.383e-07, 3.203e-07,
361 3.032e-07, 2.889e-07, 2.76e-07, 2.635e-07, 2.519e-07, 2.409e-07,
362 2.302e-07, 2.219e-07, 2.144e-07, 2.071e-07, 1.999e-07, 1.93e-07,
363 1.862e-07, 1.795e-07, 1.731e-07, 1.668e-07, 1.607e-07, 1.548e-07,
364 1.49e-07, 1.434e-07, 1.38e-07, 1.328e-07, 1.277e-07, 1.227e-07,
365 1.18e-07, 1.134e-07, 1.089e-07, 1.046e-07, 1.004e-07, 9.635e-08,
366 9.245e-08, 8.867e-08, 8.502e-08, 8.15e-08, 7.809e-08, 7.48e-08,
367 7.159e-08, 6.849e-08, 6.55e-08, 6.262e-08, 5.98e-08, 5.708e-08,
368 5.448e-08, 5.194e-08, 4.951e-08, 4.72e-08, 4.5e-08, 4.291e-08,
369 4.093e-08, 3.905e-08, 3.729e-08, 3.563e-08, 3.408e-08, 3.265e-08,
370 3.128e-08, 2.996e-08, 2.87e-08, 2.76e-08, 2.657e-08, 2.558e-08,
371 2.467e-08, 2.385e-08, 2.307e-08, 2.234e-08, 2.168e-08, 2.108e-08,
372 2.05e-08, 1.998e-08, 1.947e-08, 1.902e-08, 1.86e-08, 1.819e-08,
373 1.782e-08
374 };
375
376 static const double clo[121] = {
377 7.419e-15, 1.061e-14, 1.518e-14, 2.195e-14, 3.175e-14, 4.666e-14,
378 6.872e-14, 1.03e-13, 1.553e-13, 2.375e-13, 3.664e-13, 5.684e-13,
379 8.915e-13, 1.402e-12, 2.269e-12, 4.125e-12, 7.501e-12, 1.257e-11,
380 2.048e-11, 3.338e-11, 5.44e-11, 8.846e-11, 1.008e-10, 1.082e-10,
381 1.157e-10, 1.232e-10, 1.312e-10, 1.539e-10, 1.822e-10, 2.118e-10,
382 2.387e-10, 2.687e-10, 2.875e-10, 3.031e-10, 3.23e-10, 3.648e-10,
383 4.117e-10, 4.477e-10, 4.633e-10, 4.794e-10, 4.95e-10, 5.104e-10,
384 5.259e-10, 5.062e-10, 4.742e-10, 4.443e-10, 4.051e-10, 3.659e-10,
385 3.305e-10, 2.911e-10, 2.54e-10, 2.215e-10, 1.927e-10, 1.675e-10,
386 1.452e-10, 1.259e-10, 1.09e-10, 9.416e-11, 8.119e-11, 6.991e-11,
387 6.015e-11, 5.163e-11, 4.43e-11, 3.789e-11, 3.24e-11, 2.769e-11,
388 2.361e-11, 2.011e-11, 1.71e-11, 1.453e-11, 1.233e-11, 1.045e-11,
389 8.851e-12, 7.48e-12, 6.316e-12, 5.326e-12, 4.487e-12, 3.778e-12,
390 3.176e-12, 2.665e-12, 2.234e-12, 1.87e-12, 1.563e-12, 1.304e-12,
391 1.085e-12, 9.007e-13, 7.468e-13, 6.179e-13, 5.092e-13, 4.188e-13,
392 3.442e-13, 2.816e-13, 2.304e-13, 1.885e-13, 1.542e-13, 1.263e-13,
393 1.035e-13, 8.5e-14, 7.004e-14, 5.783e-14, 4.795e-14, 4.007e-14,
394 3.345e-14, 2.792e-14, 2.33e-14, 1.978e-14, 1.686e-14, 1.438e-14,
395 1.234e-14, 1.07e-14, 9.312e-15, 8.131e-15, 7.164e-15, 6.367e-15,
396 5.67e-15, 5.088e-15, 4.565e-15, 4.138e-15, 3.769e-15, 3.432e-15,
397 3.148e-15
398 };
399
400 static const double clono2[121] = {
401 1.011e-13, 1.515e-13, 2.272e-13, 3.446e-13, 5.231e-13, 8.085e-13,
402 1.253e-12, 1.979e-12, 3.149e-12, 5.092e-12, 8.312e-12, 1.366e-11,
403 2.272e-11, 3.791e-11, 6.209e-11, 9.101e-11, 1.334e-10, 1.951e-10,
404 2.853e-10, 3.94e-10, 4.771e-10, 5.771e-10, 6.675e-10, 7.665e-10,
405 8.504e-10, 8.924e-10, 9.363e-10, 8.923e-10, 8.411e-10, 7.646e-10,
406 6.525e-10, 5.576e-10, 4.398e-10, 3.403e-10, 2.612e-10, 1.915e-10,
407 1.407e-10, 1.028e-10, 7.455e-11, 5.42e-11, 3.708e-11, 2.438e-11,
408 1.618e-11, 1.075e-11, 7.17e-12, 4.784e-12, 3.205e-12, 2.147e-12,
409 1.44e-12, 9.654e-13, 6.469e-13, 4.332e-13, 2.891e-13, 1.926e-13,
410 1.274e-13, 8.422e-14, 5.547e-14, 3.636e-14, 2.368e-14, 1.536e-14,
411 9.937e-15, 6.39e-15, 4.101e-15, 2.61e-15, 1.659e-15, 1.052e-15,
412 6.638e-16, 4.172e-16, 2.61e-16, 1.63e-16, 1.013e-16, 6.275e-17,
413 3.879e-17, 2.383e-17, 1.461e-17, 8.918e-18, 5.43e-18, 3.301e-18,
414 1.997e-18, 1.203e-18, 7.216e-19, 4.311e-19, 2.564e-19, 1.519e-19,
415 8.911e-20, 5.203e-20, 3.026e-20, 1.748e-20, 9.99e-21, 5.673e-21,
416 3.215e-21, 1.799e-21, 1.006e-21, 5.628e-22, 3.146e-22, 1.766e-22,
417 9.94e-23, 5.614e-23, 3.206e-23, 1.841e-23, 1.071e-23, 6.366e-24,
418 3.776e-24, 2.238e-24, 1.326e-24, 8.253e-25, 5.201e-25, 3.279e-25,
419 2.108e-25, 1.395e-25, 9.326e-26, 6.299e-26, 4.365e-26, 3.104e-26,
420 2.219e-26, 1.621e-26, 1.185e-26, 8.92e-27, 6.804e-27, 5.191e-27,
421 4.041e-27
422 };
423
424 static const double co[121] = {
425 1.907e-07, 1.553e-07, 1.362e-07, 1.216e-07, 1.114e-07, 1.036e-07,
426 9.737e-08, 9.152e-08, 8.559e-08, 7.966e-08, 7.277e-08, 6.615e-08,
427 5.884e-08, 5.22e-08, 4.699e-08, 4.284e-08, 3.776e-08, 3.274e-08,
428 2.845e-08, 2.479e-08, 2.246e-08, 2.054e-08, 1.991e-08, 1.951e-08,
429 1.94e-08, 2.009e-08, 2.1e-08, 2.201e-08, 2.322e-08, 2.45e-08,
430 2.602e-08, 2.73e-08, 2.867e-08, 2.998e-08, 3.135e-08, 3.255e-08,
431 3.352e-08, 3.426e-08, 3.484e-08, 3.53e-08, 3.593e-08, 3.671e-08,
432 3.759e-08, 3.945e-08, 4.192e-08, 4.49e-08, 5.03e-08, 5.703e-08,
433 6.538e-08, 7.878e-08, 9.644e-08, 1.196e-07, 1.498e-07, 1.904e-07,
434 2.422e-07, 3.055e-07, 3.804e-07, 4.747e-07, 5.899e-07, 7.272e-07,
435 8.91e-07, 1.071e-06, 1.296e-06, 1.546e-06, 1.823e-06, 2.135e-06,
436 2.44e-06, 2.714e-06, 2.967e-06, 3.189e-06, 3.391e-06, 3.58e-06,
437 3.773e-06, 4.022e-06, 4.346e-06, 4.749e-06, 5.199e-06, 5.668e-06,
438 6.157e-06, 6.688e-06, 7.254e-06, 7.867e-06, 8.539e-06, 9.26e-06,
439 1.009e-05, 1.119e-05, 1.228e-05, 1.365e-05, 1.506e-05, 1.641e-05,
440 1.784e-05, 1.952e-05, 2.132e-05, 2.323e-05, 2.531e-05, 2.754e-05,
441 3.047e-05, 3.459e-05, 3.922e-05, 4.439e-05, 4.825e-05, 5.077e-05,
442 5.34e-05, 5.618e-05, 5.909e-05, 6.207e-05, 6.519e-05, 6.845e-05,
443 6.819e-05, 6.726e-05, 6.622e-05, 6.512e-05, 6.671e-05, 6.862e-05,
444 7.048e-05, 7.264e-05, 7.3e-05, 7.3e-05, 7.3e-05, 7.3e-05, 7.3e-05
445 };
446
447 static const double cof2[121] = {
448 7.5e-14, 1.055e-13, 1.485e-13, 2.111e-13, 3.001e-13, 4.333e-13,
449 6.269e-13, 9.221e-13, 1.364e-12, 2.046e-12, 3.093e-12, 4.703e-12,
450 7.225e-12, 1.113e-11, 1.66e-11, 2.088e-11, 2.626e-11, 3.433e-11,
451 4.549e-11, 5.886e-11, 7.21e-11, 8.824e-11, 1.015e-10, 1.155e-10,
452 1.288e-10, 1.388e-10, 1.497e-10, 1.554e-10, 1.606e-10, 1.639e-10,
453 1.64e-10, 1.64e-10, 1.596e-10, 1.542e-10, 1.482e-10, 1.382e-10,
454 1.289e-10, 1.198e-10, 1.109e-10, 1.026e-10, 9.484e-11, 8.75e-11,
455 8.086e-11, 7.49e-11, 6.948e-11, 6.446e-11, 5.961e-11, 5.505e-11,
456 5.085e-11, 4.586e-11, 4.1e-11, 3.665e-11, 3.235e-11, 2.842e-11,
457 2.491e-11, 2.11e-11, 1.769e-11, 1.479e-11, 1.197e-11, 9.631e-12,
458 7.74e-12, 6.201e-12, 4.963e-12, 3.956e-12, 3.151e-12, 2.507e-12,
459 1.99e-12, 1.576e-12, 1.245e-12, 9.83e-13, 7.742e-13, 6.088e-13,
460 4.782e-13, 3.745e-13, 2.929e-13, 2.286e-13, 1.782e-13, 1.388e-13,
461 1.079e-13, 8.362e-14, 6.471e-14, 4.996e-14, 3.85e-14, 2.96e-14,
462 2.265e-14, 1.729e-14, 1.317e-14, 9.998e-15, 7.549e-15, 5.683e-15,
463 4.273e-15, 3.193e-15, 2.385e-15, 1.782e-15, 1.331e-15, 9.957e-16,
464 7.461e-16, 5.601e-16, 4.228e-16, 3.201e-16, 2.438e-16, 1.878e-16,
465 1.445e-16, 1.111e-16, 8.544e-17, 6.734e-17, 5.341e-17, 4.237e-17,
466 3.394e-17, 2.759e-17, 2.254e-17, 1.851e-17, 1.54e-17, 1.297e-17,
467 1.096e-17, 9.365e-18, 8e-18, 6.938e-18, 6.056e-18, 5.287e-18,
468 4.662e-18
469 };
470
471 static const double f11[121] = {
472 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10,
473 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.65e-10, 2.635e-10, 2.536e-10,
474 2.44e-10, 2.348e-10, 2.258e-10, 2.153e-10, 2.046e-10, 1.929e-10,
475 1.782e-10, 1.648e-10, 1.463e-10, 1.291e-10, 1.1e-10, 8.874e-11,
476 7.165e-11, 5.201e-11, 3.744e-11, 2.577e-11, 1.64e-11, 1.048e-11,
477 5.993e-12, 3.345e-12, 1.839e-12, 9.264e-13, 4.688e-13, 2.329e-13,
478 1.129e-13, 5.505e-14, 2.825e-14, 1.492e-14, 7.997e-15, 5.384e-15,
479 3.988e-15, 2.955e-15, 2.196e-15, 1.632e-15, 1.214e-15, 9.025e-16,
480 6.708e-16, 4.984e-16, 3.693e-16, 2.733e-16, 2.013e-16, 1.481e-16,
481 1.087e-16, 7.945e-17, 5.782e-17, 4.195e-17, 3.038e-17, 2.19e-17,
482 1.577e-17, 1.128e-17, 8.063e-18, 5.753e-18, 4.09e-18, 2.899e-18,
483 2.048e-18, 1.444e-18, 1.015e-18, 7.12e-19, 4.985e-19, 3.474e-19,
484 2.417e-19, 1.677e-19, 1.161e-19, 8.029e-20, 5.533e-20, 3.799e-20,
485 2.602e-20, 1.776e-20, 1.209e-20, 8.202e-21, 5.522e-21, 3.707e-21,
486 2.48e-21, 1.652e-21, 1.091e-21, 7.174e-22, 4.709e-22, 3.063e-22,
487 1.991e-22, 1.294e-22, 8.412e-23, 5.483e-23, 3.581e-23, 2.345e-23,
488 1.548e-23, 1.027e-23, 6.869e-24, 4.673e-24, 3.173e-24, 2.153e-24,
489 1.461e-24, 1.028e-24, 7.302e-25, 5.188e-25, 3.739e-25, 2.753e-25,
490 2.043e-25, 1.528e-25, 1.164e-25, 9.041e-26, 7.051e-26, 5.587e-26,
491 4.428e-26, 3.588e-26, 2.936e-26, 2.402e-26, 1.995e-26
492 };
493
494 static const double f113[121] = {
495 1.9e-11, 1.9e-11, 1.899e-11, 1.899e-11, 1.898e-11, 1.898e-11,
496 1.897e-11, 1.896e-11, 1.895e-11, 1.894e-11, 1.893e-11, 1.89e-11,
497 1.887e-11, 1.871e-11, 1.854e-11, 1.803e-11, 1.751e-11, 1.664e-11,
498 1.576e-11, 1.466e-11, 1.356e-11, 1.236e-11, 1.116e-11, 9.931e-12,
499 8.702e-12, 7.515e-12, 6.4238e-12, 5.3326e-12, 4.3652e-12, 3.5216e-12,
500 2.678e-12, 2.1532e-12, 1.6284e-12, 1.2202e-12, 9.286e-13, 6.37e-13,
501 4.95e-13, 3.53e-13, 2.5004e-13, 1.8612e-13, 1.222e-13, 9.704e-14,
502 7.188e-14, 5.3338e-14, 4.1414e-14, 2.949e-14, 2.3722e-14, 1.7954e-14,
503 1.37794e-14, 1.11982e-14, 8.617e-15, 7.6036e-15, 6.5902e-15,
504 5.5768e-15, 4.5634e-15, 3.55e-15, 3.1008e-15, 2.6516e-15, 2.2024e-15,
505 1.7532e-15, 1.304e-15, 1.1354e-15, 9.668e-16, 7.982e-16, 6.296e-16,
506 4.61e-16, 3.9734e-16, 3.3368e-16, 2.7002e-16, 2.0636e-16, 1.427e-16,
507 1.22804e-16, 1.02908e-16, 8.3012e-17, 6.3116e-17, 4.322e-17,
508 3.6838e-17, 3.0456e-17, 2.4074e-17, 1.7692e-17, 1.131e-17,
509 9.6202e-18, 7.9304e-18, 6.2406e-18, 4.5508e-18, 2.861e-18,
510 2.40476e-18, 1.94852e-18, 1.49228e-18, 1.03604e-18, 5.798e-19,
511 4.8502e-19, 3.9024e-19, 2.9546e-19, 2.0068e-19, 1.059e-19,
512 8.7084e-20, 6.8268e-20, 4.9452e-20, 3.0636e-20, 1.182e-20,
513 9.64344e-21, 7.46688e-21, 5.29032e-21, 3.11376e-21, 9.372e-22,
514 7.5685e-22, 5.765e-22, 3.9615e-22, 2.158e-22, 3.545e-23,
515 2.86046e-23, 2.17592e-23, 1.49138e-23, 8.0684e-24, 1.223e-24,
516 9.92358e-25, 7.61716e-25, 5.31074e-25, 3.00432e-25, 6.979e-26
517 };
518
519 static const double f114[121] = {
520 1.2e-11, 1.2e-11, 1.2e-11, 1.2e-11, 1.199e-11, 1.199e-11,
521 1.199e-11, 1.199e-11, 1.198e-11, 1.198e-11, 1.198e-11, 1.197e-11,
522 1.196e-11, 1.191e-11, 1.185e-11, 1.167e-11, 1.149e-11, 1.12e-11,
523 1.09e-11, 1.053e-11, 1.015e-11, 9.731e-12, 9.311e-12, 8.865e-12,
524 8.419e-12, 7.949e-12, 7.4774e-12, 7.0058e-12, 6.54e-12, 6.08e-12,
525 5.62e-12, 5.1908e-12, 4.7616e-12, 4.3622e-12, 3.9926e-12, 3.623e-12,
526 3.3274e-12, 3.0318e-12, 2.7702e-12, 2.5426e-12, 2.315e-12, 2.1514e-12,
527 1.9878e-12, 1.8448e-12, 1.7224e-12, 1.6e-12, 1.51e-12, 1.42e-12,
528 1.3462e-12, 1.2886e-12, 1.231e-12, 1.1922e-12, 1.1534e-12, 1.1146e-12,
529 1.0758e-12, 1.037e-12, 1.0025e-12, 9.68e-13, 9.335e-13, 8.99e-13,
530 8.645e-13, 8.344e-13, 8.043e-13, 7.742e-13, 7.441e-13, 7.14e-13,
531 6.8718e-13, 6.6036e-13, 6.3354e-13, 6.0672e-13, 5.799e-13, 5.5612e-13,
532 5.3234e-13, 5.0856e-13, 4.8478e-13, 4.61e-13, 4.394e-13, 4.178e-13,
533 3.962e-13, 3.746e-13, 3.53e-13, 3.3288e-13, 3.1276e-13, 2.9264e-13,
534 2.7252e-13, 2.524e-13, 2.3368e-13, 2.1496e-13, 1.9624e-13, 1.7752e-13,
535 1.588e-13, 1.4221e-13, 1.2562e-13, 1.0903e-13, 9.244e-14, 7.585e-14,
536 6.4942e-14, 5.4034e-14, 4.3126e-14, 3.2218e-14, 2.131e-14, 1.76694e-14,
537 1.40288e-14, 1.03882e-14, 6.7476e-15, 3.107e-15, 2.52738e-15,
538 1.94776e-15, 1.36814e-15, 7.8852e-16, 2.089e-16, 1.69288e-16,
539 1.29676e-16, 9.0064e-17, 5.0452e-17, 1.084e-17, 8.85136e-18,
540 6.86272e-18, 4.87408e-18, 2.88544e-18, 8.968e-19
541 };
542
543 static const double f12[121] = {
544 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10,
545 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.45e-10, 5.429e-10, 5.291e-10,
546 5.155e-10, 5.022e-10, 4.893e-10, 4.772e-10, 4.655e-10, 4.497e-10,
547 4.249e-10, 4.015e-10, 3.632e-10, 3.261e-10, 2.858e-10, 2.408e-10,
548 2.03e-10, 1.685e-10, 1.4e-10, 1.163e-10, 9.65e-11, 8.02e-11, 6.705e-11,
549 5.624e-11, 4.764e-11, 4.249e-11, 3.792e-11, 3.315e-11, 2.819e-11,
550 2.4e-11, 1.999e-11, 1.64e-11, 1.352e-11, 1.14e-11, 9.714e-12,
551 8.28e-12, 7.176e-12, 6.251e-12, 5.446e-12, 4.72e-12, 4.081e-12,
552 3.528e-12, 3.08e-12, 2.699e-12, 2.359e-12, 2.111e-12, 1.901e-12,
553 1.709e-12, 1.534e-12, 1.376e-12, 1.233e-12, 1.103e-12, 9.869e-13,
554 8.808e-13, 7.859e-13, 7.008e-13, 6.241e-13, 5.553e-13, 4.935e-13,
555 4.383e-13, 3.889e-13, 3.447e-13, 3.054e-13, 2.702e-13, 2.389e-13,
556 2.11e-13, 1.862e-13, 1.643e-13, 1.448e-13, 1.274e-13, 1.121e-13,
557 9.844e-14, 8.638e-14, 7.572e-14, 6.62e-14, 5.782e-14, 5.045e-14,
558 4.394e-14, 3.817e-14, 3.311e-14, 2.87e-14, 2.48e-14, 2.142e-14,
559 1.851e-14, 1.599e-14, 1.383e-14, 1.196e-14, 1.036e-14, 9e-15,
560 7.828e-15, 6.829e-15, 5.992e-15, 5.254e-15, 4.606e-15, 4.037e-15,
561 3.583e-15, 3.19e-15, 2.841e-15, 2.542e-15, 2.291e-15, 2.07e-15,
562 1.875e-15, 1.71e-15, 1.57e-15, 1.442e-15, 1.333e-15, 1.232e-15,
563 1.147e-15, 1.071e-15, 1.001e-15, 9.396e-16
564 };
565
566 static const double f14[121] = {
567 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 9e-11,
568 9e-11, 9e-11, 9e-11, 9e-11, 9e-11, 8.91e-11, 8.73e-11, 8.46e-11,
569 8.19e-11, 7.92e-11, 7.74e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
570 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
571 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
572 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
573 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
574 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
575 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
576 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
577 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
578 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
579 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
580 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
581 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
582 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11,
583 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11, 7.65e-11
584 };
585
586 static const double f22[121] = {
587 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10, 1.4e-10,
588 1.4e-10, 1.4e-10, 1.4e-10, 1.372e-10, 1.317e-10, 1.235e-10, 1.153e-10,
589 1.075e-10, 1.002e-10, 9.332e-11, 8.738e-11, 8.194e-11, 7.7e-11,
590 7.165e-11, 6.753e-11, 6.341e-11, 5.971e-11, 5.6e-11, 5.229e-11,
591 4.859e-11, 4.488e-11, 4.118e-11, 3.83e-11, 3.568e-11, 3.308e-11,
592 3.047e-11, 2.82e-11, 2.594e-11, 2.409e-11, 2.237e-11, 2.065e-11,
593 1.894e-11, 1.771e-11, 1.647e-11, 1.532e-11, 1.416e-11, 1.332e-11,
594 1.246e-11, 1.161e-11, 1.087e-11, 1.017e-11, 9.471e-12, 8.853e-12,
595 8.235e-12, 7.741e-12, 7.247e-12, 6.836e-12, 6.506e-12, 6.176e-12,
596 5.913e-12, 5.65e-12, 5.419e-12, 5.221e-12, 5.024e-12, 4.859e-12,
597 4.694e-12, 4.546e-12, 4.414e-12, 4.282e-12, 4.15e-12, 4.019e-12,
598 3.903e-12, 3.805e-12, 3.706e-12, 3.607e-12, 3.508e-12, 3.41e-12,
599 3.31e-12, 3.212e-12, 3.129e-12, 3.047e-12, 2.964e-12, 2.882e-12,
600 2.8e-12, 2.734e-12, 2.668e-12, 2.602e-12, 2.537e-12, 2.471e-12,
601 2.421e-12, 2.372e-12, 2.322e-12, 2.273e-12, 2.224e-12, 2.182e-12,
602 2.141e-12, 2.1e-12, 2.059e-12, 2.018e-12, 1.977e-12, 1.935e-12,
603 1.894e-12, 1.853e-12, 1.812e-12, 1.77e-12, 1.73e-12, 1.688e-12,
604 1.647e-12, 1.606e-12, 1.565e-12, 1.524e-12, 1.483e-12, 1.441e-12,
605 1.4e-12, 1.359e-12, 1.317e-12, 1.276e-12, 1.235e-12, 1.194e-12,
606 1.153e-12, 1.112e-12, 1.071e-12, 1.029e-12, 9.883e-13
607 };
608
609 static const double h2co[121] = {
610 8.71857e-11, 8.71857e-11, 8.71857e-11, 8.71857e-11, 8.71857e-11,
611 8.71857e-11, 7.72315e-11, 6.85464e-11, 6.0758e-11, 5.32087e-11,
612 4.5719e-11, 3.79458e-11, 3.07607e-11, 2.46025e-11, 1.94038e-11,
613 1.40882e-11, 1.0623e-11, 8.35457e-12, 6.87427e-12, 7.09071e-12,
614 8.96183e-12, 1.09012e-11, 1.50545e-11, 1.92077e-11, 2.3361e-11,
615 2.7054e-11, 3.01936e-11, 3.33333e-11, 3.69281e-11, 4.08069e-11,
616 4.57318e-11, 5.1348e-11, 5.69642e-11, 6.33173e-11, 6.98984e-11,
617 7.63144e-11, 8.22774e-11, 8.82405e-11, 9.3746e-11, 9.92074e-11,
618 1.04669e-10, 1.10055e-10, 1.15293e-10, 1.20531e-10, 1.26293e-10,
619 1.32585e-10, 1.35966e-10, 1.36242e-10, 1.36519e-10, 1.61155e-10,
620 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
621 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
622 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
623 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
624 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
625 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
626 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
627 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
628 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
629 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
630 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
631 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
632 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
633 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10, 1.99157e-10,
634 1.99157e-10
635 };
636
637 static const double h2o[121] = {
638 0.01166, 0.008269, 0.005742, 0.003845, 0.00277, 0.001897, 0.001272,
639 0.000827, 0.000539, 0.0003469, 0.0001579, 3.134e-05, 1.341e-05,
640 6.764e-06, 4.498e-06, 3.703e-06, 3.724e-06, 3.899e-06, 4.002e-06,
641 4.122e-06, 4.277e-06, 4.438e-06, 4.558e-06, 4.673e-06, 4.763e-06,
642 4.809e-06, 4.856e-06, 4.936e-06, 5.021e-06, 5.114e-06, 5.222e-06,
643 5.331e-06, 5.414e-06, 5.488e-06, 5.563e-06, 5.633e-06, 5.704e-06,
644 5.767e-06, 5.819e-06, 5.872e-06, 5.914e-06, 5.949e-06, 5.984e-06,
645 6.015e-06, 6.044e-06, 6.073e-06, 6.104e-06, 6.136e-06, 6.167e-06,
646 6.189e-06, 6.208e-06, 6.226e-06, 6.212e-06, 6.185e-06, 6.158e-06,
647 6.114e-06, 6.066e-06, 6.018e-06, 5.877e-06, 5.728e-06, 5.582e-06,
648 5.437e-06, 5.296e-06, 5.156e-06, 5.02e-06, 4.886e-06, 4.754e-06,
649 4.625e-06, 4.498e-06, 4.374e-06, 4.242e-06, 4.096e-06, 3.955e-06,
650 3.817e-06, 3.683e-06, 3.491e-06, 3.204e-06, 2.94e-06, 2.696e-06,
651 2.47e-06, 2.252e-06, 2.019e-06, 1.808e-06, 1.618e-06, 1.445e-06,
652 1.285e-06, 1.105e-06, 9.489e-07, 8.121e-07, 6.938e-07, 5.924e-07,
653 5.04e-07, 4.288e-07, 3.648e-07, 3.103e-07, 2.642e-07, 2.252e-07,
654 1.921e-07, 1.643e-07, 1.408e-07, 1.211e-07, 1.048e-07, 9.063e-08,
655 7.835e-08, 6.774e-08, 5.936e-08, 5.221e-08, 4.592e-08, 4.061e-08,
656 3.62e-08, 3.236e-08, 2.902e-08, 2.62e-08, 2.383e-08, 2.171e-08,
657 1.989e-08, 1.823e-08, 1.684e-08, 1.562e-08, 1.449e-08, 1.351e-08
658 };
659
660 static const double h2o2[121] = {
661 1.779e-10, 7.938e-10, 8.953e-10, 8.032e-10, 6.564e-10, 5.159e-10,
662 4.003e-10, 3.026e-10, 2.222e-10, 1.58e-10, 1.044e-10, 6.605e-11,
663 3.413e-11, 1.453e-11, 1.062e-11, 1.009e-11, 9.597e-12, 1.175e-11,
664 1.572e-11, 2.091e-11, 2.746e-11, 3.603e-11, 4.791e-11, 6.387e-11,
665 8.239e-11, 1.007e-10, 1.23e-10, 1.363e-10, 1.489e-10, 1.585e-10,
666 1.608e-10, 1.632e-10, 1.576e-10, 1.502e-10, 1.423e-10, 1.302e-10,
667 1.192e-10, 1.085e-10, 9.795e-11, 8.854e-11, 8.057e-11, 7.36e-11,
668 6.736e-11, 6.362e-11, 6.087e-11, 5.825e-11, 5.623e-11, 5.443e-11,
669 5.27e-11, 5.098e-11, 4.931e-11, 4.769e-11, 4.611e-11, 4.458e-11,
670 4.308e-11, 4.102e-11, 3.887e-11, 3.682e-11, 3.521e-11, 3.369e-11,
671 3.224e-11, 3.082e-11, 2.946e-11, 2.814e-11, 2.687e-11, 2.566e-11,
672 2.449e-11, 2.336e-11, 2.227e-11, 2.123e-11, 2.023e-11, 1.927e-11,
673 1.835e-11, 1.746e-11, 1.661e-11, 1.58e-11, 1.502e-11, 1.428e-11,
674 1.357e-11, 1.289e-11, 1.224e-11, 1.161e-11, 1.102e-11, 1.045e-11,
675 9.895e-12, 9.369e-12, 8.866e-12, 8.386e-12, 7.922e-12, 7.479e-12,
676 7.06e-12, 6.656e-12, 6.274e-12, 5.914e-12, 5.575e-12, 5.257e-12,
677 4.959e-12, 4.679e-12, 4.42e-12, 4.178e-12, 3.954e-12, 3.75e-12,
678 3.557e-12, 3.372e-12, 3.198e-12, 3.047e-12, 2.908e-12, 2.775e-12,
679 2.653e-12, 2.544e-12, 2.442e-12, 2.346e-12, 2.26e-12, 2.183e-12,
680 2.11e-12, 2.044e-12, 1.98e-12, 1.924e-12, 1.871e-12, 1.821e-12,
681 1.775e-12
682 };
683
684 static const double hcl[121] = {
685 3.70385e-11, 3.70385e-11, 3.70385e-11, 3.70385e-11, 3.70385e-11,
686 3.70385e-11, 2.21247e-11, 1.88117e-11, 2.36957e-11, 3.72192e-11,
687 5.79399e-11, 8.04158e-11, 1.01779e-10, 1.2301e-10, 1.53924e-10,
688 1.93737e-10, 2.5561e-10, 3.84228e-10, 6.18248e-10, 6.31222e-10,
689 7.84907e-10, 9.36932e-10, 1.03508e-09, 1.13323e-09, 1.23138e-09,
690 1.31985e-09, 1.39669e-09, 1.47352e-09, 1.56375e-09, 1.66234e-09,
691 1.78086e-09, 1.91256e-09, 2.04425e-09, 2.16629e-09, 2.28535e-09,
692 2.39439e-09, 2.47597e-09, 2.55755e-09, 2.60873e-09, 2.65696e-09,
693 2.70519e-09, 2.75658e-09, 2.81422e-09, 2.87187e-09, 2.94013e-09,
694 3.01911e-09, 3.09497e-09, 3.16749e-09, 3.24001e-09, 3.30525e-09,
695 3.3665e-09, 3.42424e-09, 3.4619e-09, 3.49956e-09, 3.52273e-09,
696 3.54214e-09, 3.56154e-09, 3.57918e-09, 3.59049e-09, 3.6018e-09,
697 3.6132e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
698 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
699 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
700 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
701 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
702 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
703 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
704 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
705 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
706 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
707 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
708 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09, 3.62476e-09,
709 3.62476e-09
710 };
711
712 static const double hcn[121] = {
713 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10,
714 5.5e-10, 5.5e-10, 5.5e-10, 5.5e-10, 5.498e-10, 5.495e-10, 5.493e-10,
715 5.49e-10, 5.488e-10, 4.717e-10, 3.946e-10, 3.174e-10, 2.4e-10,
716 1.626e-10, 1.619e-10, 1.612e-10, 1.602e-10, 1.593e-10, 1.582e-10,
717 1.572e-10, 1.56e-10, 1.549e-10, 1.539e-10, 1.53e-10, 1.519e-10,
718 1.506e-10, 1.487e-10, 1.467e-10, 1.449e-10, 1.43e-10, 1.413e-10,
719 1.397e-10, 1.382e-10, 1.368e-10, 1.354e-10, 1.337e-10, 1.315e-10,
720 1.292e-10, 1.267e-10, 1.241e-10, 1.215e-10, 1.19e-10, 1.165e-10,
721 1.141e-10, 1.118e-10, 1.096e-10, 1.072e-10, 1.047e-10, 1.021e-10,
722 9.968e-11, 9.739e-11, 9.539e-11, 9.339e-11, 9.135e-11, 8.898e-11,
723 8.664e-11, 8.439e-11, 8.249e-11, 8.075e-11, 7.904e-11, 7.735e-11,
724 7.565e-11, 7.399e-11, 7.245e-11, 7.109e-11, 6.982e-11, 6.863e-11,
725 6.755e-11, 6.657e-11, 6.587e-11, 6.527e-11, 6.476e-11, 6.428e-11,
726 6.382e-11, 6.343e-11, 6.307e-11, 6.272e-11, 6.238e-11, 6.205e-11,
727 6.17e-11, 6.137e-11, 6.102e-11, 6.072e-11, 6.046e-11, 6.03e-11,
728 6.018e-11, 6.01e-11, 6.001e-11, 5.992e-11, 5.984e-11, 5.975e-11,
729 5.967e-11, 5.958e-11, 5.95e-11, 5.941e-11, 5.933e-11, 5.925e-11,
730 5.916e-11, 5.908e-11, 5.899e-11, 5.891e-11, 5.883e-11, 5.874e-11,
731 5.866e-11, 5.858e-11, 5.85e-11, 5.841e-11, 5.833e-11, 5.825e-11,
732 5.817e-11, 5.808e-11, 5.8e-11, 5.792e-11, 5.784e-11
733 };
734
735 static const double hf[121] = {
736 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11,
737 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11, 2.64279e-11,
738 2.64279e-11, 2.64279e-11, 2.64279e-11, 3.86691e-11, 5.22002e-11,
739 6.92471e-11, 9.13979e-11, 1.37918e-10, 2.24918e-10, 2.29824e-10,
740 2.94241e-10, 3.58363e-10, 4.12881e-10, 4.67399e-10, 5.21917e-10,
741 5.74229e-10, 6.23889e-10, 6.73549e-10, 7.24119e-10, 7.75256e-10,
742 8.319e-10, 8.92185e-10, 9.52469e-10, 1.01325e-09, 1.07419e-09,
743 1.13565e-09, 1.19856e-09, 1.26146e-09, 1.31439e-09, 1.36635e-09,
744 1.41831e-09, 1.46549e-09, 1.50321e-09, 1.54093e-09, 1.57986e-09,
745 1.62e-09, 1.66286e-09, 1.70863e-09, 1.75439e-09, 1.79827e-09,
746 1.84111e-09, 1.88125e-09, 1.90603e-09, 1.93081e-09, 1.9413e-09,
747 1.94807e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
748 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
749 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
750 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
751 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
752 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
753 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
754 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
755 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
756 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
757 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
758 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
759 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09, 1.95485e-09,
760 1.95485e-09
761 };
762
763 static const double hno3[121] = {
764 1.809e-10, 7.234e-10, 5.899e-10, 4.342e-10, 3.277e-10, 2.661e-10,
765 2.35e-10, 2.267e-10, 2.389e-10, 2.651e-10, 3.255e-10, 4.099e-10,
766 5.42e-10, 6.978e-10, 8.807e-10, 1.112e-09, 1.405e-09, 2.04e-09,
767 3.111e-09, 4.5e-09, 5.762e-09, 7.37e-09, 7.852e-09, 8.109e-09,
768 8.067e-09, 7.554e-09, 7.076e-09, 6.268e-09, 5.524e-09, 4.749e-09,
769 3.909e-09, 3.223e-09, 2.517e-09, 1.942e-09, 1.493e-09, 1.122e-09,
770 8.449e-10, 6.361e-10, 4.787e-10, 3.611e-10, 2.804e-10, 2.215e-10,
771 1.758e-10, 1.441e-10, 1.197e-10, 9.953e-11, 8.505e-11, 7.334e-11,
772 6.325e-11, 5.625e-11, 5.058e-11, 4.548e-11, 4.122e-11, 3.748e-11,
773 3.402e-11, 3.088e-11, 2.8e-11, 2.536e-11, 2.293e-11, 2.072e-11,
774 1.871e-11, 1.687e-11, 1.52e-11, 1.368e-11, 1.23e-11, 1.105e-11,
775 9.922e-12, 8.898e-12, 7.972e-12, 7.139e-12, 6.385e-12, 5.708e-12,
776 5.099e-12, 4.549e-12, 4.056e-12, 3.613e-12, 3.216e-12, 2.862e-12,
777 2.544e-12, 2.259e-12, 2.004e-12, 1.776e-12, 1.572e-12, 1.391e-12,
778 1.227e-12, 1.082e-12, 9.528e-13, 8.379e-13, 7.349e-13, 6.436e-13,
779 5.634e-13, 4.917e-13, 4.291e-13, 3.745e-13, 3.267e-13, 2.854e-13,
780 2.494e-13, 2.181e-13, 1.913e-13, 1.68e-13, 1.479e-13, 1.31e-13,
781 1.159e-13, 1.025e-13, 9.067e-14, 8.113e-14, 7.281e-14, 6.535e-14,
782 5.892e-14, 5.348e-14, 4.867e-14, 4.439e-14, 4.073e-14, 3.76e-14,
783 3.476e-14, 3.229e-14, 3e-14, 2.807e-14, 2.635e-14, 2.473e-14,
784 2.332e-14
785 };
786
787 static const double hno4[121] = {
788 6.118e-12, 3.594e-12, 2.807e-12, 3.04e-12, 4.458e-12, 7.986e-12,
789 1.509e-11, 2.661e-11, 3.738e-11, 4.652e-11, 4.429e-11, 3.992e-11,
790 3.347e-11, 3.005e-11, 3.173e-11, 4.055e-11, 5.812e-11, 8.489e-11,
791 1.19e-10, 1.482e-10, 1.766e-10, 2.103e-10, 2.35e-10, 2.598e-10,
792 2.801e-10, 2.899e-10, 3e-10, 2.817e-10, 2.617e-10, 2.332e-10,
793 1.933e-10, 1.605e-10, 1.232e-10, 9.285e-11, 6.941e-11, 4.951e-11,
794 3.539e-11, 2.402e-11, 1.522e-11, 9.676e-12, 6.056e-12, 3.745e-12,
795 2.34e-12, 1.463e-12, 9.186e-13, 5.769e-13, 3.322e-13, 1.853e-13,
796 1.035e-13, 7.173e-14, 5.382e-14, 4.036e-14, 3.401e-14, 2.997e-14,
797 2.635e-14, 2.316e-14, 2.034e-14, 1.783e-14, 1.56e-14, 1.363e-14,
798 1.19e-14, 1.037e-14, 9.032e-15, 7.846e-15, 6.813e-15, 5.912e-15,
799 5.121e-15, 4.431e-15, 3.829e-15, 3.306e-15, 2.851e-15, 2.456e-15,
800 2.114e-15, 1.816e-15, 1.559e-15, 1.337e-15, 1.146e-15, 9.811e-16,
801 8.389e-16, 7.162e-16, 6.109e-16, 5.203e-16, 4.425e-16, 3.76e-16,
802 3.184e-16, 2.692e-16, 2.274e-16, 1.917e-16, 1.61e-16, 1.35e-16,
803 1.131e-16, 9.437e-17, 7.874e-17, 6.57e-17, 5.481e-17, 4.579e-17,
804 3.828e-17, 3.204e-17, 2.691e-17, 2.264e-17, 1.912e-17, 1.626e-17,
805 1.382e-17, 1.174e-17, 9.972e-18, 8.603e-18, 7.45e-18, 6.453e-18,
806 5.623e-18, 4.944e-18, 4.361e-18, 3.859e-18, 3.443e-18, 3.096e-18,
807 2.788e-18, 2.528e-18, 2.293e-18, 2.099e-18, 1.929e-18, 1.773e-18,
808 1.64e-18
809 };
810
811 static const double hocl[121] = {
812 1.056e-12, 1.194e-12, 1.35e-12, 1.531e-12, 1.737e-12, 1.982e-12,
813 2.263e-12, 2.599e-12, 2.991e-12, 3.459e-12, 4.012e-12, 4.662e-12,
814 5.438e-12, 6.35e-12, 7.425e-12, 8.686e-12, 1.016e-11, 1.188e-11,
815 1.389e-11, 1.659e-11, 2.087e-11, 2.621e-11, 3.265e-11, 4.064e-11,
816 4.859e-11, 5.441e-11, 6.09e-11, 6.373e-11, 6.611e-11, 6.94e-11,
817 7.44e-11, 7.97e-11, 8.775e-11, 9.722e-11, 1.064e-10, 1.089e-10,
818 1.114e-10, 1.106e-10, 1.053e-10, 1.004e-10, 9.006e-11, 7.778e-11,
819 6.739e-11, 5.636e-11, 4.655e-11, 3.845e-11, 3.042e-11, 2.368e-11,
820 1.845e-11, 1.442e-11, 1.127e-11, 8.814e-12, 6.544e-12, 4.763e-12,
821 3.449e-12, 2.612e-12, 1.999e-12, 1.526e-12, 1.16e-12, 8.793e-13,
822 6.655e-13, 5.017e-13, 3.778e-13, 2.829e-13, 2.117e-13, 1.582e-13,
823 1.178e-13, 8.755e-14, 6.486e-14, 4.799e-14, 3.54e-14, 2.606e-14,
824 1.916e-14, 1.403e-14, 1.026e-14, 7.48e-15, 5.446e-15, 3.961e-15,
825 2.872e-15, 2.076e-15, 1.498e-15, 1.077e-15, 7.726e-16, 5.528e-16,
826 3.929e-16, 2.785e-16, 1.969e-16, 1.386e-16, 9.69e-17, 6.747e-17,
827 4.692e-17, 3.236e-17, 2.232e-17, 1.539e-17, 1.061e-17, 7.332e-18,
828 5.076e-18, 3.522e-18, 2.461e-18, 1.726e-18, 1.22e-18, 8.75e-19,
829 6.264e-19, 4.482e-19, 3.207e-19, 2.368e-19, 1.762e-19, 1.312e-19,
830 9.891e-20, 7.595e-20, 5.87e-20, 4.567e-20, 3.612e-20, 2.904e-20,
831 2.343e-20, 1.917e-20, 1.568e-20, 1.308e-20, 1.1e-20, 9.25e-21,
832 7.881e-21
833 };
834
835 static const double n2o[121] = {
836 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07, 3.17e-07,
837 3.17e-07, 3.17e-07, 3.17e-07, 3.124e-07, 3.077e-07, 3.03e-07,
838 2.984e-07, 2.938e-07, 2.892e-07, 2.847e-07, 2.779e-07, 2.705e-07,
839 2.631e-07, 2.557e-07, 2.484e-07, 2.345e-07, 2.201e-07, 2.01e-07,
840 1.754e-07, 1.532e-07, 1.329e-07, 1.154e-07, 1.003e-07, 8.735e-08,
841 7.617e-08, 6.512e-08, 5.547e-08, 4.709e-08, 3.915e-08, 3.259e-08,
842 2.738e-08, 2.327e-08, 1.98e-08, 1.711e-08, 1.493e-08, 1.306e-08,
843 1.165e-08, 1.049e-08, 9.439e-09, 8.375e-09, 7.391e-09, 6.525e-09,
844 5.759e-09, 5.083e-09, 4.485e-09, 3.953e-09, 3.601e-09, 3.27e-09,
845 2.975e-09, 2.757e-09, 2.556e-09, 2.37e-09, 2.195e-09, 2.032e-09,
846 1.912e-09, 1.79e-09, 1.679e-09, 1.572e-09, 1.482e-09, 1.402e-09,
847 1.326e-09, 1.254e-09, 1.187e-09, 1.127e-09, 1.071e-09, 1.02e-09,
848 9.673e-10, 9.193e-10, 8.752e-10, 8.379e-10, 8.017e-10, 7.66e-10,
849 7.319e-10, 7.004e-10, 6.721e-10, 6.459e-10, 6.199e-10, 5.942e-10,
850 5.703e-10, 5.488e-10, 5.283e-10, 5.082e-10, 4.877e-10, 4.696e-10,
851 4.52e-10, 4.355e-10, 4.198e-10, 4.039e-10, 3.888e-10, 3.754e-10,
852 3.624e-10, 3.499e-10, 3.381e-10, 3.267e-10, 3.163e-10, 3.058e-10,
853 2.959e-10, 2.864e-10, 2.77e-10, 2.686e-10, 2.604e-10, 2.534e-10,
854 2.462e-10, 2.386e-10, 2.318e-10, 2.247e-10, 2.189e-10, 2.133e-10,
855 2.071e-10, 2.014e-10, 1.955e-10, 1.908e-10, 1.86e-10, 1.817e-10
856 };
857
858 static const double n2o5[121] = {
859 1.231e-11, 3.035e-12, 1.702e-12, 9.877e-13, 8.081e-13, 9.039e-13,
860 1.169e-12, 1.474e-12, 1.651e-12, 1.795e-12, 1.998e-12, 2.543e-12,
861 4.398e-12, 7.698e-12, 1.28e-11, 2.131e-11, 3.548e-11, 5.894e-11,
862 7.645e-11, 1.089e-10, 1.391e-10, 1.886e-10, 2.386e-10, 2.986e-10,
863 3.487e-10, 3.994e-10, 4.5e-10, 4.6e-10, 4.591e-10, 4.1e-10, 3.488e-10,
864 2.846e-10, 2.287e-10, 1.696e-10, 1.011e-10, 6.428e-11, 4.324e-11,
865 2.225e-11, 6.214e-12, 3.608e-12, 8.793e-13, 4.491e-13, 1.04e-13,
866 6.1e-14, 3.436e-14, 6.671e-15, 1.171e-15, 5.848e-16, 1.212e-16,
867 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
868 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
869 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
870 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
871 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
872 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
873 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16, 1e-16,
874 1e-16, 1e-16
875 };
876
877 static const double nh3[121] = {
878 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10,
879 1e-10, 1e-10, 1e-10, 1e-10, 9.444e-11, 8.488e-11, 7.241e-11, 5.785e-11,
880 4.178e-11, 3.018e-11, 2.18e-11, 1.574e-11, 1.137e-11, 8.211e-12,
881 5.973e-12, 4.327e-12, 3.118e-12, 2.234e-12, 1.573e-12, 1.04e-12,
882 6.762e-13, 4.202e-13, 2.406e-13, 1.335e-13, 6.938e-14, 3.105e-14,
883 1.609e-14, 1.033e-14, 6.432e-15, 4.031e-15, 2.555e-15, 1.656e-15,
884 1.115e-15, 7.904e-16, 5.63e-16, 4.048e-16, 2.876e-16, 2.004e-16,
885 1.356e-16, 9.237e-17, 6.235e-17, 4.223e-17, 3.009e-17, 2.328e-17,
886 2.002e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
887 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
888 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
889 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
890 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
891 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
892 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
893 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
894 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
895 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
896 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17, 1.914e-17,
897 1.914e-17
898 };
899
900 static const double no[121] = {
901 2.586e-10, 4.143e-11, 1.566e-11, 9.591e-12, 8.088e-12, 8.462e-12,
902 1.013e-11, 1.328e-11, 1.855e-11, 2.678e-11, 3.926e-11, 5.464e-11,
903 7.012e-11, 8.912e-11, 1.127e-10, 1.347e-10, 1.498e-10, 1.544e-10,
904 1.602e-10, 1.824e-10, 2.078e-10, 2.366e-10, 2.691e-10, 5.141e-10,
905 8.259e-10, 1.254e-09, 1.849e-09, 2.473e-09, 3.294e-09, 4.16e-09,
906 5.095e-09, 6.11e-09, 6.93e-09, 7.888e-09, 8.903e-09, 9.713e-09,
907 1.052e-08, 1.115e-08, 1.173e-08, 1.21e-08, 1.228e-08, 1.239e-08,
908 1.231e-08, 1.213e-08, 1.192e-08, 1.138e-08, 1.085e-08, 1.008e-08,
909 9.224e-09, 8.389e-09, 7.262e-09, 6.278e-09, 5.335e-09, 4.388e-09,
910 3.589e-09, 2.761e-09, 2.129e-09, 1.633e-09, 1.243e-09, 9.681e-10,
911 8.355e-10, 7.665e-10, 7.442e-10, 8.584e-10, 9.732e-10, 1.063e-09,
912 1.163e-09, 1.286e-09, 1.472e-09, 1.707e-09, 2.032e-09, 2.474e-09,
913 2.977e-09, 3.506e-09, 4.102e-09, 5.013e-09, 6.493e-09, 8.414e-09,
914 1.077e-08, 1.367e-08, 1.777e-08, 2.625e-08, 3.926e-08, 5.545e-08,
915 7.195e-08, 9.464e-08, 1.404e-07, 2.183e-07, 3.329e-07, 4.535e-07,
916 6.158e-07, 8.187e-07, 1.075e-06, 1.422e-06, 1.979e-06, 2.71e-06,
917 3.58e-06, 4.573e-06, 5.951e-06, 7.999e-06, 1.072e-05, 1.372e-05,
918 1.697e-05, 2.112e-05, 2.643e-05, 3.288e-05, 3.994e-05, 4.794e-05,
919 5.606e-05, 6.383e-05, 7.286e-05, 8.156e-05, 8.883e-05, 9.469e-05,
920 9.848e-05, 0.0001023, 0.0001066, 0.0001115, 0.0001145, 0.0001142,
921 0.0001133
922 };
923
924 static const double no2[121] = {
925 3.036e-09, 2.945e-10, 9.982e-11, 5.069e-11, 3.485e-11, 2.982e-11,
926 2.947e-11, 3.164e-11, 3.714e-11, 4.586e-11, 6.164e-11, 8.041e-11,
927 9.982e-11, 1.283e-10, 1.73e-10, 2.56e-10, 3.909e-10, 5.959e-10,
928 9.081e-10, 1.384e-09, 1.788e-09, 2.189e-09, 2.686e-09, 3.091e-09,
929 3.49e-09, 3.796e-09, 4.2e-09, 5.103e-09, 6.005e-09, 6.3e-09, 6.706e-09,
930 7.07e-09, 7.434e-09, 7.663e-09, 7.788e-09, 7.8e-09, 7.597e-09,
931 7.482e-09, 7.227e-09, 6.403e-09, 5.585e-09, 4.606e-09, 3.703e-09,
932 2.984e-09, 2.183e-09, 1.48e-09, 8.441e-10, 5.994e-10, 3.799e-10,
933 2.751e-10, 1.927e-10, 1.507e-10, 1.102e-10, 6.971e-11, 5.839e-11,
934 3.904e-11, 3.087e-11, 2.176e-11, 1.464e-11, 1.209e-11, 8.497e-12,
935 6.477e-12, 4.371e-12, 2.914e-12, 2.424e-12, 1.753e-12, 1.35e-12,
936 9.417e-13, 6.622e-13, 5.148e-13, 3.841e-13, 3.446e-13, 3.01e-13,
937 2.551e-13, 2.151e-13, 1.829e-13, 1.64e-13, 1.475e-13, 1.352e-13,
938 1.155e-13, 9.963e-14, 9.771e-14, 9.577e-14, 9.384e-14, 9.186e-14,
939 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14,
940 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14,
941 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14,
942 9e-14, 9e-14, 9e-14, 9e-14, 9e-14, 9e-14
943 };
944
945 static const double o3[121] = {
946 2.218e-08, 3.394e-08, 3.869e-08, 4.219e-08, 4.501e-08, 4.778e-08,
947 5.067e-08, 5.402e-08, 5.872e-08, 6.521e-08, 7.709e-08, 9.461e-08,
948 1.269e-07, 1.853e-07, 2.723e-07, 3.964e-07, 5.773e-07, 8.2e-07,
949 1.155e-06, 1.59e-06, 2.076e-06, 2.706e-06, 3.249e-06, 3.848e-06,
950 4.459e-06, 4.986e-06, 5.573e-06, 5.958e-06, 6.328e-06, 6.661e-06,
951 6.9e-06, 7.146e-06, 7.276e-06, 7.374e-06, 7.447e-06, 7.383e-06,
952 7.321e-06, 7.161e-06, 6.879e-06, 6.611e-06, 6.216e-06, 5.765e-06,
953 5.355e-06, 4.905e-06, 4.471e-06, 4.075e-06, 3.728e-06, 3.413e-06,
954 3.125e-06, 2.856e-06, 2.607e-06, 2.379e-06, 2.17e-06, 1.978e-06,
955 1.8e-06, 1.646e-06, 1.506e-06, 1.376e-06, 1.233e-06, 1.102e-06,
956 9.839e-07, 8.771e-07, 7.814e-07, 6.947e-07, 6.102e-07, 5.228e-07,
957 4.509e-07, 3.922e-07, 3.501e-07, 3.183e-07, 2.909e-07, 2.686e-07,
958 2.476e-07, 2.284e-07, 2.109e-07, 2.003e-07, 2.013e-07, 2.022e-07,
959 2.032e-07, 2.042e-07, 2.097e-07, 2.361e-07, 2.656e-07, 2.989e-07,
960 3.37e-07, 3.826e-07, 4.489e-07, 5.26e-07, 6.189e-07, 7.312e-07,
961 8.496e-07, 8.444e-07, 8.392e-07, 8.339e-07, 8.286e-07, 8.234e-07,
962 8.181e-07, 8.129e-07, 8.077e-07, 8.026e-07, 6.918e-07, 5.176e-07,
963 3.865e-07, 2.885e-07, 2.156e-07, 1.619e-07, 1.219e-07, 9.161e-08,
964 6.972e-08, 5.399e-08, 3.498e-08, 2.111e-08, 1.322e-08, 8.482e-09,
965 5.527e-09, 3.423e-09, 2.071e-09, 1.314e-09, 8.529e-10, 5.503e-10,
966 3.665e-10
967 };
968
969 static const double ocs[121] = {
970 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 6e-10, 5.997e-10,
971 5.989e-10, 5.881e-10, 5.765e-10, 5.433e-10, 5.074e-10, 4.567e-10,
972 4.067e-10, 3.601e-10, 3.093e-10, 2.619e-10, 2.232e-10, 1.805e-10,
973 1.46e-10, 1.187e-10, 8.03e-11, 5.435e-11, 3.686e-11, 2.217e-11,
974 1.341e-11, 8.756e-12, 4.511e-12, 2.37e-12, 1.264e-12, 8.28e-13,
975 5.263e-13, 3.209e-13, 1.717e-13, 9.068e-14, 4.709e-14, 2.389e-14,
976 1.236e-14, 1.127e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
977 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
978 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
979 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
980 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
981 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
982 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
983 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
984 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
985 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
986 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
987 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
988 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14, 1.091e-14,
989 1.091e-14, 1.091e-14, 1.091e-14
990 };
991
992 static const double sf6[121] = {
993 4.103e-12, 4.103e-12, 4.103e-12, 4.103e-12, 4.103e-12, 4.103e-12,
994 4.103e-12, 4.103e-12, 4.103e-12, 4.087e-12, 4.064e-12, 4.023e-12,
995 3.988e-12, 3.941e-12, 3.884e-12, 3.755e-12, 3.622e-12, 3.484e-12,
996 3.32e-12, 3.144e-12, 2.978e-12, 2.811e-12, 2.653e-12, 2.489e-12,
997 2.332e-12, 2.199e-12, 2.089e-12, 2.013e-12, 1.953e-12, 1.898e-12,
998 1.859e-12, 1.826e-12, 1.798e-12, 1.776e-12, 1.757e-12, 1.742e-12,
999 1.728e-12, 1.717e-12, 1.707e-12, 1.698e-12, 1.691e-12, 1.685e-12,
1000 1.679e-12, 1.675e-12, 1.671e-12, 1.668e-12, 1.665e-12, 1.663e-12,
1001 1.661e-12, 1.659e-12, 1.658e-12, 1.657e-12, 1.656e-12, 1.655e-12,
1002 1.654e-12, 1.653e-12, 1.653e-12, 1.652e-12, 1.652e-12, 1.652e-12,
1003 1.651e-12, 1.651e-12, 1.651e-12, 1.651e-12, 1.651e-12, 1.651e-12,
1004 1.651e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1005 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1006 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1007 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1008 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1009 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1010 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12,
1011 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12, 1.65e-12
1012 };
1013
1014 static const double so2[121] = {
1015 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10, 1e-10,
1016 1e-10, 1e-10, 9.867e-11, 9.537e-11, 9e-11, 8.404e-11, 7.799e-11,
1017 7.205e-11, 6.616e-11, 6.036e-11, 5.475e-11, 5.007e-11, 4.638e-11,
1018 4.346e-11, 4.055e-11, 3.763e-11, 3.471e-11, 3.186e-11, 2.905e-11,
1019 2.631e-11, 2.358e-11, 2.415e-11, 2.949e-11, 3.952e-11, 5.155e-11,
1020 6.76e-11, 8.741e-11, 1.099e-10, 1.278e-10, 1.414e-10, 1.512e-10,
1021 1.607e-10, 1.699e-10, 1.774e-10, 1.832e-10, 1.871e-10, 1.907e-10,
1022 1.943e-10, 1.974e-10, 1.993e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1023 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1024 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1025 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1026 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1027 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1028 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10,
1029 2e-10, 2e-10, 2e-10, 2e-10, 2e-10, 2e-10
1030 };
1031
1032 const double *q[NG] = { NULL };
1033
1034 /* Identify variable... */
1035 for (int ig = 0; ig < ctl->ng; ig++) {
1036 q[ig] = NULL;
1037 if (strcasecmp(ctl->emitter[ig], "C2H2") == 0)
1038 q[ig] = c2h2;
1039 if (strcasecmp(ctl->emitter[ig], "C2H6") == 0)
1040 q[ig] = c2h6;
1041 if (strcasecmp(ctl->emitter[ig], "CCl4") == 0)
1042 q[ig] = ccl4;
1043 if (strcasecmp(ctl->emitter[ig], "CH3OH") == 0)
1044 q[ig] = ch3oh;
1045 if (strcasecmp(ctl->emitter[ig], "CH4") == 0)
1046 q[ig] = ch4;
1047 if (strcasecmp(ctl->emitter[ig], "ClO") == 0)
1048 q[ig] = clo;
1049 if (strcasecmp(ctl->emitter[ig], "ClONO2") == 0)
1050 q[ig] = clono2;
1051 if (strcasecmp(ctl->emitter[ig], "CO") == 0)
1052 q[ig] = co;
1053 if (strcasecmp(ctl->emitter[ig], "COF2") == 0)
1054 q[ig] = cof2;
1055 if (strcasecmp(ctl->emitter[ig], "F11") == 0)
1056 q[ig] = f11;
1057 if (strcasecmp(ctl->emitter[ig], "F113") == 0)
1058 q[ig] = f113;
1059 if (strcasecmp(ctl->emitter[ig], "F114") == 0)
1060 q[ig] = f114;
1061 if (strcasecmp(ctl->emitter[ig], "F12") == 0)
1062 q[ig] = f12;
1063 if (strcasecmp(ctl->emitter[ig], "F14") == 0)
1064 q[ig] = f14;
1065 if (strcasecmp(ctl->emitter[ig], "F22") == 0)
1066 q[ig] = f22;
1067 if (strcasecmp(ctl->emitter[ig], "H2CO") == 0)
1068 q[ig] = h2co;
1069 if (strcasecmp(ctl->emitter[ig], "H2O") == 0)
1070 q[ig] = h2o;
1071 if (strcasecmp(ctl->emitter[ig], "H2O2") == 0)
1072 q[ig] = h2o2;
1073 if (strcasecmp(ctl->emitter[ig], "HCl") == 0)
1074 q[ig] = hcl;
1075 if (strcasecmp(ctl->emitter[ig], "HCN") == 0)
1076 q[ig] = hcn;
1077 if (strcasecmp(ctl->emitter[ig], "HF") == 0)
1078 q[ig] = hf;
1079 if (strcasecmp(ctl->emitter[ig], "HNO3") == 0)
1080 q[ig] = hno3;
1081 if (strcasecmp(ctl->emitter[ig], "HNO4") == 0)
1082 q[ig] = hno4;
1083 if (strcasecmp(ctl->emitter[ig], "HOCl") == 0)
1084 q[ig] = hocl;
1085 if (strcasecmp(ctl->emitter[ig], "N2O") == 0)
1086 q[ig] = n2o;
1087 if (strcasecmp(ctl->emitter[ig], "N2O5") == 0)
1088 q[ig] = n2o5;
1089 if (strcasecmp(ctl->emitter[ig], "NH3") == 0)
1090 q[ig] = nh3;
1091 if (strcasecmp(ctl->emitter[ig], "NO") == 0)
1092 q[ig] = no;
1093 if (strcasecmp(ctl->emitter[ig], "NO2") == 0)
1094 q[ig] = no2;
1095 if (strcasecmp(ctl->emitter[ig], "O3") == 0)
1096 q[ig] = o3;
1097 if (strcasecmp(ctl->emitter[ig], "OCS") == 0)
1098 q[ig] = ocs;
1099 if (strcasecmp(ctl->emitter[ig], "SF6") == 0)
1100 q[ig] = sf6;
1101 if (strcasecmp(ctl->emitter[ig], "SO2") == 0)
1102 q[ig] = so2;
1103 }
1104
1105 /* Loop over atmospheric data points... */
1106 for (int ip = 0; ip < atm->np; ip++) {
1107
1108 /* Get altitude index... */
1109 const int iz = locate_reg(z, 121, atm->z[ip]);
1110
1111 /* Interpolate pressure... */
1112 atm->p[ip] = LOGY(z[iz], pre[iz], z[iz + 1], pre[iz + 1], atm->z[ip]);
1113
1114 /* Interpolate temperature and trace gases, holding them constant
1115 above the top of the built-in climatology table... */
1116 const double zt = MIN(atm->z[ip], z[120]);
1117
1118 atm->t[ip] = LIN(z[iz], tem[iz], z[iz + 1], tem[iz + 1], zt);
1119
1120 for (int ig = 0; ig < ctl->ng; ig++)
1121 if (q[ig] != NULL)
1122 atm->q[ig][ip] =
1123 LIN(z[iz], q[ig][iz], z[iz + 1], q[ig][iz + 1], zt);
1124 else
1125 atm->q[ig][ip] = 0;
1126
1127 /* Set CO2... */
1128 if (ctl->ig_co2 >= 0)
1129 atm->q[ctl->ig_co2][ip] = CO2_FIT(atm->time[ip]);
1130
1131 /* Set N2... */
1132 if (ctl->ig_n2 >= 0)
1133 atm->q[ctl->ig_n2][ip] = N2;
1134
1135 /* Set O2... */
1136 if (ctl->ig_o2 >= 0)
1137 atm->q[ctl->ig_o2][ip] = O2;
1138
1139 /* Set extinction to zero... */
1140 for (int iw = 0; iw < ctl->nw; iw++)
1141 atm->k[iw][ip] = 0;
1142
1143 /* Set cloud layer... */
1144 atm->clz = atm->cldz = 0;
1145 for (int icl = 0; icl < ctl->ncl; icl++)
1146 atm->clk[icl] = 0;
1147
1148 /* Set surface... */
1149 atm->sft = 0;
1150 for (int isf = 0; isf < ctl->nsf; isf++)
1151 atm->sfeps[isf] = 1;
1152 }
1153
1154 /* Overwrite with JuMACS climatology... */
1155 if (clim != NULL)
1156 climatology_external(ctl, clim, atm);
1157 else
1158 LOG(1, "Use built-in climatology...");
1159
1160 /* Ensure non-negative trace-gas mixing ratios... */
1161 for (int ip = 0; ip < atm->np; ip++)
1162 for (int ig = 0; ig < ctl->ng; ig++)
1163 atm->q[ig][ip] = MAX(atm->q[ig][ip], 0.0);
1164}
1165
1166/*****************************************************************************/
1167
1169 const char *filename,
1170 const char *varname,
1171 const int ncid,
1172 const int dim_month,
1173 const int dim_alt,
1174 const int dim_lat,
1175 const int nalt,
1176 const int nlat,
1177 double field[CT][CZ][CLAT],
1178 double *vmin,
1179 double *vmax) {
1180
1181 int varid;
1182
1183 /* Skip missing variables... */
1184 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR)
1185 return 0;
1186
1187 /* Check dimensions... */
1188 int ndims = 0;
1189 int dims[3] = { -1, -1, -1 };
1190 NC(nc_inq_varndims(ncid, varid, &ndims));
1191 if (ndims != 3)
1192 ERRMSG("NetCDF variable %s in climatology file %s has wrong number of "
1193 "dimensions!", varname, filename);
1194 NC(nc_inq_vardimid(ncid, varid, dims));
1195 if (dims[0] != dim_month || dims[1] != dim_alt || dims[2] != dim_lat)
1196 ERRMSG("NetCDF variable %s in climatology file %s has wrong dimensions!",
1197 varname, filename);
1198
1199 /* Read the whole field in a single call into a compact temporary buffer
1200 and copy it into the padded target array, checking for non-finite
1201 values... */
1202 double *tmp;
1203 ALLOC(tmp, double, (size_t) CT * (size_t) nalt * (size_t) nlat);
1204 NC(nc_get_var_double(ncid, varid, tmp));
1205 double min = 1e100;
1206 double max = -1e100;
1207 for (int m = 0; m < CT; m++)
1208 for (int iz = 0; iz < nalt; iz++)
1209 for (int il = 0; il < nlat; il++) {
1210 const size_t idx = ((size_t) m * (size_t) nalt + (size_t) iz)
1211 * (size_t) nlat + (size_t) il;
1212 if (!isfinite(tmp[idx]))
1213 ERRMSG("Non-finite value in NetCDF variable %s of climatology "
1214 "file %s!", varname, filename);
1215 min = MIN(min, tmp[idx]);
1216 max = MAX(max, tmp[idx]);
1217 field[m][iz][il] = tmp[idx];
1218 }
1219 free(tmp);
1220
1221 *vmin = min;
1222 *vmax = max;
1223
1224 return 1;
1225}
1226
1227/*****************************************************************************/
1228
1229/* Width of transition region towards built-in climatology [km]. */
1230#define CLIM_TRANSITION 20.
1231
1232/* Top-boundary policies for blending back to the built-in climatology
1233 above the JuMACS model top. Default is a cosine blend of the mixing
1234 ratio itself. Gases for which such a blend is scientifically less
1235 appropriate instead keep the top-level JuMACS value constant with
1236 altitude... */
1237#define CLIM_TOP_CONSTANT 1
1238#define CLIM_TOP_LOG 2
1239
1240static int climatology_external_top_policy(
1241 const char *emitter) {
1242 static const char *constant_gases[] = {
1243 "C2H6", "CCl4", "F11", "F12", "F22", "H2CO", "HNO3", "HNO4",
1244 "N2O", "N2O5", "NO2", "OCS"
1245 };
1246 static const char *log_gases[] = { "ClONO2" };
1247
1248 for (size_t i = 0; i < sizeof(constant_gases) / sizeof(constant_gases[0]);
1249 i++)
1250 if (strcasecmp(emitter, constant_gases[i]) == 0)
1251 return CLIM_TOP_CONSTANT;
1252
1253 for (size_t i = 0; i < sizeof(log_gases) / sizeof(log_gases[0]); i++)
1254 if (strcasecmp(emitter, log_gases[i]) == 0)
1255 return CLIM_TOP_LOG;
1256
1257 return 0;
1258}
1259
1261 const clim_t *clim,
1262 const atm_t *atm,
1263 const double field[CT][CZ][CLAT],
1264 const int top_policy,
1265 double *out) {
1266
1267 const double *alt = clim->alt;
1268 const double *latg = clim->lat;
1269 const int nalt = clim->nalt;
1270 const int nlat = clim->nlat;
1271
1272 /* JuMACS model top... */
1273 const double ztop = alt[nalt - 1];
1274
1275 /* Length of a climatological year [s]... */
1276 const double year = 365.25 * 86400.;
1277
1278 for (int ip = 0; ip < atm->np; ip++) {
1279
1280 /* Keep built-in climatology above the transition region, except for
1281 fields with constant extrapolation... */
1282 if (top_policy != CLIM_TOP_CONSTANT &&
1283 atm->z[ip] >= ztop + CLIM_TRANSITION)
1284 continue;
1285
1286 /* Position within the climatological year... */
1287 double sec = FMOD(atm->time[ip], year);
1288 while (sec < 0)
1289 sec += year;
1290
1291 /* Determine climatological time interval, cyclically interpolating
1292 between December and January across the turn of the year... */
1293 int it;
1294 double t0, t1;
1295 if (sec < clim->time[0]) {
1296 it = clim->ntime - 1;
1297 t0 = clim->time[it] - year;
1298 t1 = clim->time[0];
1299 } else if (sec >= clim->time[clim->ntime - 1]) {
1300 it = clim->ntime - 1;
1301 t0 = clim->time[it];
1302 t1 = clim->time[0] + year;
1303 } else {
1304 it = locate_irr(clim->time, clim->ntime, sec);
1305 t0 = clim->time[it];
1306 t1 = clim->time[it + 1];
1307 }
1308 const int it2 = (it + 1) % clim->ntime;
1309
1310 /* Latitude index (clamped at the polar band centers)... */
1311 double latq = atm->lat[ip];
1312 if (latq < latg[0])
1313 latq = latg[0];
1314 else if (latq > latg[nlat - 1])
1315 latq = latg[nlat - 1];
1316 const int il = locate_reg(latg, nlat, latq);
1317
1318 /* Altitude index (clamped at the JuMACS grid boundaries)... */
1319 double zq = atm->z[ip];
1320 if (zq < alt[0])
1321 zq = alt[0];
1322 else if (zq > ztop)
1323 zq = ztop;
1324 const int iz = locate_reg(alt, nalt, zq);
1325
1326 /* Trilinear interpolation (linear in all directions)... */
1327 const double v0 = LIN(alt[iz],
1328 LIN(latg[il], field[it][iz][il], latg[il + 1],
1329 field[it][iz][il + 1], latq),
1330 alt[iz + 1],
1331 LIN(latg[il], field[it][iz + 1][il], latg[il + 1],
1332 field[it][iz + 1][il + 1], latq), zq);
1333 const double v1 = LIN(alt[iz],
1334 LIN(latg[il], field[it2][iz][il], latg[il + 1],
1335 field[it2][iz][il + 1], latq),
1336 alt[iz + 1],
1337 LIN(latg[il], field[it2][iz + 1][il], latg[il + 1],
1338 field[it2][iz + 1][il + 1], latq), zq);
1339
1340 const double jumacs = LIN(t0, v0, t1, v1, sec);
1341
1342 /* Blend smoothly towards the built-in climatology above the model
1343 top, using a cosine taper over the transition region; before
1344 overwriting, out[] holds the built-in climatology. For gases with
1345 constant extrapolation, keep the top-level JuMACS value. For gases
1346 with logarithmic blending, taper the logarithms of the mixing
1347 ratios if both are strictly positive, falling back to the ordinary
1348 blend otherwise... */
1349 if (atm->z[ip] > ztop && top_policy != CLIM_TOP_CONSTANT) {
1350 const double x = (atm->z[ip] - ztop) / CLIM_TRANSITION;
1351 const double w = 0.5 * (1. + cos(M_PI * x));
1352 if (top_policy == CLIM_TOP_LOG && jumacs > 0. && out[ip] > 0.)
1353 out[ip] = exp(w * log(jumacs) + (1. - w) * log(out[ip]));
1354 else
1355 out[ip] = w * jumacs + (1. - w) * out[ip];
1356 } else
1357 out[ip] = jumacs;
1358 }
1359}
1360
1361/*****************************************************************************/
1362
1364 const ctl_t *ctl) {
1365
1366 /* No JuMACS climatology requested... */
1367 if (strcmp(ctl->climfile, "-") == 0)
1368 return NULL;
1369
1370 /* Allocate... */
1371 clim_t *clim;
1372 ALLOC(clim, clim_t, 1);
1373
1374 /* Start with an empty climatology... */
1375 memset(clim, 0, sizeof(clim_t));
1376
1377 /* Set climatological time coordinates as seconds into a year of 365.25
1378 days, matching the centers of the twelve monthly fields... */
1379 static const double jumacs_time[CT] = { 1209600.0, 3888000.0, 6393600.0,
1380 9072000.0, 11664000.0, 14342400.0,
1381 16934400.0, 19612800.0, 22291200.0,
1382 24883200.0, 27561600.0, 30153600.0
1383 };
1384 clim->ntime = CT;
1385 memcpy(clim->time, jumacs_time, sizeof(clim->time));
1386
1387 LOG(1, "Read JuMACS climatology: %s", ctl->climfile);
1388
1389 /* Open climatology file... */
1390 int ncid;
1391 const int status = nc_open(ctl->climfile, NC_NOWRITE, &ncid);
1392 if (status != NC_NOERR)
1393 ERRMSG("Cannot open climatology file %s: %s",
1394 ctl->climfile, nc_strerror(status));
1395
1396 /* Check dimensions... */
1397 int dim_month, dim_alt, dim_lat;
1398 size_t len;
1399 if (nc_inq_dimid(ncid, "month", &dim_month) != NC_NOERR ||
1400 nc_inq_dimlen(ncid, dim_month, &len) != NC_NOERR || (int) len != 12)
1401 ERRMSG("Climatology file %s has no dimension 'month' of length 12 - "
1402 "not a JuMACS climatology file?", ctl->climfile);
1403 if (nc_inq_dimid(ncid, "altitude", &dim_alt) != NC_NOERR ||
1404 nc_inq_dimlen(ncid, dim_alt, &len) != NC_NOERR || (int) len < 2)
1405 ERRMSG("Climatology file %s has no dimension 'altitude' - "
1406 "not a JuMACS climatology file?", ctl->climfile);
1407 if ((int) len > CZ)
1408 ERRMSG("Climatology file %s has %d altitude levels, exceeding the "
1409 "maximum of %d supported by this version of JURASSIC!",
1410 ctl->climfile, (int) len, CZ);
1411 clim->nalt = (int) len;
1412 if (nc_inq_dimid(ncid, "lat", &dim_lat) != NC_NOERR ||
1413 nc_inq_dimlen(ncid, dim_lat, &len) != NC_NOERR || (int) len < 2)
1414 ERRMSG("Climatology file %s has no dimension 'lat' - "
1415 "not a JuMACS climatology file?", ctl->climfile);
1416 if ((int) len > CLAT)
1417 ERRMSG("Climatology file %s has %d latitude bands, exceeding the "
1418 "maximum of %d supported by this version of JURASSIC!",
1419 ctl->climfile, (int) len, CLAT);
1420 clim->nlat = (int) len;
1421
1422 /* Read and check coordinates... */
1423 int varid;
1424 int ndims;
1425 int dims[4];
1426 if (nc_inq_varid(ncid, "altitude", &varid) != NC_NOERR)
1427 ERRMSG("Cannot find coordinate 'altitude' in climatology file %s!",
1428 ctl->climfile);
1429 ndims = 0;
1430 NC(nc_inq_varndims(ncid, varid, &ndims));
1431 if (ndims != 1)
1432 ERRMSG("Coordinate 'altitude' in climatology file %s is not a "
1433 "one-dimensional variable!", ctl->climfile);
1434 NC(nc_inq_vardimid(ncid, varid, dims));
1435 if (dims[0] != dim_alt)
1436 ERRMSG("Coordinate 'altitude' in climatology file %s does not use the "
1437 "dimension 'altitude'!", ctl->climfile);
1438 NC(nc_get_var_double(ncid, varid, clim->alt));
1439 if (nc_inq_varid(ncid, "lat", &varid) != NC_NOERR)
1440 ERRMSG("Cannot find coordinate 'lat' in climatology file %s!",
1441 ctl->climfile);
1442 ndims = 0;
1443 NC(nc_inq_varndims(ncid, varid, &ndims));
1444 if (ndims != 1)
1445 ERRMSG("Coordinate 'lat' in climatology file %s is not a "
1446 "one-dimensional variable!", ctl->climfile);
1447 NC(nc_inq_vardimid(ncid, varid, dims));
1448 if (dims[0] != dim_lat)
1449 ERRMSG("Coordinate 'lat' in climatology file %s does not use the "
1450 "dimension 'lat'!", ctl->climfile);
1451 NC(nc_get_var_double(ncid, varid, clim->lat));
1452 for (int i = 0; i < clim->nalt; i++) {
1453 if (!isfinite(clim->alt[i]))
1454 ERRMSG("Non-finite coordinate 'altitude' in climatology file %s!",
1455 ctl->climfile);
1456 if (i > 0 && clim->alt[i] <= clim->alt[i - 1])
1457 ERRMSG("Coordinate 'altitude' not strictly increasing in climatology "
1458 "file %s!", ctl->climfile);
1459 }
1460 for (int i = 0; i < clim->nlat; i++) {
1461 if (!isfinite(clim->lat[i]))
1462 ERRMSG("Non-finite coordinate 'lat' in climatology file %s!",
1463 ctl->climfile);
1464 if (i > 0 && clim->lat[i] <= clim->lat[i - 1])
1465 ERRMSG("Coordinate 'lat' not strictly increasing in climatology file "
1466 "%s!", ctl->climfile);
1467 }
1468
1469 /* Check that the coordinates are equally spaced, since the interpolation
1470 locates grid cells by index arithmetic rather than by searching... */
1471 const double dz = clim->alt[1] - clim->alt[0];
1472 for (int i = 2; i < clim->nalt; i++)
1473 if (fabs(clim->alt[i] - clim->alt[i - 1] - dz) > 1e-6 * fabs(dz))
1474 ERRMSG("Coordinate 'altitude' not equally spaced in climatology "
1475 "file %s - interpolation requires a regular grid!",
1476 ctl->climfile);
1477 const double dy = clim->lat[1] - clim->lat[0];
1478 for (int i = 2; i < clim->nlat; i++)
1479 if (fabs(clim->lat[i] - clim->lat[i - 1] - dy) > 1e-6 * fabs(dy))
1480 ERRMSG("Coordinate 'lat' not equally spaced in climatology "
1481 "file %s - interpolation requires a regular grid!",
1482 ctl->climfile);
1483
1484 LOG(2, "Number of time steps: %d", clim->ntime);
1485 LOG(2, "Altitude grid: %d levels, %g ... %g km | dz = %g km",
1486 clim->nalt, clim->alt[0], clim->alt[clim->nalt - 1], dz);
1487 LOG(2, "Latitude grid: %d bands, %g ... %g deg | dy = %g deg",
1488 clim->nlat, clim->lat[0], clim->lat[clim->nlat - 1], dy);
1489
1490 /* Read and check temperature... */
1491 double vmin;
1492 double vmax;
1493 if (!read_clim_field(ctl->climfile, "temperature_mean", ncid,
1494 dim_month, dim_alt, dim_lat, clim->nalt,
1495 clim->nlat, clim->t, &vmin, &vmax))
1496 ERRMSG("Climatology file %s has no variable 'temperature_mean' - "
1497 "not a complete JuMACS climatology file?", ctl->climfile);
1498 clim->has_t = 1;
1499 LOG(2, "Temperature: JuMACS temperature_mean, %g ... %g K", vmin, vmax);
1500
1501 /* Read trace gases... */
1502 /* Mapping of JURASSIC emitter names to JuMACS climatology variable base
1503 names. Species without an entry keep their built-in climatological
1504 values. CO2, N2, and O2 are deliberately not mapped, since they are
1505 handled specially by the built-in climatology. */
1506 const struct {
1507 const char *emitter;
1508 const char *varname;
1509 } jumacs_map[] = {
1510 {"C2H2", "c2h2"},
1511 {"C2H6", "c2h6"},
1512 {"CCl4", "ccl4"},
1513 {"CH4", "ch4"},
1514 {"ClO", "clo"},
1515 {"ClONO2", "clono2"},
1516 {"CO", "co"},
1517 {"F11", "cfc_11"},
1518 {"F12", "cfc_12"},
1519 {"F22", "hcfc_22"},
1520 {"H2CO", "ch2o"},
1521 {"H2O", "h2o"},
1522 {"H2O2", "h2o2"},
1523 {"HCl", "hcl"},
1524 {"HNO3", "hno3"},
1525 {"HNO4", "hno4"},
1526 {"HOCl", "hocl"},
1527 {"N2O", "n2o"},
1528 {"N2O5", "n2o5"},
1529 {"NO", "no"},
1530 {"NO2", "no2"},
1531 {"O3", "o3"},
1532 {"OCS", "cos"},
1533 {"SO2", "so2"}
1534 };
1535
1536 char varname[LEN];
1537 for (int ig = 0; ig < ctl->ng; ig++) {
1538 const char *base = NULL;
1539 for (size_t i = 0; i < sizeof(jumacs_map) / sizeof(jumacs_map[0]); i++)
1540 if (strcasecmp(ctl->emitter[ig], jumacs_map[i].emitter) == 0) {
1541 base = jumacs_map[i].varname;
1542 break;
1543 }
1544 if (base == NULL) {
1545 if (ig == ctl->ig_co2) {
1546 LOG(2, "%s: built-in CO2 fit", ctl->emitter[ig]);
1547 } else if (ig == ctl->ig_n2 || ig == ctl->ig_o2) {
1548 LOG(2, "%s: constant", ctl->emitter[ig]);
1549 } else {
1550 LOG(2, "%s: built-in climatology", ctl->emitter[ig]);
1551 }
1552 continue;
1553 }
1554 sprintf(varname, "%s_mean", base);
1555 clim->has_q[ig] = read_clim_field(ctl->climfile, varname,
1556 ncid, dim_month, dim_alt,
1557 dim_lat, clim->nalt,
1558 clim->nlat, clim->q[ig],
1559 &vmin, &vmax);
1560 if (clim->has_q[ig]) {
1561 LOG(2, "%s: JuMACS %s, %g ... %g ppv", ctl->emitter[ig], varname,
1562 vmin, vmax);
1563 } else {
1564 LOG(2, "%s: built-in climatology (JuMACS variable %s not found)",
1565 ctl->emitter[ig], varname);
1566 }
1567 }
1568
1569 LOG(2, "Pressure: built-in climatology");
1570
1571 /* Close climatology file... */
1572 NC(nc_close(ncid));
1573
1574 /* Return pointer... */
1575 return clim;
1576}
1577
1578/*****************************************************************************/
1579
1581 const ctl_t *ctl,
1582 const clim_t *clim,
1583 atm_t *atm) {
1584
1585 /* Overwrite temperature... */
1586 if (clim->has_t)
1587 climatology_external_interp(clim, atm, clim->t, 0, atm->t);
1588
1589 /* Overwrite trace gases... */
1590 for (int ig = 0; ig < ctl->ng; ig++)
1591 if (clim->has_q[ig])
1592 climatology_external_interp(clim, atm, clim->q[ig],
1593 climatology_external_top_policy(
1594 ctl->emitter[ig]),
1595 atm->q[ig]);
1596}
1597
1598/*****************************************************************************/
1599
1600double cos_sza(
1601 const double sec,
1602 const double lon,
1603 const double lat) {
1604
1605 /* Number of days and fraction with respect to 2000-01-01T12:00Z... */
1606 const double D = sec / 86400 - 0.5;
1607
1608 /* Geocentric apparent ecliptic longitude [rad]... */
1609 const double g = DEG2RAD(357.529 + 0.98560028 * D);
1610 const double q = 280.459 + 0.98564736 * D;
1611 const double L = DEG2RAD(q + 1.915 * sin(g) + 0.020 * sin(2 * g));
1612
1613 /* Mean obliquity of the ecliptic [rad]... */
1614 const double e = DEG2RAD(23.439 - 0.00000036 * D);
1615
1616 /* Declination [rad]... */
1617 const double sindec = sin(e) * sin(L);
1618
1619 /* Right ascension [rad]... */
1620 const double ra = atan2(cos(e) * sin(L), cos(L));
1621
1622 /* Greenwich Mean Sidereal Time [h]... */
1623 const double GMST = 18.697374558 + 24.06570982441908 * D;
1624
1625 /* Local Sidereal Time [h]... */
1626 const double LST = GMST + lon / 15;
1627
1628 /* Hour angle [rad]... */
1629 const double h = LST / 12 * M_PI - ra;
1630
1631 /* Convert latitude... */
1632 const double lat_help = DEG2RAD(lat);
1633
1634 /* Return cosine of solar zenith angle... */
1635 return sin(lat_help) * sindec + cos(lat_help)
1636 * sqrt(1 - POW2(sindec)) * cos(h);
1637}
1638
1639/*****************************************************************************/
1640
1642 const gsl_vector *dx,
1643 const gsl_vector *dy,
1644 const gsl_matrix *s_a_inv,
1645 const gsl_vector *sig_eps_inv) {
1646
1647 double chisq_a, chisq_m = 0;
1648
1649 /* Get sizes... */
1650 const size_t m = dy->size;
1651 const size_t n = dx->size;
1652
1653 /* Allocate... */
1654 gsl_vector *x_aux = gsl_vector_alloc(n);
1655
1656 /* Determine normalized cost function...
1657 (chi^2 = 1/m * [dy^T * S_eps^{-1} * dy + dx^T * S_a^{-1} * dx]) */
1658 for (size_t i = 0; i < m; i++)
1659 chisq_m += POW2(gsl_vector_get(dy, i) * gsl_vector_get(sig_eps_inv, i));
1660 gsl_blas_dgemv(CblasNoTrans, 1.0, s_a_inv, dx, 0.0, x_aux);
1661 gsl_blas_ddot(dx, x_aux, &chisq_a);
1662
1663 /* Free... */
1664 gsl_vector_free(x_aux);
1665
1666 /* Return cost function value... */
1667 return (chisq_m + chisq_a) / (double) m;
1668}
1669
1670/*****************************************************************************/
1671
1672double ctmco2(
1673 const double nu,
1674 const double p,
1675 const double t,
1676 const double u) {
1677
1678 static const double co2296[2001] =
1679 { 9.3388e-5, 9.7711e-5, 1.0224e-4, 1.0697e-4,
1680 1.1193e-4, 1.1712e-4, 1.2255e-4, 1.2824e-4, 1.3419e-4, 1.4043e-4,
1681 1.4695e-4, 1.5378e-4, 1.6094e-4, 1.6842e-4, 1.7626e-4, 1.8447e-4,
1682 1.9307e-4, 2.0207e-4, 2.1149e-4, 2.2136e-4, 2.3169e-4, 2.4251e-4,
1683 2.5384e-4, 2.657e-4, 2.7813e-4, 2.9114e-4, 3.0477e-4, 3.1904e-4,
1684 3.3399e-4, 3.4965e-4, 3.6604e-4, 3.8322e-4, 4.0121e-4, 4.2006e-4,
1685 4.398e-4, 4.6047e-4, 4.8214e-4, 5.0483e-4, 5.286e-4, 5.535e-4,
1686 5.7959e-4, 6.0693e-4, 6.3557e-4, 6.6558e-4, 6.9702e-4, 7.2996e-4,
1687 7.6449e-4, 8.0066e-4, 8.3856e-4, 8.7829e-4, 9.1991e-4, 9.6354e-4,
1688 .0010093, .0010572, .0011074, .00116, .0012152, .001273,
1689 .0013336, .0013972, .0014638, .0015336, .0016068, .0016835,
1690 .001764, .0018483, .0019367, .0020295, .0021267, .0022286,
1691 .0023355, .0024476, .0025652, .0026885, .0028178, .0029534,
1692 .0030956, .0032448, .0034012, .0035654, .0037375, .0039181,
1693 .0041076, .0043063, .0045148, .0047336, .0049632, .005204,
1694 .0054567, .0057219, .0060002, .0062923, .0065988, .0069204,
1695 .007258, .0076123, .0079842, .0083746, .0087844, .0092146,
1696 .0096663, .01014, .010638, .011161, .01171, .012286, .012891,
1697 .013527, .014194, .014895, .015631, .016404, .017217, .01807,
1698 .018966, .019908, .020897, .021936, .023028, .024176, .025382,
1699 .026649, .027981, .02938, .030851, .032397, .034023, .035732,
1700 .037528, .039416, .041402, .04349, .045685, .047994, .050422,
1701 .052975, .055661, .058486, .061458, .064584, .067873, .071334,
1702 .074975, .078807, .082839, .087082, .091549, .096249, .1012,
1703 .10641, .11189, .11767, .12375, .13015, .13689, .14399, .15147,
1704 .15935, .16765, .17639, .18561, .19531, .20554, .21632, .22769,
1705 .23967, .25229, .2656, .27964, .29443, .31004, .3265, .34386,
1706 .36218, .3815, .40188, .42339, .44609, .47004, .49533, .52202,
1707 .5502, .57995, .61137, .64455, .6796, .71663, .75574, .79707,
1708 .84075, .88691, .9357, .98728, 1.0418, 1.0995, 1.1605, 1.225,
1709 1.2932, 1.3654, 1.4418, 1.5227, 1.6083, 1.6989, 1.7948, 1.8964,
1710 2.004, 2.118, 2.2388, 2.3668, 2.5025, 2.6463, 2.7988, 2.9606,
1711 3.1321, 3.314, 3.5071, 3.712, 3.9296, 4.1605, 4.4058, 4.6663,
1712 4.9431, 5.2374, 5.5501, 5.8818, 6.2353, 6.6114, 7.0115, 7.4372,
1713 7.8905, 8.3731, 8.8871, 9.4349, 10.019, 10.641, 11.305, 12.013,
1714 12.769, 13.576, 14.437, 15.358, 16.342, 17.39, 18.513, 19.716,
1715 21.003, 22.379, 23.854, 25.436, 27.126, 28.942, 30.89, 32.973,
1716 35.219, 37.634, 40.224, 43.021, 46.037, 49.29, 52.803, 56.447,
1717 60.418, 64.792, 69.526, 74.637, 80.182, 86.193, 92.713, 99.786,
1718 107.47, 115.84, 124.94, 134.86, 145.69, 157.49, 170.3, 184.39,
1719 199.83, 216.4, 234.55, 254.72, 276.82, 299.85, 326.16, 354.99,
1720 386.51, 416.68, 449.89, 490.12, 534.35, 578.25, 632.26, 692.61,
1721 756.43, 834.75, 924.11, 1016.9, 996.96, 1102.7, 1219.2, 1351.9,
1722 1494.3, 1654.1, 1826.5, 2027.9, 2249., 2453.8, 2714.4, 2999.4,
1723 3209.5, 3509., 3840.4, 3907.5, 4190.7, 4533.5, 4648.3, 5059.1,
1724 5561.6, 6191.4, 6820.8, 7905.9, 9362.2, 2431.3, 2211.3, 2046.8,
1725 2023.8, 1985.9, 1905.9, 1491.1, 1369.8, 1262.2, 1200.7, 887.74,
1726 820.25, 885.23, 887.21, 816.73, 1126.9, 1216.2, 1272.4, 1579.5,
1727 1634.2, 1656.3, 1657.9, 1789.5, 1670.8, 1509.5, 8474.6, 7489.2,
1728 6793.6, 6117., 5574.1, 5141.2, 5084.6, 4745.1, 4413.2, 4102.8,
1729 4024.7, 3715., 3398.6, 3100.8, 2900.4, 2629.2, 2374., 2144.7,
1730 1955.8, 1760.8, 1591.2, 1435.2, 1296.2, 1174., 1065.1, 967.76,
1731 999.48, 897.45, 809.23, 732.77, 670.26, 611.93, 560.11, 518.77,
1732 476.84, 438.8, 408.48, 380.21, 349.24, 322.71, 296.65, 272.85,
1733 251.96, 232.04, 213.88, 197.69, 182.41, 168.41, 155.79, 144.05,
1734 133.31, 123.48, 114.5, 106.21, 98.591, 91.612, 85.156, 79.204,
1735 73.719, 68.666, 63.975, 59.637, 56.35, 52.545, 49.042, 45.788,
1736 42.78, 39.992, 37.441, 35.037, 32.8, 30.744, 28.801, 26.986,
1737 25.297, 23.731, 22.258, 20.883, 19.603, 18.403, 17.295, 16.249,
1738 15.271, 14.356, 13.501, 12.701, 11.954, 11.254, 10.6, 9.9864,
1739 9.4118, 8.8745, 8.3714, 7.8997, 7.4578, 7.0446, 6.6573, 6.2949,
1740 5.9577, 5.6395, 5.3419, 5.063, 4.8037, 4.5608, 4.3452, 4.1364,
1741 3.9413, 3.7394, 3.562, 3.3932, 3.2325, 3.0789, 2.9318, 2.7898,
1742 2.6537, 2.5225, 2.3958, 2.2305, 2.1215, 2.0245, 1.9427, 1.8795,
1743 1.8336, 1.7604, 1.7016, 1.6419, 1.5282, 1.4611, 1.3443, 1.27,
1744 1.1675, 1.0824, 1.0534, .99833, .95854, .92981, .90887, .89346,
1745 .88113, .87068, .86102, .85096, .88262, .86151, .83565, .80518,
1746 .77045, .73736, .74744, .74954, .75773, .82267, .83493, .89402,
1747 .89725, .93426, .95564, .94045, .94174, .93404, .92035, .90456,
1748 .88621, .86673, .78117, .7515, .72056, .68822, .65658, .62764,
1749 .55984, .55598, .57407, .60963, .63763, .66198, .61132, .60972,
1750 .52496, .50649, .41872, .3964, .32422, .27276, .24048, .23772,
1751 .2286, .22711, .23999, .32038, .34371, .36621, .38561, .39953,
1752 .40636, .44913, .42716, .3919, .35477, .33935, .3351, .39746,
1753 .40993, .49398, .49956, .56157, .54742, .57295, .57386, .55417,
1754 .50745, .471, .43446, .39102, .34993, .31269, .27888, .24912,
1755 .22291, .19994, .17972, .16197, .14633, .13252, .12029, .10942,
1756 .099745, .091118, .083404, .076494, .070292, .064716, .059697,
1757 .055173, .051093, .047411, .044089, .041092, .038392, .035965,
1758 .033789, .031846, .030122, .028607, .02729, .026169, .025209,
1759 .024405, .023766, .023288, .022925, .022716, .022681, .022685,
1760 .022768, .023133, .023325, .023486, .024004, .024126, .024083,
1761 .023785, .024023, .023029, .021649, .021108, .019454, .017809,
1762 .017292, .016635, .017037, .018068, .018977, .018756, .017847,
1763 .016557, .016142, .014459, .012869, .012381, .010875, .0098701,
1764 .009285, .0091698, .0091701, .0096145, .010553, .01106, .012613,
1765 .014362, .015017, .016507, .017741, .01768, .017784, .0171,
1766 .016357, .016172, .017257, .018978, .020935, .021741, .023567,
1767 .025183, .025589, .026732, .027648, .028278, .028215, .02856,
1768 .029015, .029062, .028851, .028497, .027825, .027801, .026523,
1769 .02487, .022967, .022168, .020194, .018605, .017903, .018439,
1770 .019697, .020311, .020855, .020057, .018608, .016738, .015963,
1771 .013844, .011801, .011134, .0097573, .0086007, .0086226,
1772 .0083721, .0090978, .0097616, .0098426, .011317, .012853, .01447,
1773 .014657, .015771, .016351, .016079, .014829, .013431, .013185,
1774 .013207, .01448, .016176, .017971, .018265, .019526, .020455,
1775 .019797, .019802, .0194, .018176, .017505, .016197, .015339,
1776 .014401, .013213, .012203, .011186, .010236, .0093288, .0084854,
1777 .0076837, .0069375, .0062614, .0056628, .0051153, .0046015,
1778 .0041501, .003752, .0033996, .0030865, .0028077, .0025586,
1779 .0023355, .0021353, .0019553, .0017931, .0016466, .0015141,
1780 .0013941, .0012852, .0011862, .0010962, .0010142, 9.3935e-4,
1781 8.71e-4, 8.0851e-4, 7.5132e-4, 6.9894e-4, 6.5093e-4, 6.0689e-4,
1782 5.6647e-4, 5.2935e-4, 4.9525e-4, 4.6391e-4, 4.3509e-4, 4.086e-4,
1783 3.8424e-4, 3.6185e-4, 3.4126e-4, 3.2235e-4, 3.0498e-4, 2.8904e-4,
1784 2.7444e-4, 2.6106e-4, 2.4883e-4, 2.3766e-4, 2.275e-4, 2.1827e-4,
1785 2.0992e-4, 2.0239e-4, 1.9563e-4, 1.896e-4, 1.8427e-4, 1.796e-4,
1786 1.7555e-4, 1.7209e-4, 1.692e-4, 1.6687e-4, 1.6505e-4, 1.6375e-4,
1787 1.6294e-4, 1.6261e-4, 1.6274e-4, 1.6334e-4, 1.6438e-4, 1.6587e-4,
1788 1.678e-4, 1.7017e-4, 1.7297e-4, 1.762e-4, 1.7988e-4, 1.8399e-4,
1789 1.8855e-4, 1.9355e-4, 1.9902e-4, 2.0494e-4, 2.1134e-4, 2.1823e-4,
1790 2.2561e-4, 2.335e-4, 2.4192e-4, 2.5088e-4, 2.604e-4, 2.705e-4,
1791 2.8119e-4, 2.9251e-4, 3.0447e-4, 3.171e-4, 3.3042e-4, 3.4447e-4,
1792 3.5927e-4, 3.7486e-4, 3.9127e-4, 4.0854e-4, 4.267e-4, 4.4579e-4,
1793 4.6586e-4, 4.8696e-4, 5.0912e-4, 5.324e-4, 5.5685e-4, 5.8253e-4,
1794 6.0949e-4, 6.378e-4, 6.6753e-4, 6.9873e-4, 7.3149e-4, 7.6588e-4,
1795 8.0198e-4, 8.3987e-4, 8.7964e-4, 9.2139e-4, 9.6522e-4, .0010112,
1796 .0010595, .0011102, .0011634, .0012193, .001278, .0013396,
1797 .0014043, .0014722, .0015436, .0016185, .0016972, .0017799,
1798 .0018668, .001958, .0020539, .0021547, .0022606, .0023719,
1799 .002489, .002612, .0027414, .0028775, .0030206, .0031712,
1800 .0033295, .0034962, .0036716, .0038563, .0040506, .0042553,
1801 .0044709, .004698, .0049373, .0051894, .0054552, .0057354,
1802 .006031, .0063427, .0066717, .0070188, .0073854, .0077726,
1803 .0081816, .0086138, .0090709, .0095543, .010066, .010607,
1804 .011181, .011789, .012433, .013116, .013842, .014613, .015432,
1805 .016304, .017233, .018224, .019281, .020394, .021574, .022836,
1806 .024181, .025594, .027088, .028707, .030401, .032245, .034219,
1807 .036262, .038539, .040987, .043578, .04641, .04949, .052726,
1808 .056326, .0602, .064093, .068521, .073278, .077734, .083064,
1809 .088731, .093885, .1003, .1072, .11365, .12187, .13078, .13989,
1810 .15095, .16299, .17634, .19116, .20628, .22419, .24386, .26587,
1811 .28811, .31399, .34321, .36606, .39675, .42742, .44243, .47197,
1812 .49993, .49027, .51147, .52803, .48931, .49729, .5026, .43854,
1813 .441, .44766, .43414, .46151, .50029, .55247, .43855, .32115,
1814 .32607, .3431, .36119, .38029, .41179, .43996, .47144, .51853,
1815 .55362, .59122, .66338, .69877, .74001, .82923, .86907, .90361,
1816 1.0025, 1.031, 1.0559, 1.104, 1.1178, 1.1341, 1.1547, 1.351,
1817 1.4772, 1.4812, 1.4907, 1.512, 1.5442, 1.5853, 1.6358, 1.6963,
1818 1.7674, 1.8474, 1.9353, 2.0335, 2.143, 2.2592, 2.3853, 2.5217,
1819 2.6686, 2.8273, 2.9998, 3.183, 3.3868, 3.6109, 3.8564, 4.1159,
1820 4.4079, 4.7278, 5.0497, 5.3695, 5.758, 6.0834, 6.4976, 6.9312,
1821 7.38, 7.5746, 7.9833, 8.3791, 8.3956, 8.7501, 9.1067, 9.072,
1822 9.4649, 9.9112, 10.402, 10.829, 11.605, 12.54, 12.713, 10.443,
1823 10.825, 11.375, 11.955, 12.623, 13.326, 14.101, 15.041, 15.547,
1824 16.461, 17.439, 18.716, 19.84, 21.036, 22.642, 23.901, 25.244,
1825 27.03, 28.411, 29.871, 31.403, 33.147, 34.744, 36.456, 39.239,
1826 43.605, 45.162, 47.004, 49.093, 51.391, 53.946, 56.673, 59.629,
1827 63.167, 66.576, 70.254, 74.222, 78.477, 83.034, 87.914, 93.18,
1828 98.77, 104.74, 111.15, 117.95, 125.23, 133.01, 141.33, 150.21,
1829 159.71, 169.89, 180.93, 192.54, 204.99, 218.34, 232.65, 248.,
1830 264.47, 282.14, 301.13, 321.53, 343.48, 367.08, 392.5, 419.88,
1831 449.4, 481.26, 515.64, 552.79, 592.99, 636.48, 683.61, 734.65,
1832 789.99, 850.02, 915.14, 985.81, 1062.5, 1147.1, 1237.8, 1336.4,
1833 1443.2, 1558.9, 1684.2, 1819.2, 1965.2, 2122.6, 2291.7, 2470.8,
1834 2665.7, 2874.9, 3099.4, 3337.9, 3541., 3813.3, 4111.9, 4439.3,
1835 4798.9, 5196., 5639.2, 6087.5, 6657.7, 7306.7, 8040.7, 8845.5,
1836 9702.2, 10670., 11739., 12842., 14141., 15498., 17068., 18729.,
1837 20557., 22559., 25248., 27664., 30207., 32915., 35611., 38081.,
1838 40715., 43191., 41651., 42750., 43785., 44353., 44366., 44189.,
1839 43618., 42862., 41878., 35133., 35215., 36383., 39420., 44055.,
1840 44155., 45850., 46853., 39197., 38274., 29942., 28553., 21792.,
1841 21228., 17106., 14955., 18181., 19557., 21427., 23728., 26301.,
1842 28584., 30775., 32536., 33867., 40089., 39204., 37329., 34452.,
1843 31373., 33921., 34800., 36043., 44415., 45162., 52181., 50895.,
1844 54140., 50840., 50468., 48302., 44915., 40910., 36754., 32755.,
1845 29093., 25860., 22962., 20448., 18247., 16326., 14645., 13165.,
1846 11861., 10708., 9686.9, 8779.7, 7971.9, 7250.8, 6605.7, 6027.2,
1847 5507.3, 5039.1, 4616.6, 4234.8, 3889., 3575.4, 3290.5, 3031.3,
1848 2795.2, 2579.9, 2383.1, 2203.3, 2038.6, 1887.6, 1749.1, 1621.9,
1849 1505., 1397.4, 1298.3, 1207., 1122.8, 1045., 973.1, 906.64,
1850 845.16, 788.22, 735.48, 686.57, 641.21, 599.1, 559.99, 523.64,
1851 489.85, 458.42, 429.16, 401.92, 376.54, 352.88, 330.82, 310.24,
1852 291.03, 273.09, 256.34, 240.69, 226.05, 212.37, 199.57, 187.59,
1853 176.37, 165.87, 156.03, 146.82, 138.17, 130.07, 122.47, 115.34,
1854 108.65, 102.37, 96.473, 90.934, 85.73, 80.84, 76.243, 71.922,
1855 67.858, 64.034, 60.438, 57.052, 53.866, 50.866, 48.04, 45.379,
1856 42.872, 40.51, 38.285, 36.188, 34.211, 32.347, 30.588, 28.929,
1857 27.362, 25.884, 24.489, 23.171, 21.929, 20.755, 19.646, 18.599,
1858 17.61, 16.677, 15.795, 14.961, 14.174, 13.43, 12.725, 12.06,
1859 11.431, 10.834, 10.27, 9.7361, 9.2302, 8.7518, 8.2997, 7.8724,
1860 7.4674, 7.0848, 6.7226, 6.3794, 6.054, 5.745, 5.4525, 5.1752,
1861 4.9121, 4.6625, 4.4259, 4.2015, 3.9888, 3.7872, 3.5961, 3.4149,
1862 3.2431, 3.0802, 2.9257, 2.7792, 2.6402, 2.5084, 2.3834, 2.2648,
1863 2.1522, 2.0455, 1.9441, 1.848, 1.7567, 1.6701, 1.5878, 1.5097,
1864 1.4356, 1.3651, 1.2981, 1.2345, 1.174, 1.1167, 1.062, 1.0101,
1865 .96087, .91414, .86986, .82781, .78777, .74971, .71339, .67882,
1866 .64604, .61473, .58507, .55676, .52987, .5044, .48014, .45715,
1867 .43527, .41453, .3948, .37609, .35831, .34142, .32524, .30995,
1868 .29536, .28142, .26807, .25527, .24311, .23166, .22077, .21053,
1869 .20081, .19143, .18261, .17407, .16603, .15833, .15089, .14385,
1870 .13707, .13065, .12449, .11865, .11306, .10774, .10266, .097818,
1871 .093203, .088815, .084641, .080671, .076892, .073296, .069873,
1872 .066613, .06351, .060555, .05774, .055058, .052504, .050071,
1873 .047752, .045543, .043438, .041432, .039521, .037699, .035962,
1874 .034307, .032729, .031225, .029791, .028423, .02712, .025877,
1875 .024692, .023563, .022485, .021458, .020478, .019543, .018652,
1876 .017802, .016992, .016219, .015481, .014778, .014107, .013467,
1877 .012856, .012274, .011718, .011188, .010682, .0102, .0097393,
1878 .0093001, .008881, .0084812, .0080997, .0077358, .0073885,
1879 .0070571, .0067409, .0064393, .0061514, .0058768, .0056147,
1880 .0053647, .0051262, .0048987, .0046816, .0044745, .0042769,
1881 .0040884, .0039088, .0037373, .0035739, .003418, .0032693,
1882 .0031277, .0029926, .0028639, .0027413, .0026245, .0025133,
1883 .0024074, .0023066, .0022108, .0021196, .002033, .0019507,
1884 .0018726, .0017985, .0017282, .0016617, .0015988, .0015394,
1885 .0014834, .0014306, .0013811, .0013346, .0012911, .0012506,
1886 .0012131, .0011784, .0011465, .0011175, .0010912, .0010678,
1887 .0010472, .0010295, .0010147, .001003, 9.9428e-4, 9.8883e-4,
1888 9.8673e-4, 9.8821e-4, 9.9343e-4, .0010027, .0010164, .0010348,
1889 .0010586, .0010882, .0011245, .0011685, .0012145, .0012666,
1890 .0013095, .0013688, .0014048, .0014663, .0015309, .0015499,
1891 .0016144, .0016312, .001705, .0017892, .0018499, .0019715,
1892 .0021102, .0022442, .0024284, .0025893, .0027703, .0029445,
1893 .0031193, .003346, .0034552, .0036906, .0037584, .0040084,
1894 .0041934, .0044587, .0047093, .0049759, .0053421, .0055134,
1895 .0059048, .0058663, .0061036, .0063259, .0059657, .0060653,
1896 .0060972, .0055539, .0055653, .0055772, .005331, .0054953,
1897 .0055919, .0058684, .006183, .0066675, .0069808, .0075142,
1898 .0078536, .0084282, .0089454, .0094625, .0093703, .0095857,
1899 .0099283, .010063, .010521, .0097778, .0098175, .010379, .010447,
1900 .0105, .010617, .010706, .01078, .011177, .011212, .011304,
1901 .011446, .011603, .011816, .012165, .012545, .013069, .013539,
1902 .01411, .014776, .016103, .017016, .017994, .018978, .01998,
1903 .021799, .022745, .023681, .024627, .025562, .026992, .027958,
1904 .029013, .030154, .031402, .03228, .033651, .035272, .037088,
1905 .039021, .041213, .043597, .045977, .04877, .051809, .054943,
1906 .058064, .061528, .06537, .069309, .071928, .075752, .079589,
1907 .083352, .084096, .087497, .090817, .091198, .094966, .099045,
1908 .10429, .10867, .11518, .12269, .13126, .14087, .15161, .16388,
1909 .16423, .1759, .18721, .19994, .21275, .22513, .23041, .24231,
1910 .25299, .25396, .26396, .27696, .27929, .2908, .30595, .31433,
1911 .3282, .3429, .35944, .37467, .39277, .41245, .43326, .45649,
1912 .48152, .51897, .54686, .57877, .61263, .64962, .68983, .73945,
1913 .78619, .83537, .89622, .95002, 1.0067, 1.0742, 1.1355, 1.2007,
1914 1.2738, 1.347, 1.4254, 1.5094, 1.6009, 1.6976, 1.8019, 1.9148,
1915 2.0357, 2.166, 2.3066, 2.4579, 2.6208, 2.7966, 2.986, 3.188,
1916 3.4081, 3.6456, 3.9, 4.1747, 4.4712, 4.7931, 5.1359, 5.5097,
1917 5.9117, 6.3435, 6.8003, 7.3001, 7.8385, 8.3945, 9.011, 9.6869,
1918 10.392, 11.18, 12.036, 12.938, 13.944, 14.881, 16.029, 17.255,
1919 18.574, 19.945, 21.38, 22.9, 24.477, 26.128, 27.87, 29.037,
1920 30.988, 33.145, 35.506, 37.76, 40.885, 44.487, 48.505, 52.911,
1921 57.56, 61.964, 67.217, 72.26, 78.343, 85.08, 91.867, 99.435,
1922 107.68, 116.97, 127.12, 138.32, 150.26, 163.04, 174.81, 189.26,
1923 205.61, 224.68, 240.98, 261.88, 285.1, 307.58, 334.35, 363.53,
1924 394.68, 427.85, 458.85, 489.25, 472.87, 486.93, 496.27, 501.52,
1925 501.57, 497.14, 488.09, 476.32, 393.76, 388.51, 393.42, 414.45,
1926 455.12, 514.62, 520.38, 547.42, 562.6, 487.47, 480.83, 391.06,
1927 376.92, 303.7, 295.91, 256.03, 236.73, 280.38, 310.71, 335.53,
1928 367.88, 401.94, 435.52, 469.13, 497.94, 588.82, 597.94, 597.2,
1929 588.28, 571.2, 555.75, 603.56, 638.15, 680.75, 801.72, 848.01,
1930 962.15, 990.06, 1068.1, 1076.2, 1115.3, 1134.2, 1136.6, 1119.1,
1931 1108.9, 1090.6, 1068.7, 1041.9, 1005.4, 967.98, 927.08, 780.1,
1932 751.41, 733.12, 742.65, 785.56, 855.16, 852.45, 878.1, 784.59,
1933 777.81, 765.13, 622.93, 498.09, 474.89, 386.9, 378.48, 336.17,
1934 322.04, 329.57, 350.5, 383.38, 420.02, 462.39, 499.71, 531.98,
1935 654.99, 653.43, 639.99, 605.16, 554.16, 504.42, 540.64, 552.33,
1936 679.46, 699.51, 713.91, 832.17, 919.91, 884.96, 907.57, 846.56,
1937 818.56, 768.93, 706.71, 642.17, 575.95, 515.38, 459.07, 409.02,
1938 364.61, 325.46, 291.1, 260.89, 234.39, 211.01, 190.38, 172.11,
1939 155.91, 141.49, 128.63, 117.13, 106.84, 97.584, 89.262, 81.756,
1940 74.975, 68.842, 63.28, 58.232, 53.641, 49.46, 45.649, 42.168,
1941 38.991, 36.078, 33.409, 30.96, 28.71, 26.642, 24.737, 22.985,
1942 21.37, 19.882, 18.512, 17.242, 16.073, 14.987, 13.984, 13.05,
1943 12.186, 11.384, 10.637, 9.9436, 9.2988, 8.6991, 8.141, 7.6215,
1944 7.1378, 6.6872, 6.2671, 5.8754, 5.51, 5.1691, 4.851, 4.5539,
1945 4.2764, 4.0169, 3.7742, 3.5472, 3.3348, 3.1359, 2.9495, 2.7749,
1946 2.6113, 2.4578, 2.3139, 2.1789, 2.0523, 1.9334, 1.8219, 1.7171,
1947 1.6188, 1.5263, 1.4395, 1.3579, 1.2812, 1.209, 1.1411, 1.0773,
1948 1.0171, .96048, .90713, .85684, .80959, .76495, .72282, .68309,
1949 .64563, .61035, .57707, .54573, .51622, .48834, .46199, .43709,
1950 .41359, .39129, .37034, .35064, .33198, .31442, .29784, .28218,
1951 .26732, .25337, .24017, .22774, .21601, .20479, .19426
1952 };
1953
1954 static const double co2260[2001] =
1955 { 5.7971e-5, 6.0733e-5, 6.3628e-5, 6.6662e-5,
1956 6.9843e-5, 7.3176e-5, 7.6671e-5, 8.0334e-5, 8.4175e-5, 8.8201e-5,
1957 9.2421e-5, 9.6846e-5, 1.0149e-4, 1.0635e-4, 1.1145e-4, 1.1679e-4,
1958 1.224e-4, 1.2828e-4, 1.3444e-4, 1.409e-4, 1.4768e-4, 1.5479e-4,
1959 1.6224e-4, 1.7006e-4, 1.7826e-4, 1.8685e-4, 1.9587e-4, 2.0532e-4,
1960 2.1524e-4, 2.2565e-4, 2.3656e-4, 2.48e-4, 2.6001e-4, 2.7261e-4,
1961 2.8582e-4, 2.9968e-4, 3.1422e-4, 3.2948e-4, 3.4548e-4, 3.6228e-4,
1962 3.799e-4, 3.9838e-4, 4.1778e-4, 4.3814e-4, 4.595e-4, 4.8191e-4,
1963 5.0543e-4, 5.3012e-4, 5.5603e-4, 5.8321e-4, 6.1175e-4, 6.417e-4,
1964 6.7314e-4, 7.0614e-4, 7.4078e-4, 7.7714e-4, 8.1531e-4, 8.5538e-4,
1965 8.9745e-4, 9.4162e-4, 9.8798e-4, .0010367, .0010878, .0011415,
1966 .0011978, .001257, .0013191, .0013844, .001453, .0015249,
1967 .0016006, .00168, .0017634, .001851, .001943, .0020397, .0021412,
1968 .0022479, .00236, .0024778, .0026015, .0027316, .0028682,
1969 .0030117, .0031626, .0033211, .0034877, .0036628, .0038469,
1970 .0040403, .0042436, .0044574, .004682, .0049182, .0051665,
1971 .0054276, .0057021, .0059907, .0062942, .0066133, .0069489,
1972 .0073018, .0076729, .0080632, .0084738, .0089056, .0093599,
1973 .0098377, .01034, .010869, .011426, .012011, .012627, .013276,
1974 .013958, .014676, .015431, .016226, .017063, .017944, .018872,
1975 .019848, .020876, .021958, .023098, .024298, .025561, .026892,
1976 .028293, .029769, .031323, .032961, .034686, .036503, .038418,
1977 .040435, .042561, .044801, .047161, .049649, .052271, .055035,
1978 .057948, .061019, .064256, .06767, .07127, .075066, .079069,
1979 .083291, .087744, .092441, .097396, .10262, .10814, .11396,
1980 .1201, .12658, .13342, .14064, .14826, .1563, .1648, .17376,
1981 .18323, .19324, .2038, .21496, .22674, .23919, .25234, .26624,
1982 .28093, .29646, .31287, .33021, .34855, .36794, .38844, .41012,
1983 .43305, .45731, .48297, .51011, .53884, .56924, .60141, .63547,
1984 .67152, .70969, .75012, .79292, .83826, .8863, .93718, .99111,
1985 1.0482, 1.1088, 1.173, 1.2411, 1.3133, 1.3898, 1.471, 1.5571,
1986 1.6485, 1.7455, 1.8485, 1.9577, 2.0737, 2.197, 2.3278, 2.4668,
1987 2.6145, 2.7715, 2.9383, 3.1156, 3.3042, 3.5047, 3.7181, 3.9451,
1988 4.1866, 4.4437, 4.7174, 5.0089, 5.3192, 5.65, 6.0025, 6.3782,
1989 6.7787, 7.206, 7.6617, 8.1479, 8.6669, 9.221, 9.8128, 10.445,
1990 11.12, 11.843, 12.615, 13.441, 14.325, 15.271, 16.283, 17.367,
1991 18.529, 19.776, 21.111, 22.544, 24.082, 25.731, 27.504, 29.409,
1992 31.452, 33.654, 36.024, 38.573, 41.323, 44.29, 47.492, 50.951,
1993 54.608, 58.588, 62.929, 67.629, 72.712, 78.226, 84.207, 90.699,
1994 97.749, 105.42, 113.77, 122.86, 132.78, 143.61, 155.44, 168.33,
1995 182.48, 198.01, 214.87, 233.39, 253.86, 276.34, 300.3, 327.28,
1996 356.89, 389.48, 422.29, 458.99, 501.39, 548.13, 595.62, 652.74,
1997 716.54, 784.57, 866.78, 960.59, 1062.8, 1072.5, 1189.5, 1319.4,
1998 1467.6, 1630.2, 1813.7, 2016.9, 2253., 2515.3, 2773.5, 3092.8,
1999 3444.4, 3720.4, 4104.3, 4527.5, 4645.9, 5021.7, 5462.2, 5597.,
2000 6110.6, 6732.5, 7513.8, 8270.6, 9640.6, 11487., 2796.1, 2680.1,
2001 2441.6, 2404.2, 2334.8, 2215.2, 1642.5, 1477.9, 1328.1, 1223.5,
2002 843.34, 766.96, 831.65, 834.84, 774.85, 1156.3, 1275.6, 1366.1,
2003 1795.6, 1885., 1936.5, 1953.4, 2154.4, 2002.7, 1789.8, 10381.,
2004 9040., 8216.5, 7384.7, 6721.9, 6187.7, 6143.8, 5703.9, 5276.6,
2005 4873.1, 4736., 4325.3, 3927., 3554.1, 3286.1, 2950.1, 2642.4,
2006 2368.7, 2138.9, 1914., 1719.6, 1543.9, 1388.6, 1252.1, 1132.2,
2007 1024.1, 1025.4, 920.58, 829.59, 750.54, 685.01, 624.25, 570.14,
2008 525.81, 481.85, 441.95, 408.71, 377.23, 345.86, 318.51, 292.26,
2009 268.34, 247.04, 227.14, 209.02, 192.69, 177.59, 163.78, 151.26,
2010 139.73, 129.19, 119.53, 110.7, 102.57, 95.109, 88.264, 81.948,
2011 76.13, 70.768, 65.827, 61.251, 57.022, 53.495, 49.824, 46.443,
2012 43.307, 40.405, 37.716, 35.241, 32.923, 30.77, 28.78, 26.915,
2013 25.177, 23.56, 22.059, 20.654, 19.345, 18.126, 16.988, 15.93,
2014 14.939, 14.014, 13.149, 12.343, 11.589, 10.884, 10.225, 9.6093,
2015 9.0327, 8.4934, 7.9889, 7.5166, 7.0744, 6.6604, 6.2727, 5.9098,
2016 5.5701, 5.2529, 4.955, 4.676, 4.4148, 4.171, 3.9426, 3.7332,
2017 3.5347, 3.3493, 3.1677, 3.0025, 2.8466, 2.6994, 2.5601, 2.4277,
2018 2.3016, 2.1814, 2.0664, 1.9564, 1.8279, 1.7311, 1.6427, 1.5645,
2019 1.4982, 1.443, 1.374, 1.3146, 1.2562, 1.17, 1.1105, 1.0272,
2020 .96863, .89718, .83654, .80226, .75908, .72431, .69573, .67174,
2021 .65126, .63315, .61693, .60182, .58715, .59554, .57649, .55526,
2022 .53177, .50622, .48176, .4813, .47642, .47492, .50273, .50293,
2023 .52687, .52239, .53419, .53814, .52626, .52211, .51492, .50622,
2024 .49746, .48841, .4792, .43534, .41999, .40349, .38586, .36799,
2025 .35108, .31089, .30803, .3171, .33599, .35041, .36149, .32924,
2026 .32462, .27309, .25961, .20922, .19504, .15683, .13098, .11588,
2027 .11478, .11204, .11363, .12135, .16423, .17785, .19094, .20236,
2028 .21084, .2154, .24108, .22848, .20871, .18797, .17963, .17834,
2029 .21552, .22284, .26945, .27052, .30108, .28977, .29772, .29224,
2030 .27658, .24956, .22777, .20654, .18392, .16338, .1452, .12916,
2031 .1152, .10304, .092437, .083163, .075031, .067878, .061564,
2032 .055976, .051018, .046609, .042679, .03917, .036032, .033223,
2033 .030706, .02845, .026428, .024617, .022998, .021554, .02027,
2034 .019136, .018141, .017278, .016541, .015926, .015432, .015058,
2035 .014807, .014666, .014635, .014728, .014947, .01527, .015728,
2036 .016345, .017026, .017798, .018839, .019752, .020636, .021886,
2037 .022695, .02327, .023478, .024292, .023544, .022222, .021932,
2038 .020052, .018143, .017722, .017031, .017782, .01938, .020734,
2039 .020476, .019255, .017477, .016878, .014617, .012489, .011765,
2040 .0099077, .0086446, .0079446, .0078644, .0079763, .008671,
2041 .01001, .0108, .012933, .015349, .016341, .018484, .020254,
2042 .020254, .020478, .019591, .018595, .018385, .019913, .022254,
2043 .024847, .025809, .028053, .029924, .030212, .031367, .03222,
2044 .032739, .032537, .03286, .033344, .033507, .033499, .033339,
2045 .032809, .033041, .031723, .029837, .027511, .026603, .024032,
2046 .021914, .020948, .021701, .023425, .024259, .024987, .023818,
2047 .021768, .019223, .018144, .015282, .012604, .01163, .0097907,
2048 .008336, .0082473, .0079582, .0088077, .009779, .010129, .012145,
2049 .014378, .016761, .01726, .018997, .019998, .019809, .01819,
2050 .016358, .016099, .01617, .017939, .020223, .022521, .02277,
2051 .024279, .025247, .024222, .023989, .023224, .021493, .020362,
2052 .018596, .017309, .015975, .014466, .013171, .011921, .01078,
2053 .0097229, .0087612, .0078729, .0070682, .0063494, .0057156,
2054 .0051459, .0046273, .0041712, .0037686, .0034119, .003095,
2055 .0028126, .0025603, .0023342, .0021314, .0019489, .0017845,
2056 .001636, .0015017, .00138, .0012697, .0011694, .0010782,
2057 9.9507e-4, 9.1931e-4, 8.5013e-4, 7.869e-4, 7.2907e-4, 6.7611e-4,
2058 6.2758e-4, 5.8308e-4, 5.4223e-4, 5.0473e-4, 4.7027e-4, 4.3859e-4,
2059 4.0946e-4, 3.8265e-4, 3.5798e-4, 3.3526e-4, 3.1436e-4, 2.9511e-4,
2060 2.7739e-4, 2.6109e-4, 2.4609e-4, 2.3229e-4, 2.1961e-4, 2.0797e-4,
2061 1.9729e-4, 1.875e-4, 1.7855e-4, 1.7038e-4, 1.6294e-4, 1.5619e-4,
2062 1.5007e-4, 1.4456e-4, 1.3961e-4, 1.3521e-4, 1.3131e-4, 1.2789e-4,
2063 1.2494e-4, 1.2242e-4, 1.2032e-4, 1.1863e-4, 1.1733e-4, 1.1641e-4,
2064 1.1585e-4, 1.1565e-4, 1.158e-4, 1.1629e-4, 1.1712e-4, 1.1827e-4,
2065 1.1976e-4, 1.2158e-4, 1.2373e-4, 1.262e-4, 1.2901e-4, 1.3214e-4,
2066 1.3562e-4, 1.3944e-4, 1.4361e-4, 1.4814e-4, 1.5303e-4, 1.5829e-4,
2067 1.6394e-4, 1.6999e-4, 1.7644e-4, 1.8332e-4, 1.9063e-4, 1.984e-4,
2068 2.0663e-4, 2.1536e-4, 2.246e-4, 2.3436e-4, 2.4468e-4, 2.5558e-4,
2069 2.6708e-4, 2.7921e-4, 2.92e-4, 3.0548e-4, 3.1968e-4, 3.3464e-4,
2070 3.5039e-4, 3.6698e-4, 3.8443e-4, 4.0281e-4, 4.2214e-4, 4.4248e-4,
2071 4.6389e-4, 4.864e-4, 5.1009e-4, 5.3501e-4, 5.6123e-4, 5.888e-4,
2072 6.1781e-4, 6.4833e-4, 6.8043e-4, 7.142e-4, 7.4973e-4, 7.8711e-4,
2073 8.2644e-4, 8.6783e-4, 9.1137e-4, 9.5721e-4, .0010054, .0010562,
2074 .0011096, .0011659, .0012251, .0012875, .0013532, .0014224,
2075 .0014953, .001572, .0016529, .0017381, .0018279, .0019226,
2076 .0020224, .0021277, .0022386, .0023557, .0024792, .0026095,
2077 .002747, .0028921, .0030453, .0032071, .003378, .0035586,
2078 .0037494, .003951, .0041642, .0043897, .0046282, .0048805,
2079 .0051476, .0054304, .00573, .0060473, .0063837, .0067404,
2080 .0071188, .0075203, .0079466, .0083994, .0088806, .0093922,
2081 .0099366, .010516, .011134, .011792, .012494, .013244, .014046,
2082 .014898, .015808, .016781, .017822, .018929, .020108, .02138,
2083 .022729, .02419, .02576, .027412, .029233, .031198, .033301,
2084 .035594, .038092, .040767, .04372, .046918, .050246, .053974,
2085 .058009, .061976, .066586, .071537, .076209, .081856, .087998,
2086 .093821, .10113, .10913, .11731, .12724, .13821, .15025, .1639,
2087 .17807, .19472, .21356, .23496, .25758, .28387, .31389, .34104,
2088 .37469, .40989, .43309, .46845, .5042, .5023, .52981, .55275,
2089 .51075, .51976, .52457, .44779, .44721, .4503, .4243, .45244,
2090 .49491, .55399, .39021, .24802, .2501, .2618, .27475, .28879,
2091 .31317, .33643, .36257, .4018, .43275, .46525, .53333, .56599,
2092 .60557, .70142, .74194, .77736, .88567, .91182, .93294, .98407,
2093 .98772, .99176, .9995, 1.2405, 1.3602, 1.338, 1.3255, 1.3267,
2094 1.3404, 1.3634, 1.3967, 1.4407, 1.4961, 1.5603, 1.6328, 1.7153,
2095 1.8094, 1.9091, 2.018, 2.1367, 2.264, 2.4035, 2.5562, 2.7179,
2096 2.9017, 3.1052, 3.3304, 3.5731, 3.8488, 4.1553, 4.4769, 4.7818,
2097 5.1711, 5.5204, 5.9516, 6.4097, 6.8899, 7.1118, 7.5469, 7.9735,
2098 7.9511, 8.3014, 8.6418, 8.4757, 8.8256, 9.2294, 9.6923, 10.033,
2099 10.842, 11.851, 11.78, 8.8435, 9.1381, 9.5956, 10.076, 10.629,
2100 11.22, 11.883, 12.69, 13.163, 13.974, 14.846, 16.027, 17.053,
2101 18.148, 19.715, 20.907, 22.163, 23.956, 25.235, 26.566, 27.94,
2102 29.576, 30.956, 32.432, 35.337, 39.911, 41.128, 42.625, 44.386,
2103 46.369, 48.619, 51.031, 53.674, 56.825, 59.921, 63.286, 66.929,
2104 70.859, 75.081, 79.618, 84.513, 89.739, 95.335, 101.35, 107.76,
2105 114.63, 121.98, 129.87, 138.3, 147.34, 157.04, 167.56, 178.67,
2106 190.61, 203.43, 217.19, 231.99, 247.88, 264.98, 283.37, 303.17,
2107 324.49, 347.47, 372.25, 398.98, 427.85, 459.06, 492.8, 529.31,
2108 568.89, 611.79, 658.35, 708.91, 763.87, 823.65, 888.72, 959.58,
2109 1036.8, 1121.8, 1213.9, 1314.3, 1423.8, 1543., 1672.8, 1813.4,
2110 1966.1, 2131.4, 2309.5, 2499.3, 2705., 2925.7, 3161.6, 3411.3,
2111 3611.5, 3889.2, 4191.1, 4519.3, 4877.9, 5272.9, 5712.9, 6142.7,
2112 6719.6, 7385., 8145., 8977.7, 9831.9, 10827., 11934., 13063.,
2113 14434., 15878., 17591., 19435., 21510., 23835., 26835., 29740.,
2114 32878., 36305., 39830., 43273., 46931., 50499., 49586., 51598.,
2115 53429., 54619., 55081., 55102., 54485., 53487., 52042., 42689.,
2116 42607., 44020., 47994., 54169., 53916., 55808., 56642., 46049.,
2117 44243., 32929., 30658., 21963., 20835., 15962., 13679., 17652.,
2118 19680., 22388., 25625., 29184., 32520., 35720., 38414., 40523.,
2119 49228., 48173., 45678., 41768., 37600., 41313., 42654., 44465.,
2120 55736., 56630., 65409., 63308., 66572., 61845., 60379., 56777.,
2121 51920., 46601., 41367., 36529., 32219., 28470., 25192., 22362.,
2122 19907., 17772., 15907., 14273., 12835., 11567., 10445., 9450.2,
2123 8565.1, 7776., 7070.8, 6439.2, 5872.3, 5362.4, 4903., 4488.3,
2124 4113.4, 3773.8, 3465.8, 3186.1, 2931.7, 2700.1, 2488.8, 2296.,
2125 2119.8, 1958.6, 1810.9, 1675.6, 1551.4, 1437.3, 1332.4, 1236.,
2126 1147.2, 1065.3, 989.86, 920.22, 855.91, 796.48, 741.53, 690.69,
2127 643.62, 600.02, 559.6, 522.13, 487.35, 455.06, 425.08, 397.21,
2128 371.3, 347.2, 324.78, 303.9, 284.46, 266.34, 249.45, 233.7,
2129 219.01, 205.3, 192.5, 180.55, 169.38, 158.95, 149.2, 140.07,
2130 131.54, 123.56, 116.09, 109.09, 102.54, 96.405, 90.655, 85.266,
2131 80.213, 75.475, 71.031, 66.861, 62.948, 59.275, 55.827, 52.587,
2132 49.544, 46.686, 43.998, 41.473, 39.099, 36.867, 34.768, 32.795,
2133 30.939, 29.192, 27.546, 25.998, 24.539, 23.164, 21.869, 20.65,
2134 19.501, 18.419, 17.399, 16.438, 15.532, 14.678, 13.874, 13.115,
2135 12.4, 11.726, 11.088, 10.488, 9.921, 9.3846, 8.8784, 8.3996,
2136 7.9469, 7.5197, 7.1174, 6.738, 6.379, 6.0409, 5.7213, 5.419,
2137 5.1327, 4.8611, 4.6046, 4.3617, 4.1316, 3.9138, 3.7077, 3.5125,
2138 3.3281, 3.1536, 2.9885, 2.8323, 2.6846, 2.5447, 2.4124, 2.2871,
2139 2.1686, 2.0564, 1.9501, 1.8495, 1.7543, 1.6641, 1.5787, 1.4978,
2140 1.4212, 1.3486, 1.2799, 1.2147, 1.1529, 1.0943, 1.0388, .98602,
2141 .93596, .8886, .84352, .80078, .76029, .722, .68585, .65161,
2142 .61901, .58808, .55854, .53044, .5039, .47853, .45459, .43173,
2143 .41008, .38965, .37021, .35186, .33444, .31797, .30234, .28758,
2144 .2736, .26036, .24764, .2357, .22431, .21342, .20295, .19288,
2145 .18334, .17444, .166, .15815, .15072, .14348, .13674, .13015,
2146 .12399, .11807, .11231, .10689, .10164, .096696, .091955,
2147 .087476, .083183, .079113, .075229, .071536, .068026, .064698,
2148 .06154, .058544, .055699, .052997, .050431, .047993, .045676,
2149 .043475, .041382, .039392, .037501, .035702, .033991, .032364,
2150 .030817, .029345, .027945, .026613, .025345, .024139, .022991,
2151 .021899, .02086, .019871, .018929, .018033, .01718, .016368,
2152 .015595, .014859, .014158, .013491, .012856, .012251, .011675,
2153 .011126, .010604, .010107, .0096331, .009182, .0087523, .0083431,
2154 .0079533, .0075821, .0072284, .0068915, .0065706, .0062649,
2155 .0059737, .0056963, .005432, .0051802, .0049404, .0047118,
2156 .0044941, .0042867, .0040891, .0039009, .0037216, .0035507,
2157 .003388, .0032329, .0030852, .0029445, .0028105, .0026829,
2158 .0025613, .0024455, .0023353, .0022303, .0021304, .0020353,
2159 .0019448, .0018587, .0017767, .0016988, .0016247, .0015543,
2160 .0014874, .0014238, .0013635, .0013062, .0012519, .0012005,
2161 .0011517, .0011057, .0010621, .001021, 9.8233e-4, 9.4589e-4,
2162 9.1167e-4, 8.7961e-4, 8.4964e-4, 8.2173e-4, 7.9582e-4, 7.7189e-4,
2163 7.499e-4, 7.2983e-4, 7.1167e-4, 6.9542e-4, 6.8108e-4, 6.6866e-4,
2164 6.5819e-4, 6.4971e-4, 6.4328e-4, 6.3895e-4, 6.3681e-4, 6.3697e-4,
2165 6.3956e-4, 6.4472e-4, 6.5266e-4, 6.6359e-4, 6.778e-4, 6.9563e-4,
2166 7.1749e-4, 7.4392e-4, 7.7556e-4, 8.1028e-4, 8.4994e-4, 8.8709e-4,
2167 9.3413e-4, 9.6953e-4, .0010202, .0010738, .0010976, .0011507,
2168 .0011686, .0012264, .001291, .0013346, .0014246, .0015293,
2169 .0016359, .0017824, .0019255, .0020854, .002247, .0024148,
2170 .0026199, .0027523, .0029704, .0030702, .0033047, .0035013,
2171 .0037576, .0040275, .0043089, .0046927, .0049307, .0053486,
2172 .0053809, .0056699, .0059325, .0055488, .005634, .0056392,
2173 .004946, .0048855, .0048208, .0044386, .0045498, .0046377,
2174 .0048939, .0052396, .0057324, .0060859, .0066906, .0071148,
2175 .0077224, .0082687, .008769, .0084471, .008572, .0087729,
2176 .008775, .0090742, .0080704, .0080288, .0085747, .0086087,
2177 .0086408, .0088752, .0089381, .0089757, .0093532, .0092824,
2178 .0092566, .0092645, .0092735, .009342, .0095806, .0097991,
2179 .010213, .010611, .011129, .011756, .013237, .01412, .015034,
2180 .015936, .01682, .018597, .019315, .019995, .020658, .021289,
2181 .022363, .022996, .023716, .024512, .025434, .026067, .027118,
2182 .028396, .029865, .031442, .033253, .03525, .037296, .039701,
2183 .042356, .045154, .048059, .051294, .054893, .058636, .061407,
2184 .065172, .068974, .072676, .073379, .076547, .079556, .079134,
2185 .082308, .085739, .090192, .09359, .099599, .10669, .11496,
2186 .1244, .13512, .14752, .14494, .15647, .1668, .17863, .19029,
2187 .20124, .20254, .21179, .21982, .21625, .22364, .23405, .23382,
2188 .2434, .25708, .26406, .27621, .28909, .30395, .31717, .33271,
2189 .3496, .36765, .38774, .40949, .446, .46985, .49846, .5287, .562,
2190 .59841, .64598, .68834, .7327, .78978, .8373, .88708, .94744,
2191 1.0006, 1.0574, 1.1215, 1.1856, 1.2546, 1.3292, 1.4107, 1.4974,
2192 1.5913, 1.6931, 1.8028, 1.9212, 2.0492, 2.1874, 2.3365, 2.4978,
2193 2.6718, 2.8588, 3.062, 3.2818, 3.5188, 3.7752, 4.0527, 4.3542,
2194 4.6782, 5.0312, 5.4123, 5.8246, 6.2639, 6.7435, 7.2636, 7.8064,
2195 8.4091, 9.0696, 9.7677, 10.548, 11.4, 12.309, 13.324, 14.284,
2196 15.445, 16.687, 18.019, 19.403, 20.847, 22.366, 23.925, 25.537,
2197 27.213, 28.069, 29.864, 31.829, 33.988, 35.856, 38.829, 42.321,
2198 46.319, 50.606, 55.126, 59.126, 64.162, 68.708, 74.615, 81.176,
2199 87.739, 95.494, 103.83, 113.38, 123.99, 135.8, 148.7, 162.58,
2200 176.32, 192.6, 211.47, 232.7, 252.64, 277.41, 305.38, 333.44,
2201 366.42, 402.66, 442.14, 484.53, 526.42, 568.15, 558.78, 582.6,
2202 600.98, 613.94, 619.44, 618.24, 609.84, 595.96, 484.86, 475.59,
2203 478.49, 501.56, 552.19, 628.44, 630.39, 658.92, 671.96, 562.7,
2204 545.88, 423.43, 400.14, 306.59, 294.13, 246.8, 226.51, 278.21,
2205 314.39, 347.22, 389.13, 433.16, 477.48, 521.67, 560.54, 683.6,
2206 696.37, 695.91, 683.1, 658.24, 634.89, 698.85, 742.87, 796.66,
2207 954.49, 1009.5, 1150.5, 1179.1, 1267.9, 1272.4, 1312.7, 1330.4,
2208 1331.6, 1315.8, 1308.3, 1293.3, 1274.6, 1249.5, 1213.2, 1172.1,
2209 1124.4, 930.33, 893.36, 871.27, 883.54, 940.76, 1036., 1025.6,
2210 1053.1, 914.51, 894.15, 865.03, 670.63, 508.41, 475.15, 370.85,
2211 361.06, 319.38, 312.75, 331.87, 367.13, 415., 467.94, 525.49,
2212 578.41, 624.66, 794.82, 796.97, 780.29, 736.49, 670.18, 603.75,
2213 659.67, 679.8, 857.12, 884.05, 900.65, 1046.1, 1141.9, 1083.,
2214 1089.2, 1e3, 947.08, 872.31, 787.91, 704.75, 624.93, 553.68,
2215 489.91, 434.21, 385.64, 343.3, 306.42, 274.18, 245.94, 221.11,
2216 199.23, 179.88, 162.73, 147.48, 133.88, 121.73, 110.86, 101.1,
2217 92.323, 84.417, 77.281, 70.831, 64.991, 59.694, 54.884, 50.509,
2218 46.526, 42.893, 39.58, 36.549, 33.776, 31.236, 28.907, 26.77,
2219 24.805, 23., 21.339, 19.81, 18.404, 17.105, 15.909, 14.801,
2220 13.778, 12.83, 11.954, 11.142, 10.389, 9.691, 9.0434, 8.4423,
2221 7.8842, 7.3657, 6.8838, 6.4357, 6.0189, 5.6308, 5.2696, 4.9332,
2222 4.6198, 4.3277, 4.0553, 3.8012, 3.5639, 3.3424, 3.1355, 2.9422,
2223 2.7614, 2.5924, 2.4343, 2.2864, 2.148, 2.0184, 1.8971, 1.7835,
2224 1.677, 1.5773, 1.4838, 1.3961, 1.3139, 1.2369, 1.1645, 1.0966,
2225 1.0329, .97309, .91686, .86406, .81439, .76767, .72381, .68252,
2226 .64359, .60695, .57247, .54008, .50957, .48092, .45401, .42862,
2227 .40465, .38202, .36072, .34052, .3216, .30386, .28711, .27135,
2228 .25651, .24252, .2293, .21689, .20517, .19416, .18381, .17396,
2229 .16469
2230 };
2231
2232 static const double co2230[2001] =
2233 { 2.743e-5, 2.8815e-5, 3.027e-5, 3.1798e-5,
2234 3.3405e-5, 3.5094e-5, 3.6869e-5, 3.8734e-5, 4.0694e-5, 4.2754e-5,
2235 4.492e-5, 4.7196e-5, 4.9588e-5, 5.2103e-5, 5.4747e-5, 5.7525e-5,
2236 6.0446e-5, 6.3516e-5, 6.6744e-5, 7.0137e-5, 7.3704e-5, 7.7455e-5,
2237 8.1397e-5, 8.5543e-5, 8.9901e-5, 9.4484e-5, 9.9302e-5, 1.0437e-4,
2238 1.097e-4, 1.153e-4, 1.2119e-4, 1.2738e-4, 1.3389e-4, 1.4074e-4,
2239 1.4795e-4, 1.5552e-4, 1.6349e-4, 1.7187e-4, 1.8068e-4, 1.8995e-4,
2240 1.997e-4, 2.0996e-4, 2.2075e-4, 2.321e-4, 2.4403e-4, 2.5659e-4,
2241 2.698e-4, 2.837e-4, 2.9832e-4, 3.137e-4, 3.2988e-4, 3.4691e-4,
2242 3.6483e-4, 3.8368e-4, 4.0351e-4, 4.2439e-4, 4.4635e-4, 4.6947e-4,
2243 4.9379e-4, 5.1939e-4, 5.4633e-4, 5.7468e-4, 6.0452e-4, 6.3593e-4,
2244 6.69e-4, 7.038e-4, 7.4043e-4, 7.79e-4, 8.1959e-4, 8.6233e-4,
2245 9.0732e-4, 9.5469e-4, .0010046, .0010571, .0011124, .0011706,
2246 .0012319, .0012964, .0013644, .001436, .0015114, .0015908,
2247 .0016745, .0017625, .0018553, .0019531, .002056, .0021645,
2248 .0022788, .0023992, .002526, .0026596, .0028004, .0029488,
2249 .0031052, .0032699, .0034436, .0036265, .0038194, .0040227,
2250 .0042369, .0044628, .0047008, .0049518, .0052164, .0054953,
2251 .0057894, .0060995, .0064265, .0067713, .007135, .0075184,
2252 .0079228, .0083494, .0087993, .0092738, .0097745, .010303,
2253 .01086, .011448, .012068, .012722, .013413, .014142, .014911,
2254 .015723, .01658, .017484, .018439, .019447, .020511, .021635,
2255 .022821, .024074, .025397, .026794, .02827, .029829, .031475,
2256 .033215, .035052, .036994, .039045, .041213, .043504, .045926,
2257 .048485, .05119, .05405, .057074, .060271, .063651, .067225,
2258 .071006, .075004, .079233, .083708, .088441, .093449, .098749,
2259 .10436, .11029, .11657, .12322, .13026, .13772, .14561, .15397,
2260 .16282, .1722, .18214, .19266, .20381, .21563, .22816, .24143,
2261 .2555, .27043, .28625, .30303, .32082, .3397, .35972, .38097,
2262 .40352, .42746, .45286, .47983, .50847, .53888, .57119, .6055,
2263 .64196, .6807, .72187, .76564, .81217, .86165, .91427, .97025,
2264 1.0298, 1.0932, 1.1606, 1.2324, 1.3088, 1.3902, 1.477, 1.5693,
2265 1.6678, 1.7727, 1.8845, 2.0038, 2.131, 2.2666, 2.4114, 2.5659,
2266 2.7309, 2.907, 3.0951, 3.2961, 3.5109, 3.7405, 3.986, 4.2485,
2267 4.5293, 4.8299, 5.1516, 5.4961, 5.8651, 6.2605, 6.6842, 7.1385,
2268 7.6256, 8.1481, 8.7089, 9.3109, 9.9573, 10.652, 11.398, 12.2,
2269 13.063, 13.992, 14.99, 16.064, 17.222, 18.469, 19.813, 21.263,
2270 22.828, 24.516, 26.34, 28.31, 30.437, 32.738, 35.226, 37.914,
2271 40.824, 43.974, 47.377, 51.061, 55.011, 59.299, 63.961, 69.013,
2272 74.492, 80.444, 86.919, 93.836, 101.23, 109.25, 117.98, 127.47,
2273 137.81, 149.07, 161.35, 174.75, 189.42, 205.49, 223.02, 242.26,
2274 263.45, 286.75, 311.94, 340.01, 370.86, 404.92, 440.44, 480.27,
2275 525.17, 574.71, 626.22, 686.8, 754.38, 827.07, 913.38, 1011.7,
2276 1121.5, 1161.6, 1289.5, 1432.2, 1595.4, 1777., 1983.3, 2216.1,
2277 2485.7, 2788.3, 3101.5, 3481., 3902.1, 4257.1, 4740., 5272.8,
2278 5457.9, 5946.2, 6505.3, 6668.4, 7302.4, 8061.6, 9015.8, 9908.3,
2279 11613., 13956., 3249.6, 3243., 2901.5, 2841.3, 2729.6, 2558.2,
2280 1797.8, 1583.2, 1386., 1233.5, 787.74, 701.46, 761.66, 767.21,
2281 722.83, 1180.6, 1332.1, 1461.6, 2032.9, 2166., 2255.9, 2294.7,
2282 2587.2, 2396.5, 2122.4, 12553., 10784., 9832.5, 8827.3, 8029.1,
2283 7377.9, 7347.1, 6783.8, 6239.1, 5721.1, 5503., 4975.1, 4477.8,
2284 4021.3, 3676.8, 3275.3, 2914.9, 2597.4, 2328.2, 2075.4, 1857.6,
2285 1663.6, 1493.3, 1343.8, 1213.3, 1095.6, 1066.5, 958.91, 865.15,
2286 783.31, 714.35, 650.77, 593.98, 546.2, 499.9, 457.87, 421.75,
2287 387.61, 355.25, 326.62, 299.7, 275.21, 253.17, 232.83, 214.31,
2288 197.5, 182.08, 167.98, 155.12, 143.32, 132.5, 122.58, 113.48,
2289 105.11, 97.415, 90.182, 83.463, 77.281, 71.587, 66.341, 61.493,
2290 57.014, 53.062, 49.21, 45.663, 42.38, 39.348, 36.547, 33.967,
2291 31.573, 29.357, 27.314, 25.415, 23.658, 22.03, 20.524, 19.125,
2292 17.829, 16.627, 15.511, 14.476, 13.514, 12.618, 11.786, 11.013,
2293 10.294, 9.6246, 9.0018, 8.4218, 7.8816, 7.3783, 6.9092, 6.4719,
2294 6.0641, 5.6838, 5.3289, 4.998, 4.6893, 4.4014, 4.1325, 3.8813,
2295 3.6469, 3.4283, 3.2241, 3.035, 2.8576, 2.6922, 2.5348, 2.3896,
2296 2.2535, 2.1258, 2.0059, 1.8929, 1.7862, 1.6854, 1.5898, 1.4992,
2297 1.4017, 1.3218, 1.2479, 1.1809, 1.1215, 1.0693, 1.0116, .96016,
2298 .9105, .84859, .80105, .74381, .69982, .65127, .60899, .57843,
2299 .54592, .51792, .49336, .47155, .45201, .43426, .41807, .40303,
2300 .38876, .3863, .37098, .35492, .33801, .32032, .30341, .29874,
2301 .29193, .28689, .29584, .29155, .29826, .29195, .29287, .2904,
2302 .28199, .27709, .27162, .26622, .26133, .25676, .25235, .23137,
2303 .22365, .21519, .20597, .19636, .18699, .16485, .16262, .16643,
2304 .17542, .18198, .18631, .16759, .16338, .13505, .1267, .10053,
2305 .092554, .074093, .062159, .055523, .054849, .05401, .05528,
2306 .058982, .07952, .08647, .093244, .099285, .10393, .10661,
2307 .12072, .11417, .10396, .093265, .089137, .088909, .10902,
2308 .11277, .13625, .13565, .14907, .14167, .1428, .13744, .12768,
2309 .11382, .10244, .091686, .08109, .071739, .063616, .056579,
2310 .050504, .045251, .040689, .036715, .033237, .030181, .027488,
2311 .025107, .022998, .021125, .01946, .017979, .016661, .015489,
2312 .014448, .013526, .012712, .011998, .011375, .010839, .010384,
2313 .010007, .0097053, .0094783, .0093257, .0092489, .0092504,
2314 .0093346, .0095077, .0097676, .01012, .01058, .011157, .011844,
2315 .012672, .013665, .014766, .015999, .017509, .018972, .020444,
2316 .022311, .023742, .0249, .025599, .026981, .026462, .025143,
2317 .025066, .022814, .020458, .020026, .019142, .020189, .022371,
2318 .024163, .023728, .02199, .019506, .018591, .015576, .012784,
2319 .011744, .0094777, .0079148, .0070652, .006986, .0071758,
2320 .008086, .0098025, .01087, .013609, .016764, .018137, .021061,
2321 .023498, .023576, .023965, .022828, .021519, .021283, .023364,
2322 .026457, .029782, .030856, .033486, .035515, .035543, .036558,
2323 .037198, .037472, .037045, .037284, .03777, .038085, .038366,
2324 .038526, .038282, .038915, .037697, .035667, .032941, .031959,
2325 .028692, .025918, .024596, .025592, .027873, .028935, .02984,
2326 .028148, .025305, .021912, .020454, .016732, .013357, .01205,
2327 .009731, .0079881, .0077704, .0074387, .0083895, .0096776,
2328 .010326, .01293, .015955, .019247, .020145, .02267, .024231,
2329 .024184, .022131, .019784, .01955, .01971, .022119, .025116,
2330 .027978, .028107, .029808, .030701, .029164, .028551, .027286,
2331 .024946, .023259, .020982, .019221, .017471, .015643, .014074,
2332 .01261, .011301, .010116, .0090582, .0081036, .0072542, .0065034,
2333 .0058436, .0052571, .0047321, .0042697, .0038607, .0034977,
2334 .0031747, .0028864, .0026284, .002397, .002189, .0020017,
2335 .0018326, .0016798, .0015414, .0014159, .0013019, .0011983,
2336 .0011039, .0010177, 9.391e-4, 8.6717e-4, 8.0131e-4, 7.4093e-4,
2337 6.8553e-4, 6.3464e-4, 5.8787e-4, 5.4487e-4, 5.0533e-4, 4.69e-4,
2338 4.3556e-4, 4.0474e-4, 3.7629e-4, 3.5e-4, 3.2569e-4, 3.032e-4,
2339 2.8239e-4, 2.6314e-4, 2.4535e-4, 2.2891e-4, 2.1374e-4, 1.9975e-4,
2340 1.8685e-4, 1.7498e-4, 1.6406e-4, 1.5401e-4, 1.4479e-4, 1.3633e-4,
2341 1.2858e-4, 1.2148e-4, 1.1499e-4, 1.0907e-4, 1.0369e-4, 9.8791e-5,
2342 9.4359e-5, 9.0359e-5, 8.6766e-5, 8.3555e-5, 8.0703e-5, 7.8192e-5,
2343 7.6003e-5, 7.4119e-5, 7.2528e-5, 7.1216e-5, 7.0171e-5, 6.9385e-5,
2344 6.8848e-5, 6.8554e-5, 6.8496e-5, 6.8669e-5, 6.9069e-5, 6.9694e-5,
2345 7.054e-5, 7.1608e-5, 7.2896e-5, 7.4406e-5, 7.6139e-5, 7.8097e-5,
2346 8.0283e-5, 8.2702e-5, 8.5357e-5, 8.8255e-5, 9.1402e-5, 9.4806e-5,
2347 9.8473e-5, 1.0241e-4, 1.0664e-4, 1.1115e-4, 1.1598e-4, 1.2112e-4,
2348 1.2659e-4, 1.3241e-4, 1.3859e-4, 1.4515e-4, 1.521e-4, 1.5947e-4,
2349 1.6728e-4, 1.7555e-4, 1.8429e-4, 1.9355e-4, 2.0334e-4, 2.1369e-4,
2350 2.2463e-4, 2.3619e-4, 2.4841e-4, 2.6132e-4, 2.7497e-4, 2.8938e-4,
2351 3.0462e-4, 3.2071e-4, 3.3771e-4, 3.5567e-4, 3.7465e-4, 3.947e-4,
2352 4.1588e-4, 4.3828e-4, 4.6194e-4, 4.8695e-4, 5.1338e-4, 5.4133e-4,
2353 5.7087e-4, 6.0211e-4, 6.3515e-4, 6.701e-4, 7.0706e-4, 7.4617e-4,
2354 7.8756e-4, 8.3136e-4, 8.7772e-4, 9.2681e-4, 9.788e-4, .0010339,
2355 .0010922, .001154, .0012195, .0012889, .0013626, .0014407,
2356 .0015235, .0016114, .0017048, .0018038, .001909, .0020207,
2357 .0021395, .0022657, .0023998, .0025426, .0026944, .002856,
2358 .0030281, .0032114, .0034068, .003615, .0038371, .004074,
2359 .004327, .0045971, .0048857, .0051942, .0055239, .0058766,
2360 .0062538, .0066573, .0070891, .007551, .0080455, .0085747,
2361 .0091412, .0097481, .010397, .011092, .011837, .012638, .013495,
2362 .014415, .01541, .016475, .017621, .018857, .020175, .02162,
2363 .023185, .024876, .02672, .028732, .030916, .033319, .035939,
2364 .038736, .041847, .04524, .048715, .052678, .056977, .061203,
2365 .066184, .07164, .076952, .083477, .090674, .098049, .10697,
2366 .1169, .1277, .14011, .15323, .1684, .18601, .20626, .22831,
2367 .25417, .28407, .31405, .34957, .38823, .41923, .46026, .50409,
2368 .51227, .54805, .57976, .53818, .55056, .557, .46741, .46403,
2369 .4636, .42265, .45166, .49852, .56663, .34306, .17779, .17697,
2370 .18346, .19129, .20014, .21778, .23604, .25649, .28676, .31238,
2371 .33856, .39998, .4288, .46568, .56654, .60786, .64473, .76466,
2372 .7897, .80778, .86443, .85736, .84798, .84157, 1.1385, 1.2446,
2373 1.1923, 1.1552, 1.1338, 1.1266, 1.1292, 1.1431, 1.1683, 1.2059,
2374 1.2521, 1.3069, 1.3712, 1.4471, 1.5275, 1.6165, 1.7145, 1.8189,
2375 1.9359, 2.065, 2.2007, 2.3591, 2.5362, 2.7346, 2.9515, 3.2021,
2376 3.4851, 3.7935, 4.0694, 4.4463, 4.807, 5.2443, 5.7178, 6.2231,
2377 6.4796, 6.9461, 7.4099, 7.3652, 7.7182, 8.048, 7.7373, 8.0363,
2378 8.3855, 8.8044, 9.0257, 9.8574, 10.948, 10.563, 6.8979, 7.0744,
2379 7.4121, 7.7663, 8.1768, 8.6243, 9.1437, 9.7847, 10.182, 10.849,
2380 11.572, 12.602, 13.482, 14.431, 15.907, 16.983, 18.11, 19.884,
2381 21.02, 22.18, 23.355, 24.848, 25.954, 27.13, 30.186, 34.893,
2382 35.682, 36.755, 38.111, 39.703, 41.58, 43.606, 45.868, 48.573,
2383 51.298, 54.291, 57.559, 61.116, 64.964, 69.124, 73.628, 78.471,
2384 83.683, 89.307, 95.341, 101.84, 108.83, 116.36, 124.46, 133.18,
2385 142.57, 152.79, 163.69, 175.43, 188.11, 201.79, 216.55, 232.51,
2386 249.74, 268.38, 288.54, 310.35, 333.97, 359.55, 387.26, 417.3,
2387 449.88, 485.2, 523.54, 565.14, 610.28, 659.31, 712.56, 770.43,
2388 833.36, 901.82, 976.36, 1057.6, 1146.8, 1243.8, 1350., 1466.3,
2389 1593.6, 1732.7, 1884.1, 2049.1, 2228.2, 2421.9, 2629.4, 2853.7,
2390 3094.4, 3351.1, 3622.3, 3829.8, 4123.1, 4438.3, 4777.2, 5144.1,
2391 5545.4, 5990.5, 6404.5, 6996.8, 7687.6, 8482.9, 9349.4, 10203.,
2392 11223., 12358., 13493., 14916., 16416., 18236., 20222., 22501.,
2393 25102., 28358., 31707., 35404., 39538., 43911., 48391., 53193.,
2394 58028., 58082., 61276., 64193., 66294., 67480., 67921., 67423.,
2395 66254., 64341., 51737., 51420., 53072., 58145., 66195., 65358.,
2396 67377., 67869., 53509., 50553., 35737., 32425., 21704., 19974.,
2397 14457., 12142., 16798., 19489., 23049., 27270., 31910., 36457.,
2398 40877., 44748., 47876., 59793., 58626., 55454., 50337., 44893.,
2399 50228., 52216., 54747., 69541., 70455., 81014., 77694., 80533.,
2400 73953., 70927., 65539., 59002., 52281., 45953., 40292., 35360.,
2401 31124., 27478., 24346., 21647., 19308., 17271., 15491., 13927.,
2402 12550., 11331., 10250., 9288.8, 8431.4, 7664.9, 6978.3, 6361.8,
2403 5807.4, 5307.7, 4856.8, 4449., 4079.8, 3744.9, 3440.8, 3164.2,
2404 2912.3, 2682.7, 2473., 2281.4, 2106., 1945.3, 1797.9, 1662.5,
2405 1538.1, 1423.6, 1318.1, 1221., 1131.5, 1049., 972.99, 902.87,
2406 838.01, 777.95, 722.2, 670.44, 622.35, 577.68, 536.21, 497.76,
2407 462.12, 429.13, 398.61, 370.39, 344.29, 320.16, 297.85, 277.2,
2408 258.08, 240.38, 223.97, 208.77, 194.66, 181.58, 169.43, 158.15,
2409 147.67, 137.92, 128.86, 120.44, 112.6, 105.3, 98.499, 92.166,
2410 86.264, 80.763, 75.632, 70.846, 66.381, 62.213, 58.321, 54.685,
2411 51.288, 48.114, 45.145, 42.368, 39.772, 37.341, 35.065, 32.937,
2412 30.943, 29.077, 27.33, 25.693, 24.158, 22.717, 21.367, 20.099,
2413 18.909, 17.792, 16.744, 15.761, 14.838, 13.971, 13.157, 12.393,
2414 11.676, 11.003, 10.369, 9.775, 9.2165, 8.6902, 8.1963, 7.7314,
2415 7.2923, 6.8794, 6.4898, 6.122, 5.7764, 5.4525, 5.1484, 4.8611,
2416 4.5918, 4.3379, 4.0982, 3.8716, 3.6567, 3.4545, 3.2634, 3.0828,
2417 2.9122, 2.7512, 2.5993, 2.4561, 2.3211, 2.1938, 2.0737, 1.9603,
2418 1.8534, 1.7525, 1.6572, 1.5673, 1.4824, 1.4022, 1.3265, 1.2551,
2419 1.1876, 1.1239, 1.0637, 1.0069, .9532, .90248, .85454, .80921,
2420 .76631, .72569, .6872, .65072, .61635, .5836, .55261, .52336,
2421 .49581, .46998, .44559, .42236, .40036, .37929, .35924, .34043,
2422 .32238, .30547, .28931, .27405, .25975, .24616, .23341, .22133,
2423 .20997, .19924, .18917, .17967, .17075, .16211, .15411, .14646,
2424 .13912, .13201, .12509, .11857, .11261, .10698, .10186, .097039,
2425 .092236, .087844, .083443, .07938, .075452, .071564, .067931,
2426 .064389, .061078, .057901, .054921, .052061, .049364, .046789,
2427 .04435, .042044, .039866, .037808, .035863, .034023, .032282,
2428 .030634, .029073, .027595, .026194, .024866, .023608, .022415,
2429 .021283, .02021, .019193, .018228, .017312, .016443, .015619,
2430 .014837, .014094, .01339, .012721, .012086, .011483, .010911,
2431 .010368, .009852, .0093623, .0088972, .0084556, .0080362,
2432 .0076379, .0072596, .0069003, .006559, .0062349, .0059269,
2433 .0056344, .0053565, .0050925, .0048417, .0046034, .004377,
2434 .0041618, .0039575, .0037633, .0035788, .0034034, .0032368,
2435 .0030785, .002928, .0027851, .0026492, .0025201, .0023975,
2436 .0022809, .0021701, .0020649, .0019649, .0018699, .0017796,
2437 .0016938, .0016122, .0015348, .0014612, .0013913, .001325,
2438 .0012619, .0012021, .0011452, .0010913, .0010401, 9.9149e-4,
2439 9.454e-4, 9.0169e-4, 8.6024e-4, 8.2097e-4, 7.8377e-4, 7.4854e-4,
2440 7.1522e-4, 6.8371e-4, 6.5393e-4, 6.2582e-4, 5.9932e-4, 5.7435e-4,
2441 5.5087e-4, 5.2882e-4, 5.0814e-4, 4.8881e-4, 4.7076e-4, 4.5398e-4,
2442 4.3843e-4, 4.2407e-4, 4.109e-4, 3.9888e-4, 3.88e-4, 3.7826e-4,
2443 3.6963e-4, 3.6213e-4, 3.5575e-4, 3.505e-4, 3.464e-4, 3.4346e-4,
2444 3.4173e-4, 3.4125e-4, 3.4206e-4, 3.4424e-4, 3.4787e-4, 3.5303e-4,
2445 3.5986e-4, 3.6847e-4, 3.7903e-4, 3.9174e-4, 4.0681e-4, 4.2455e-4,
2446 4.4527e-4, 4.6942e-4, 4.9637e-4, 5.2698e-4, 5.5808e-4, 5.9514e-4,
2447 6.2757e-4, 6.689e-4, 7.1298e-4, 7.3955e-4, 7.8403e-4, 8.0449e-4,
2448 8.5131e-4, 9.0256e-4, 9.3692e-4, .0010051, .0010846, .0011678,
2449 .001282, .0014016, .0015355, .0016764, .0018272, .0020055,
2450 .0021455, .0023421, .0024615, .0026786, .0028787, .0031259,
2451 .0034046, .0036985, .0040917, .0043902, .0048349, .0049531,
2452 .0052989, .0056148, .0052452, .0053357, .005333, .0045069,
2453 .0043851, .004253, .003738, .0038084, .0039013, .0041505,
2454 .0045372, .0050569, .0054507, .0061267, .0066122, .0072449,
2455 .0078012, .0082651, .0076538, .0076573, .0076806, .0075227,
2456 .0076269, .0063758, .006254, .0067749, .0067909, .0068231,
2457 .0072143, .0072762, .0072954, .007679, .0075107, .0073658,
2458 .0072441, .0071074, .0070378, .007176, .0072472, .0075844,
2459 .0079291, .008412, .0090165, .010688, .011535, .012375, .013166,
2460 .013895, .015567, .016011, .016392, .016737, .017043, .017731,
2461 .018031, .018419, .018877, .019474, .019868, .020604, .021538,
2462 .022653, .023869, .025288, .026879, .028547, .030524, .03274,
2463 .035132, .03769, .040567, .043793, .047188, .049962, .053542,
2464 .057205, .060776, .061489, .064419, .067124, .065945, .068487,
2465 .071209, .074783, .077039, .082444, .08902, .09692, .10617,
2466 .11687, .12952, .12362, .13498, .14412, .15492, .16519, .1744,
2467 .17096, .17714, .18208, .17363, .17813, .18564, .18295, .19045,
2468 .20252, .20815, .21844, .22929, .24229, .25321, .26588, .2797,
2469 .29465, .31136, .32961, .36529, .38486, .41027, .43694, .4667,
2470 .49943, .54542, .58348, .62303, .67633, .71755, .76054, .81371,
2471 .85934, .90841, .96438, 1.0207, 1.0821, 1.1491, 1.2226, 1.3018,
2472 1.388, 1.4818, 1.5835, 1.6939, 1.8137, 1.9435, 2.0843, 2.237,
2473 2.4026, 2.5818, 2.7767, 2.9885, 3.2182, 3.4679, 3.7391, 4.0349,
2474 4.3554, 4.7053, 5.0849, 5.4986, 5.9436, 6.4294, 6.9598, 7.5203,
2475 8.143, 8.8253, 9.5568, 10.371, 11.267, 12.233, 13.31, 14.357,
2476 15.598, 16.93, 18.358, 19.849, 21.408, 23.04, 24.706, 26.409,
2477 28.153, 28.795, 30.549, 32.43, 34.49, 36.027, 38.955, 42.465,
2478 46.565, 50.875, 55.378, 59.002, 63.882, 67.949, 73.693, 80.095,
2479 86.403, 94.264, 102.65, 112.37, 123.3, 135.54, 149.14, 163.83,
2480 179.17, 196.89, 217.91, 240.94, 264.13, 292.39, 324.83, 358.21,
2481 397.16, 440.5, 488.6, 541.04, 595.3, 650.43, 652.03, 688.74,
2482 719.47, 743.54, 757.68, 762.35, 756.43, 741.42, 595.43, 580.97,
2483 580.83, 605.68, 667.88, 764.49, 759.93, 789.12, 798.17, 645.66,
2484 615.65, 455.05, 421.09, 306.45, 289.14, 235.7, 215.52, 274.57,
2485 316.53, 357.73, 409.89, 465.06, 521.84, 579.02, 630.64, 794.46,
2486 813., 813.56, 796.25, 761.57, 727.97, 812.14, 866.75, 932.5,
2487 1132.8, 1194.8, 1362.2, 1387.2, 1482.3, 1479.7, 1517.9, 1533.1,
2488 1534.2, 1523.3, 1522.5, 1515.5, 1505.2, 1486.5, 1454., 1412.,
2489 1358.8, 1107.8, 1060.9, 1033.5, 1048.2, 1122.4, 1248.9, 1227.1,
2490 1255.4, 1058.9, 1020.7, 970.59, 715.24, 512.56, 468.47, 349.3,
2491 338.26, 299.22, 301.26, 332.38, 382.08, 445.49, 515.87, 590.85,
2492 662.3, 726.05, 955.59, 964.11, 945.17, 891.48, 807.11, 720.9,
2493 803.36, 834.46, 1073.9, 1107.1, 1123.6, 1296., 1393.7, 1303.1,
2494 1284.3, 1161.8, 1078.8, 976.13, 868.72, 767.4, 674.72, 593.73,
2495 523.12, 462.24, 409.75, 364.34, 325., 290.73, 260.76, 234.46,
2496 211.28, 190.78, 172.61, 156.44, 142.01, 129.12, 117.57, 107.2,
2497 97.877, 89.47, 81.882, 75.021, 68.807, 63.171, 58.052, 53.396,
2498 49.155, 45.288, 41.759, 38.531, 35.576, 32.868, 30.384, 28.102,
2499 26.003, 24.071, 22.293, 20.655, 19.147, 17.756, 16.476, 15.292,
2500 14.198, 13.183, 12.241, 11.367, 10.554, 9.7989, 9.0978, 8.4475,
2501 7.845, 7.2868, 6.7704, 6.2927, 5.8508, 5.4421, 5.064, 4.714,
2502 4.3902, 4.0902, 3.8121, 3.5543, 3.315, 3.093, 2.8869, 2.6953,
2503 2.5172, 2.3517, 2.1977, 2.0544, 1.9211, 1.7969, 1.6812, 1.5735,
2504 1.4731, 1.3794, 1.2921, 1.2107, 1.1346, 1.0637, .99744, .93554,
2505 .87771, .82368, .77313, .72587, .6816, .64014, .60134, .565,
2506 .53086, .49883, .46881, .44074, .4144, .38979, .36679, .34513,
2507 .32474, .30552, .28751, .27045, .25458, .23976, .22584, .21278,
2508 .20051, .18899, .17815, .16801, .15846, .14954, .14117, .13328,
2509 .12584
2510 };
2511
2512 /* Get CO2 continuum absorption... */
2513 const double xw = nu / 2 + 1;
2514 if (xw >= 1 && xw < 2001) {
2515 const int iw = (int) xw;
2516 const double dw = xw - iw;
2517 const double ew = 1 - dw;
2518 const double cw296 = ew * co2296[iw - 1] + dw * co2296[iw];
2519 const double cw260 = ew * co2260[iw - 1] + dw * co2260[iw];
2520 const double cw230 = ew * co2230[iw - 1] + dw * co2230[iw];
2521 const double dt230 = t - 230;
2522 const double dt260 = t - 260;
2523 const double dt296 = t - 296;
2524 const double ctw =
2525 dt260 * 5.050505e-4 * dt296 * cw230 -
2526 dt230 * 9.259259e-4 * dt296 * cw260 +
2527 dt230 * 4.208754e-4 * dt260 * cw296;
2528 return u / NA / 1000 * p / P0 * ctw;
2529 } else
2530 return 0;
2531}
2532
2533/*****************************************************************************/
2534
2535double ctmh2o(
2536 const double nu,
2537 const double p,
2538 const double t,
2539 const double q,
2540 const double u) {
2541
2542 /* MT_CKD 4.1 coefficients from RFM 5.21 (0 to 20000 cm^-1). */
2543 static const double h2oslf[2001] =
2544 { 2.877e-21, 2.855e-21, 2.731e-21, 2.49e-21, 2.178e-21, 1.863e-21,
2545 1.595e-21,
2546 1.381e-21, 1.221e-21, 1.095e-21, 9.882e-22, 8.926e-22, 8.041e-22,
2547 7.217e-22,
2548 6.45e-22, 5.74e-22, 5.088e-22, 4.492e-22, 3.952e-22, 3.466e-22, 3.031e-22,
2549 2.644e-22, 2.302e-22, 2.001e-22, 1.738e-22, 1.509e-22, 1.311e-22,
2550 1.139e-22,
2551 9.913e-23, 8.639e-23, 7.544e-23, 6.603e-23, 5.794e-23, 5.096e-23,
2552 4.495e-23,
2553 3.974e-23, 3.523e-23, 3.13e-23, 2.786e-23, 2.485e-23, 2.221e-23,
2554 1.987e-23,
2555 1.78e-23, 1.596e-23, 1.433e-23, 1.287e-23, 1.156e-23, 1.04e-23, 9.349e-24,
2556 8.41e-24, 7.568e-24, 6.81e-24, 6.13e-24, 5.517e-24, 4.967e-24, 4.471e-24,
2557 4.025e-24, 3.624e-24, 3.262e-24, 2.937e-24, 2.644e-24, 2.381e-24,
2558 2.143e-24,
2559 1.93e-24, 1.737e-24, 1.564e-24, 1.413e-24, 1.284e-24, 1.176e-24,
2560 1.087e-24,
2561 1.013e-24, 9.489e-25, 8.961e-25, 8.451e-25, 7.943e-25, 7.43e-25,
2562 6.912e-25,
2563 6.447e-25, 6.025e-25, 5.642e-25, 5.292e-25, 4.971e-25, 4.69e-25,
2564 4.444e-25,
2565 4.216e-25, 4.012e-25, 3.814e-25, 3.621e-25, 3.442e-25, 3.268e-25, 3.1e-25,
2566 2.957e-25, 2.78e-25, 2.617e-25, 2.445e-25, 2.305e-25, 2.187e-25, 2.08e-25,
2567 1.98e-25, 1.885e-25, 1.796e-25, 1.711e-25, 1.633e-25, 1.559e-25, 1.49e-25,
2568 1.426e-25, 1.367e-25, 1.312e-25, 1.263e-25, 1.218e-25, 1.178e-25,
2569 1.143e-25,
2570 1.112e-25, 1.088e-25, 1.07e-25, 1.057e-25, 1.05e-25, 1.051e-25, 1.059e-25,
2571 1.076e-25, 1.1e-25, 1.133e-25, 1.18e-25, 1.237e-25, 1.308e-25, 1.393e-25,
2572 1.483e-25, 1.614e-25, 1.758e-25, 1.93e-25, 2.123e-25, 2.346e-25,
2573 2.647e-25,
2574 2.93e-25, 3.279e-25, 3.745e-25, 4.152e-25, 4.813e-25, 5.477e-25,
2575 6.203e-25,
2576 7.331e-25, 8.056e-25, 9.882e-25, 1.05e-24, 1.21e-24, 1.341e-24, 1.572e-24,
2577 1.698e-24, 1.968e-24, 2.175e-24, 2.431e-24, 2.735e-24, 2.867e-24,
2578 3.19e-24,
2579 3.371e-24, 3.554e-24, 3.726e-24, 3.837e-24, 3.878e-24, 3.864e-24,
2580 3.858e-24,
2581 3.841e-24, 3.852e-24, 3.815e-24, 3.762e-24, 3.618e-24, 3.579e-24,
2582 3.45e-24,
2583 3.202e-24, 3.018e-24, 2.785e-24, 2.602e-24, 2.416e-24, 2.097e-24,
2584 1.939e-24,
2585 1.689e-24, 1.498e-24, 1.308e-24, 1.17e-24, 1.011e-24, 9.237e-25,
2586 7.909e-25,
2587 7.006e-25, 6.112e-25, 5.401e-25, 4.914e-25, 4.266e-25, 3.963e-25,
2588 3.316e-25,
2589 3.037e-25, 2.598e-25, 2.294e-25, 2.066e-25, 1.813e-25, 1.583e-25,
2590 1.423e-25,
2591 1.247e-25, 1.116e-25, 9.76e-26, 8.596e-26, 7.72e-26, 7.091e-26, 6.499e-26,
2592 5.801e-26, 5.15e-26, 4.5e-26, 4e-26, 3.509e-26, 3.1e-26, 2.714e-26,
2593 2.406e-26, 2.108e-26, 1.875e-26, 1.669e-26, 1.555e-26, 1.444e-26,
2594 1.345e-26,
2595 1.257e-26, 1.175e-26, 1.102e-26, 1.035e-26, 9.745e-27, 9.194e-27,
2596 8.685e-27,
2597 8.222e-27, 7.798e-27, 7.412e-27, 7.052e-27, 6.724e-27, 6.42e-27,
2598 6.143e-27,
2599 5.886e-27, 5.649e-27, 5.43e-27, 5.228e-27, 5.041e-27, 4.868e-27,
2600 4.708e-27,
2601 4.559e-27, 4.421e-27, 4.293e-27, 4.174e-27, 4.064e-27, 3.961e-27,
2602 3.865e-27,
2603 3.775e-27, 3.692e-27, 3.614e-27, 3.542e-27, 3.474e-27, 3.411e-27,
2604 3.353e-27,
2605 3.298e-27, 3.248e-27, 3.201e-27, 3.158e-27, 3.119e-27, 3.084e-27,
2606 3.053e-27,
2607 3.025e-27, 3.003e-27, 2.988e-27, 2.976e-27, 2.977e-27, 2.989e-27,
2608 3.015e-27,
2609 3.057e-27, 3.112e-27, 3.161e-27, 3.186e-27, 3.176e-27, 3.142e-27,
2610 3.099e-27,
2611 3.065e-27, 3.011e-27, 2.955e-27, 2.914e-27, 2.884e-27, 2.864e-27,
2612 2.858e-27,
2613 2.851e-27, 2.857e-27, 2.87e-27, 2.888e-27, 2.914e-27, 2.948e-27, 2.99e-27,
2614 3.042e-27, 3.105e-27, 3.185e-27, 3.276e-27, 3.385e-27, 3.511e-27,
2615 3.646e-27,
2616 3.858e-27, 4.081e-27, 4.335e-27, 4.643e-27, 5.011e-27, 5.494e-27,
2617 5.953e-27,
2618 6.354e-27, 7.116e-27, 7.498e-27, 8.613e-27, 9.35e-27, 1.002e-26, 1.09e-26,
2619 1.174e-26, 1.23e-26, 1.288e-26, 1.334e-26, 1.383e-26, 1.38e-26, 1.39e-26,
2620 1.373e-26, 1.354e-26, 1.335e-26, 1.343e-26, 1.323e-26, 1.349e-26,
2621 1.353e-26,
2622 1.362e-26, 1.344e-26, 1.329e-26, 1.336e-26, 1.327e-26, 1.325e-26,
2623 1.359e-26,
2624 1.374e-26, 1.415e-26, 1.462e-26, 1.526e-26, 1.619e-26, 1.735e-26,
2625 1.863e-26,
2626 2.034e-26, 2.265e-26, 2.482e-26, 2.756e-26, 3.103e-26, 3.466e-26,
2627 3.832e-26,
2628 4.378e-26, 4.913e-26, 5.651e-26, 6.311e-26, 7.169e-26, 8.057e-26,
2629 9.253e-26,
2630 1.047e-25, 1.212e-25, 1.36e-25, 1.569e-25, 1.776e-25, 2.02e-25, 2.281e-25,
2631 2.683e-25, 2.994e-25, 3.488e-25, 3.896e-25, 4.499e-25, 5.175e-25,
2632 6.035e-25,
2633 6.34e-25, 7.281e-25, 7.923e-25, 8.348e-25, 9.631e-25, 1.044e-24,
2634 1.102e-24,
2635 1.176e-24, 1.244e-24, 1.283e-24, 1.326e-24, 1.4e-24, 1.395e-24, 1.387e-24,
2636 1.363e-24, 1.314e-24, 1.241e-24, 1.228e-24, 1.148e-24, 1.086e-24,
2637 1.018e-24,
2638 8.89e-25, 8.316e-25, 7.292e-25, 6.452e-25, 5.625e-25, 5.045e-25, 4.38e-25,
2639 3.762e-25, 3.29e-25, 2.836e-25, 2.485e-25, 2.168e-25, 1.895e-25,
2640 1.659e-25,
2641 1.453e-25, 1.282e-25, 1.132e-25, 1.001e-25, 8.836e-26, 7.804e-26,
2642 6.922e-26,
2643 6.116e-26, 5.429e-26, 4.824e-26, 4.278e-26, 3.788e-26, 3.371e-26,
2644 2.985e-26,
2645 2.649e-26, 2.357e-26, 2.09e-26, 1.858e-26, 1.647e-26, 1.462e-26,
2646 1.299e-26,
2647 1.155e-26, 1.028e-26, 9.142e-27, 8.132e-27, 7.246e-27, 6.418e-27,
2648 5.726e-27,
2649 5.221e-27, 4.89e-27, 4.666e-27, 4.443e-27, 4.203e-27, 3.978e-27, 3.77e-27,
2650 3.575e-27, 3.395e-27, 3.227e-27, 3.07e-27, 2.924e-27, 2.788e-27,
2651 2.661e-27,
2652 2.543e-27, 2.433e-27, 2.329e-27, 2.233e-27, 2.143e-27, 2.058e-27,
2653 1.98e-27,
2654 1.906e-27, 1.837e-27, 1.773e-27, 1.713e-27, 1.657e-27, 1.605e-27,
2655 1.557e-27,
2656 1.514e-27, 1.472e-27, 1.435e-27, 1.404e-27, 1.377e-27, 1.354e-27,
2657 1.332e-27,
2658 1.308e-27, 1.282e-27, 1.256e-27, 1.227e-27, 1.192e-27, 1.159e-27,
2659 1.134e-27,
2660 1.114e-27, 1.098e-27, 1.081e-27, 1.066e-27, 1.055e-27, 1.045e-27,
2661 1.036e-27,
2662 1.03e-27, 1.026e-27, 1.025e-27, 1.025e-27, 1.028e-27, 1.033e-27,
2663 1.041e-27,
2664 1.049e-27, 1.06e-27, 1.075e-27, 1.093e-27, 1.114e-27, 1.139e-27,
2665 1.166e-27,
2666 1.199e-27, 1.239e-27, 1.282e-27, 1.316e-27, 1.355e-27, 1.436e-27,
2667 1.588e-27,
2668 1.807e-27, 2.06e-27, 2.337e-27, 2.645e-27, 2.996e-27, 3.393e-27,
2669 3.843e-27,
2670 4.363e-27, 4.935e-27, 5.607e-27, 6.363e-27, 7.242e-27, 8.23e-27,
2671 9.411e-27,
2672 1.071e-26, 1.232e-26, 1.402e-26, 1.6e-26, 1.82e-26, 2.128e-26, 2.386e-26,
2673 2.781e-26, 3.242e-26, 3.653e-26, 4.323e-26, 4.747e-26, 5.321e-26,
2674 5.919e-26,
2675 6.681e-26, 7.101e-26, 7.983e-26, 8.342e-26, 8.741e-26, 9.431e-26,
2676 9.952e-26,
2677 1.026e-25, 1.055e-25, 1.095e-25, 1.095e-25, 1.087e-25, 1.056e-25,
2678 1.026e-25,
2679 9.715e-26, 9.252e-26, 8.452e-26, 7.958e-26, 7.268e-26, 6.295e-26,
2680 6.003e-26,
2681 5e-26, 4.591e-26, 3.983e-26, 3.479e-26, 3.058e-26, 2.667e-26, 2.293e-26,
2682 1.995e-26, 1.747e-26, 1.517e-26, 1.335e-26, 1.165e-26, 1.028e-26,
2683 9.007e-27,
2684 7.956e-27, 7.015e-27, 6.192e-27, 5.491e-27, 4.859e-27, 4.297e-27,
2685 3.799e-27,
2686 3.38e-27, 3.002e-27, 2.659e-27, 2.366e-27, 2.103e-27, 1.861e-27,
2687 1.655e-27,
2688 1.469e-27, 1.309e-27, 1.162e-27, 1.032e-27, 9.198e-28, 8.181e-28,
2689 7.294e-28,
2690 6.516e-28, 5.787e-28, 5.163e-28, 4.612e-28, 4.096e-28, 3.654e-28,
2691 3.299e-28,
2692 3.052e-28, 2.856e-28, 2.683e-28, 2.507e-28, 2.346e-28, 2.194e-28,
2693 2.053e-28,
2694 1.921e-28, 1.799e-28, 1.686e-28, 1.58e-28, 1.481e-28, 1.389e-28,
2695 1.304e-28,
2696 1.226e-28, 1.151e-28, 1.083e-28, 1.02e-28, 9.618e-29, 9.08e-29, 8.575e-29,
2697 8.08e-29, 7.624e-29, 7.176e-29, 6.761e-29, 6.37e-29, 6.004e-29, 5.672e-29,
2698 5.371e-29, 5.097e-29, 4.845e-29, 4.608e-29, 4.39e-29, 4.192e-29,
2699 4.011e-29,
2700 3.846e-29, 3.698e-29, 3.568e-29, 3.45e-29, 3.351e-29, 3.268e-29,
2701 3.195e-29,
2702 3.131e-29, 3.091e-29, 3.06e-29, 3.039e-29, 3.034e-29, 3.045e-29,
2703 3.072e-29,
2704 3.116e-29, 3.176e-29, 3.253e-29, 3.347e-29, 3.467e-29, 3.605e-29,
2705 3.763e-29,
2706 3.946e-29, 4.162e-29, 4.399e-29, 4.677e-29, 4.983e-29, 5.336e-29,
2707 5.728e-29,
2708 6.168e-29, 6.684e-29, 7.214e-29, 7.861e-29, 8.62e-29, 9.481e-29,
2709 1.032e-28,
2710 1.135e-28, 1.264e-28, 1.396e-28, 1.567e-28, 1.74e-28, 1.977e-28, 2.2e-28,
2711 2.563e-28, 2.935e-28, 3.386e-28, 3.993e-28, 4.828e-28, 5.714e-28,
2712 6.877e-28,
2713 8.135e-28, 9.779e-28, 1.132e-27, 1.344e-27, 1.544e-27, 1.82e-27,
2714 2.207e-27,
2715 2.509e-27, 2.854e-27, 3.026e-27, 3.278e-27, 3.474e-27, 3.693e-27,
2716 3.93e-27,
2717 4.104e-27, 4.22e-27, 4.439e-27, 4.545e-27, 4.778e-27, 4.812e-27,
2718 5.018e-27,
2719 4.899e-27, 5.075e-27, 5.073e-27, 5.171e-27, 5.131e-27, 5.25e-27,
2720 5.617e-27,
2721 5.846e-27, 6.239e-27, 6.696e-27, 7.398e-27, 8.073e-27, 9.15e-27,
2722 1.009e-26,
2723 1.116e-26, 1.264e-26, 1.439e-26, 1.644e-26, 1.856e-26, 2.147e-26,
2724 2.317e-26,
2725 2.713e-26, 2.882e-26, 2.99e-26, 3.489e-26, 3.581e-26, 4.033e-26, 4.26e-26,
2726 4.543e-26, 4.84e-26, 4.826e-26, 5.013e-26, 5.252e-26, 5.277e-26,
2727 5.306e-26,
2728 5.234e-26, 5.111e-26, 5.134e-26, 4.748e-26, 4.434e-26, 4.109e-26,
2729 3.605e-26,
2730 3.252e-26, 2.731e-26, 2.369e-26, 1.922e-26, 1.558e-26, 1.321e-26,
2731 1.058e-26,
2732 8.515e-27, 6.811e-27, 5.431e-27, 4.348e-27, 3.51e-27, 2.853e-27,
2733 2.344e-27,
2734 1.949e-27, 1.649e-27, 1.409e-27, 1.232e-27, 1.098e-27, 9.866e-28,
2735 8.899e-28,
2736 8.135e-28, 7.409e-28, 6.809e-28, 6.237e-28, 5.728e-28, 5.267e-28,
2737 4.865e-28,
2738 4.482e-28, 4.169e-28, 3.841e-28, 3.573e-28, 3.304e-28, 3.065e-28,
2739 2.851e-28,
2740 2.634e-28, 2.448e-28, 2.275e-28, 2.114e-28, 1.965e-28, 1.83e-28,
2741 1.707e-28,
2742 1.591e-28, 1.484e-28, 1.386e-28, 1.294e-28, 1.209e-28, 1.131e-28,
2743 1.056e-28,
2744 9.901e-29, 9.263e-29, 8.68e-29, 8.137e-29, 7.627e-29, 7.158e-29,
2745 6.715e-29,
2746 6.305e-29, 5.927e-29, 5.568e-29, 5.242e-29, 4.935e-29, 4.648e-29,
2747 4.383e-29,
2748 4.137e-29, 3.909e-29, 3.697e-29, 3.5e-29, 3.321e-29, 3.156e-29, 3.006e-29,
2749 2.868e-29, 2.745e-29, 2.638e-29, 2.545e-29, 2.469e-29, 2.405e-29,
2750 2.369e-29,
2751 2.344e-29, 2.35e-29, 2.371e-29, 2.491e-29, 2.535e-29, 2.73e-29, 3.067e-29,
2752 3.322e-29, 3.63e-29, 4.045e-29, 4.524e-29, 4.981e-29, 5.613e-29,
2753 6.051e-29,
2754 6.538e-29, 6.892e-29, 7.601e-29, 8.194e-29, 8.806e-29, 9.45e-29,
2755 9.745e-29,
2756 1.009e-28, 1.017e-28, 1.039e-28, 1.061e-28, 1.076e-28, 1.086e-28,
2757 1.111e-28,
2758 1.142e-28, 1.16e-28, 1.174e-28, 1.18e-28, 1.187e-28, 1.194e-28, 1.192e-28,
2759 1.224e-28, 1.245e-28, 1.246e-28, 1.318e-28, 1.377e-28, 1.471e-28,
2760 1.582e-28,
2761 1.713e-28, 1.853e-28, 2.063e-28, 2.27e-28, 2.567e-28, 2.891e-28,
2762 3.264e-28,
2763 3.744e-28, 4.286e-28, 4.915e-28, 5.623e-28, 6.336e-28, 7.293e-28,
2764 8.309e-28,
2765 9.319e-28, 1.091e-27, 1.243e-27, 1.348e-27, 1.449e-27, 1.62e-27,
2766 1.846e-27,
2767 1.937e-27, 2.04e-27, 2.179e-27, 2.298e-27, 2.433e-27, 2.439e-27,
2768 2.464e-27,
2769 2.611e-27, 2.617e-27, 2.582e-27, 2.453e-27, 2.401e-27, 2.349e-27,
2770 2.203e-27,
2771 2.066e-27, 1.939e-27, 1.78e-27, 1.558e-27, 1.391e-27, 1.203e-27,
2772 1.048e-27,
2773 9.464e-28, 8.306e-28, 7.239e-28, 6.317e-28, 5.52e-28, 4.847e-28,
2774 4.282e-28,
2775 3.796e-28, 3.377e-28, 2.996e-28, 2.678e-28, 2.4e-28, 2.134e-28, 1.904e-28,
2776 1.705e-28, 1.523e-28, 1.35e-28, 1.204e-28, 1.07e-28, 9.408e-29, 8.476e-29,
2777 7.47e-29, 6.679e-29, 5.929e-29, 5.267e-29, 4.711e-29, 4.172e-29,
2778 3.761e-29,
2779 3.288e-29, 2.929e-29, 2.609e-29, 2.315e-29, 2.042e-29, 1.844e-29,
2780 1.64e-29,
2781 1.47e-29, 1.31e-29, 1.176e-29, 1.049e-29, 9.377e-30, 8.462e-30, 7.616e-30,
2782 6.818e-30, 6.119e-30, 5.558e-30, 5.152e-30, 4.832e-30, 4.546e-30,
2783 4.267e-30,
2784 4.009e-30, 3.77e-30, 3.546e-30, 3.34e-30, 3.149e-30, 2.971e-30, 2.805e-30,
2785 2.652e-30, 2.509e-30, 2.377e-30, 2.255e-30, 2.142e-30, 2.038e-30,
2786 1.943e-30,
2787 1.855e-30, 1.776e-30, 1.703e-30, 1.64e-30, 1.586e-30, 1.536e-30,
2788 1.494e-30,
2789 1.466e-30, 1.446e-30, 1.44e-30, 1.439e-30, 1.455e-30, 1.461e-30,
2790 1.479e-30,
2791 1.514e-30, 1.538e-30, 1.59e-30, 1.652e-30, 1.75e-30, 1.811e-30, 1.88e-30,
2792 1.933e-30, 2.027e-30, 2.078e-30, 2.17e-30, 2.249e-30, 2.323e-30,
2793 2.408e-30,
2794 2.461e-30, 2.536e-30, 2.581e-30, 2.615e-30, 2.721e-30, 2.782e-30,
2795 2.866e-30,
2796 2.938e-30, 2.958e-30, 3.011e-30, 3.155e-30, 3.237e-30, 3.589e-30,
2797 3.838e-30,
2798 4.083e-30, 4.354e-30, 4.745e-30, 5.148e-30, 5.648e-30, 6.194e-30,
2799 6.748e-30,
2800 7.566e-30, 8.421e-30, 9.427e-30, 1.042e-29, 1.165e-29, 1.341e-29,
2801 1.518e-29,
2802 1.686e-29, 2.036e-29, 2.362e-29, 2.811e-29, 3.296e-29, 4.07e-29,
2803 4.695e-29,
2804 6.152e-29, 7.572e-29, 9.557e-29, 1.135e-28, 1.279e-28, 1.364e-28,
2805 1.436e-28,
2806 1.54e-28, 1.672e-28, 1.793e-28, 1.906e-28, 2.036e-28, 2.144e-28,
2807 2.292e-28,
2808 2.371e-28, 2.493e-28, 2.606e-28, 2.706e-28, 2.866e-28, 3.036e-28,
2809 3.136e-28,
2810 3.405e-28, 3.665e-28, 3.837e-28, 4.229e-28, 4.748e-28, 5.32e-28,
2811 5.763e-28,
2812 6.677e-28, 7.216e-28, 7.716e-28, 8.958e-28, 9.419e-28, 1.036e-27,
2813 1.108e-27,
2814 1.189e-27, 1.246e-27, 1.348e-27, 1.31e-27, 1.361e-27, 1.364e-27,
2815 1.363e-27,
2816 1.343e-27, 1.293e-27, 1.254e-27, 1.235e-27, 1.158e-27, 1.107e-27,
2817 9.961e-28,
2818 9.011e-28, 7.91e-28, 6.916e-28, 6.338e-28, 5.564e-28, 4.827e-28,
2819 4.198e-28,
2820 3.695e-28, 3.276e-28, 2.929e-28, 2.633e-28, 2.391e-28, 2.192e-28,
2821 2.021e-28,
2822 1.89e-28, 1.772e-28, 1.667e-28, 1.603e-28, 1.547e-28, 1.537e-28,
2823 1.492e-28,
2824 1.515e-28, 1.479e-28, 1.45e-28, 1.513e-28, 1.495e-28, 1.529e-28,
2825 1.565e-28,
2826 1.564e-28, 1.553e-28, 1.569e-28, 1.584e-28, 1.57e-28, 1.538e-28,
2827 1.531e-28,
2828 1.346e-28, 1.199e-28, 1.044e-28, 8.892e-29, 7.076e-29, 5.884e-29,
2829 5.039e-29,
2830 4.129e-29, 3.663e-29, 2.993e-29, 2.622e-29, 2.232e-29, 1.884e-29,
2831 1.569e-29,
2832 1.348e-29, 1.144e-29, 1.009e-29, 8.833e-30, 7.907e-30, 7.079e-30,
2833 6.514e-30,
2834 5.823e-30, 5.312e-30, 4.883e-30, 4.458e-30, 4.094e-30, 3.734e-30,
2835 3.458e-30,
2836 3.205e-30, 2.962e-30, 2.733e-30, 2.532e-30, 2.351e-30, 2.187e-30,
2837 2.034e-30,
2838 1.889e-30, 1.764e-30, 1.648e-30, 1.541e-30, 1.443e-30, 1.355e-30,
2839 1.274e-30,
2840 1.198e-30, 1.133e-30, 1.071e-30, 1.015e-30, 9.648e-31, 9.195e-31,
2841 8.791e-31,
2842 8.435e-31, 8.125e-31, 7.859e-31, 7.621e-31, 7.481e-31, 7.351e-31,
2843 7.228e-31,
2844 7.295e-31, 7.339e-31, 7.588e-31, 7.701e-31, 7.886e-31, 8.511e-31,
2845 9.061e-31,
2846 9.926e-31, 1.083e-30, 1.241e-30, 1.469e-30, 1.736e-30, 1.966e-30,
2847 2.132e-30,
2848 2.28e-30, 2.473e-30, 2.718e-30, 2.922e-30, 3.128e-30, 3.361e-30,
2849 3.641e-30,
2850 3.91e-30, 4.196e-30, 4.501e-30, 4.932e-30, 5.258e-30, 5.755e-30,
2851 6.253e-30,
2852 6.664e-30, 7.344e-30, 7.985e-30, 8.877e-30, 1.005e-29, 1.118e-29,
2853 1.251e-29,
2854 1.428e-29, 1.61e-29, 1.888e-29, 2.077e-29, 2.331e-29, 2.751e-29,
2855 3.061e-29,
2856 3.522e-29, 3.805e-29, 4.181e-29, 4.575e-29, 5.167e-29, 5.634e-29,
2857 6.007e-29,
2858 6.501e-29, 6.829e-29, 7.211e-29, 7.262e-29, 7.696e-29, 7.832e-29,
2859 7.799e-29,
2860 7.651e-29, 7.304e-29, 7.15e-29, 6.977e-29, 6.603e-29, 6.209e-29, 5.69e-29,
2861 5.432e-29, 4.764e-29, 4.189e-29, 3.64e-29, 3.203e-29, 2.848e-29, 2.51e-29,
2862 2.194e-29, 1.946e-29, 1.75e-29, 1.567e-29, 1.426e-29, 1.302e-29,
2863 1.197e-29,
2864 1.109e-29, 1.035e-29, 9.719e-30, 9.207e-30, 8.957e-30, 8.578e-30,
2865 8.262e-30,
2866 8.117e-30, 7.987e-30, 7.875e-30, 7.741e-30, 7.762e-30, 7.537e-30,
2867 7.424e-30,
2868 7.474e-30, 7.294e-30, 7.216e-30, 7.233e-30, 7.14e-30, 7.085e-30,
2869 6.434e-30,
2870 5.585e-30, 5.015e-30, 3.956e-30, 3.337e-30, 2.545e-30, 2.141e-30,
2871 1.761e-30,
2872 1.685e-30, 1.507e-30, 1.241e-30, 1.081e-30, 9.675e-31, 7.964e-31,
2873 6.93e-31,
2874 5.79e-31, 5.069e-31, 4.452e-31, 3.97e-31, 3.551e-31, 3.228e-31, 2.939e-31,
2875 2.682e-31, 2.471e-31, 2.278e-31, 2.106e-31, 1.95e-31, 1.811e-31,
2876 1.682e-31,
2877 1.563e-31, 1.458e-31, 1.363e-31, 1.278e-31, 1.2e-31, 1.129e-31, 1.066e-31,
2878 1.007e-31, 9.545e-32, 9.075e-32, 8.656e-32, 8.285e-32, 7.958e-32,
2879 7.674e-32,
2880 7.431e-32, 7.227e-32, 7.061e-32, 6.934e-32, 6.843e-32, 6.79e-32,
2881 6.775e-32,
2882 6.798e-32, 6.859e-32, 6.96e-32, 7.102e-32, 7.287e-32, 7.517e-32,
2883 7.795e-32,
2884 8.123e-32, 8.504e-32, 8.945e-32, 9.45e-32, 1.003e-31, 1.07e-31, 1.148e-31,
2885 1.232e-31, 1.327e-31, 1.441e-31, 1.535e-31, 1.655e-31, 1.814e-31,
2886 2.02e-31,
2887 2.307e-31, 2.622e-31, 2.962e-31, 3.369e-31, 3.819e-31, 4.329e-31,
2888 4.932e-31,
2889 5.589e-31, 6.364e-31, 7.284e-31, 8.236e-31, 9.447e-31, 1.078e-30,
2890 1.229e-30,
2891 1.417e-30, 1.614e-30, 1.843e-30, 2.107e-30, 2.406e-30, 2.728e-30,
2892 3.195e-30,
2893 3.595e-30, 4.153e-30, 4.736e-30, 5.41e-30, 6.088e-30, 6.769e-30,
2894 7.691e-30,
2895 8.545e-30, 9.621e-30, 1.047e-29, 1.161e-29, 1.296e-29, 1.424e-29,
2896 1.576e-29,
2897 1.739e-29, 1.893e-29, 2.08e-29, 2.336e-29, 2.604e-29, 2.76e-29, 3.001e-29,
2898 3.365e-29, 3.55e-29, 3.895e-29, 4.183e-29, 4.614e-29, 4.846e-29,
2899 5.068e-29,
2900 5.427e-29, 5.541e-29, 5.864e-29, 5.997e-29, 5.997e-29, 6.061e-29,
2901 5.944e-29,
2902 5.855e-29, 5.661e-29, 5.523e-29, 5.374e-29, 4.94e-29, 4.688e-29, 4.17e-29,
2903 3.913e-29, 3.423e-29, 2.997e-29, 2.598e-29, 2.253e-29, 1.946e-29,
2904 1.71e-29,
2905 1.507e-29, 1.336e-29, 1.19e-29, 1.068e-29, 9.623e-30, 8.772e-30,
2906 8.007e-30,
2907 7.42e-30, 6.884e-30, 6.483e-30, 6.162e-30, 5.922e-30, 5.688e-30,
2908 5.654e-30,
2909 5.637e-30, 5.701e-30, 5.781e-30, 5.874e-30, 6.268e-30, 6.357e-30,
2910 6.525e-30,
2911 7.137e-30, 7.441e-30, 8.024e-30, 8.485e-30, 9.143e-30, 9.536e-30,
2912 9.717e-30,
2913 1.018e-29, 1.042e-29, 1.054e-29, 1.092e-29, 1.093e-29, 1.072e-29,
2914 1.046e-29,
2915 9.283e-30, 8.053e-30, 6.68e-30, 5.63e-30, 4.933e-30, 3.488e-30, 3.324e-30,
2916 2.826e-30, 2.429e-30, 2.051e-30, 1.679e-30, 1.411e-30, 1.24e-30,
2917 1.098e-30,
2918 9.668e-31, 8.529e-31, 7.848e-31, 7.098e-31, 6.117e-31, 5.246e-31,
2919 4.521e-31,
2920 4.059e-31, 3.783e-31, 3.502e-31, 3.271e-31, 2.956e-31, 2.636e-31,
2921 2.464e-31,
2922 2.19e-31, 1.986e-31, 1.791e-31, 1.638e-31, 1.491e-31, 1.383e-31,
2923 1.271e-31,
2924 1.166e-31, 1.082e-31, 1.002e-31, 9.317e-32, 8.697e-32, 8.157e-32,
2925 7.678e-32,
2926 7.252e-32, 6.874e-32, 6.539e-32, 6.243e-32, 5.985e-32, 5.763e-32,
2927 5.575e-32,
2928 5.421e-32, 5.3e-32, 5.212e-32, 5.157e-32, 5.138e-32, 5.156e-32, 5.214e-32,
2929 5.313e-32, 5.457e-32, 5.686e-32, 5.953e-32, 6.284e-32, 6.856e-32,
2930 7.351e-32,
2931 8.006e-32, 8.957e-32, 1.031e-31, 1.17e-31, 1.345e-31, 1.623e-31,
2932 1.999e-31,
2933 2.507e-31, 3.004e-31, 3.378e-31, 3.688e-31, 4.118e-31, 4.569e-31,
2934 5.025e-31,
2935 5.66e-31, 6.231e-31, 6.881e-31, 7.996e-31, 8.526e-31, 9.694e-31,
2936 1.106e-30,
2937 1.222e-30, 1.355e-30, 1.525e-30, 1.775e-30, 1.924e-30, 2.181e-30,
2938 2.379e-30,
2939 2.662e-30, 2.907e-30, 3.154e-30, 3.366e-30, 3.579e-30, 3.858e-30,
2940 4.046e-30,
2941 4.196e-30, 4.166e-30, 4.457e-30, 4.466e-30, 4.404e-30, 4.337e-30,
2942 4.15e-30,
2943 4.083e-30, 3.91e-30, 3.723e-30, 3.514e-30, 3.303e-30, 2.847e-30,
2944 2.546e-30,
2945 2.23e-30, 1.994e-30, 1.733e-30, 1.488e-30, 1.297e-30, 1.144e-30,
2946 1.004e-30,
2947 8.741e-31, 7.928e-31, 7.034e-31, 6.323e-31, 5.754e-31, 5.25e-31, 4.85e-31,
2948 4.502e-31, 4.286e-31, 4.028e-31, 3.899e-31, 3.824e-31, 3.761e-31,
2949 3.804e-31,
2950 3.839e-31, 3.845e-31, 4.244e-31, 4.382e-31, 4.582e-31, 4.847e-31,
2951 5.209e-31,
2952 5.384e-31, 5.887e-31, 6.371e-31, 6.737e-31, 7.168e-31, 7.415e-31,
2953 7.827e-31,
2954 8.037e-31, 8.12e-31, 8.154e-31, 7.981e-31, 7.783e-31, 6.9e-31, 6.03e-31,
2955 4.9e-31, 3.878e-31, 3.068e-31, 2.533e-31, 2.255e-31, 2.056e-31, 1.569e-31,
2956 1.398e-31, 1.149e-31, 9.249e-32, 7.706e-32, 6.436e-32, 5.514e-32,
2957 4.782e-32,
2958 4.202e-32, 3.721e-32, 3.336e-32, 3.015e-32, 2.744e-32, 2.512e-32,
2959 2.312e-32,
2960 2.138e-32, 1.987e-32, 1.855e-32, 1.741e-32, 1.642e-32, 1.557e-32,
2961 1.483e-32,
2962 1.422e-32, 1.37e-32, 1.329e-32, 1.297e-32, 1.274e-32, 1.259e-32,
2963 1.253e-32,
2964 1.255e-32, 1.266e-32, 1.284e-32, 1.312e-32, 1.348e-32, 1.393e-32,
2965 1.448e-32,
2966 1.512e-32, 1.587e-32, 1.672e-32, 1.77e-32, 1.88e-32, 1.99e-32, 2.11e-32,
2967 2.274e-32, 2.516e-32, 2.844e-32, 3.231e-32, 3.661e-32, 4.153e-32,
2968 4.717e-32,
2969 5.36e-32, 6.094e-32, 6.93e-32, 7.882e-32, 8.966e-32, 1.02e-31, 1.162e-31,
2970 1.324e-31, 1.51e-31, 1.72e-31, 1.965e-31, 2.237e-31, 2.56e-31, 2.927e-31,
2971 3.371e-31, 3.842e-31, 4.429e-31, 5.139e-31, 5.798e-31, 6.697e-31,
2972 7.626e-31,
2973 8.647e-31, 1.022e-30, 1.136e-30, 1.3e-30, 1.481e-30, 1.672e-30, 1.871e-30,
2974 2.126e-30, 2.357e-30, 2.583e-30, 2.997e-30, 3.289e-30, 3.702e-30,
2975 4.012e-30,
2976 4.319e-30, 4.527e-30, 5.001e-30, 5.448e-30, 5.611e-30, 5.76e-30,
2977 5.965e-30,
2978 6.079e-30, 6.207e-30, 6.276e-30, 6.222e-30, 6.137e-30, 6e-30, 5.814e-30,
2979 5.393e-30, 5.35e-30, 4.947e-30, 4.629e-30, 4.117e-30, 3.712e-30,
2980 3.372e-30,
2981 2.923e-30, 2.55e-30, 2.232e-30, 1.929e-30, 1.679e-30, 1.46e-30, 1.289e-30,
2982 1.13e-30, 9.953e-31, 8.763e-31, 7.76e-31, 6.9e-31, 6.16e-31, 5.525e-31,
2983 4.958e-31, 4.489e-31, 4.072e-31, 3.728e-31, 3.438e-31, 3.205e-31,
2984 3.006e-31,
2985 2.848e-31, 2.766e-31, 2.688e-31, 2.664e-31, 2.67e-31, 2.696e-31,
2986 2.786e-31,
2987 2.861e-31, 3.009e-31, 3.178e-31, 3.389e-31, 3.587e-31, 3.819e-31,
2988 4.054e-31,
2989 4.417e-31, 4.703e-31, 5.137e-31, 5.46e-31, 6.055e-31, 6.333e-31,
2990 6.773e-31,
2991 7.219e-31, 7.717e-31, 8.131e-31, 8.491e-31, 8.574e-31, 9.01e-31,
2992 9.017e-31,
2993 8.999e-31, 8.959e-31, 8.838e-31, 8.579e-31, 8.162e-31, 8.098e-31,
2994 7.472e-31,
2995 7.108e-31, 6.559e-31, 5.994e-31, 5.172e-31, 4.424e-31, 3.951e-31,
2996 3.34e-31,
2997 2.902e-31, 2.541e-31, 2.215e-31, 1.945e-31, 1.716e-31, 1.503e-31,
2998 1.339e-31,
2999 1.185e-31, 1.05e-31, 9.336e-32, 8.307e-32, 7.312e-32, 6.55e-32, 5.836e-32,
3000 5.178e-32, 4.6e-32, 4.086e-32, 3.639e-32, 3.247e-32, 2.904e-32, 2.604e-32,
3001 2.341e-32, 2.112e-32, 1.914e-32, 1.744e-32, 1.598e-32, 1.476e-32,
3002 1.374e-32,
3003 1.293e-32, 1.23e-32, 1.185e-32, 1.158e-32, 1.147e-32, 1.154e-32,
3004 1.177e-32,
3005 1.219e-32, 1.28e-32, 1.36e-32, 1.463e-32, 1.591e-32, 1.75e-32, 1.94e-32,
3006 2.156e-32, 2.43e-32, 2.748e-32, 3.052e-32, 3.533e-32, 3.967e-32,
3007 4.471e-32,
3008 5.041e-32, 5.86e-32, 6.664e-32, 7.522e-32, 8.342e-32, 9.412e-32,
3009 1.072e-31,
3010 1.213e-31, 1.343e-31, 1.496e-31, 1.664e-31, 1.822e-31, 2.029e-31,
3011 2.233e-31,
3012 2.457e-31, 2.709e-31, 2.928e-31, 3.115e-31, 3.356e-31, 3.592e-31,
3013 3.818e-31,
3014 3.936e-31, 4.061e-31, 4.149e-31, 4.299e-31, 4.223e-31, 4.251e-31,
3015 4.287e-31,
3016 4.177e-31, 4.094e-31, 3.942e-31, 3.772e-31, 3.614e-31, 3.394e-31,
3017 3.222e-31,
3018 2.791e-31, 2.665e-31, 2.309e-31, 2.032e-31, 1.74e-31, 1.535e-31,
3019 1.323e-31,
3020 1.151e-31, 9.803e-32, 8.65e-32, 7.54e-32, 6.619e-32, 5.832e-32, 5.113e-32,
3021 4.503e-32, 3.975e-32, 3.52e-32, 3.112e-32, 2.797e-32, 2.5e-32, 2.24e-32,
3022 2.013e-32, 1.819e-32, 1.653e-32, 1.513e-32, 1.395e-32, 1.299e-32,
3023 1.225e-32,
3024 1.168e-32, 1.124e-32, 1.148e-32, 1.107e-32, 1.128e-32, 1.169e-32,
3025 1.233e-32,
3026 1.307e-32, 1.359e-32, 1.543e-32, 1.686e-32, 1.794e-32, 2.028e-32,
3027 2.21e-32,
3028 2.441e-32, 2.653e-32, 2.828e-32, 3.093e-32, 3.28e-32, 3.551e-32,
3029 3.677e-32,
3030 3.803e-32, 3.844e-32, 4.068e-32, 4.093e-32, 4.002e-32, 3.904e-32,
3031 3.624e-32,
3032 3.633e-32, 3.622e-32, 3.443e-32, 3.184e-32, 2.934e-32, 2.476e-32,
3033 2.212e-32,
3034 1.867e-32, 1.594e-32, 1.37e-32, 1.192e-32, 1.045e-32, 9.211e-33, 8.17e-33,
3035 7.29e-33, 6.55e-33, 5.929e-33, 5.415e-33, 4.995e-33, 4.661e-33, 4.406e-33,
3036 4.225e-33, 4.116e-33, 4.075e-33, 4.102e-33, 4.198e-33, 4.365e-33,
3037 4.606e-33,
3038 4.925e-33, 5.326e-33, 5.818e-33, 6.407e-33, 7.104e-33, 7.92e-33,
3039 8.868e-33,
3040 9.964e-33, 1.123e-32, 1.268e-32, 1.434e-32, 1.626e-32, 1.848e-32,
3041 2.107e-32,
3042 2.422e-32, 2.772e-32, 3.145e-32, 3.704e-32, 4.27e-32, 4.721e-32,
3043 5.361e-32,
3044 6.083e-32, 7.095e-32, 7.968e-32, 9.228e-32, 1.048e-31, 1.187e-31,
3045 1.336e-31,
3046 1.577e-31, 1.772e-31, 2.017e-31, 2.25e-31, 2.63e-31, 2.911e-31, 3.356e-31,
3047 3.82e-31, 4.173e-31, 4.811e-31, 5.254e-31, 5.839e-31, 6.187e-31,
3048 6.805e-31,
3049 7.118e-31, 7.369e-31, 7.664e-31, 7.794e-31, 7.947e-31, 8.036e-31,
3050 7.954e-31,
3051 7.849e-31, 7.518e-31, 7.462e-31, 6.926e-31, 6.531e-31, 6.197e-31,
3052 5.421e-31,
3053 4.777e-31, 4.111e-31, 3.679e-31, 3.166e-31, 2.786e-31, 2.436e-31,
3054 2.144e-31,
3055 1.859e-31, 1.628e-31, 1.414e-31, 1.237e-31, 1.093e-31, 9.558e-32
3056 };
3057
3058 static const double h2ofrn[2001] =
3059 { 8.563e-23, 8.828e-23, 9.182e-23, 9.796e-23, 1.14e-22, 1.376e-22,
3060 1.545e-22,
3061 1.508e-22, 1.386e-22, 1.215e-22, 1.063e-22, 9.151e-23, 8.008e-23,
3062 6.97e-23,
3063 6.055e-23, 5.243e-23, 4.559e-23, 3.763e-23, 3.055e-23, 2.563e-23,
3064 2.197e-23,
3065 1.809e-23, 1.483e-23, 1.167e-23, 8.809e-24, 7.131e-24, 5.933e-24,
3066 5.172e-24,
3067 4.22e-24, 3.427e-24, 2.648e-24, 2.123e-24, 1.825e-24, 1.476e-24,
3068 1.101e-24,
3069 8.588e-25, 6.499e-25, 4.875e-25, 3.861e-25, 3.001e-25, 2.343e-25,
3070 2.087e-25,
3071 1.771e-25, 1.588e-25, 1.408e-25, 1.181e-25, 1.024e-25, 9.223e-26,
3072 7.916e-26,
3073 6.692e-26, 5.72e-26, 5.125e-26, 4.478e-26, 3.844e-26, 3.267e-26,
3074 2.851e-26,
3075 2.473e-26, 2.124e-26, 1.768e-26, 1.481e-26, 1.267e-26, 1.075e-26,
3076 9.212e-27,
3077 7.849e-27, 6.601e-27, 5.599e-27, 4.768e-27, 4.098e-27, 3.558e-27,
3078 3.089e-27,
3079 2.678e-27, 2.339e-27, 2.038e-27, 1.755e-27, 1.497e-27, 1.294e-27,
3080 1.129e-27,
3081 9.878e-28, 8.603e-28, 7.494e-28, 6.568e-28, 5.747e-28, 5.025e-28,
3082 4.345e-28,
3083 3.758e-28, 3.272e-28, 2.862e-28, 2.508e-28, 2.198e-28, 1.918e-28,
3084 1.68e-28,
3085 1.471e-28, 1.289e-28, 1.135e-28, 9.962e-29, 8.767e-29, 7.699e-29,
3086 6.798e-29,
3087 6.007e-29, 5.336e-29, 4.75e-29, 4.232e-29, 3.807e-29, 3.476e-29,
3088 3.237e-29,
3089 3.002e-29, 2.821e-29, 2.757e-29, 2.816e-29, 2.92e-29, 3.044e-29, 3.42e-29,
3090 3.745e-29, 4.197e-29, 4.816e-29, 5.987e-29, 7.098e-29, 8.082e-29,
3091 9.622e-29,
3092 1.211e-28, 1.502e-28, 1.766e-28, 2.223e-28, 2.901e-28, 3.951e-28,
3093 5.072e-28,
3094 6.232e-28, 7.904e-28, 1.034e-27, 1.438e-27, 1.89e-27, 2.59e-27, 3.592e-27,
3095 4.973e-27, 7.159e-27, 9.987e-27, 1.382e-26, 1.93e-26, 2.592e-26,
3096 3.454e-26,
3097 4.572e-26, 5.932e-26, 7.554e-26, 9.559e-26, 1.183e-25, 1.425e-25,
3098 1.681e-25,
3099 1.978e-25, 2.336e-25, 2.669e-25, 3.023e-25, 3.372e-25, 3.716e-25,
3100 3.968e-25,
3101 4.061e-25, 4.011e-25, 3.81e-25, 3.491e-25, 3.155e-25, 2.848e-25,
3102 2.678e-25,
3103 2.66e-25, 2.811e-25, 3.071e-25, 3.294e-25, 3.459e-25, 3.569e-25, 3.56e-25,
3104 3.434e-25, 3.186e-25, 2.916e-25, 2.622e-25, 2.275e-25, 1.918e-25,
3105 1.62e-25,
3106 1.373e-25, 1.182e-25, 1.006e-25, 8.556e-26, 7.26e-26, 6.11e-26, 5.04e-26,
3107 4.23e-26, 3.456e-26, 2.903e-26, 2.486e-26, 2.039e-26, 1.672e-26,
3108 1.285e-26,
3109 1.054e-26, 8.302e-27, 6.667e-27, 5.503e-27, 4.562e-27, 3.948e-27,
3110 3.198e-27,
3111 2.586e-27, 2.225e-27, 1.807e-27, 1.53e-27, 1.294e-27, 1.126e-27,
3112 9.604e-28,
3113 7.85e-28, 6.813e-28, 5.583e-28, 4.69e-28, 3.996e-28, 3.373e-28, 2.93e-28,
3114 2.417e-28, 2.061e-28, 1.743e-28, 1.475e-28, 1.273e-28, 1.084e-28,
3115 9.368e-29,
3116 7.985e-29, 6.785e-29, 5.804e-29, 4.975e-29, 4.311e-29, 3.738e-29,
3117 3.275e-29,
3118 2.847e-29, 2.469e-29, 2.149e-29, 1.884e-29, 1.631e-29, 1.393e-29,
3119 1.201e-29,
3120 1.027e-29, 8.807e-30, 7.521e-30, 6.436e-30, 5.509e-30, 4.729e-30,
3121 4.055e-30,
3122 3.49e-30, 3.006e-30, 2.599e-30, 2.246e-30, 1.942e-30, 1.685e-30,
3123 1.464e-30,
3124 1.273e-30, 1.115e-30, 9.794e-31, 8.729e-31, 7.893e-31, 7.313e-31,
3125 7.069e-31,
3126 7.19e-31, 7.828e-31, 9.295e-31, 1.174e-30, 1.578e-30, 2.184e-30,
3127 3.053e-30,
3128 4.212e-30, 5.733e-30, 7.497e-30, 9.487e-30, 1.153e-29, 1.343e-29,
3129 1.503e-29,
3130 1.623e-29, 1.696e-29, 1.746e-29, 1.789e-29, 1.852e-29, 1.862e-29,
3131 1.886e-29,
3132 1.912e-29, 1.942e-29, 1.938e-29, 1.914e-29, 1.898e-29, 1.864e-29,
3133 1.77e-29,
3134 1.635e-29, 1.464e-29, 1.279e-29, 1.099e-29, 9.528e-30, 8.433e-30,
3135 7.794e-30,
3136 7.793e-30, 8.241e-30, 9.417e-30, 1.179e-29, 1.616e-29, 2.144e-29,
3137 2.992e-29,
3138 4.344e-29, 6.415e-29, 9.242e-29, 1.31e-28, 1.847e-28, 2.567e-28, 3.39e-28,
3139 4.357e-28, 5.301e-28, 6.364e-28, 7.438e-28, 8.381e-28, 9.294e-28,
3140 1.013e-27,
3141 1.103e-27, 1.17e-27, 1.2e-27, 1.19e-27, 1.133e-27, 1.04e-27, 9.475e-28,
3142 8.601e-28, 8.074e-28, 8.023e-28, 8.473e-28, 9.256e-28, 9.989e-28,
3143 1.056e-27,
3144 1.079e-27, 1.079e-27, 1.049e-27, 1e-27, 9.35e-28, 8.662e-28, 7.88e-28,
3145 7.137e-28, 6.438e-28, 5.706e-28, 5.132e-28, 4.815e-28, 4.736e-28,
3146 4.709e-28,
3147 4.918e-28, 5.227e-28, 5.603e-28, 6.023e-28, 6.567e-28, 7.403e-28,
3148 8.695e-28,
3149 9.929e-28, 1.163e-27, 1.379e-27, 1.658e-27, 2.01e-27, 2.425e-27, 2.92e-27,
3150 3.562e-27, 4.274e-27, 5.173e-27, 6.285e-27, 7.787e-27, 9.563e-27,
3151 1.194e-26,
3152 1.517e-26, 1.934e-26, 2.511e-26, 3.197e-26, 4.024e-26, 4.981e-26,
3153 6.09e-26,
3154 7.229e-26, 8.439e-26, 9.367e-26, 1.016e-25, 1.057e-25, 1.088e-25,
3155 1.108e-25,
3156 1.129e-25, 1.159e-25, 1.19e-25, 1.21e-25, 1.21e-25, 1.2e-25, 1.19e-25,
3157 1.18e-25, 1.19e-25, 1.23e-25, 1.28e-25, 1.3e-25, 1.29e-25, 1.21e-25,
3158 1.09e-25, 9.44e-26, 7.79e-26, 6.22e-26, 4.64e-26, 3.4e-26, 2.47e-26,
3159 1.78e-26, 1.29e-26, 9.26e-27, 7e-27, 5.36e-27, 4.26e-27, 3.41e-27,
3160 2.79e-27, 2.36e-27, 2.01e-27, 1.75e-27, 1.52e-27, 1.33e-27, 1.16e-27,
3161 1.01e-27, 8.83e-28, 7.71e-28, 6.77e-28, 6.01e-28, 5.34e-28, 4.72e-28,
3162 4.2e-28, 3.69e-28, 3.27e-28, 2.92e-28, 2.57e-28, 2.27e-28, 2e-28,
3163 1.77e-28, 1.56e-28, 1.37e-28, 1.2e-28, 1.05e-28, 9.18e-29, 8e-29,
3164 6.98e-29, 6.08e-29, 5.27e-29, 4.56e-29, 3.94e-29, 3.4e-29, 2.93e-29,
3165 2.51e-29, 2.15e-29, 1.84e-29, 1.57e-29, 1.34e-29, 1.14e-29, 9.66e-30,
3166 8.19e-30, 6.93e-30, 5.86e-30, 4.95e-30, 4.19e-30, 3.56e-30, 3.06e-30,
3167 2.67e-30, 2.41e-30, 2.26e-30, 2.25e-30, 2.36e-30, 2.57e-30, 2.84e-30,
3168 3.18e-30, 3.49e-30, 3.71e-30, 3.81e-30, 3.84e-30, 3.8e-30, 3.59e-30,
3169 3.37e-30, 3.08e-30, 2.77e-30, 2.47e-30, 2.2e-30, 2.05e-30, 1.99e-30,
3170 2.03e-30, 2.13e-30, 2.25e-30, 2.34e-30, 2.41e-30, 2.47e-30, 2.48e-30,
3171 2.5e-30, 2.52e-30, 2.58e-30, 2.64e-30, 2.69e-30, 2.79e-30, 2.95e-30,
3172 3.13e-30, 3.34e-30, 3.57e-30, 3.84e-30, 4.2e-30, 4.66e-30, 5.21e-30,
3173 5.96e-30, 6.89e-30, 8.01e-30, 9.32e-30, 1.08e-29, 1.24e-29, 1.45e-29,
3174 1.71e-29, 2.01e-29, 2.36e-29, 2.82e-29, 3.38e-29, 4.01e-29, 4.79e-29,
3175 5.74e-29, 6.92e-29, 8.338e-29, 1.015e-28, 1.246e-28, 1.512e-28, 1.851e-28,
3176 2.32e-28, 2.988e-28, 3.989e-28, 5.351e-28, 7.256e-28, 1.011e-27,
3177 1.388e-27,
3178 1.914e-27, 2.512e-27, 3.257e-27, 4.075e-27, 4.991e-27, 5.914e-27,
3179 6.638e-27,
3180 7.16e-27, 7.45e-27, 7.59e-27, 7.54e-27, 7.47e-27, 7.53e-27, 7.94e-27,
3181 8.46e-27, 8.95e-27, 9.36e-27, 9.84e-27, 1.02e-26, 1.05e-26, 1.06e-26,
3182 1.07e-26, 1.07e-26, 1.04e-26, 9.79e-27, 8.8e-27, 7.66e-27, 6.38e-27,
3183 5.142e-27, 3.982e-27, 2.94e-27, 2.177e-27, 1.612e-27, 1.185e-27,
3184 8.966e-28,
3185 6.735e-28, 5.219e-28, 4.14e-28, 3.403e-28, 2.811e-28, 2.358e-28,
3186 1.969e-28,
3187 1.684e-28, 1.462e-28, 1.285e-28, 1.134e-28, 9.916e-29, 8.65e-29, 7.55e-29,
3188 6.62e-29, 5.83e-29, 5.14e-29, 4.51e-29, 3.98e-29, 3.53e-29, 3.12e-29,
3189 2.78e-29, 2.48e-29, 2.18e-29, 1.93e-29, 1.7e-29, 1.5e-29, 1.33e-29,
3190 1.16e-29, 1.03e-29, 9.01e-30, 7.86e-30, 6.88e-30, 6.02e-30, 5.25e-30,
3191 4.57e-30, 3.96e-30, 3.44e-30, 2.98e-30, 2.57e-30, 2.21e-30, 1.9e-30,
3192 1.63e-30, 1.4e-30, 1.21e-30, 1.04e-30, 9.09e-31, 7.96e-31, 7.05e-31,
3193 6.3e-31, 5.67e-31, 5.09e-31, 4.55e-31, 4.04e-31, 3.55e-31, 3.09e-31,
3194 2.64e-31, 2.26e-31, 1.9e-31, 1.6e-31, 1.34e-31, 1.14e-31, 1.01e-31,
3195 9.17e-32, 8.69e-32, 8.47e-32, 8.33e-32, 8.2e-32, 8.04e-32, 7.95e-32,
3196 7.98e-32, 8.25e-32, 8.47e-32, 8.74e-32, 8.87e-32, 8.92e-32, 8.71e-32,
3197 8.3e-32, 7.89e-32, 7.59e-32, 7.5e-32, 7.63e-32, 8.06e-32, 8.89e-32,
3198 1e-31, 1.14e-31, 1.28e-31, 1.45e-31, 1.64e-31, 1.87e-31, 2.12e-31,
3199 2.44e-31, 2.85e-31, 3.31e-31, 3.83e-31, 4.46e-31, 5.23e-31, 6.15e-31,
3200 7.35e-31, 8.84e-31, 1.07e-30, 1.29e-30, 1.59e-30, 1.99e-30, 2.49e-30,
3201 3.12e-30, 3.91e-30, 4.98e-30, 6.28e-30, 7.86e-30, 9.66e-30, 1.16e-29,
3202 1.41e-29, 1.7e-29, 2.06e-29, 2.54e-29, 3.17e-29, 4.08e-29, 5.24e-29,
3203 6.8e-29, 8.92e-29, 1.13e-28, 1.4e-28, 1.7e-28, 2.05e-28, 2.37e-28,
3204 2.61e-28, 2.77e-28, 2.85e-28, 2.86e-28, 2.78e-28, 2.72e-28, 2.74e-28,
3205 2.83e-28, 3.01e-28, 3.22e-28, 3.52e-28, 3.78e-28, 4.03e-28, 4.21e-28,
3206 4.33e-28, 4.39e-28, 4.34e-28, 4.25e-28, 4.07e-28, 3.88e-28, 3.67e-28,
3207 3.56e-28, 3.52e-28, 3.67e-28, 4.02e-28, 4.64e-28, 5.63e-28, 6.89e-28,
3208 8.82e-28, 1.11e-27, 1.41e-27, 1.73e-27, 2.12e-27, 2.57e-27, 2.99e-27,
3209 3.45e-27, 3.79e-27, 4.09e-27, 4.23e-27, 4.3e-27, 4.33e-27, 4.35e-27,
3210 4.44e-27, 4.54e-27, 4.62e-27, 4.67e-27, 4.71e-27, 4.77e-27, 4.93e-27,
3211 5.19e-27, 5.54e-27, 5.9e-27, 6.12e-27, 6.15e-27, 5.81e-27, 5.21e-27,
3212 4.51e-27, 3.69e-27, 2.89e-27, 2.14e-27, 1.55e-27, 1.11e-27, 7.78e-28,
3213 5.46e-28, 3.93e-28, 2.93e-28, 2.26e-28, 1.82e-28, 1.52e-28, 1.31e-28,
3214 1.15e-28, 1.02e-28, 9.01e-29, 7.95e-29, 7.04e-29, 6.2e-29, 5.49e-29,
3215 4.86e-29, 4.34e-29, 3.88e-29, 3.46e-29, 3.07e-29, 2.71e-29, 2.38e-29,
3216 2.09e-29, 1.82e-29, 1.59e-29, 1.38e-29, 1.2e-29, 1.04e-29, 9.08e-30,
3217 7.88e-30, 6.85e-30, 5.96e-30, 5.2e-30, 4.53e-30, 3.94e-30, 3.43e-30,
3218 2.97e-30, 2.58e-30, 2.23e-30, 1.92e-30, 1.66e-30, 1.43e-30, 1.24e-30,
3219 1.06e-30, 9.1e-31, 7.79e-31, 6.65e-31, 5.68e-31, 4.84e-31, 4.11e-31,
3220 3.51e-31, 2.99e-31, 2.54e-31, 2.17e-31, 1.86e-31, 1.59e-31, 1.37e-31,
3221 1.18e-31, 1.04e-31, 9.24e-32, 8.39e-32, 7.86e-32, 7.7e-32, 7.85e-32,
3222 8.41e-32, 9.62e-32, 1.16e-31, 1.47e-31, 1.94e-31, 2.58e-31, 3.51e-31,
3223 4.73e-31, 6.26e-31, 7.98e-31, 9.95e-31, 1.21e-30, 1.4e-30, 1.58e-30,
3224 1.77e-30, 1.98e-30, 2.22e-30, 2.47e-30, 2.79e-30, 3.14e-30, 3.55e-30,
3225 4e-30, 4.51e-30, 5.15e-30, 5.73e-30, 6.25e-30, 6.65e-30, 6.91e-30,
3226 6.98e-30, 6.83e-30, 6.67e-30, 6.57e-30, 6.6e-30, 6.84e-30, 7.39e-30,
3227 8.04e-30, 8.73e-30, 9.44e-30, 9.95e-30, 1.03e-29, 1.01e-29, 9.8e-30,
3228 9.32e-30, 8.67e-30, 7.99e-30, 7.29e-30, 6.67e-30, 6.14e-30, 5.78e-30,
3229 5.65e-30, 5.65e-30, 5.88e-30, 6.43e-30, 7.5e-30, 9.16e-30, 1.16e-29,
3230 1.51e-29, 1.99e-29, 2.7e-29, 3.66e-29, 4.95e-29, 6.41e-29, 8.16e-29,
3231 1.02e-28, 1.24e-28, 1.46e-28, 1.64e-28, 1.79e-28, 1.87e-28, 1.93e-28,
3232 1.93e-28, 1.93e-28, 1.95e-28, 2.07e-28, 2.23e-28, 2.34e-28, 2.44e-28,
3233 2.55e-28, 2.67e-28, 2.76e-28, 2.81e-28, 2.9e-28, 2.94e-28, 2.91e-28,
3234 2.77e-28, 2.52e-28, 2.21e-28, 1.84e-28, 1.49e-28, 1.15e-28, 8.64e-29,
3235 6.44e-29, 4.79e-29, 3.64e-29, 2.75e-29, 2.14e-29, 1.75e-29, 1.48e-29,
3236 1.3e-29, 1.16e-29, 1.05e-29, 9.46e-30, 8.55e-30, 7.66e-30, 6.79e-30,
3237 6.01e-30, 5.3e-30, 4.67e-30, 4.13e-30, 3.67e-30, 3.29e-30, 2.92e-30,
3238 2.57e-30, 2.27e-30, 1.96e-30, 1.7e-30, 1.47e-30, 1.27e-30, 1.1e-30,
3239 9.19e-31, 7.79e-31, 6.59e-31, 5.61e-31, 4.81e-31, 4.07e-31, 3.54e-31,
3240 3.04e-31, 2.62e-31, 2.3e-31, 1.97e-31, 1.71e-31, 1.48e-31, 1.28e-31,
3241 1.1e-31, 9.44e-32, 8.08e-32, 6.94e-32, 5.93e-32, 5.06e-32, 4.31e-32,
3242 3.66e-32, 3.12e-32, 2.67e-32, 2.28e-32, 1.95e-32, 1.67e-32, 1.43e-32,
3243 1.22e-32, 1.05e-32, 9.06e-33, 7.86e-33, 6.87e-33, 6.09e-33, 5.5e-33,
3244 5.07e-33, 4.78e-33, 4.66e-33, 4.77e-33, 5.21e-33, 5.94e-33, 7.44e-33,
3245 9.71e-33, 1.35e-32, 1.87e-32, 2.63e-32, 3.67e-32, 4.95e-32, 6.39e-32,
3246 8e-32, 9.88e-32, 1.15e-31, 1.28e-31, 1.37e-31, 1.43e-31, 1.47e-31,
3247 1.45e-31, 1.42e-31, 1.4e-31, 1.41e-31, 1.43e-31, 1.51e-31, 1.65e-31,
3248 1.83e-31, 2.07e-31, 2.25e-31, 2.38e-31, 2.42e-31, 2.38e-31, 2.27e-31,
3249 2.1e-31, 1.98e-31, 1.89e-31, 1.79e-31, 1.72e-31, 1.62e-31, 1.54e-31,
3250 1.43e-31, 1.35e-31, 1.35e-31, 1.42e-31, 1.57e-31, 1.77e-31, 2.06e-31,
3251 2.42e-31, 2.85e-31, 3.43e-31, 4.16e-31, 5.24e-31, 6.82e-31, 8.92e-31,
3252 1.2e-30, 1.6e-30, 2.15e-30, 2.89e-30, 3.77e-30, 4.8e-30, 5.93e-30,
3253 7.25e-30, 8.53e-30, 9.6e-30, 1.04e-29, 1.08e-29, 1.1e-29, 1.09e-29,
3254 1.07e-29, 1.07e-29, 1.12e-29, 1.21e-29, 1.33e-29, 1.48e-29, 1.64e-29,
3255 1.79e-29, 1.94e-29, 2.05e-29, 2.17e-29, 2.28e-29, 2.4e-29, 2.53e-29,
3256 2.74e-29, 3.03e-29, 3.42e-29, 3.87e-29, 4.47e-29, 5.19e-29, 5.91e-29,
3257 6.77e-29, 7.5e-29, 8.28e-29, 8.83e-29, 9.36e-29, 9.91e-29, 1.03e-28,
3258 1.09e-28, 1.14e-28, 1.17e-28, 1.18e-28, 1.18e-28, 1.18e-28, 1.21e-28,
3259 1.26e-28, 1.35e-28, 1.43e-28, 1.49e-28, 1.49e-28, 1.4e-28, 1.25e-28,
3260 1.07e-28, 8.61e-29, 6.57e-29, 4.8e-29, 3.47e-29, 2.47e-29, 1.78e-29,
3261 1.33e-29, 1.05e-29, 8.72e-30, 7.51e-30, 6.76e-30, 6.27e-30, 6e-30,
3262 5.99e-30, 6.26e-30, 6.86e-30, 7.58e-30, 8.49e-30, 9.53e-30, 1.05e-29,
3263 1.14e-29, 1.2e-29, 1.25e-29, 1.28e-29, 1.3e-29, 1.31e-29, 1.32e-29,
3264 1.33e-29, 1.33e-29, 1.31e-29, 1.27e-29, 1.23e-29, 1.19e-29, 1.2e-29,
3265 1.25e-29, 1.33e-29, 1.42e-29, 1.48e-29, 1.49e-29, 1.41e-29, 1.26e-29,
3266 1.08e-29, 8.8e-30, 6.78e-30, 4.95e-30, 3.58e-30, 2.54e-30, 1.78e-30,
3267 1.26e-30, 9.28e-31, 7.13e-31, 5.56e-31, 4.5e-31, 3.75e-31, 3.21e-31,
3268 2.76e-31, 2.41e-31, 2.09e-31, 1.82e-31, 1.59e-31, 1.36e-31, 1.18e-31,
3269 1.03e-31, 9.01e-32, 7.94e-32, 6.9e-32, 6.02e-32, 5.26e-32, 4.62e-32,
3270 4.06e-32, 3.55e-32, 3.13e-32, 2.76e-32, 2.43e-32, 2.15e-32, 1.9e-32,
3271 1.68e-32, 1.49e-32, 1.32e-32, 1.17e-32, 1.04e-32, 9.35e-33, 8.47e-33,
3272 7.79e-33, 7.3e-33, 6.96e-33, 6.88e-33, 7.11e-33, 7.6e-33, 8.67e-33,
3273 1.04e-32, 1.31e-32, 1.71e-32, 2.2e-32, 2.93e-32, 3.8e-32, 4.97e-32,
3274 6.22e-32, 7.63e-32, 9.29e-32, 1.1e-31, 1.24e-31, 1.34e-31, 1.41e-31,
3275 1.44e-31, 1.44e-31, 1.39e-31, 1.38e-31, 1.41e-31, 1.49e-31, 1.64e-31,
3276 1.86e-31, 2.11e-31, 2.38e-31, 2.65e-31, 2.89e-31, 3.04e-31, 3.14e-31,
3277 3.29e-31, 3.43e-31, 3.6e-31, 3.91e-31, 4.44e-31, 5.21e-31, 6.43e-31,
3278 8.18e-31, 1.06e-30, 1.4e-30, 1.78e-30, 2.24e-30, 2.77e-30, 3.35e-30,
3279 3.95e-30, 4.47e-30, 4.92e-30, 5.2e-30, 5.39e-30, 5.46e-30, 5.53e-30,
3280 5.66e-30, 6.02e-30, 6.43e-30, 6.68e-30, 6.91e-30, 7.12e-30, 7.42e-30,
3281 7.55e-30, 7.75e-30, 8.09e-30, 8.3e-30, 8.35e-30, 7.95e-30, 7.22e-30,
3282 6.3e-30, 5.23e-30, 4.2e-30, 3.19e-30, 2.39e-30, 1.79e-30, 1.36e-30,
3283 1.05e-30, 8.32e-31, 6.89e-31, 5.89e-31, 5.14e-31, 4.6e-31, 4.19e-31,
3284 3.94e-31, 3.9e-31, 4.07e-31, 4.39e-31, 4.82e-31, 5.29e-31, 5.75e-31,
3285 6.09e-31, 6.28e-31, 6.31e-31, 6.19e-31, 6.04e-31, 5.85e-31, 5.71e-31,
3286 5.68e-31, 5.68e-31, 5.64e-31, 5.58e-31, 5.51e-31, 5.48e-31, 5.45e-31,
3287 5.57e-31, 5.77e-31, 5.96e-31, 6.05e-31, 5.89e-31, 5.43e-31, 4.77e-31,
3288 4.02e-31, 3.25e-31, 2.5e-31, 1.82e-31, 1.31e-31, 9.32e-32, 6.58e-32,
3289 4.64e-32, 3.35e-32, 2.53e-32, 1.96e-32, 1.58e-32, 1.31e-32, 1.11e-32,
3290 9.58e-33, 8.32e-33, 7.31e-33, 6.43e-33, 5.62e-33, 4.89e-33, 4.27e-33,
3291 3.73e-33, 3.25e-33, 2.84e-33, 2.5e-33, 2.21e-33, 1.95e-33, 1.72e-33,
3292 1.52e-33, 1.34e-33, 1.18e-33, 1.05e-33, 9.26e-34, 8.21e-34, 7.29e-34,
3293 6.48e-34, 5.77e-34, 5.15e-34, 4.62e-34, 4.17e-34, 3.79e-34, 3.49e-34,
3294 3.26e-34, 3.09e-34, 3e-34, 2.98e-34, 3.04e-34, 3.2e-34, 3.49e-34,
3295 3.96e-34, 4.68e-34, 5.78e-34, 7.42e-34, 9.8e-34, 1.32e-33, 1.79e-33,
3296 2.23e-33, 2.65e-33, 3.02e-33, 3.38e-33, 3.74e-33, 4.05e-33, 4.42e-33,
3297 4.94e-33, 5.48e-33, 6.11e-33, 6.77e-33, 7.56e-33, 8.49e-33, 9.59e-33,
3298 1.09e-32, 1.27e-32, 1.48e-32, 1.73e-32, 2.08e-32, 2.48e-32, 3.03e-32,
3299 3.88e-32, 4.86e-32, 6.25e-32, 8.05e-32, 1.04e-31, 1.37e-31, 1.75e-31,
3300 2.2e-31, 2.75e-31, 3.35e-31, 4.08e-31, 4.79e-31, 5.44e-31, 5.99e-31,
3301 6.46e-31, 6.82e-31, 7.13e-31, 7.62e-31, 8.36e-31, 9.59e-31, 1.15e-30,
3302 1.38e-30, 1.67e-30, 1.99e-30, 2.35e-30, 2.74e-30, 3.11e-30, 3.51e-30,
3303 3.89e-30, 4.21e-30, 4.49e-30, 4.66e-30, 4.86e-30, 4.96e-30, 5.08e-30,
3304 5.2e-30, 5.29e-30, 5.3e-30, 5.22e-30, 5.16e-30, 5.18e-30, 5.35e-30,
3305 5.68e-30, 6.07e-30, 6.42e-30, 6.6e-30, 6.39e-30, 5.83e-30, 5.03e-30,
3306 4.11e-30, 3.2e-30, 2.35e-30, 1.7e-30, 1.2e-30, 8.54e-31, 6.31e-31,
3307 4.92e-31, 4.01e-31, 3.38e-31, 2.97e-31, 2.71e-31, 2.55e-31, 2.45e-31,
3308 2.42e-31, 2.43e-31, 2.49e-31, 2.6e-31, 2.73e-31, 2.91e-31, 3.16e-31,
3309 3.45e-31, 3.81e-31, 4.14e-31, 4.54e-31, 5.02e-31, 5.48e-31, 6.11e-31,
3310 6.72e-31, 7.37e-31, 7.99e-31, 8.5e-31, 9.01e-31, 9.3e-31, 9.52e-31,
3311 9.64e-31, 9.59e-31, 9.39e-31, 9.14e-31, 8.95e-31, 8.97e-31, 9.3e-31,
3312 9.91e-31, 1.06e-30, 1.12e-30, 1.14e-30, 1.1e-30, 1e-30, 8.68e-31,
3313 7.14e-31, 5.61e-31, 4.17e-31, 3.05e-31, 2.18e-31, 1.55e-31, 1.11e-31,
3314 8.29e-32, 6.38e-32, 5.07e-32, 4.2e-32, 3.64e-32, 3.28e-32, 3.03e-32,
3315 2.9e-32, 2.78e-32, 2.67e-32, 2.52e-32, 2.34e-32, 2.15e-32, 1.95e-32,
3316 1.75e-32, 1.54e-32, 1.32e-32, 1.13e-32, 9.55e-33, 7.9e-33, 6.44e-33,
3317 5.18e-33, 4.14e-33, 3.32e-33, 2.67e-33, 2.18e-33, 1.83e-33, 1.56e-33,
3318 1.35e-33, 1.18e-33, 1.05e-33, 9.31e-34, 8.35e-34, 7.55e-34, 6.89e-34,
3319 6.36e-34, 5.96e-34, 5.69e-34, 5.56e-34, 5.6e-34, 5.86e-34, 6.42e-34,
3320 7.33e-34, 8.85e-34, 1.14e-33, 1.49e-33, 1.97e-33, 2.69e-33, 3.61e-33,
3321 4.79e-33, 6.04e-33, 7.51e-33, 9.2e-33, 1.09e-32, 1.26e-32, 1.39e-32,
3322 1.53e-32, 1.64e-32, 1.71e-32, 1.77e-32, 1.88e-32, 2.08e-32, 2.37e-32,
3323 2.82e-32, 3.42e-32, 4.18e-32, 5.18e-32, 6.47e-32, 7.98e-32, 9.97e-32,
3324 1.22e-31, 1.47e-31, 1.75e-31, 2.05e-31, 2.38e-31, 2.66e-31, 2.91e-31,
3325 3.09e-31, 3.21e-31, 3.29e-31, 3.31e-31, 3.37e-31, 3.49e-31, 3.69e-31,
3326 3.82e-31, 3.92e-31, 4.05e-31, 4.17e-31, 4.3e-31, 4.42e-31, 4.61e-31,
3327 4.78e-31, 4.83e-31, 4.69e-31, 4.31e-31, 3.81e-31, 3.21e-31, 2.61e-31,
3328 2.04e-31, 1.56e-31, 1.2e-31, 9.2e-32, 7.1e-32, 5.65e-32, 4.63e-32,
3329 3.86e-32, 3.27e-32, 2.83e-32, 2.48e-32, 2.22e-32, 2.03e-32, 1.91e-32,
3330 1.84e-32, 1.82e-32, 1.82e-32, 1.86e-32, 1.94e-32, 2.11e-32, 2.36e-32,
3331 2.6e-32, 2.94e-32, 3.31e-32, 3.73e-32, 4.17e-32, 4.57e-32, 4.98e-32,
3332 5.26e-32, 5.54e-32, 5.79e-32, 6.05e-32, 6.38e-32, 6.71e-32, 6.93e-32,
3333 7.03e-32, 7.05e-32, 7.05e-32, 7.16e-32, 7.37e-32, 7.79e-32, 8.3e-32,
3334 8.65e-32, 8.76e-32, 8.32e-32, 7.51e-32, 6.48e-32, 5.31e-32, 4.18e-32,
3335 3.07e-32, 2.22e-32, 1.57e-32, 1.09e-32, 7.39e-33, 5.11e-33, 3.66e-33,
3336 2.68e-33, 2e-33, 1.56e-33, 1.27e-33, 1.06e-33, 9.05e-34, 7.85e-34,
3337 6.9e-34, 6.1e-34, 5.42e-34, 4.84e-34, 4.32e-34, 3.87e-34, 3.47e-34,
3338 3.12e-34, 2.8e-34, 2.52e-34, 2.27e-34, 2.05e-34, 1.86e-34, 1.69e-34,
3339 1.55e-34, 1.43e-34, 1.33e-34, 1.25e-34, 1.2e-34, 1.16e-34, 1.15e-34,
3340 1.16e-34, 1.19e-34, 1.25e-34, 1.34e-34, 1.45e-34, 1.6e-34, 1.78e-34,
3341 2.01e-34, 2.27e-34, 2.59e-34, 2.96e-34, 3.4e-34, 3.92e-34, 4.53e-34,
3342 5.24e-34, 6.08e-34, 7.09e-34, 8.31e-34, 9.81e-34, 1.17e-33, 1.42e-33,
3343 1.78e-33, 2.25e-33, 2.79e-33, 3.5e-33, 4.4e-33, 5.53e-33, 6.92e-33,
3344 8.92e-33, 1.15e-32, 1.48e-32, 1.92e-32, 2.54e-32, 3.37e-32, 4.37e-32,
3345 5.71e-32, 7.26e-32, 8.98e-32, 1.1e-31, 1.34e-31, 1.59e-31, 1.86e-31,
3346 2.14e-31, 2.4e-31, 2.69e-31, 2.98e-31, 3.33e-31, 3.77e-31, 4.25e-31,
3347 4.75e-31, 5.11e-31, 5.37e-31, 5.56e-31, 5.61e-31, 5.67e-31, 5.68e-31,
3348 5.78e-31, 5.86e-31, 5.91e-31, 5.93e-31, 5.91e-31, 5.92e-31, 5.93e-31,
3349 5.94e-31, 5.87e-31, 5.65e-31, 5.21e-31, 4.54e-31, 3.82e-31, 3.07e-31,
3350 2.37e-31, 1.78e-31, 1.32e-31, 9.82e-32, 7.34e-32, 5.59e-32, 4.33e-32,
3351 3.42e-32, 2.74e-32, 2.23e-32, 1.86e-32, 1.56e-32, 1.35e-32, 1.17e-32,
3352 1.05e-32, 9.54e-33, 8.83e-33, 8.34e-33, 8.1e-33, 8.11e-33, 8.2e-33,
3353 8.46e-33, 8.83e-33, 9.33e-33, 9.92e-33, 1.07e-32, 1.19e-32, 1.35e-32,
3354 1.58e-32, 1.86e-32, 2.17e-32, 2.52e-32, 2.92e-32, 3.36e-32, 3.83e-32,
3355 4.3e-32, 4.83e-32, 5.37e-32, 5.81e-32, 6.23e-32, 6.48e-32, 6.77e-32,
3356 6.99e-32, 7.17e-32, 7.47e-32, 7.66e-32, 7.77e-32, 7.77e-32, 7.72e-32,
3357 7.77e-32, 7.97e-32, 8.4e-32, 8.9e-32, 9.42e-32, 9.71e-32, 9.55e-32,
3358 8.85e-32, 7.68e-32, 6.39e-32, 5.02e-32, 3.74e-32, 2.68e-32, 1.87e-32,
3359 1.33e-32, 9.48e-33, 7e-33, 5.37e-33, 4.17e-33, 3.33e-33, 2.76e-33,
3360 2.35e-33, 2.04e-33, 1.78e-33, 1.59e-33, 1.42e-33, 1.23e-33, 1.06e-33,
3361 8.95e-34, 7.45e-34, 6.06e-34, 5.02e-34, 4.22e-34, 3.61e-34, 3.13e-34,
3362 2.75e-34, 2.45e-34, 2.19e-34, 1.97e-34, 1.79e-34, 1.63e-34, 1.49e-34,
3363 1.38e-34, 1.29e-34, 1.22e-34, 1.17e-34, 1.14e-34, 1.14e-34, 1.18e-34,
3364 1.26e-34, 1.41e-34, 1.65e-34, 2.04e-34, 2.65e-34, 3.59e-34, 4.87e-34,
3365 6.41e-34, 8.47e-34, 1.07e-33, 1.32e-33, 1.66e-33, 2.07e-33, 2.62e-33,
3366 3.21e-33, 3.94e-33, 4.84e-33, 5.81e-33, 6.84e-33, 7.73e-33, 8.67e-33,
3367 9.62e-33, 1.06e-32, 1.19e-32, 1.35e-32, 1.56e-32, 1.85e-32, 2.21e-32,
3368 2.66e-32, 3.14e-32, 3.6e-32, 3.99e-32, 4.22e-32, 4.36e-32, 4.35e-32,
3369 4.25e-32, 4.1e-32, 3.99e-32, 3.95e-32, 3.87e-32, 3.83e-32, 3.82e-32,
3370 3.89e-32, 3.98e-32, 4.06e-32, 4.19e-32, 4.22e-32, 4.17e-32, 3.9e-32,
3371 3.5e-32, 3.03e-32, 2.49e-32, 1.99e-32, 1.51e-32, 1.15e-32, 8.68e-33,
3372 6.53e-33, 4.89e-33, 3.78e-33, 2.92e-33, 2.25e-33, 1.74e-33, 1.35e-33,
3373 1.07e-33, 8.54e-34, 7.02e-34, 5.95e-34, 5.13e-34, 4.48e-34, 3.89e-34,
3374 3.34e-34, 2.94e-34, 2.63e-34, 2.42e-34, 2.3e-34, 2.27e-34, 2.37e-34,
3375 2.56e-34, 2.78e-34, 3.16e-34, 3.8e-34, 4.86e-34, 6.25e-34, 8.15e-34,
3376 1.01e-33, 1.24e-33, 1.49e-33, 1.73e-33, 1.99e-33, 2.22e-33, 2.44e-33,
3377 2.61e-33, 2.72e-33, 2.85e-33, 2.94e-33, 3.1e-33, 3.29e-33, 3.5e-33,
3378 3.62e-33, 3.66e-33, 3.7e-33, 3.72e-33, 3.83e-33, 4.01e-33, 4.26e-33,
3379 4.51e-33, 4.64e-33, 4.49e-33, 4.05e-33, 3.45e-33, 2.79e-33, 2.12e-33,
3380 1.46e-33, 9.67e-34, 6.18e-34, 3.98e-34, 2.63e-34, 1.81e-34, 1.32e-34,
3381 1.03e-34, 8.42e-35, 7.22e-35, 6.39e-35, 5.78e-35, 5.33e-35, 5e-35,
3382 4.76e-35, 4.61e-35, 4.54e-35, 4.55e-35, 4.64e-35, 4.81e-35, 5.06e-35,
3383 5.41e-35, 5.87e-35, 6.44e-35, 7.15e-35, 8.02e-35, 9.1e-35, 1.05e-34,
3384 1.22e-34, 1.46e-34, 1.8e-34, 2.28e-34, 2.98e-34, 4.02e-34, 5.53e-34,
3385 7.81e-34, 1.04e-33, 1.31e-33, 1.58e-33, 1.89e-33, 2.2e-33, 2.54e-33,
3386 3.01e-33, 3.67e-33, 4.43e-33, 5.42e-33, 6.85e-33, 8.44e-33, 1.04e-32,
3387 1.31e-32, 1.61e-32, 1.95e-32, 2.38e-32, 2.88e-32, 3.42e-32, 4.03e-32,
3388 4.65e-32, 5.24e-32, 5.7e-32, 6.09e-32, 6.39e-32, 6.48e-32, 6.58e-32,
3389 6.66e-32, 6.7e-32, 6.66e-32, 6.65e-32, 6.8e-32, 7.09e-32, 7.54e-32,
3390 8.06e-32, 8.62e-32, 8.89e-32, 8.68e-32, 8.04e-32, 7e-32, 5.83e-32,
3391 4.58e-32, 3.49e-32, 2.71e-32, 2.1e-32, 1.65e-32, 1.31e-32, 1.06e-32,
3392 8.35e-33, 6.45e-33, 5.02e-33, 3.94e-33, 3.09e-33, 2.46e-33
3393 };
3394
3395 static const double tcoslf_table[2001] =
3396 { 6.413, 6.414, 6.275, 6.049, 5.789, 5.557, 5.33,
3397 5.107, 4.893, 4.685, 4.481, 4.282, 4.09, 3.905,
3398 3.72, 3.548, 3.379, 3.215, 3.056, 2.903, 2.756,
3399 2.614, 2.475, 2.344, 2.219, 2.1, 1.983, 1.873,
3400 1.768, 1.67, 1.575, 1.486, 1.45, 1.432, 1.429,
3401 1.431, 1.428, 1.458, 1.517, 1.57, 1.628, 1.689,
3402 1.753, 1.819, 1.886, 1.976, 2.032, 2.106, 2.19,
3403 2.259, 2.33, 2.397, 2.466, 2.537, 2.613, 2.675,
3404 2.746, 2.819, 2.893, 2.97, 3.058, 3.168, 3.319,
3405 3.456, 3.601, 3.752, 3.9, 4.04, 4.183, 4.327,
3406 4.47, 4.602, 4.753, 4.897, 5.039, 5.214, 5.409,
3407 5.608, 5.782, 5.917, 5.983, 5.998, 6.016, 6.016,
3408 6.037, 6.026, 6.018, 6.021, 6.006, 6.005, 5.988,
3409 5.978, 5.956, 5.947, 5.898, 5.91, 5.88, 5.842,
3410 5.819, 5.772, 5.775, 5.74, 5.712, 5.685, 5.659,
3411 5.631, 5.601, 5.574, 5.541, 5.509, 5.474, 5.437,
3412 5.399, 5.359, 5.314, 5.261, 5.205, 5.146, 5.075,
3413 4.997, 4.909, 4.818, 4.709, 4.575, 4.411, 4.245,
3414 4.075, 3.889, 3.672, 3.387, 3.173, 2.907, 2.708,
3415 2.536, 2.35, 2.273, 2.196, 2.178, 2.201, 2.238,
3416 2.309, 2.382, 2.462, 2.579, 2.679, 2.737, 2.81,
3417 2.887, 2.964, 2.98, 3.011, 3.098, 3.157, 3.211,
3418 3.274, 3.388, 3.475, 3.527, 3.618, 3.772, 3.864,
3419 3.884, 3.889, 3.894, 3.884, 3.821, 3.758, 3.703,
3420 3.657, 3.567, 3.49, 3.435, 3.377, 3.29, 3.204,
3421 3.178, 3.146, 3.103, 3.088, 3.108, 3.116, 3.07,
3422 3.046, 3.029, 3.017, 3.001, 3.007, 2.984, 2.98,
3423 2.936, 2.908, 2.896, 2.875, 2.893, 2.888, 2.948,
3424 3.028, 3.064, 3.182, 3.228, 3.26, 3.335, 3.412,
3425 3.468, 3.523, 3.616, 3.659, 3.704, 3.81, 3.833,
3426 3.966, 4.026, 4.088, 4.141, 4.2, 4.269, 4.377,
3427 4.459, 4.566, 4.638, 4.709, 4.802, 4.878, 4.974,
3428 5.047, 5.147, 5.211, 5.315, 5.391, 5.483, 5.566,
3429 5.603, 5.643, 5.767, 5.807, 5.843, 5.904, 5.924,
3430 5.983, 5.993, 6.059, 6.095, 6.13, 6.153, 6.174,
3431 6.18, 6.201, 6.202, 6.21, 6.206, 6.209, 6.187,
3432 6.172, 6.138, 6.129, 6.085, 6.066, 6.043, 6.001,
3433 5.951, 5.93, 5.869, 5.822, 5.809, 5.777, 5.739,
3434 5.7, 5.68, 5.659, 5.598, 5.558, 5.519, 5.465,
3435 5.399, 5.358, 5.294, 5.225, 5.158, 5.094, 5.023,
3436 4.94, 4.846, 4.759, 4.662, 4.557, 4.435, 4.304,
3437 4.188, 4.042, 3.954, 3.803, 3.695, 3.619, 3.51,
3438 3.414, 3.366, 3.284, 3.217, 3.152, 3.044, 2.983,
3439 2.898, 2.784, 2.68, 2.627, 2.634, 2.704, 2.637,
3440 2.756, 2.79, 2.941, 3.091, 3.203, 3.308, 3.431,
3441 3.49, 3.57, 3.652, 3.683, 3.708, 3.722, 3.687,
3442 3.631, 3.584, 3.566, 3.536, 3.459, 3.401, 3.326,
3443 3.216, 3.103, 2.944, 2.828, 2.652, 2.597, 2.559,
3444 2.522, 2.468, 2.466, 2.43, 2.412, 2.383, 2.357,
3445 2.338, 2.312, 2.287, 2.25, 2.221, 2.174, 2.174,
3446 2.135, 2.109, 2.107, 2.106, 2.062, 2.075, 2.08,
3447 2.136, 2.219, 2.291, 2.415, 2.52, 2.663, 2.797,
3448 2.936, 3.112, 3.244, 3.347, 3.437, 3.501, 3.513,
3449 3.511, 3.515, 3.553, 3.553, 3.568, 3.621, 3.713,
3450 3.836, 3.888, 3.897, 3.874, 3.825, 3.743, 3.626,
3451 3.503, 3.365, 3.225, 3.077, 2.914, 2.764, 2.623,
3452 2.508, 2.433, 2.42, 2.41, 2.445, 2.49, 2.623,
3453 2.753, 2.871, 2.981, 3.069, 3.176, 3.27, 3.339,
3454 3.394, 3.45, 3.511, 3.572, 3.623, 3.668, 3.742,
3455 3.807, 3.893, 3.961, 4.019, 4.106, 4.194, 4.286,
3456 4.364, 4.447, 4.532, 4.629, 4.719, 4.815, 4.9,
3457 4.989, 5.067, 5.16, 5.245, 5.326, 5.406, 5.479,
3458 5.558, 5.632, 5.702, 5.772, 5.831, 5.893, 5.953,
3459 6.009, 6.056, 6.103, 6.143, 6.183, 6.21, 6.239,
3460 6.258, 6.264, 6.263, 6.247, 6.229, 6.201, 6.176,
3461 6.141, 6.11, 6.096, 6.085, 6.071, 6.05, 6.053,
3462 6.042, 6.035, 6.018, 6.005, 5.99, 5.955, 5.931,
3463 5.884, 5.833, 5.782, 5.724, 5.664, 5.594, 5.542,
3464 5.484, 5.422, 5.351, 5.284, 5.222, 5.143, 5.063,
3465 4.978, 4.896, 4.81, 4.723, 4.625, 4.525, 4.431,
3466 4.334, 4.231, 4.123, 4.022, 3.918, 3.831, 3.726,
3467 3.624, 3.537, 3.454, 3.367, 3.279, 3.211, 3.137,
3468 3.056, 2.968, 2.876, 2.764, 2.638, 2.486, 2.392,
3469 2.28, 2.193, 2.08, 2.056, 2.097, 2.155, 2.239,
3470 2.327, 2.461, 2.617, 2.759, 2.925, 3.082, 3.253,
3471 3.366, 3.491, 3.58, 3.67, 3.733, 3.756, 3.735,
3472 3.663, 3.612, 3.604, 3.655, 3.671, 3.68, 3.721,
3473 3.769, 3.769, 3.71, 3.605, 3.493, 3.383, 3.231,
3474 3.109, 2.936, 2.781, 2.645, 2.514, 2.397, 2.304,
3475 2.236, 2.212, 2.195, 2.204, 2.248, 2.337, 2.464,
3476 2.575, 2.714, 2.815, 2.941, 3.072, 3.173, 3.263,
3477 3.331, 3.398, 3.471, 3.531, 3.597, 3.657, 3.737,
3478 3.8, 3.844, 3.932, 3.997, 4.062, 4.135, 4.214,
3479 4.303, 4.378, 4.46, 4.563, 4.642, 4.72, 4.808,
3480 4.885, 4.978, 5.063, 5.142, 5.234, 5.318, 5.395,
3481 5.482, 5.553, 5.624, 5.684, 5.737, 5.792, 5.84,
3482 5.886, 5.925, 5.969, 6.01, 6.043, 6.078, 6.109,
3483 6.142, 6.159, 6.184, 6.201, 6.207, 6.211, 6.207,
3484 6.204, 6.187, 6.17, 6.151, 6.126, 6.099, 6.067,
3485 6.033, 5.992, 5.956, 5.919, 5.885, 5.847, 5.813,
3486 5.787, 5.755, 5.725, 5.687, 5.651, 5.607, 5.557,
3487 5.51, 5.458, 5.406, 5.35, 5.29, 5.225, 5.163,
3488 5.094, 5.013, 4.933, 4.852, 4.756, 4.661, 4.554,
3489 4.44, 4.326, 4.198, 4.078, 3.961, 3.823, 3.714,
3490 3.606, 3.527, 3.43, 3.345, 3.28, 3.216, 3.151,
3491 3.057, 2.985, 2.902, 2.786, 2.694, 2.64, 2.634,
3492 2.655, 2.667, 2.741, 2.824, 2.955, 3.069, 3.196,
3493 3.298, 3.408, 3.501, 3.577, 3.642, 3.673, 3.712,
3494 3.712, 3.688, 3.632, 3.598, 3.567, 3.536, 3.461,
3495 3.398, 3.331, 3.211, 3.099, 2.947, 2.825, 2.651,
3496 2.467, 2.338, 2.184, 2.098, 2.061, 2.037, 2.101,
3497 2.154, 2.279, 2.397, 2.514, 2.669, 2.799, 2.946,
3498 3.099, 3.232, 3.331, 3.404, 3.471, 3.481, 3.516,
3499 3.537, 3.587, 3.613, 3.637, 3.702, 3.772, 3.874,
3500 3.898, 3.883, 3.84, 3.771, 3.692, 3.566, 3.436,
3501 3.29, 3.133, 3.002, 2.833, 2.686, 2.565, 2.498,
3502 2.489, 2.51, 2.575, 2.69, 2.836, 2.967, 3.067,
3503 3.15, 3.215, 3.275, 3.333, 3.369, 3.416, 3.478,
3504 3.526, 3.563, 3.603, 3.649, 3.678, 3.694, 3.716,
3505 3.74, 3.761, 3.8, 3.831, 3.874, 3.942, 4.005,
3506 4.099, 4.193, 4.29, 4.387, 4.497, 4.617, 4.715,
3507 4.805, 4.894, 4.991, 5.084, 5.161, 5.236, 5.3,
3508 5.368, 5.454, 5.529, 5.589, 5.654, 5.714, 5.786,
3509 5.838, 5.886, 5.947, 5.987, 6.032, 6.071, 6.099,
3510 6.122, 6.136, 6.147, 6.151, 6.144, 6.129, 6.104,
3511 6.063, 6.008, 5.936, 5.835, 5.713, 5.572, 5.404,
3512 5.225, 5.042, 4.88, 4.718, 4.576, 4.46, 4.355,
3513 4.234, 4.111, 3.975, 3.888, 3.766, 3.683, 3.633,
3514 3.637, 3.669, 3.702, 3.739, 3.804, 3.87, 3.916,
3515 3.948, 3.943, 3.971, 3.98, 3.982, 3.967, 3.95,
3516 3.947, 3.92, 3.888, 3.819, 3.756, 3.689, 3.618,
3517 3.523, 3.405, 3.303, 3.206, 3.098, 2.963, 2.816,
3518 2.667, 2.521, 2.39, 2.261, 2.135, 2.031, 1.988,
3519 1.995, 2.044, 2.105, 2.189, 2.315, 2.445, 2.592,
3520 2.745, 2.907, 3.07, 3.231, 3.34, 3.45, 3.547,
3521 3.617, 3.682, 3.683, 3.653, 3.577, 3.558, 3.572,
3522 3.597, 3.648, 3.693, 3.772, 3.801, 3.772, 3.703,
3523 3.597, 3.459, 3.335, 3.189, 3.054, 2.901, 2.756,
3524 2.629, 2.519, 2.415, 2.379, 2.391, 2.433, 2.485,
3525 2.612, 2.787, 2.913, 3.033, 3.11, 3.185, 3.21,
3526 3.254, 3.286, 3.316, 3.334, 3.376, 3.422, 3.443,
3527 3.471, 3.492, 3.496, 3.491, 3.491, 3.481, 3.46,
3528 3.475, 3.466, 3.471, 3.485, 3.482, 3.548, 3.566,
3529 3.643, 3.748, 3.8, 3.956, 4.068, 4.223, 4.357,
3530 4.506, 4.634, 4.752, 4.839, 4.89, 4.95, 5.034,
3531 5.113, 5.176, 5.228, 5.383, 5.523, 5.62, 5.705,
3532 5.775, 5.823, 5.885, 5.931, 5.96, 5.985, 6.006,
3533 6.019, 6.021, 6.015, 5.997, 5.954, 5.901, 5.817,
3534 5.716, 5.554, 5.389, 5.18, 4.951, 4.772, 4.646,
3535 4.551, 4.424, 4.389, 4.41, 4.457, 4.471, 4.473,
3536 4.545, 4.605, 4.644, 4.652, 4.669, 4.666, 4.639,
3537 4.603, 4.531, 4.493, 4.449, 4.411, 4.361, 4.304,
3538 4.269, 4.212, 4.17, 4.152, 4.133, 4.119, 4.1,
3539 4.105, 4.096, 4.042, 3.964, 3.876, 3.779, 3.652,
3540 3.513, 3.359, 3.201, 3.075, 2.935, 2.775, 2.682,
3541 2.601, 2.613, 2.64, 2.663, 2.73, 2.82, 2.936,
3542 3.052, 3.149, 3.243, 3.322, 3.394, 3.441, 3.479,
3543 3.449, 3.423, 3.388, 3.331, 3.253, 3.153, 3.109,
3544 3.05, 2.952, 2.864, 2.808, 2.708, 2.657, 2.594,
3545 2.554, 2.543, 2.549, 2.623, 2.708, 2.798, 2.909,
3546 3.039, 3.161, 3.244, 3.293, 3.358, 3.389, 3.424,
3547 3.489, 3.559, 3.601, 3.641, 3.707, 3.791, 3.879,
3548 3.902, 3.873, 3.811, 3.726, 3.637, 3.519, 3.357,
3549 3.205, 3.055, 2.898, 2.737, 2.612, 2.543, 2.531,
3550 2.589, 2.697, 2.819, 2.914, 2.991, 3.045, 3.067,
3551 3.06, 3.082, 3.087, 3.11, 3.145, 3.183, 3.249,
3552 3.296, 3.346, 3.399, 3.409, 3.449, 3.472, 3.497,
3553 3.55, 3.593, 3.638, 3.674, 3.731, 3.795, 3.863,
3554 3.874, 3.845, 3.808, 3.739, 3.661, 3.556, 3.411,
3555 3.273, 3.139, 3.009, 2.865, 2.736, 2.675, 2.674,
3556 2.73, 2.845, 2.969, 3.148, 3.3, 3.429, 3.55,
3557 3.642, 3.721, 3.797, 3.866, 3.918, 3.992, 4.054,
3558 4.117, 4.18, 4.237, 4.318, 4.4, 4.482, 4.567,
3559 4.648, 4.735, 4.813, 4.886, 4.958, 5.022, 5.083,
3560 5.137, 5.186, 5.231, 5.266, 5.295, 5.317, 5.324,
3561 5.311, 5.287, 5.248, 5.178, 5.076, 4.954, 4.793,
3562 4.605, 4.349, 4.099, 3.939, 3.72, 3.578, 3.462,
3563 3.431, 3.463, 3.48, 3.528, 3.564, 3.631, 3.705,
3564 3.747, 3.782, 3.802, 3.825, 3.821, 3.787, 3.737,
3565 3.698, 3.642, 3.563, 3.445, 3.32, 3.2, 3.072,
3566 2.931, 2.722, 2.582, 2.409, 2.311, 2.237, 2.194,
3567 2.209, 2.256, 2.352, 2.45, 2.584, 2.72, 2.87,
3568 3.018, 3.184, 3.316, 3.408, 3.506, 3.577, 3.623,
3569 3.604, 3.565, 3.555, 3.562, 3.585, 3.603, 3.681,
3570 3.774, 3.838, 3.83, 3.779, 3.711, 3.592, 3.455,
3571 3.326, 3.157, 3.007, 2.847, 2.702, 2.583, 2.503,
3572 2.479, 2.513, 2.588, 2.656, 2.78, 2.894, 2.967,
3573 3.026, 3.076, 3.122, 3.164, 3.212, 3.282, 3.335,
3574 3.405, 3.468, 3.508, 3.546, 3.57, 3.591, 3.575,
3575 3.576, 3.611, 3.619, 3.649, 3.675, 3.764, 3.854,
3576 3.88, 3.873, 3.83, 3.767, 3.673, 3.556, 3.44,
3577 3.309, 3.188, 3.07, 2.969, 2.906, 2.871, 2.904,
3578 3.003, 3.162, 3.317, 3.469, 3.647, 3.774, 3.884,
3579 3.98, 4.066, 4.143, 4.225, 4.323, 4.419, 4.515,
3580 4.603, 4.707, 4.809, 4.893, 4.984, 5.071, 5.156,
3581 5.251, 5.329, 5.407, 5.478, 5.543, 5.594, 5.641,
3582 5.684, 5.708, 5.73, 5.741, 5.745, 5.738, 5.727,
3583 5.701, 5.676, 5.633, 5.591, 5.547, 5.489, 5.431,
3584 5.368, 5.299, 5.224, 5.154, 5.069, 4.99, 4.903,
3585 4.812, 4.717, 4.615, 4.513, 4.404, 4.29, 4.162,
3586 4.023, 3.904, 3.796, 3.683, 3.552, 3.424, 3.295,
3587 3.189, 3.034, 2.878, 2.751, 2.577, 2.47, 2.358,
3588 2.215, 2.154, 2.105, 2.104, 2.117, 2.129, 2.184,
3589 2.237, 2.298, 2.374, 2.462, 2.52, 2.606, 2.6,
3590 2.596, 2.619, 2.618, 2.572, 2.536, 2.573, 2.618,
3591 2.634, 2.646, 2.714, 2.787, 2.875, 2.963, 3.065,
3592 3.179, 3.253, 3.316, 3.352, 3.393, 3.404, 3.445,
3593 3.496, 3.547, 3.597, 3.632, 3.712, 3.787, 3.846,
3594 3.85, 3.806, 3.747, 3.662, 3.573, 3.424, 3.274,
3595 3.142, 3.017, 2.87, 2.765, 2.73, 2.781, 2.864,
3596 2.937, 3.002, 3.032, 3.044, 3.027, 3.007, 2.979,
3597 2.934, 2.897, 2.887, 2.875, 2.853, 2.848, 2.859,
3598 2.903, 2.925, 2.953, 3.006, 3.061, 3.12, 3.184,
3599 3.277, 3.343, 3.374, 3.422, 3.481, 3.521, 3.588,
3600 3.641, 3.695, 3.742, 3.776, 3.85, 3.899, 3.919,
3601 3.891, 3.84, 3.761, 3.662, 3.562, 3.395, 3.261,
3602 3.131, 3.018, 2.887, 2.802, 2.796, 2.87, 2.986,
3603 3.102, 3.247, 3.332, 3.4, 3.455, 3.511, 3.567,
3604 3.624, 3.671, 3.702, 3.734, 3.782, 3.823, 3.835,
3605 3.851, 3.883, 3.919, 3.949, 3.975, 4.014, 4.061,
3606 4.13, 4.218, 4.317, 4.422, 4.559, 4.68, 4.776,
3607 4.862, 4.932, 4.991, 5.033, 5.078, 5.106, 5.117,
3608 5.119, 5.095, 5.053, 4.988, 4.896, 4.785, 4.648,
3609 4.498, 4.352, 4.161, 4.005, 3.841, 3.673, 3.543,
3610 3.398, 3.323, 3.23, 3.17, 3.118, 3.049, 3,
3611 2.932, 2.83, 2.744, 2.617, 2.49, 2.368, 2.261,
3612 2.172, 2.135, 2.165, 2.189, 2.229, 2.313, 2.407,
3613 2.503, 2.601, 2.723, 2.853, 2.968, 3.109, 3.253,
3614 3.342, 3.43, 3.521, 3.572, 3.613, 3.582, 3.603,
3615 3.622, 3.633, 3.662, 3.702, 3.806, 3.86, 3.85,
3616 3.796, 3.722, 3.618, 3.481, 3.347, 3.2, 3.082,
3617 2.952, 2.846, 2.798, 2.783, 2.848, 2.912, 2.97,
3618 3.023, 3.085, 3.107, 3.104, 3.067, 3.034, 2.996,
3619 2.941, 2.914, 2.897, 2.887, 2.903, 2.915, 2.92,
3620 2.969, 3.023, 3.104, 3.174, 3.268, 3.393, 3.481,
3621 3.557, 3.633, 3.662, 3.664, 3.665, 3.712, 3.729,
3622 3.739, 3.774, 3.844, 3.971, 4.023, 4.02, 3.983,
3623 3.913, 3.853, 3.703, 3.511, 3.351, 3.168, 3.014,
3624 2.897, 2.844, 2.918, 3.074, 3.295, 3.464, 3.614,
3625 3.74, 3.858, 3.972, 4.079, 4.188, 4.286, 4.385,
3626 4.486, 4.581, 4.678, 4.767, 4.855, 4.937, 5.008,
3627 5.079, 5.137, 5.187, 5.225, 5.255, 5.271, 5.273,
3628 5.264, 5.247, 5.216, 5.176, 5.131, 5.072, 5.007,
3629 4.941, 4.865, 4.785, 4.704, 4.617, 4.529, 4.439,
3630 4.348, 4.251, 4.153, 4.047, 3.942, 3.826, 3.697,
3631 3.562, 3.403, 3.239, 3.069, 2.915, 2.731, 2.531,
3632 2.341, 2.183, 2.069, 1.908, 1.781, 1.717, 1.691,
3633 1.629, 1.601, 1.635, 1.693, 1.756, 1.826, 1.951,
3634 2.048, 2.126, 2.238, 2.359, 2.474, 2.578, 2.696,
3635 2.803, 2.875, 2.968, 3.056, 3.12, 3.174, 3.258,
3636 3.342, 3.398, 3.466, 3.531, 3.623, 3.712, 3.772,
3637 3.806, 3.811, 3.796, 3.777, 3.757, 3.752, 3.707,
3638 3.672, 3.627, 3.572, 3.506, 3.398, 3.316, 3.227,
3639 3.12, 3.033, 3.028, 3.04, 3.092, 3.143, 3.177,
3640 3.227, 3.242, 3.265, 3.267, 3.243, 3.215, 3.21,
3641 3.215, 3.226, 3.236, 3.258, 3.289, 3.279, 3.268,
3642 3.242, 3.147, 3.11, 3.044, 2.985, 2.903, 2.832,
3643 2.808, 2.782, 2.797, 2.832, 2.903, 2.979, 3.061,
3644 3.163, 3.247, 3.331, 3.383, 3.419, 3.46, 3.496,
3645 3.518, 3.557, 3.623, 3.679, 3.725, 3.762, 3.821,
3646 3.864, 3.899, 3.892, 3.829, 3.752, 3.661, 3.565,
3647 3.44, 3.331, 3.231, 3.13, 3.018, 2.99, 3.044,
3648 3.098, 3.194, 3.294, 3.382, 3.44, 3.485, 3.522,
3649 3.55, 3.568, 3.623, 3.668, 3.715, 3.774, 3.841,
3650 3.903, 3.952, 3.981, 4.009, 4.044, 4.062, 4.099,
3651 4.142, 4.207, 4.286, 4.378, 4.483, 4.578, 4.679,
3652 4.771, 4.857, 4.934, 5.007, 5.086, 5.154, 5.224,
3653 5.295, 5.358, 5.427, 5.489, 5.55, 5.612, 5.671,
3654 5.729, 5.782, 5.836, 5.885, 5.933, 5.978, 6.023,
3655 6.065, 6.102, 6.136, 6.169, 6.197, 6.228, 6.253,
3656 6.275, 6.292, 6.309, 6.323, 6.334, 6.341, 6.349,
3657 6.356, 6.359, 6.359, 6.359, 6.359, 6.356, 6.352,
3658 6.349, 6.342, 6.335, 6.331, 6.324, 6.317, 6.309,
3659 6.306, 6.299, 6.295, 6.288, 6.284, 6.281, 6.281,
3660 6.278, 6.277, 6.278, 6.277, 6.282, 6.283, 6.289,
3661 6.297, 6.3, 6.305, 6.317, 6.325, 6.337, 6.345,
3662 6.36, 6.37, 6.384, 6.398, 6.416, 6.43, 6.448,
3663 6.465, 6.483, 6.502, 6.52, 6.541, 6.562, 6.583,
3664 6.605, 6.628, 6.649, 6.672, 6.697, 6.72, 6.743,
3665 6.768, 6.791, 6.818, 6.841, 6.867, 6.891, 6.916,
3666 6.943, 6.97, 6.996, 7.022, 7.052, 7.077, 7.103,
3667 7.132, 7.158, 7.185, 7.215, 7.241, 7.269, 7.298,
3668 7.326, 7.354, 7.382, 7.41, 7.438, 7.469, 7.497,
3669 7.528, 7.555, 7.585, 7.613, 7.643, 7.669, 7.698,
3670 7.729, 7.759, 7.787, 7.819, 7.849, 7.878, 7.909,
3671 7.936, 7.968, 7.998, 8.03, 8.055, 8.088, 8.115,
3672 8.146, 8.18, 8.205, 8.235, 8.269, 8.297, 8.328,
3673 8.36, 8.393, 8.421, 8.452, 8.484, 8.513, 8.547,
3674 8.576, 8.607, 8.64, 8.671, 8.699, 8.733, 8.762,
3675 8.794, 8.827, 8.855, 8.891, 8.922, 8.954, 8.984,
3676 9.015, 9.049, 9.08, 9.114, 9.143, 9.175, 9.209,
3677 9.241, 9.271, 9.306, 9.338, 9.369, 9.403, 9.435,
3678 9.466, 9.5, 9.532, 9.562, 9.594, 9.63, 9.661,
3679 9.695, 9.726, 9.761, 9.792, 9.825, 9.859, 9.891,
3680 9.924, 9.954, 9.987, 10.02, 10.06, 10.09, 10.12,
3681 10.16, 10.19, 10.22, 10.26, 10.29, 10.32
3682 };
3683
3684 /* Get MT_CKD 4.1 H2O continuum absorption... */
3685 const double xw = nu / 10 + 1;
3686 if (xw >= 1 && xw < 2001) {
3687 const int iw = (int) xw;
3688 const double dw = xw - iw;
3689 const double ew = 1 - dw;
3690 const double cwslf = ew * h2oslf[iw - 1] + dw * h2oslf[iw];
3691 const double cwfrn = ew * h2ofrn[iw - 1] + dw * h2ofrn[iw];
3692 const double tcoslf = ew * tcoslf_table[iw - 1]
3693 + dw * tcoslf_table[iw];
3694 const double ctwslf = cwslf * pow(296 / t, tcoslf);
3695 const double a1 = nu * u * tanh(.7193876 / t * nu);
3696 const double a2 = 296 / t;
3697 const double a3 = p / 1013 * (q * ctwslf + (1 - q) * cwfrn);
3698 return a1 * a2 * a3;
3699 } else
3700 return 0;
3701}
3702
3703/*****************************************************************************/
3704
3705double ctmn2(
3706 const double nu,
3707 const double p,
3708 const double t) {
3709
3710 static const double ba[98] =
3711 { 0., 4.45e-8, 5.22e-8, 6.46e-8, 7.75e-8, 9.03e-8,
3712 1.06e-7, 1.21e-7, 1.37e-7, 1.57e-7, 1.75e-7, 2.01e-7, 2.3e-7,
3713 2.59e-7, 2.95e-7, 3.26e-7, 3.66e-7, 4.05e-7, 4.47e-7, 4.92e-7,
3714 5.34e-7, 5.84e-7, 6.24e-7, 6.67e-7, 7.14e-7, 7.26e-7, 7.54e-7,
3715 7.84e-7, 8.09e-7, 8.42e-7, 8.62e-7, 8.87e-7, 9.11e-7, 9.36e-7,
3716 9.76e-7, 1.03e-6, 1.11e-6, 1.23e-6, 1.39e-6, 1.61e-6, 1.76e-6,
3717 1.94e-6, 1.97e-6, 1.87e-6, 1.75e-6, 1.56e-6, 1.42e-6, 1.35e-6,
3718 1.32e-6, 1.29e-6, 1.29e-6, 1.29e-6, 1.3e-6, 1.32e-6, 1.33e-6,
3719 1.34e-6, 1.35e-6, 1.33e-6, 1.31e-6, 1.29e-6, 1.24e-6, 1.2e-6,
3720 1.16e-6, 1.1e-6, 1.04e-6, 9.96e-7, 9.38e-7, 8.63e-7, 7.98e-7,
3721 7.26e-7, 6.55e-7, 5.94e-7, 5.35e-7, 4.74e-7, 4.24e-7, 3.77e-7,
3722 3.33e-7, 2.96e-7, 2.63e-7, 2.34e-7, 2.08e-7, 1.85e-7, 1.67e-7,
3723 1.47e-7, 1.32e-7, 1.2e-7, 1.09e-7, 9.85e-8, 9.08e-8, 8.18e-8,
3724 7.56e-8, 6.85e-8, 6.14e-8, 5.83e-8, 5.77e-8, 5e-8, 4.32e-8, 0.
3725 };
3726
3727 static const double betaa[98] =
3728 { 802., 802., 761., 722., 679., 646., 609., 562.,
3729 511., 472., 436., 406., 377., 355., 338., 319., 299., 278., 255.,
3730 233., 208., 184., 149., 107., 66., 25., -13., -49., -82., -104.,
3731 -119., -130., -139., -144., -146., -146., -147., -148., -150.,
3732 -153., -160., -169., -181., -189., -195., -200., -205., -209.,
3733 -211., -210., -210., -209., -205., -199., -190., -180., -168.,
3734 -157., -143., -126., -108., -89., -63., -32., 1., 35., 65., 95.,
3735 121., 141., 152., 161., 164., 164., 161., 155., 148., 143., 137.,
3736 133., 131., 133., 139., 150., 165., 187., 213., 248., 284., 321.,
3737 372., 449., 514., 569., 609., 642., 673., 673.
3738 };
3739
3740 static const double nua[98] =
3741 { 2120., 2125., 2130., 2135., 2140., 2145., 2150.,
3742 2155., 2160., 2165., 2170., 2175., 2180., 2185., 2190., 2195.,
3743 2200., 2205., 2210., 2215., 2220., 2225., 2230., 2235., 2240.,
3744 2245., 2250., 2255., 2260., 2265., 2270., 2275., 2280., 2285.,
3745 2290., 2295., 2300., 2305., 2310., 2315., 2320., 2325., 2330.,
3746 2335., 2340., 2345., 2350., 2355., 2360., 2365., 2370., 2375.,
3747 2380., 2385., 2390., 2395., 2400., 2405., 2410., 2415., 2420.,
3748 2425., 2430., 2435., 2440., 2445., 2450., 2455., 2460., 2465.,
3749 2470., 2475., 2480., 2485., 2490., 2495., 2500., 2505., 2510.,
3750 2515., 2520., 2525., 2530., 2535., 2540., 2545., 2550., 2555.,
3751 2560., 2565., 2570., 2575., 2580., 2585., 2590., 2595., 2600., 2605.
3752 };
3753
3754 const double t0 = 273.0, tr = 296.0;
3755
3756 /* Check wavenumber range... */
3757 if (nu < nua[0] || nu > nua[97])
3758 return 0;
3759
3760 /* Interpolate B and beta... */
3761 const int idx = locate_reg(nua, 98, nu);
3762 const double b =
3763 1e6 * LIN(nua[idx], ba[idx], nua[idx + 1], ba[idx + 1], nu);
3764 const double beta =
3765 LIN(nua[idx], betaa[idx], nua[idx + 1], betaa[idx + 1], nu);
3766
3767 /* Compute absorption coefficient... */
3768 return 0.1 * POW2(p / P0 * t0 / t) * exp(beta * (1 / tr - 1 / t))
3769 * N2 * b * (N2 + (1 - N2) * (1.294 - 0.4545 * t / tr));
3770}
3771
3772/*****************************************************************************/
3773
3774double ctmo2(
3775 const double nu,
3776 const double p,
3777 const double t) {
3778
3779 static const double ba[90] =
3780 { 0., .061, .074, .084, .096, .12, .162, .208, .246,
3781 .285, .314, .38, .444, .5, .571, .673, .768, .853, .966, 1.097,
3782 1.214, 1.333, 1.466, 1.591, 1.693, 1.796, 1.922, 2.037, 2.154,
3783 2.264, 2.375, 2.508, 2.671, 2.847, 3.066, 3.417, 3.828, 4.204,
3784 4.453, 4.599, 4.528, 4.284, 3.955, 3.678, 3.477, 3.346, 3.29,
3785 3.251, 3.231, 3.226, 3.212, 3.192, 3.108, 3.033, 2.911, 2.798,
3786 2.646, 2.508, 2.322, 2.13, 1.928, 1.757, 1.588, 1.417, 1.253,
3787 1.109, .99, .888, .791, .678, .587, .524, .464, .403, .357, .32,
3788 .29, .267, .242, .215, .182, .16, .146, .128, .103, .087, .081,
3789 .071, .064, 0.
3790 };
3791
3792 static const double betaa[90] =
3793 { 467., 467., 400., 315., 379., 368., 475., 521.,
3794 531., 512., 442., 444., 430., 381., 335., 324., 296., 248., 215.,
3795 193., 158., 127., 101., 71., 31., -6., -26., -47., -63., -79.,
3796 -88., -88., -87., -90., -98., -99., -109., -134., -160., -167.,
3797 -164., -158., -153., -151., -156., -166., -168., -173., -170.,
3798 -161., -145., -126., -108., -84., -59., -29., 4., 41., 73., 97.,
3799 123., 159., 198., 220., 242., 256., 281., 311., 334., 319., 313.,
3800 321., 323., 310., 315., 320., 335., 361., 378., 373., 338., 319.,
3801 346., 322., 291., 290., 350., 371., 504., 504.
3802 };
3803
3804 static const double nua[90] =
3805 { 1360., 1365., 1370., 1375., 1380., 1385., 1390.,
3806 1395., 1400., 1405., 1410., 1415., 1420., 1425., 1430., 1435.,
3807 1440., 1445., 1450., 1455., 1460., 1465., 1470., 1475., 1480.,
3808 1485., 1490., 1495., 1500., 1505., 1510., 1515., 1520., 1525.,
3809 1530., 1535., 1540., 1545., 1550., 1555., 1560., 1565., 1570.,
3810 1575., 1580., 1585., 1590., 1595., 1600., 1605., 1610., 1615.,
3811 1620., 1625., 1630., 1635., 1640., 1645., 1650., 1655., 1660.,
3812 1665., 1670., 1675., 1680., 1685., 1690., 1695., 1700., 1705.,
3813 1710., 1715., 1720., 1725., 1730., 1735., 1740., 1745., 1750.,
3814 1755., 1760., 1765., 1770., 1775., 1780., 1785., 1790., 1795.,
3815 1800., 1805.
3816 };
3817
3818 const double t0 = 273, tr = 296;
3819
3820 /* Check wavenumber range... */
3821 if (nu < nua[0] || nu > nua[89])
3822 return 0;
3823
3824 /* Interpolate B and beta... */
3825 const int idx = locate_reg(nua, 90, nu);
3826 const double b = LIN(nua[idx], ba[idx], nua[idx + 1], ba[idx + 1], nu);
3827 const double beta =
3828 LIN(nua[idx], betaa[idx], nua[idx + 1], betaa[idx + 1], nu);
3829
3830 /* Compute absorption coefficient... */
3831 return 0.1 * POW2(p / P0 * t0 / t) * exp(beta * (1 / tr - 1 / t)) * O2 * b;
3832}
3833
3834/*****************************************************************************/
3835
3837 const ctl_t *ctl,
3838 atm_t *atm_dest,
3839 const atm_t *atm_src,
3840 const int init) {
3841
3842 /* Data size... */
3843 const size_t s = (size_t) atm_src->np * sizeof(double);
3844
3845 /* Copy data... */
3846 atm_dest->np = atm_src->np;
3847 memcpy(atm_dest->time, atm_src->time, s);
3848 memcpy(atm_dest->z, atm_src->z, s);
3849 memcpy(atm_dest->lon, atm_src->lon, s);
3850 memcpy(atm_dest->lat, atm_src->lat, s);
3851 memcpy(atm_dest->p, atm_src->p, s);
3852 memcpy(atm_dest->t, atm_src->t, s);
3853 for (int ig = 0; ig < ctl->ng; ig++)
3854 memcpy(atm_dest->q[ig], atm_src->q[ig], s);
3855 for (int iw = 0; iw < ctl->nw; iw++)
3856 memcpy(atm_dest->k[iw], atm_src->k[iw], s);
3857 atm_dest->clz = atm_src->clz;
3858 atm_dest->cldz = atm_src->cldz;
3859 for (int icl = 0; icl < ctl->ncl; icl++)
3860 atm_dest->clk[icl] = atm_src->clk[icl];
3861 atm_dest->sft = atm_src->sft;
3862 for (int isf = 0; isf < ctl->nsf; isf++)
3863 atm_dest->sfeps[isf] = atm_src->sfeps[isf];
3864
3865 /* Initialize... */
3866 if (init)
3867 for (int ip = 0; ip < atm_dest->np; ip++) {
3868 atm_dest->p[ip] = 0;
3869 atm_dest->t[ip] = 0;
3870 for (int ig = 0; ig < ctl->ng; ig++)
3871 atm_dest->q[ig][ip] = 0;
3872 for (int iw = 0; iw < ctl->nw; iw++)
3873 atm_dest->k[iw][ip] = 0;
3874 atm_dest->clz = 0;
3875 atm_dest->cldz = 0;
3876 for (int icl = 0; icl < ctl->ncl; icl++)
3877 atm_dest->clk[icl] = 0;
3878 atm_dest->sft = 0;
3879 for (int isf = 0; isf < ctl->nsf; isf++)
3880 atm_dest->sfeps[isf] = 1;
3881 }
3882}
3883
3884/*****************************************************************************/
3885
3887 const ctl_t *ctl,
3888 obs_t *obs_dest,
3889 const obs_t *obs_src,
3890 const int init) {
3891
3892 /* Data size... */
3893 const size_t s = (size_t) obs_src->nr * sizeof(double);
3894
3895 /* Copy data... */
3896 obs_dest->nr = obs_src->nr;
3897 memcpy(obs_dest->time, obs_src->time, s);
3898 memcpy(obs_dest->obsz, obs_src->obsz, s);
3899 memcpy(obs_dest->obslon, obs_src->obslon, s);
3900 memcpy(obs_dest->obslat, obs_src->obslat, s);
3901 memcpy(obs_dest->vpz, obs_src->vpz, s);
3902 memcpy(obs_dest->vplon, obs_src->vplon, s);
3903 memcpy(obs_dest->vplat, obs_src->vplat, s);
3904 memcpy(obs_dest->tpz, obs_src->tpz, s);
3905 memcpy(obs_dest->tplon, obs_src->tplon, s);
3906 memcpy(obs_dest->tplat, obs_src->tplat, s);
3907 for (int id = 0; id < ctl->nd; id++)
3908 memcpy(obs_dest->rad[id], obs_src->rad[id], s);
3909 for (int id = 0; id < ctl->nd; id++)
3910 memcpy(obs_dest->tau[id], obs_src->tau[id], s);
3911
3912 /* Initialize... */
3913 if (init)
3914 for (int id = 0; id < ctl->nd; id++)
3915 for (int ir = 0; ir < obs_dest->nr; ir++)
3916 if (isfinite(obs_dest->rad[id][ir])) {
3917 obs_dest->rad[id][ir] = 0;
3918 obs_dest->tau[id][ir] = 0;
3919 }
3920}
3921
3922/*****************************************************************************/
3923
3925 int year,
3926 int mon,
3927 int day,
3928 int *doy) {
3929
3930 const int d0[12] =
3931 { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
3932 const int d0l[12] =
3933 { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
3934
3935 /* Get day of year... */
3936 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
3937 *doy = d0l[mon - 1] + day - 1;
3938 else
3939 *doy = d0[mon - 1] + day - 1;
3940}
3941
3942/*****************************************************************************/
3943
3945 int year,
3946 int doy,
3947 int *mon,
3948 int *day) {
3949
3950 const int d0[12] =
3951 { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
3952 const int d0l[12] =
3953 { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
3954 int i;
3955
3956 /* Get month and day... */
3957 if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
3958 for (i = 11; i >= 0; i--)
3959 if (d0l[i] <= doy)
3960 break;
3961 *mon = i + 1;
3962 *day = doy - d0l[i] + 1;
3963 } else {
3964 for (i = 11; i >= 0; i--)
3965 if (d0[i] <= doy)
3966 break;
3967 *mon = i + 1;
3968 *day = doy - d0[i] + 1;
3969 }
3970}
3971
3972/*****************************************************************************/
3973
3975 const ctl_t *ctl,
3976 const char *emitter) {
3977
3978 for (int ig = 0; ig < ctl->ng; ig++)
3979 if (strcasecmp(ctl->emitter[ig], emitter) == 0)
3980 return ig;
3981
3982 return -1;
3983}
3984
3985/*****************************************************************************/
3986
3988 const ctl_t *ctl,
3989 const tbl_t *tbl,
3990 atm_t *atm,
3991 obs_t *obs,
3992 los_t *los_scratch,
3993 obs_t *obs_scratch) {
3994
3995 /* Save observation mask... */
3996 for (int id = 0; id < ctl->nd; id++)
3997 for (int ir = 0; ir < obs->nr; ir++)
3998 obs->mask[id][ir] = !isfinite(obs->rad[id][ir]);
3999
4000 /* Hydrostatic equilibrium... */
4001 hydrostatic(ctl, atm);
4002
4003 /* CGA or EGA forward model... */
4004 if (ctl->formod == 0 || ctl->formod == 1) {
4005 for (int ir = 0; ir < obs->nr; ir++) {
4006 const int status = formod_pencil(ctl, tbl, atm, obs, ir, los_scratch);
4007 if (status != FORMOD_STATUS_OK)
4008 return status;
4009 }
4010 }
4011
4012 /* Call RFM... */
4013 else if (ctl->formod == 2)
4014 formod_rfm(ctl, tbl, atm, obs);
4015
4016 /* Apply field-of-view convolution... */
4017 const int fov_status = formod_fov(ctl, obs, obs_scratch);
4018 if (fov_status != FORMOD_STATUS_OK)
4019 return fov_status;
4020
4021 /* Convert radiance to brightness temperature... */
4022 if (ctl->write_bbt)
4023 for (int id = 0; id < ctl->nd; id++)
4024 for (int ir = 0; ir < obs->nr; ir++)
4025 obs->rad[id][ir] = BRIGHT(obs->rad[id][ir], ctl->nu[id]);
4026
4027 /* Apply observation mask... */
4028 for (int id = 0; id < ctl->nd; id++)
4029 for (int ir = 0; ir < obs->nr; ir++)
4030 if (obs->mask[id][ir])
4031 obs->rad[id][ir] = NAN;
4032
4033 return FORMOD_STATUS_OK;
4034}
4035
4036/*****************************************************************************/
4037
4039 const ctl_t *ctl,
4040 const tbl_t *tbl,
4041 atm_t *atm,
4042 obs_t *obs,
4043 const int nbatch,
4044 int *status,
4045 los_t *los_scratch,
4046 obs_t *obs_scratch) {
4047
4048 if (nbatch <= 0)
4049 return;
4050
4051 if (los_scratch == NULL || obs_scratch == NULL)
4052 ERRMSG("formod_batch requires scratch arrays for los and obs_scratch!");
4053
4054 /* The RFM interface uses fixed temporary filenames and is therefore
4055 not thread-safe... */
4056 if (ctl->formod == 2) {
4057 for (int ib = 0; ib < nbatch; ib++) {
4058 const int ib_status = formod(ctl, tbl, &atm[ib], &obs[ib],
4059 &los_scratch[ib], &obs_scratch[ib]);
4060 if (status)
4061 status[ib] = ib_status;
4062 else if (ib_status != FORMOD_STATUS_OK)
4063 ERRMSG("Forward model failed with status code %d!", ib_status);
4064 }
4065 return;
4066 }
4067
4068 /* Run independent cases in parallel... */
4069#pragma omp parallel for schedule(static) default(none) shared(ctl,tbl,atm,obs,nbatch,status,los_scratch,obs_scratch)
4070 for (int ib = 0; ib < nbatch; ib++) {
4071 const int ib_status = formod(ctl, tbl, &atm[ib], &obs[ib],
4072 &los_scratch[ib], &obs_scratch[ib]);
4073 if (status)
4074 status[ib] = ib_status;
4075 else if (ib_status != FORMOD_STATUS_OK)
4076 ERRMSG("Forward model failed with status code %d!", ib_status);
4077 }
4078}
4079
4080/*****************************************************************************/
4081
4083 const ctl_t *ctl,
4084 const los_t *los,
4085 const int ip,
4086 double *beta) {
4087
4088 /* Extinction... */
4089 for (int id = 0; id < ctl->nd; id++)
4090 beta[id] = los->k[ip][id];
4091
4092 /* CO2 continuum... */
4093 if (ctl->ctm_co2 && ctl->ig_co2 >= 0)
4094 for (int id = 0; id < ctl->nd; id++)
4095 beta[id] += ctmco2(ctl->nu[id], los->p[ip], los->t[ip],
4096 los->u[ip][ctl->ig_co2]) / los->ds[ip];
4097
4098 /* H2O continuum... */
4099 if (ctl->ctm_h2o && ctl->ig_h2o >= 0)
4100 for (int id = 0; id < ctl->nd; id++)
4101 beta[id] += ctmh2o(ctl->nu[id], los->p[ip], los->t[ip],
4102 los->q[ip][ctl->ig_h2o], los->u[ip][ctl->ig_h2o])
4103 / los->ds[ip];
4104
4105 /* N2 continuum... */
4106 if (ctl->ctm_n2)
4107 for (int id = 0; id < ctl->nd; id++)
4108 beta[id] += ctmn2(ctl->nu[id], los->p[ip], los->t[ip]);
4109
4110 /* O2 continuum... */
4111 if (ctl->ctm_o2)
4112 for (int id = 0; id < ctl->nd; id++)
4113 beta[id] += ctmo2(ctl->nu[id], los->p[ip], los->t[ip]);
4114}
4115
4116/*****************************************************************************/
4117
4119 const ctl_t *ctl,
4120 obs_t *obs,
4121 obs_t *obs_scratch) {
4122
4123 int rays[2 * NFOV + 1];
4124 double z[2 * NFOV + 1];
4125
4126 /* Do not take into account FOV... */
4127 if (ctl->fov[0] == '-')
4128 return FORMOD_STATUS_OK;
4129
4130 /* Copy observation data... */
4131 copy_obs(ctl, obs_scratch, obs, 0);
4132
4133 /* Loop over ray paths... */
4134 for (int ir = 0; ir < obs->nr; ir++) {
4135
4136 /* Collect neighbouring ray paths for the same time step... */
4137 int nz = 0;
4138 for (int ir2 = MAX(ir - NFOV, 0);
4139 ir2 < MIN(ir + 1 + NFOV, obs->nr); ir2++)
4140 if (obs->time[ir2] == obs->time[ir]) {
4141 rays[nz] = ir2;
4142 z[nz] = obs_scratch->vpz[ir2];
4143 nz++;
4144 }
4145 if (nz < 2)
4147
4148 /* Convolute profiles with FOV... */
4149 double wsum = 0;
4150 for (int id = 0; id < ctl->nd; id++) {
4151 obs->rad[id][ir] = 0;
4152 obs->tau[id][ir] = 0;
4153 }
4154 for (int i = 0; i < ctl->fov_n; i++) {
4155 const double zfov = obs->vpz[ir] + ctl->fov_dz[i];
4156 const int idx = locate_irr(z, nz, zfov);
4157 const int ir0 = rays[idx];
4158 const int ir1 = rays[idx + 1];
4159 for (int id = 0; id < ctl->nd; id++) {
4160 obs->rad[id][ir] += ctl->fov_w[i]
4161 * LIN(z[idx], obs_scratch->rad[id][ir0],
4162 z[idx + 1], obs_scratch->rad[id][ir1], zfov);
4163 obs->tau[id][ir] += ctl->fov_w[i]
4164 * LIN(z[idx], obs_scratch->tau[id][ir0],
4165 z[idx + 1], obs_scratch->tau[id][ir1], zfov);
4166 }
4167 wsum += ctl->fov_w[i];
4168 }
4169 for (int id = 0; id < ctl->nd; id++) {
4170 obs->rad[id][ir] /= wsum;
4171 obs->tau[id][ir] /= wsum;
4172 }
4173 }
4174
4175 return FORMOD_STATUS_OK;
4176}
4177
4178/*****************************************************************************/
4179
4181 const ctl_t *ctl,
4182 const tbl_t *tbl,
4183 const atm_t *atm,
4184 obs_t *obs,
4185 const int ir,
4186 los_t *los) {
4187
4188 double rad[ND], tau[ND], tau_path[ND][NG];
4189
4190 /* Reset scratch LOS data (raytrace relies on zero-initialized fields)... */
4191 memset(los, 0, sizeof(*los));
4192
4193 /* Initialize... */
4194 for (int id = 0; id < ctl->nd; id++) {
4195 rad[id] = 0;
4196 tau[id] = 1;
4197 for (int ig = 0; ig < ctl->ng; ig++)
4198 tau_path[id][ig] = 1;
4199 }
4200
4201 /* Raytracing... */
4202 {
4203 const int status = raytrace(ctl, atm, obs, los, ir);
4204 if (status != FORMOD_STATUS_OK)
4205 return status;
4206 }
4207
4208 /* Loop over LOS points... */
4209 for (int ip = 0; ip < los->np; ip++) {
4210
4211 /* Get trace gas transmittance... */
4212 double tau_gas[ND];
4213 if (ctl->formod == 0)
4214 intpol_tbl_cga(ctl, tbl, los, ip, tau_path, tau_gas);
4215 else
4216 intpol_tbl_ega(ctl, tbl, los, ip, tau_path, tau_gas);
4217
4218 /* Get continuum absorption... */
4219 double beta_ctm[ND];
4220 formod_continua(ctl, los, ip, beta_ctm);
4221
4222 /* Compute Planck function... */
4223 formod_srcfunc(ctl, tbl, los->t[ip], los->src[ip]);
4224
4225 /* Loop over channels... */
4226 for (int id = 0; id < ctl->nd; id++)
4227 if (tau_gas[id] >= 0) {
4228
4229 /* Get segment emissivity. An exactly zero transmittance represents
4230 a fully opaque segment and must contribute with emissivity one. */
4231 los->eps[ip][id] = 1 - tau_gas[id] * exp(-beta_ctm[id] * los->ds[ip]);
4232
4233 /* Compute radiance... */
4234 rad[id] += los->src[ip][id] * los->eps[ip][id] * tau[id];
4235
4236 /* Compute path transmittance... */
4237 tau[id] *= (1 - los->eps[ip][id]);
4238 }
4239 }
4240
4241 /* Check whether LOS hit the ground... */
4242 if (ctl->sftype >= 1 && los->sft > 0) {
4243
4244 /* Add surface emissions... */
4245 double src_sf[ND];
4246 formod_srcfunc(ctl, tbl, los->sft, src_sf);
4247 for (int id = 0; id < ctl->nd; id++)
4248 rad[id] += los->sfeps[id] * src_sf[id] * tau[id];
4249
4250 /* Check reflectivity... */
4251 int refl = 0;
4252 if (ctl->sftype >= 2)
4253 for (int id = 0; id < ctl->nd; id++)
4254 if (los->sfeps[id] < 1) {
4255 refl = 1;
4256 break;
4257 }
4258
4259 /* Calculate reflection... */
4260 if (refl) {
4261
4262 /* Initialize... */
4263 double tau_refl[ND];
4264 for (int id = 0; id < ctl->nd; id++)
4265 tau_refl[id] = 1;
4266
4267 /* Add down-welling radiance... */
4268 for (int ip = los->np - 1; ip >= 0; ip--)
4269 for (int id = 0; id < ctl->nd; id++) {
4270 rad[id] += los->src[ip][id] * los->eps[ip][id] * tau_refl[id]
4271 * tau[id] * (1 - los->sfeps[id]);
4272 tau_refl[id] *= (1 - los->eps[ip][id]);
4273 }
4274
4275 /* Add solar term... */
4276 if (ctl->sftype >= 3) {
4277
4278 /* Get cosine of solar zenith angle... */
4279 double cos_sza_val;
4280 if (ctl->sfsza < 0)
4281 cos_sza_val = cos_sza(obs->time[ir],
4282 los->lon[los->np - 1], los->lat[los->np - 1]);
4283 else
4284 cos_sza_val = cos(DEG2RAD(ctl->sfsza));
4285
4286 /* Check validity (avoid division by zero)... */
4287 if (cos_sza_val > 1e-6) {
4288
4289 /* Compute incidence direction cosine... */
4290 double x0[3], x1[3];
4291 geo2cart(los->z[los->np - 1], los->lon[los->np - 1],
4292 los->lat[los->np - 1], x0);
4293 geo2cart(los->z[0], los->lon[0], los->lat[0], x1);
4294 for (int i = 0; i < 3; i++)
4295 x1[i] -= x0[i];
4296 const double cosa = DOTP(x0, x1) / NORM(x0) / NORM(x1);
4297
4298 /* Ratio of incident direction to solar zenith direction... */
4299 const double rcos = cosa / cos_sza_val;
4300
4301 /* 6.764e-5 sr approximates the solid angle of the solar disk. */
4302 /* Add solar radiance contribution... */
4303 for (int id = 0; id < ctl->nd; id++)
4304 rad[id] += 6.764e-5 / (2. * M_PI) * PLANCK(TSUN, ctl->nu[id])
4305 * tau_refl[id] * (1 - los->sfeps[id]) * tau[id] * rcos;
4306 }
4307 }
4308 }
4309 }
4310
4311 /* Copy results... */
4312 for (int id = 0; id < ctl->nd; id++) {
4313 obs->rad[id][ir] = rad[id];
4314 obs->tau[id][ir] = tau[id];
4315 }
4316
4317 return FORMOD_STATUS_OK;
4318}
4319
4320/*****************************************************************************/
4321
4322static double convolve_rfm(
4323 const double *nurfm,
4324 const double *spec,
4325 const int npts,
4326 const double *nu,
4327 const double *f,
4328 const int n) {
4329
4330 double fsum = 0, specsum = 0;
4331
4332 /* Convolute... */
4333 for (int ipts = 0; ipts < npts; ipts++)
4334 if (nurfm[ipts] >= nu[0] && nurfm[ipts] <= nu[n - 1]) {
4335 const int idx = locate_irr(nu, n, nurfm[ipts]);
4336 const double filt =
4337 LIN(nu[idx], f[idx], nu[idx + 1], f[idx + 1], nurfm[ipts]);
4338 fsum += filt;
4339 specsum += filt * spec[ipts];
4340 }
4341
4342 return specsum / fsum;
4343}
4344
4345/*****************************************************************************/
4346
4347static void find_rfm_file(
4348 char *filename,
4349 const size_t filename_size,
4350 const char *basename,
4351 const double z) {
4352
4353 /* Search RFM spectrum... */
4354 FILE *in;
4355 int n = snprintf(filename, filename_size, "%s_%05d.asc",
4356 basename, (int) (z * 1000));
4357 if (n < 0 || (size_t) n >= filename_size)
4358 ERRMSG("RFM spectrum filename too long!");
4359 if (!(in = fopen(filename, "r"))) {
4360 n = snprintf(filename, filename_size, "%s_%05d.asc",
4361 basename, (int) (z * 1000) + 1);
4362 if (n < 0 || (size_t) n >= filename_size)
4363 ERRMSG("RFM spectrum filename too long!");
4364 if (!(in = fopen(filename, "r")))
4365 ERRMSG("Cannot find RFM data file! Tried %s", filename);
4366 }
4367 fclose(in);
4368}
4369
4370/*****************************************************************************/
4371
4373 const ctl_t *ctl,
4374 const tbl_t *tbl,
4375 const atm_t *atm,
4376 obs_t *obs) {
4377
4378 los_t *los;
4379
4380 char filename[3 * LEN], tmpdir[2 * LEN], cwd[LEN];
4381 char rfmflg[LEN] = { "RAD TRA MIX LIN SFC" };
4382
4383 double lower[ND], upper[ND], nu0, nu1, obsz = -999, *nurfm, *spec, tsurf,
4384 xd[3], xo[3], xv[3], z[NR], zmin, zmax;
4385
4386 int nadir = 0, npts, order[ND], zenith = 0;
4387
4388 /* Allocate... */
4389 ALLOC(los, los_t, 1);
4390 ALLOC(nurfm, double,
4391 RFMNPTS);
4392 ALLOC(spec, double,
4393 RFMNPTS);
4394
4395 /* Check observer positions... */
4396 for (int ir = 1; ir < obs->nr; ir++)
4397 if (obs->obsz[ir] != obs->obsz[0]
4398 || obs->obslon[ir] != obs->obslon[0]
4399 || obs->obslat[ir] != obs->obslat[0])
4400 ERRMSG("RFM interface requires identical observer positions!");
4401
4402 /* Check extinction data... */
4403 for (int iw = 0; iw < ctl->nw; iw++)
4404 for (int ip = 0; ip < atm->np; ip++)
4405 if (atm->k[iw][ip] != 0)
4406 ERRMSG("RFM interface cannot handle extinction data!");
4407
4408 /* Get altitude range of atmospheric data... */
4409 gsl_stats_minmax(&zmin, &zmax, atm->z, 1, (size_t) atm->np);
4410
4411 /* Observer within atmosphere? */
4412 if (obs->obsz[0] >= zmin && obs->obsz[0] <= zmax) {
4413 obsz = obs->obsz[0];
4414 strcat(rfmflg, " OBS");
4415 }
4416
4417 /* Determine tangent altitude or air mass factor... */
4418 for (int ir = 0; ir < obs->nr; ir++) {
4419
4420 /* Raytracing... */
4421 if (raytrace(ctl, atm, obs, los, ir) != FORMOD_STATUS_OK)
4422 ERRMSG("Ray tracing failed!");
4423
4424 /* Nadir or zenith? (air mass factor / secant of zenith angle) */
4425 if (obs->tpz[ir] <= zmin) {
4426
4427 /* Nadir: path intersects the surface. */
4428 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xo);
4429 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xv);
4430 for (int i = 0; i < 3; i++)
4431 xd[i] = xo[i] - xv[i];
4432 z[ir] = NORM(xo) * NORM(xd) / DOTP(xo, xd);
4433 nadir++;
4434
4435 } else if (obs->tpz[ir] >= zmax - 1e-3 && obs->vpz[ir] > obs->obsz[ir]) {
4436
4437 /* Zenith: upward-looking path leaves the atmosphere at the top boundary. */
4438 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xo);
4439 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xv);
4440 for (int i = 0; i < 3; i++)
4441 xd[i] = xv[i] - xo[i];
4442 z[ir] = NORM(xo) * NORM(xd) / DOTP(xo, xd);
4443 zenith++;
4444
4445 } else
4446 /* Limb: use tangent altitude. */
4447 z[ir] = obs->tpz[ir];
4448 }
4449 if ((nadir > 0 && nadir < obs->nr)
4450 || (zenith > 0 && zenith < obs->nr)
4451 || (nadir > 0 && zenith > 0))
4452 ERRMSG("Limb, nadir, and zenith not simultaneously possible!");
4453
4454 /* Viewing geometry... */
4455 if (nadir)
4456 strcat(rfmflg, " NAD");
4457 if (zenith)
4458 strcat(rfmflg, " ZEN");
4459
4460 /* Get surface temperature... */
4461 tsurf = atm->t[gsl_stats_min_index(atm->z, 1, (size_t) atm->np)];
4462
4463 /* Refraction? */
4464 if (!nadir && !zenith && !ctl->refrac)
4465 strcat(rfmflg, " GEO");
4466
4467 /* Continua? */
4468 if (ctl->ctm_co2 || ctl->ctm_h2o || ctl->ctm_n2 || ctl->ctm_o2)
4469 strcat(rfmflg, " CTM");
4470
4471 /* Check filter functions and initialize channel order... */
4472 for (int id = 0; id < ctl->nd; id++) {
4473 const int n = tbl->filt_n[id];
4474 if (n < 2 || n > NSHAPE)
4475 ERRMSG("Missing or invalid filter function in lookup table!");
4476 for (int i = 1; i < n; i++)
4477 if (tbl->filt_nu[id][i] <= tbl->filt_nu[id][i - 1])
4478 ERRMSG("Filter wavenumbers must be strictly increasing!");
4479 lower[id] = tbl->filt_nu[id][0];
4480 upper[id] = tbl->filt_nu[id][n - 1];
4481 order[id] = id;
4482 }
4483
4484 /* Sort channels by lower filter bound... */
4485 for (int i = 1; i < ctl->nd; i++) {
4486 const int id = order[i];
4487 int j = i;
4488 while (j > 0 && lower[order[j - 1]] > lower[id]) {
4489 order[j] = order[j - 1];
4490 j--;
4491 }
4492 order[j] = id;
4493 }
4494
4495 /* Create a private RFM working directory... */
4496 const char *base = strcmp(ctl->rfmtmp, "-") == 0 ? "." : ctl->rfmtmp;
4497 int n;
4498 if (base[0] == '/')
4499 n = snprintf(tmpdir, sizeof(tmpdir), "%s/jurassic-rfm-XXXXXX", base);
4500 else {
4501 if (!getcwd(cwd, sizeof(cwd)))
4502 ERRMSG("Cannot determine current working directory!");
4503 n = snprintf(tmpdir, sizeof(tmpdir), "%s/%s/jurassic-rfm-XXXXXX",
4504 cwd, base);
4505 }
4506 if (n < 0 || (size_t) n >= sizeof(tmpdir) || !mkdtemp(tmpdir))
4507 ERRMSG("Cannot create RFM working directory!");
4508
4509 snprintf(filename, sizeof(filename), "%s/rfm.atm", tmpdir);
4510 write_atm_rfm(filename, ctl, atm);
4511
4512 /* Supply the blank input line used by the previous RFM command... */
4513 snprintf(filename, sizeof(filename), "%s/rfm.stdin", tmpdir);
4514 FILE *input = fopen(filename, "w");
4515 if (!input || fputs("\n", input) == EOF || fclose(input) != 0)
4516 ERRMSG("Cannot create RFM input in %s!", tmpdir);
4517
4518 /* Loop over overlapping spectral blocks... */
4519 for (int ib = 0; ib < ctl->nd;) {
4520 int ie = ib + 1;
4521 nu0 = lower[order[ib]];
4522 nu1 = upper[order[ib]];
4523 while (ie < ctl->nd && lower[order[ie]] <= nu1) {
4524 nu1 = MAX(nu1, upper[order[ie]]);
4525 ie++;
4526 }
4527
4528 /* Create RFM driver file... */
4529 FILE *out;
4530 snprintf(filename, sizeof(filename), "%s/rfm.drv", tmpdir);
4531 if (!(out = fopen(filename, "w")))
4532 ERRMSG("Cannot create file!");
4533 fprintf(out, "*HDR\nRFM call by JURASSIC.\n");
4534 fprintf(out, "*FLG\n%s\n", rfmflg);
4535 fprintf(out, "*SPC\n%.4f %.4f 0.0005\n", nu0, nu1);
4536 fprintf(out, "*GAS\n");
4537 for (int ig = 0; ig < ctl->ng; ig++)
4538 fprintf(out, "%s\n", ctl->emitter[ig]);
4539 fprintf(out, "*ATM\nrfm.atm\n");
4540 fprintf(out, "*TAN\n");
4541 for (int ir = 0; ir < obs->nr; ir++)
4542 fprintf(out, "%g\n", z[ir]);
4543 fprintf(out, "*SFC\n%g 1.0\n", tsurf);
4544 if (obsz >= 0)
4545 fprintf(out, "*OBS\n%g\n", obsz);
4546 fprintf(out, "*HIT\n%s\n", ctl->rfmhit);
4547 fprintf(out, "*XSC\n");
4548 for (int ig = 0; ig < ctl->ng; ig++)
4549 if (ctl->rfmxsc[ig][0] != '-')
4550 fprintf(out, "%s\n", ctl->rfmxsc[ig]);
4551 fprintf(out, "*END\n");
4552 fclose(out);
4553
4554 /* Remove spectra from the previous spectral block... */
4555 DIR *dir = opendir(tmpdir);
4556 if (!dir)
4557 ERRMSG("Cannot open RFM working directory %s!", tmpdir);
4558 struct dirent *entry;
4559 while ((entry = readdir(dir)))
4560 if (strncmp(entry->d_name, "rad_", 4) == 0
4561 || strncmp(entry->d_name, "tra_", 4) == 0) {
4562 snprintf(filename, sizeof(filename), "%s/%s", tmpdir, entry->d_name);
4563 if (unlink(filename))
4564 ERRMSG("Cannot remove old RFM spectrum in %s!", tmpdir);
4565 }
4566 closedir(dir);
4567
4568 /* Run RFM in the child without changing the parent's directory... */
4569 char program[LEN];
4570 strcpy(program, ctl->rfmbin);
4571 pid_t pid = fork();
4572 if (pid == 0) {
4573 if (chdir(tmpdir))
4574 _exit(126);
4575 int fd = open("rfm.stdin", O_RDONLY);
4576 if (fd < 0 || dup2(fd, STDIN_FILENO) < 0)
4577 _exit(126);
4578 close(fd);
4579 char *const args[] = { program, NULL };
4580 execvp(program, args);
4581 _exit(127);
4582 }
4583 if (pid < 0)
4584 ERRMSG("Cannot launch RFM; files retained in %s!", tmpdir);
4585 int status;
4586 while (waitpid(pid, &status, 0) < 0)
4587 if (errno != EINTR)
4588 ERRMSG("Cannot wait for RFM; files retained in %s!", tmpdir);
4589 if (WIFSIGNALED(status))
4590 ERRMSG("RFM terminated by signal %d; files retained in %s!",
4591 WTERMSIG(status), tmpdir);
4592 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
4593 ERRMSG("RFM exited with status %d; files retained in %s!",
4594 WIFEXITED(status) ? WEXITSTATUS(status) : -1, tmpdir);
4595
4596 /* Read and convolute each spectrum once... */
4597 for (int ir = 0; ir < obs->nr; ir++) {
4598 char basename[3 * LEN];
4599 snprintf(basename, sizeof(basename), "%s/rad", tmpdir);
4600 find_rfm_file(filename, sizeof(filename), basename, z[ir]);
4601 read_rfm_spec(filename, nurfm, spec, &npts);
4602 for (int i = ib; i < ie; i++) {
4603 const int id = order[i];
4604 obs->rad[id][ir] = convolve_rfm(nurfm, spec, npts,
4605 tbl->filt_nu[id], tbl->filt_f[id],
4606 tbl->filt_n[id]) * 1e-5;
4607 }
4608
4609 snprintf(basename, sizeof(basename), "%s/tra", tmpdir);
4610 find_rfm_file(filename, sizeof(filename), basename, z[ir]);
4611 read_rfm_spec(filename, nurfm, spec, &npts);
4612 for (int i = ib; i < ie; i++) {
4613 const int id = order[i];
4614 obs->tau[id][ir] = convolve_rfm(nurfm, spec, npts,
4615 tbl->filt_nu[id], tbl->filt_f[id],
4616 tbl->filt_n[id]);
4617 }
4618 }
4619 ib = ie;
4620 }
4621
4622 /* Remove files from this invocation's private directory... */
4623 DIR *dir = opendir(tmpdir);
4624 if (!dir)
4625 ERRMSG("Cannot open RFM working directory %s!", tmpdir);
4626 struct dirent *entry;
4627 while ((entry = readdir(dir))) {
4628 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
4629 continue;
4630 snprintf(filename, sizeof(filename), "%s/%s", tmpdir, entry->d_name);
4631 if (unlink(filename))
4632 ERRMSG("Cannot remove RFM file in %s!", tmpdir);
4633 }
4634 closedir(dir);
4635 if (rmdir(tmpdir))
4636 ERRMSG("Cannot remove RFM working directory %s!", tmpdir);
4637
4638 /* Free... */
4639 free(los);
4640 free(nurfm);
4641 free(spec);
4642}
4643
4644/*****************************************************************************/
4645
4647 const ctl_t *ctl,
4648 const tbl_t *tbl,
4649 const double t,
4650 double *src) {
4651
4652 /* Determine index in temperature array... */
4653 const int it = locate_reg(tbl->st, TBLNS, t);
4654
4655 /* Interpolate Planck function value... */
4656 for (int id = 0; id < ctl->nd; id++)
4657 src[id] = LIN(tbl->st[it], tbl->sr[it][id],
4658 tbl->st[it + 1], tbl->sr[it + 1][id], t);
4659}
4660
4661/*****************************************************************************/
4662
4664 const double z,
4665 const double lon,
4666 const double lat,
4667 double *x) {
4668
4669 const double radius = z + RE;
4670 const double latrad = lat / 180. * M_PI;
4671 const double lonrad = lon / 180. * M_PI;
4672 const double coslat = cos(latrad);
4673
4674 x[0] = radius * coslat * cos(lonrad);
4675 x[1] = radius * coslat * sin(lonrad);
4676 x[2] = radius * sin(latrad);
4677}
4678
4679/*****************************************************************************/
4680
4682 const ctl_t *ctl,
4683 atm_t *atm) {
4684
4685 const double mmair = 28.96456e-3, mmh2o = 18.0153e-3;
4686
4687 const int ipts = 20;
4688
4689 double dzmin = 1e99, e = 0;
4690
4691 int ipref = 0;
4692
4693 /* Check reference height... */
4694 if (ctl->hydz < 0)
4695 return;
4696
4697 /* Find air parcel next to reference height... */
4698 for (int ip = 0; ip < atm->np; ip++)
4699 if (fabs(atm->z[ip] - ctl->hydz) < dzmin) {
4700 dzmin = fabs(atm->z[ip] - ctl->hydz);
4701 ipref = ip;
4702 }
4703
4704 /* Upper part of profile... */
4705 for (int ip = ipref + 1; ip < atm->np; ip++) {
4706 double mean = 0;
4707 for (int i = 0; i < ipts; i++) {
4708 if (ctl->ig_h2o >= 0)
4709 e = LIN(0.0, atm->q[ctl->ig_h2o][ip - 1],
4710 ipts - 1.0, atm->q[ctl->ig_h2o][ip], (double) i);
4711 mean += (e * mmh2o + (1 - e) * mmair)
4712 * G0 / RI
4713 / LIN(0.0, atm->t[ip - 1], ipts - 1.0, atm->t[ip], (double) i) / ipts;
4714 }
4715
4716 /* Compute p(z,T)... */
4717 atm->p[ip] =
4718 exp(log(atm->p[ip - 1]) - mean * 1000 * (atm->z[ip] - atm->z[ip - 1]));
4719 }
4720
4721 /* Lower part of profile... */
4722 for (int ip = ipref - 1; ip >= 0; ip--) {
4723 double mean = 0;
4724 for (int i = 0; i < ipts; i++) {
4725 if (ctl->ig_h2o >= 0)
4726 e = LIN(0.0, atm->q[ctl->ig_h2o][ip + 1],
4727 ipts - 1.0, atm->q[ctl->ig_h2o][ip], (double) i);
4728 mean += (e * mmh2o + (1 - e) * mmair)
4729 * G0 / RI
4730 / LIN(0.0, atm->t[ip + 1], ipts - 1.0, atm->t[ip], (double) i) / ipts;
4731 }
4732
4733 /* Compute p(z,T)... */
4734 atm->p[ip] =
4735 exp(log(atm->p[ip + 1]) - mean * 1000 * (atm->z[ip] - atm->z[ip + 1]));
4736 }
4737}
4738
4739/*****************************************************************************/
4740
4742 const ctl_t *ctl,
4743 const int idx,
4744 char *quantity) {
4745
4746 if (idx == IDXP)
4747 sprintf(quantity, "PRESSURE");
4748
4749 if (idx == IDXT)
4750 sprintf(quantity, "TEMPERATURE");
4751
4752 for (int ig = 0; ig < ctl->ng; ig++)
4753 if (idx == IDXQ(ig))
4754 sprintf(quantity, "%s", ctl->emitter[ig]);
4755
4756 for (int iw = 0; iw < ctl->nw; iw++)
4757 if (idx == IDXK(iw))
4758 sprintf(quantity, "EXTINCT_WINDOW_%d", iw);
4759
4760 if (idx == IDXCLZ)
4761 sprintf(quantity, "CLOUD_HEIGHT");
4762
4763 if (idx == IDXCLDZ)
4764 sprintf(quantity, "CLOUD_DEPTH");
4765
4766 for (int icl = 0; icl < ctl->ncl; icl++)
4767 if (idx == IDXCLK(icl))
4768 sprintf(quantity, "CLOUD_EXTINCT_%.4f", ctl->clnu[icl]);
4769
4770 if (idx == IDXSFT)
4771 sprintf(quantity, "SURFACE_TEMPERATURE");
4772
4773 for (int isf = 0; isf < ctl->nsf; isf++)
4774 if (idx == IDXSFEPS(isf))
4775 sprintf(quantity, "SURFACE_EMISSIVITY_%.4f", ctl->sfnu[isf]);
4776}
4777
4778/*****************************************************************************/
4779
4781 const ctl_t *ctl,
4782 tbl_t *tbl) {
4783
4784 /* Write info... */
4785 LOG(1, "Initialize source function table...");
4786 LOG(2, "Number of data points: %d", TBLNS);
4787
4788 /* Loop over channels... */
4789 for (int id = 0; id < ctl->nd; id++) {
4790
4791 /* Get minimum grid spacing... */
4792 double dnu = 1.0;
4793 for (int i = 1; i < tbl->filt_n[id]; i++)
4794 dnu = MIN(dnu, tbl->filt_nu[id][i] - tbl->filt_nu[id][i - 1]);
4795
4796 /* Compute source function table... */
4797#pragma omp parallel for default(none) shared(ctl,tbl,id,dnu)
4798 for (int it = 0; it < TBLNS; it++) {
4799
4800 /* Set temperature... */
4801 tbl->st[it] = LIN(0.0, TMIN, TBLNS - 1.0, TMAX, (double) it);
4802
4803 /* Integrate Planck function... */
4804 double fsum = tbl->sr[it][id] = 0;
4805 for (double fnu = tbl->filt_nu[id][0];
4806 fnu <= tbl->filt_nu[id][tbl->filt_n[id] - 1]; fnu += dnu) {
4807 const int i = locate_irr(tbl->filt_nu[id], tbl->filt_n[id], fnu);
4808 const double ff = LIN(tbl->filt_nu[id][i], tbl->filt_f[id][i],
4809 tbl->filt_nu[id][i + 1], tbl->filt_f[id][i + 1],
4810 fnu);
4811 fsum += ff;
4812 tbl->sr[it][id] += ff * PLANCK(tbl->st[it], fnu);
4813 }
4814 tbl->sr[it][id] /= fsum;
4815 }
4816
4817 /* Write info... */
4818 LOG(2,
4819 "channel= %.4f cm^-1 | T= %g ... %g K | B= %g ... %g W/(m^2 sr cm^-1)",
4820 ctl->nu[id], tbl->st[0], tbl->st[TBLNS - 1], tbl->sr[0][id],
4821 tbl->sr[TBLNS - 1][id]);
4822 }
4823}
4824
4825/*****************************************************************************/
4826
4828 const ctl_t *ctl,
4829 const atm_t *atm,
4830 const double z,
4831 double *p,
4832 double *t,
4833 double *q,
4834 double *k) {
4835
4836 /* Get array index... */
4837 const int ip = locate_irr(atm->z, atm->np, z);
4838
4839 /* Interpolate... */
4840 *p = LOGY(atm->z[ip], atm->p[ip], atm->z[ip + 1], atm->p[ip + 1], z);
4841 *t = LIN(atm->z[ip], atm->t[ip], atm->z[ip + 1], atm->t[ip + 1], z);
4842 for (int ig = 0; ig < ctl->ng; ig++)
4843 q[ig] =
4844 LIN(atm->z[ip], atm->q[ig][ip], atm->z[ip + 1], atm->q[ig][ip + 1], z);
4845 for (int iw = 0; iw < ctl->nw; iw++)
4846 k[iw] =
4847 LIN(atm->z[ip], atm->k[iw][ip], atm->z[ip + 1], atm->k[iw][ip + 1], z);
4848}
4849
4850/*****************************************************************************/
4851
4853 const ctl_t *ctl,
4854 const tbl_t *tbl,
4855 const los_t *los,
4856 const int ip,
4857 double tau_path[ND][NG],
4858 double tau_seg[ND]) {
4859
4860 double eps, lnp[NG];
4861
4862 /* Precompute log-pressure... */
4863 for (int ig = 0; ig < ctl->ng; ig++)
4864 lnp[ig] = log(los->cgp[ip][ig]);
4865
4866 /* Loop over channels... */
4867 for (int id = 0; id < ctl->nd; id++) {
4868
4869 /* Initialize... */
4870 tau_seg[id] = 1;
4871
4872 /* Loop over emitters.... */
4873 for (int ig = 0; ig < ctl->ng; ig++) {
4874
4875 /* Check size of table (pressure) and column density... */
4876 if (tbl->np[id][ig] < 30 || los->cgu[ip][ig] <= 0)
4877 eps = 0;
4878
4879 /* Check transmittance... */
4880 else if (tau_path[id][ig] < 1e-9)
4881 eps = 1;
4882
4883 /* Interpolate... */
4884 else {
4885
4886 /* Determine pressure and temperature indices... */
4887 const int ipr =
4888 locate_irr(tbl->p[id][ig], tbl->np[id][ig], los->cgp[ip][ig]);
4889 const int it0 = locate_reg(tbl->t[id][ig][ipr], tbl->nt[id][ig][ipr],
4890 los->cgt[ip][ig]);
4891 const int it1 =
4892 locate_reg(tbl->t[id][ig][ipr + 1], tbl->nt[id][ig][ipr + 1],
4893 los->cgt[ip][ig]);
4894
4895 /* Check size of table (temperature and column density)... */
4896 if (tbl->nt[id][ig][ipr] < 2 || tbl->nt[id][ig][ipr + 1] < 2
4897 || tbl->nu[id][ig][ipr][it0] < 2
4898 || tbl->nu[id][ig][ipr][it0 + 1] < 2
4899 || tbl->nu[id][ig][ipr + 1][it1] < 2
4900 || tbl->nu[id][ig][ipr + 1][it1 + 1] < 2)
4901 eps = 0;
4902
4903 else {
4904
4905 /* Get emissivities of extended path... */
4906 const double logu = log(los->cgu[ip][ig]);
4907 double eps00 = intpol_tbl_eps(tbl, ig, id, ipr, it0, logu);
4908 double eps01 = intpol_tbl_eps(tbl, ig, id, ipr, it0 + 1, logu);
4909 double eps10 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1, logu);
4910 double eps11 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1 + 1, logu);
4911
4912 /* Interpolate with respect to temperature... */
4913 eps00 = LIN(tbl->t[id][ig][ipr][it0], eps00,
4914 tbl->t[id][ig][ipr][it0 + 1], eps01, los->cgt[ip][ig]);
4915 eps11 = LIN(tbl->t[id][ig][ipr + 1][it1], eps10,
4916 tbl->t[id][ig][ipr + 1][it1 + 1],
4917 eps11, los->cgt[ip][ig]);
4918
4919 /* Interpolate with respect to log-pressure... */
4920 eps00 = LIN(tbl->lnp[id][ig][ipr], eps00,
4921 tbl->lnp[id][ig][ipr + 1], eps11, lnp[ig]);
4922
4923 /* Check emissivity range... */
4924 eps00 = CLAMP(eps00, 0.0, 1.0);
4925
4926 /* Determine segment emissivity... */
4927 eps = 1 - (1 - eps00) / tau_path[id][ig];
4928
4929 /* Check emissivity range... */
4930 eps = CLAMP(eps, 0.0, 1.0);
4931 }
4932 }
4933
4934 /* Get transmittance of extended path... */
4935 tau_path[id][ig] *= (1 - eps);
4936
4937 /* Get segment transmittance... */
4938 tau_seg[id] *= (1 - eps);
4939 }
4940 }
4941}
4942
4943/*****************************************************************************/
4944
4946 const ctl_t *ctl,
4947 const tbl_t *tbl,
4948 const los_t *los,
4949 const int ip,
4950 double tau_path[ND][NG],
4951 double tau_seg[ND]) {
4952
4953 const double lnp = log(los->p[ip]);
4954
4955 double eps, u;
4956
4957 /* Loop over channels... */
4958 for (int id = 0; id < ctl->nd; id++) {
4959
4960 /* Initialize... */
4961 tau_seg[id] = 1;
4962
4963 /* Loop over emitters.... */
4964 for (int ig = 0; ig < ctl->ng; ig++) {
4965
4966 /* Check size of table (pressure) and column density... */
4967 if (tbl->np[id][ig] < 30 || los->cgu[ip][ig] <= 0)
4968 eps = 0;
4969
4970 /* Check transmittance... */
4971 else if (tau_path[id][ig] < 1e-9)
4972 eps = 1;
4973
4974 /* Interpolate... */
4975 else {
4976
4977 /* Determine pressure and temperature indices... */
4978 const int ipr =
4979 locate_irr(tbl->p[id][ig], tbl->np[id][ig], los->p[ip]);
4980 const int it0 =
4981 locate_reg(tbl->t[id][ig][ipr], tbl->nt[id][ig][ipr], los->t[ip]);
4982 const int it1 =
4983 locate_reg(tbl->t[id][ig][ipr + 1], tbl->nt[id][ig][ipr + 1],
4984 los->t[ip]);
4985
4986 /* Check size of table (temperature and column density)... */
4987 if (tbl->nt[id][ig][ipr] < 2 || tbl->nt[id][ig][ipr + 1] < 2
4988 || tbl->nu[id][ig][ipr][it0] < 2
4989 || tbl->nu[id][ig][ipr][it0 + 1] < 2
4990 || tbl->nu[id][ig][ipr + 1][it1] < 2
4991 || tbl->nu[id][ig][ipr + 1][it1 + 1] < 2)
4992 eps = 0;
4993
4994 else {
4995
4996 /* Get emissivities of extended path... */
4997 const double logeps = log(1.0 - tau_path[id][ig]);
4998
4999 u = intpol_tbl_u(tbl, ig, id, ipr, it0, logeps);
5000 double eps00
5001 = intpol_tbl_eps(tbl, ig, id, ipr, it0, log(u + los->u[ip][ig]));
5002
5003 u = intpol_tbl_u(tbl, ig, id, ipr, it0 + 1, logeps);
5004 double eps01 = intpol_tbl_eps(tbl, ig, id, ipr, it0 + 1,
5005 log(u + los->u[ip][ig]));
5006
5007 u = intpol_tbl_u(tbl, ig, id, ipr + 1, it1, logeps);
5008 double eps10 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1,
5009 log(u + los->u[ip][ig]));
5010
5011 u = intpol_tbl_u(tbl, ig, id, ipr + 1, it1 + 1, logeps);
5012 double eps11 = intpol_tbl_eps(tbl, ig, id, ipr + 1, it1 + 1,
5013 log(u + los->u[ip][ig]));
5014
5015 /* Interpolate with respect to temperature... */
5016 eps00 = LIN(tbl->t[id][ig][ipr][it0], eps00,
5017 tbl->t[id][ig][ipr][it0 + 1], eps01, los->t[ip]);
5018 eps11 = LIN(tbl->t[id][ig][ipr + 1][it1], eps10,
5019 tbl->t[id][ig][ipr + 1][it1 + 1], eps11, los->t[ip]);
5020
5021 /* Interpolate with respect to log-pressure... */
5022 eps00 = LIN(tbl->lnp[id][ig][ipr], eps00,
5023 tbl->lnp[id][ig][ipr + 1], eps11, lnp);
5024
5025 /* Check emissivity range... */
5026 eps00 = CLAMP(eps00, 0.0, 1.0);
5027
5028 /* Determine segment emissivity... */
5029 eps = 1 - (1 - eps00) / tau_path[id][ig];
5030
5031 /* Check emissivity range... */
5032 eps = CLAMP(eps, 0.0, 1.0);
5033 }
5034 }
5035
5036 /* Get transmittance of extended path... */
5037 tau_path[id][ig] *= (1 - eps);
5038
5039 /* Get segment transmittance... */
5040 tau_seg[id] *= (1 - eps);
5041 }
5042 }
5043}
5044
5045/*****************************************************************************/
5046
5047inline double intpol_tbl_eps(
5048 const tbl_t *tbl,
5049 const int ig,
5050 const int id,
5051 const int ip,
5052 const int it,
5053 const double logu) {
5054
5055 const int nu = tbl->nu[id][ig][ip][it];
5056 const float *logu_arr = tbl->logu[id][ig][ip][it];
5057 const float *logeps_arr = tbl->logeps[id][ig][ip][it];
5058
5059 /* Work in log-space and only convert back when needed... */
5060 const double logu_min = (double) logu_arr[0];
5061 const double logu_max = (double) logu_arr[nu - 1];
5062
5063 /* Lower boundary extrapolation (u < u_min)...
5064 eps ~ eps_min * u/u_min => log(eps) = logeps_min + log(u) - log(u_min) */
5065 if (logu < logu_min) {
5066 const double logeps_min = (double) logeps_arr[0];
5067 return exp(logeps_min + logu - logu_min);
5068 }
5069
5070 /* Upper boundary extrapolation (u > u_max)...
5071 * Assume eps(u) approaches 1 exponentially:
5072 * eps(u) = 1 - exp(a * u), a < 0
5073 * Continuity at (u_max, eps_max) gives
5074 * a = log(1 - eps_max) / u_max.
5075 * Use log1p/expm1 and u/u_max = exp(log(u) - log(u_max)) for stability.
5076 */
5077 if (logu > logu_max) {
5078 const double eps_max = exp((double) logeps_arr[nu - 1]);
5079 const double l1m_eps_max = log1p(-eps_max);
5080 const double r = exp(logu - logu_max);
5081 return -expm1(l1m_eps_max * r);
5082 }
5083
5084 /* Interpolation (log-log using precomputed logs)... */
5085 const int idx = locate_tbl(logu_arr, nu, logu);
5086 return exp(LIN(logu_arr[idx], logeps_arr[idx],
5087 logu_arr[idx + 1], logeps_arr[idx + 1], logu));
5088}
5089
5090/*****************************************************************************/
5091
5092inline double intpol_tbl_u(
5093 const tbl_t *tbl,
5094 const int ig,
5095 const int id,
5096 const int ip,
5097 const int it,
5098 const double logeps) {
5099
5100 const int nu = tbl->nu[id][ig][ip][it];
5101 const float *logeps_arr = tbl->logeps[id][ig][ip][it];
5102 const float *logu_arr = tbl->logu[id][ig][ip][it];
5103
5104 /* Work in log-space and only convert back when needed.... */
5105 const double logeps_min = (double) logeps_arr[0];
5106 const double logeps_max = (double) logeps_arr[nu - 1];
5107
5108 /* Lower boundary extrapolation (eps < eps_min)...
5109 u ~ u_min * eps/eps_min => log(u) = log(u_min) + log(eps) - log(eps_min) */
5110 if (logeps < logeps_min) {
5111 const double logu_min = (double) logu_arr[0];
5112 return exp(logu_min + logeps - logeps_min);
5113 }
5114
5115 /* Upper boundary extrapolation (eps > eps_max):
5116 * Invert the exponential tail used for eps(u):
5117 * u = log(1 - eps) / a,
5118 * with a = log(1 - eps_max) / u_max.
5119 * Rewritten as
5120 * u = u_max * log(tau) / log(1 - eps_max)
5121 * for numerical stability (log1p).
5122 */
5123 if (logeps > logeps_max) {
5124 const double u_max = exp((double) logu_arr[nu - 1]);
5125 const double l1m_eps_max = log1p(-exp(logeps_max));
5126 const double logtau = log1p(-exp(logeps));
5127 return u_max * (logtau / l1m_eps_max);
5128 }
5129
5130 /* Interpolation (log-log using precomputed logs)... */
5131 const int idx = locate_tbl(logeps_arr, nu, logeps);
5132 return exp(LIN(logeps_arr[idx], logu_arr[idx],
5133 logeps_arr[idx + 1], logu_arr[idx + 1], logeps));
5134}
5135
5136/*****************************************************************************/
5137
5139 const double jsec,
5140 int *year,
5141 int *mon,
5142 int *day,
5143 int *hour,
5144 int *min,
5145 int *sec,
5146 double *remain) {
5147
5148 struct tm t0, *t1;
5149
5150 t0.tm_year = 100;
5151 t0.tm_mon = 0;
5152 t0.tm_mday = 1;
5153 t0.tm_hour = 0;
5154 t0.tm_min = 0;
5155 t0.tm_sec = 0;
5156
5157 const time_t jsec0 = (time_t) jsec + timegm(&t0);
5158 t1 = gmtime(&jsec0);
5159
5160 *year = t1->tm_year + 1900;
5161 *mon = t1->tm_mon + 1;
5162 *day = t1->tm_mday;
5163 *hour = t1->tm_hour;
5164 *min = t1->tm_min;
5165 *sec = t1->tm_sec;
5166 *remain = jsec - floor(jsec);
5167}
5168
5169/*****************************************************************************/
5170
5172 const ctl_t *ctl,
5173 const tbl_t *tbl,
5174 atm_t *atm,
5175 obs_t *obs,
5176 gsl_matrix *k) {
5177
5178 /* Get sizes... */
5179 const size_t m = k->size1;
5180 const size_t n = k->size2;
5181 const size_t nthreads = (size_t) MAX(1, omp_get_max_threads());
5182 const size_t batch_size = n < nthreads ? n : nthreads;
5183
5184 /* Allocate... */
5185 gsl_vector *x0 = gsl_vector_alloc(n);
5186 gsl_vector *yy0 = gsl_vector_alloc(m);
5187 gsl_vector *x1 = gsl_vector_alloc(n);
5188 gsl_vector *yy1 = gsl_vector_alloc(m);
5189 int *iqa;
5190 ALLOC(iqa, int,
5191 N);
5192 double *h_batch;
5193 int *status;
5194 ALLOC(h_batch, double,
5195 batch_size);
5196 ALLOC(status, int,
5197 batch_size);
5198 los_t *los0, *los1;
5199 atm_t *atm1;
5200 obs_t *obs_scratch0, *obs1, *obs_scratch1;
5201 ALLOC(los0, los_t, 1);
5202 ALLOC(obs_scratch0, obs_t, 1);
5203 ALLOC(atm1, atm_t, batch_size);
5204 ALLOC(obs1, obs_t, batch_size);
5205 ALLOC(los1, los_t, batch_size);
5206 ALLOC(obs_scratch1, obs_t, batch_size);
5207
5208 /* Compute radiance for undisturbed atmospheric data... */
5209 if (formod(ctl, tbl, atm, obs, los0, obs_scratch0) != FORMOD_STATUS_OK)
5210 ERRMSG("Forward model failed!");
5211 free(los0);
5212 free(obs_scratch0);
5213
5214 /* Compose vectors... */
5215 atm2x(ctl, atm, x0, iqa, NULL);
5216 obs2y(ctl, obs, yy0, NULL, NULL);
5217
5218 /* Initialize kernel matrix... */
5219 gsl_matrix_set_zero(k);
5220
5221 /* Loop over state vector elements in batches... */
5222 for (size_t j0 = 0; j0 < n; j0 += batch_size) {
5223 const size_t nbatch = MIN(batch_size, n - j0);
5224
5225 /* Prepare disturbed states... */
5226 for (size_t jb = 0; jb < nbatch; jb++) {
5227 const size_t j = j0 + jb;
5228
5229 /* Set perturbation size... */
5230 double h;
5231 if (iqa[j] == IDXP)
5232 h = MAX(fabs(KERNEL_P_REL * gsl_vector_get(x0, j)),
5233 KERNEL_P_MIN);
5234 else if (iqa[j] == IDXT)
5235 h = KERNEL_T_ABS;
5236 else if (iqa[j] >= IDXQ(0) && iqa[j] < IDXQ(ctl->ng))
5237 h = MAX(fabs(KERNEL_Q_REL * gsl_vector_get(x0, j)),
5238 KERNEL_Q_MIN);
5239 else if (iqa[j] >= IDXK(0) && iqa[j] < IDXK(ctl->nw))
5240 h = KERNEL_K_ABS;
5241 else if (iqa[j] == IDXCLZ)
5242 h = KERNEL_CLZ_ABS;
5243 else if (iqa[j] == IDXCLDZ)
5244 h = KERNEL_CLDZ_ABS;
5245 else if (iqa[j] >= IDXCLK(0) && iqa[j] < IDXCLK(ctl->ncl))
5246 h = KERNEL_CLK_ABS;
5247 else if (iqa[j] == IDXSFT)
5248 h = KERNEL_SFT_ABS;
5249 else if (iqa[j] >= IDXSFEPS(0) && iqa[j] < IDXSFEPS(ctl->nsf))
5250 h = KERNEL_SFEPS_ABS;
5251 else
5252 ERRMSG("Cannot set perturbation size!");
5253
5254 /* Disturb state vector element... */
5255 gsl_vector_memcpy(x1, x0);
5256 gsl_vector_set(x1, j, gsl_vector_get(x1, j) + h);
5257 copy_atm(ctl, &atm1[jb], atm, 0);
5258 copy_obs(ctl, &obs1[jb], obs, 0);
5259 x2atm(ctl, x1, &atm1[jb]);
5260 h_batch[jb] = h;
5261 }
5262
5263 /* Compute radiance for disturbed atmospheric data... */
5264 formod_batch(ctl, tbl, atm1, obs1, (int) nbatch, status, los1,
5265 obs_scratch1);
5266
5267 /* Compose measurement vectors and derivatives... */
5268 for (size_t jb = 0; jb < nbatch; jb++) {
5269 const size_t j = j0 + jb;
5270 if (status[jb] != FORMOD_STATUS_OK)
5271 ERRMSG("Forward model failed!");
5272 obs2y(ctl, &obs1[jb], yy1, NULL, NULL);
5273
5274 /* Compute derivatives... */
5275 for (size_t i = 0; i < m; i++)
5276 gsl_matrix_set(k, i, j,
5277 (gsl_vector_get(yy1, i) - gsl_vector_get(yy0, i))
5278 / h_batch[jb]);
5279 }
5280 }
5281
5282 /* Free... */
5283 gsl_vector_free(x0);
5284 gsl_vector_free(yy0);
5285 gsl_vector_free(x1);
5286 gsl_vector_free(yy1);
5287 free(atm1);
5288 free(obs1);
5289 free(obs_scratch1);
5290 free(los1);
5291 free(status);
5292 free(h_batch);
5293 free(iqa);
5294}
5295
5296/*****************************************************************************/
5297
5299 const double *xx,
5300 const int n,
5301 const double x) {
5302
5303 int ilo = 0;
5304 int ihi = n - 1;
5305 int i = (ihi + ilo) >> 1;
5306
5307 if (xx[i] < xx[i + 1])
5308 while (ihi > ilo + 1) {
5309 i = (ihi + ilo) >> 1;
5310 if (xx[i] > x)
5311 ihi = i;
5312 else
5313 ilo = i;
5314 } else
5315 while (ihi > ilo + 1) {
5316 i = (ihi + ilo) >> 1;
5317 if (xx[i] <= x)
5318 ihi = i;
5319 else
5320 ilo = i;
5321 }
5322
5323 return ilo;
5324}
5325
5326/*****************************************************************************/
5327
5329 const double *xx,
5330 const int n,
5331 const double x) {
5332
5333 /* Calculate index... */
5334 const int i = (int) ((x - xx[0]) / (xx[1] - xx[0]));
5335
5336 /* Check range... */
5337 if (i < 0)
5338 return 0;
5339 else if (i > n - 2)
5340 return n - 2;
5341 else
5342 return i;
5343}
5344
5345/*****************************************************************************/
5346
5347inline int locate_tbl(
5348 const float *xx,
5349 const int n,
5350 const double x) {
5351
5352 int ilo = 0;
5353 int ihi = n - 1;
5354 int i = (ihi + ilo) >> 1;
5355
5356 while (ihi > ilo + 1) {
5357 i = (ihi + ilo) >> 1;
5358 if (xx[i] > x)
5359 ihi = i;
5360 else
5361 ilo = i;
5362 }
5363
5364 return ilo;
5365}
5366
5367/*****************************************************************************/
5368
5370 gsl_matrix *a) {
5371
5372 size_t diag = 1;
5373
5374 /* Get size... */
5375 const size_t n = a->size1;
5376
5377 /* Check if matrix is diagonal... */
5378 for (size_t i = 0; i < n && diag; i++)
5379 for (size_t j = i + 1; j < n; j++)
5380 if (gsl_matrix_get(a, i, j) != 0) {
5381 diag = 0;
5382 break;
5383 }
5384
5385 /* Quick inversion of diagonal matrix... */
5386 if (diag)
5387 for (size_t i = 0; i < n; i++)
5388 gsl_matrix_set(a, i, i, 1 / gsl_matrix_get(a, i, i));
5389
5390 /* Matrix inversion by means of Cholesky decomposition... */
5391 else {
5392 gsl_linalg_cholesky_decomp(a);
5393 gsl_linalg_cholesky_invert(a);
5394 }
5395}
5396
5397/*****************************************************************************/
5398
5400 const gsl_matrix *a,
5401 const gsl_vector *b,
5402 const int transpose,
5403 gsl_matrix *c) {
5404
5405 /* Set sizes... */
5406 const size_t m = a->size1;
5407 const size_t n = a->size2;
5408
5409 /* Allocate... */
5410 gsl_matrix *aux = gsl_matrix_alloc(m, n);
5411
5412 /* Compute A^T B A... */
5413 if (transpose == 1) {
5414
5415 /* Compute B^1/2 A... */
5416 for (size_t i = 0; i < m; i++)
5417 for (size_t j = 0; j < n; j++)
5418 gsl_matrix_set(aux, i, j,
5419 gsl_vector_get(b, i) * gsl_matrix_get(a, i, j));
5420
5421 /* Compute A^T B A = (B^1/2 A)^T (B^1/2 A)... */
5422 gsl_blas_dgemm(CblasTrans, CblasNoTrans, 1.0, aux, aux, 0.0, c);
5423 }
5424
5425 /* Compute A B A^T... */
5426 else if (transpose == 2) {
5427
5428 /* Compute A B^1/2... */
5429 for (size_t i = 0; i < m; i++)
5430 for (size_t j = 0; j < n; j++)
5431 gsl_matrix_set(aux, i, j,
5432 gsl_matrix_get(a, i, j) * gsl_vector_get(b, j));
5433
5434 /* Compute A B A^T = (A B^1/2) (A B^1/2)^T... */
5435 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, aux, aux, 0.0, c);
5436 }
5437
5438 /* Free... */
5439 gsl_matrix_free(aux);
5440}
5441
5442/*****************************************************************************/
5443
5444size_t obs2y(
5445 const ctl_t *ctl,
5446 const obs_t *obs,
5447 gsl_vector *y,
5448 int *ida,
5449 int *ira) {
5450
5451 size_t m = 0;
5452
5453 /* Determine measurement vector... */
5454 for (int ir = 0; ir < obs->nr; ir++)
5455 for (int id = 0; id < ctl->nd; id++)
5456 if (isfinite(obs->rad[id][ir])) {
5457 if (y != NULL)
5458 gsl_vector_set(y, m, obs->rad[id][ir]);
5459 if (ida != NULL)
5460 ida[m] = id;
5461 if (ira != NULL)
5462 ira[m] = ir;
5463 m++;
5464 }
5465
5466 return m;
5467}
5468
5469/*****************************************************************************/
5470
5472 ret_t *ret,
5473 ctl_t *ctl,
5474 tbl_t *tbl,
5475 obs_t *obs_meas,
5476 obs_t *obs_i,
5477 atm_t *atm_apr,
5478 atm_t *atm_i,
5479 double *chisq) {
5480
5481 double disq = 0, lmpar = 0.001;
5482
5483 /* ------------------------------------------------------------
5484 Initialize...
5485 ------------------------------------------------------------ */
5486
5487 /* Allocate... */
5488 int *ipa, *iqa;
5489 ALLOC(ipa, int,
5490 N);
5491 ALLOC(iqa, int,
5492 N);
5493
5494 /* Get sizes... */
5495 const size_t m = obs2y(ctl, obs_meas, NULL, NULL, NULL);
5496 const size_t n = atm2x(ctl, atm_apr, NULL, iqa, ipa);
5497 if (m == 0 || n == 0) {
5498 WARN("Check problem definition (m = 0 or n = 0)!");
5499 *chisq = GSL_NAN;
5500 return;
5501 }
5502
5503 /* Allocate... */
5504 gsl_matrix *a = gsl_matrix_alloc(n, n);
5505 gsl_matrix *cov = gsl_matrix_alloc(n, n);
5506 gsl_matrix *k_i = gsl_matrix_alloc(m, n);
5507 gsl_matrix *s_a_inv = gsl_matrix_alloc(n, n);
5508
5509 gsl_vector *b = gsl_vector_alloc(n);
5510 gsl_vector *dx = gsl_vector_alloc(n);
5511 gsl_vector *dy = gsl_vector_alloc(m);
5512 gsl_vector *sig_eps_inv = gsl_vector_alloc(m);
5513 gsl_vector *sig_formod = gsl_vector_alloc(m);
5514 gsl_vector *sig_noise = gsl_vector_alloc(m);
5515 gsl_vector *x_a = gsl_vector_alloc(n);
5516 gsl_vector *x_i = gsl_vector_alloc(n);
5517 gsl_vector *x_step = gsl_vector_alloc(n);
5518 gsl_vector *y_aux = gsl_vector_alloc(m);
5519 gsl_vector *y_i = gsl_vector_alloc(m);
5520 gsl_vector *y_m = gsl_vector_alloc(m);
5521
5522 los_t *los_scratch;
5523 obs_t *obs_scratch;
5524 ALLOC(los_scratch, los_t, 1);
5525 ALLOC(obs_scratch, obs_t, 1);
5526
5527 /* Set timer... */
5528 SELECT_TIMER("RET_SETUP", "RETRIEVAL");
5529
5530 /* Set initial state... */
5531 copy_atm(ctl, atm_i, atm_apr, 0);
5532 copy_obs(ctl, obs_i, obs_meas, 0);
5533 if (formod(ctl, tbl, atm_i, obs_i, los_scratch, obs_scratch)
5535 ERRMSG("Forward model failed!");
5536
5537 /* Set state vectors and observation vectors... */
5538 atm2x(ctl, atm_apr, x_a, NULL, NULL);
5539 atm2x(ctl, atm_i, x_i, NULL, NULL);
5540 obs2y(ctl, obs_meas, y_m, NULL, NULL);
5541 obs2y(ctl, obs_i, y_i, NULL, NULL);
5542
5543 /* Set inverse a priori covariance S_a^-1... */
5544 set_cov_apr(ret, ctl, atm_apr, iqa, ipa, s_a_inv);
5545 int lockfd = shared_io_lock(ret);
5546 const char *dirname;
5547 int profile;
5548 const char *filename =
5550 "matrix_cov_apr.tab", &dirname, &profile);
5551 write_matrix(dirname, filename, ctl, s_a_inv,
5552 atm_i, obs_i, "x", "x", "r", profile);
5553 shared_io_unlock(lockfd);
5554 matrix_invert(s_a_inv);
5555
5556 /* Get measurement errors... */
5557 set_cov_meas(ret, ctl, obs_meas, sig_noise, sig_formod, sig_eps_inv);
5558
5559 /* Determine dx = x_i - x_a and dy = y - F(x_i) ... */
5560 gsl_vector_memcpy(dx, x_i);
5561 gsl_vector_sub(dx, x_a);
5562 gsl_vector_memcpy(dy, y_m);
5563 gsl_vector_sub(dy, y_i);
5564
5565 /* Compute cost function... */
5566 *chisq = cost_function(dx, dy, s_a_inv, sig_eps_inv);
5567
5568 /* Write info... */
5569 LOG(2, "it= %d / chi^2/m= %g", 0, *chisq);
5570
5571 /* Compute initial kernel... */
5572 SELECT_TIMER("RET_KERNEL_INIT", "RETRIEVAL");
5573 kernel(ctl, tbl, atm_i, obs_i, k_i);
5574
5575 /* ------------------------------------------------------------
5576 Levenberg-Marquardt minimization...
5577 ------------------------------------------------------------ */
5578
5579 SELECT_TIMER("RET_ITERATE", "RETRIEVAL");
5580
5581 /* Outer loop... */
5582 for (int it = 1; it <= ret->conv_itmax; it++) {
5583
5584 /* Store current cost function value... */
5585 double chisq_old = *chisq;
5586
5587 /* Compute kernel matrix K_i... */
5588 if (it > 1 && it % ret->kernel_recomp == 0)
5589 kernel(ctl, tbl, atm_i, obs_i, k_i);
5590
5591 /* Compute K_i^T * S_eps^{-1} * K_i ... */
5592 if (it == 1 || it % ret->kernel_recomp == 0)
5593 matrix_product(k_i, sig_eps_inv, 1, cov);
5594
5595 /* Determine b = K_i^T * S_eps^{-1} * dy - S_a^{-1} * dx ... */
5596 for (size_t i = 0; i < m; i++)
5597 gsl_vector_set(y_aux, i, gsl_vector_get(dy, i)
5598 * POW2(gsl_vector_get(sig_eps_inv, i)));
5599 gsl_blas_dgemv(CblasTrans, 1.0, k_i, y_aux, 0.0, b);
5600 gsl_blas_dgemv(CblasNoTrans, -1.0, s_a_inv, dx, 1.0, b);
5601
5602 /* Inner loop... */
5603 for (int it2 = 0; it2 < 20; it2++) {
5604
5605 /* Compute A = (1 + lmpar) * S_a^{-1} + K_i^T * S_eps^{-1} * K_i ... */
5606 gsl_matrix_memcpy(a, s_a_inv);
5607 gsl_matrix_scale(a, 1 + lmpar);
5608 gsl_matrix_add(a, cov);
5609
5610 /* Solve A * x_step = b by means of Cholesky decomposition... */
5611 gsl_linalg_cholesky_decomp(a);
5612 gsl_linalg_cholesky_solve(a, b, x_step);
5613
5614 /* Update atmospheric state... */
5615 gsl_vector_add(x_i, x_step);
5616 copy_atm(ctl, atm_i, atm_apr, 0);
5617 copy_obs(ctl, obs_i, obs_meas, 0);
5618 x2atm(ctl, x_i, atm_i);
5619
5620 /* Check atmospheric state... */
5621 for (int ip = 0; ip < atm_i->np; ip++) {
5622 atm_i->p[ip] = CLAMP(atm_i->p[ip], 5e-7, 5e4);
5623 atm_i->t[ip] = CLAMP(atm_i->t[ip], 100.0, 400.0);
5624 for (int ig = 0; ig < ctl->ng; ig++)
5625 atm_i->q[ig][ip] = CLAMP(atm_i->q[ig][ip], 0.0, 1.0);
5626 for (int iw = 0; iw < ctl->nw; iw++)
5627 atm_i->k[iw][ip] = MAX(atm_i->k[iw][ip], 0.0);
5628 }
5629 atm_i->clz = MAX(atm_i->clz, 0.0);
5630 atm_i->cldz = MAX(atm_i->cldz, 0.1);
5631 for (int icl = 0; icl < ctl->ncl; icl++)
5632 atm_i->clk[icl] = MAX(atm_i->clk[icl], 0.0);
5633 atm_i->sft = CLAMP(atm_i->sft, 100.0, 400.0);
5634 for (int isf = 0; isf < ctl->nsf; isf++)
5635 atm_i->sfeps[isf] = CLAMP(atm_i->sfeps[isf], 0.0, 1.0);
5636
5637 /* Forward calculation... */
5638 if (formod(ctl, tbl, atm_i, obs_i, los_scratch, obs_scratch)
5640 ERRMSG("Forward model failed!");
5641 obs2y(ctl, obs_i, y_i, NULL, NULL);
5642
5643 /* Determine dx = x_i - x_a and dy = y - F(x_i) ... */
5644 gsl_vector_memcpy(dx, x_i);
5645 gsl_vector_sub(dx, x_a);
5646 gsl_vector_memcpy(dy, y_m);
5647 gsl_vector_sub(dy, y_i);
5648
5649 /* Compute cost function... */
5650 *chisq = cost_function(dx, dy, s_a_inv, sig_eps_inv);
5651
5652 /* Modify Levenberg-Marquardt parameter... */
5653 if (*chisq > chisq_old) {
5654 lmpar *= 10;
5655 gsl_vector_sub(x_i, x_step);
5656 } else {
5657 lmpar /= 10;
5658 break;
5659 }
5660 }
5661
5662 /* Write info... */
5663 LOG(2, "it= %d / chi^2/m= %g", it, *chisq);
5664
5665 /* Get normalized step size in state space... */
5666 gsl_blas_ddot(x_step, b, &disq);
5667 disq /= (double) n;
5668
5669 /* Convergence test... */
5670 if ((it == 1 || it % ret->kernel_recomp == 0) && disq < ret->conv_dmin)
5671 break;
5672 }
5673
5674 /* ------------------------------------------------------------
5675 Analysis of retrieval results...
5676 ------------------------------------------------------------ */
5677
5678 /* Check if error analysis is requested... */
5679 if (ret->err_ana) {
5680
5681 SELECT_TIMER("RET_DIAGNOSTICS", "OUTPUT");
5682
5683 /* Store results... */
5684 lockfd = shared_io_lock(ret);
5686 "atm_final.tab", &dirname, &profile);
5687 write_atm(dirname, filename, ctl, atm_i, profile);
5689 "obs_final.tab", &dirname, &profile);
5690 write_obs(dirname, filename, ctl, obs_i, profile);
5691 filename =
5693 "matrix_kernel.tab", &dirname, &profile);
5694 write_matrix(dirname, filename, ctl, k_i,
5695 atm_i, obs_i, "y", "x", "r", profile);
5696
5697 /* Allocate... */
5698 gsl_matrix *auxnm = gsl_matrix_alloc(n, m);
5699 gsl_matrix *corr = gsl_matrix_alloc(n, n);
5700 gsl_matrix *gain = gsl_matrix_alloc(n, m);
5701
5702 /* Compute inverse retrieval covariance...
5703 cov^{-1} = S_a^{-1} + K_i^T * S_eps^{-1} * K_i */
5704 matrix_product(k_i, sig_eps_inv, 1, cov);
5705 gsl_matrix_add(cov, s_a_inv);
5706
5707 /* Compute retrieval covariance... */
5708 matrix_invert(cov);
5709 filename =
5711 "matrix_cov_ret.tab", &dirname, &profile);
5712 write_matrix(dirname, filename, ctl, cov,
5713 atm_i, obs_i, "x", "x", "r", profile);
5714 write_stddev("total", ret, ctl, atm_i, cov);
5715
5716 /* Compute correlation matrix... */
5717 for (size_t i = 0; i < n; i++)
5718 for (size_t j = 0; j < n; j++)
5719 gsl_matrix_set(corr, i, j, gsl_matrix_get(cov, i, j)
5720 / sqrt(gsl_matrix_get(cov, i, i))
5721 / sqrt(gsl_matrix_get(cov, j, j)));
5723 "matrix_corr.tab", &dirname, &profile);
5724 write_matrix(dirname, filename, ctl, corr,
5725 atm_i, obs_i, "x", "x", "r", profile);
5726
5727 /* Compute gain matrix...
5728 G = cov * K^T * S_eps^{-1} */
5729 for (size_t i = 0; i < n; i++)
5730 for (size_t j = 0; j < m; j++)
5731 gsl_matrix_set(auxnm, i, j, gsl_matrix_get(k_i, j, i)
5732 * POW2(gsl_vector_get(sig_eps_inv, j)));
5733 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, cov, auxnm, 0.0, gain);
5735 "matrix_gain.tab", &dirname, &profile);
5736 write_matrix(dirname, filename, ctl, gain,
5737 atm_i, obs_i, "x", "y", "c", profile);
5738
5739 /* Compute retrieval error due to noise... */
5740 matrix_product(gain, sig_noise, 2, a);
5741 write_stddev("noise", ret, ctl, atm_i, a);
5742
5743 /* Compute retrieval error due to forward model errors... */
5744 matrix_product(gain, sig_formod, 2, a);
5745 write_stddev("formod", ret, ctl, atm_i, a);
5746
5747 /* Compute averaging kernel matrix
5748 A = G * K ... */
5749 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, gain, k_i, 0.0, a);
5751 "matrix_avk.tab", &dirname, &profile);
5752 write_matrix(dirname, filename, ctl, a,
5753 atm_i, obs_i, "x", "x", "r", profile);
5754
5755 /* Analyze averaging kernel matrix... */
5756 analyze_avk(ret, ctl, atm_i, iqa, ipa, a);
5757 shared_io_unlock(lockfd);
5758
5759 /* Free... */
5760 gsl_matrix_free(auxnm);
5761 gsl_matrix_free(corr);
5762 gsl_matrix_free(gain);
5763 }
5764
5765 /* ------------------------------------------------------------
5766 Finalize...
5767 ------------------------------------------------------------ */
5768
5769 gsl_matrix_free(a);
5770 gsl_matrix_free(cov);
5771 gsl_matrix_free(k_i);
5772 gsl_matrix_free(s_a_inv);
5773
5774 gsl_vector_free(b);
5775 gsl_vector_free(dx);
5776 gsl_vector_free(dy);
5777 gsl_vector_free(sig_eps_inv);
5778 gsl_vector_free(sig_formod);
5779 gsl_vector_free(sig_noise);
5780 gsl_vector_free(x_a);
5781 gsl_vector_free(x_i);
5782 gsl_vector_free(x_step);
5783 gsl_vector_free(y_aux);
5784 gsl_vector_free(y_i);
5785 gsl_vector_free(y_m);
5786 free(los_scratch);
5787 free(obs_scratch);
5788
5789 free(ipa);
5790 free(iqa);
5791}
5792
5793/*****************************************************************************/
5794
5796 const ctl_t *ctl,
5797 const atm_t *atm,
5798 obs_t *obs,
5799 los_t *los,
5800 const int ir) {
5801
5802 /* Cartesian gradient step and refraction cutoff [km]. */
5803 const double h = 0.02, zrefrac = 60;
5804
5805 double ex0[3], ex1[3], k[NW], lat, lon, n, ng[3], norm, p, q[NG], t,
5806 x[3], xh[3], xobs[3], xvp[3], z = 1e99, zmax, zmin;
5807
5808 int stop = 0;
5809
5810 /* Initialize... */
5811 los->np = 0;
5812 los->sft = -999;
5813 obs->tpz[ir] = obs->vpz[ir];
5814 obs->tplon[ir] = obs->vplon[ir];
5815 obs->tplat[ir] = obs->vplat[ir];
5816
5817 /* Get altitude range of atmospheric data... */
5818 gsl_stats_minmax(&zmin, &zmax, atm->z, 1, (size_t) atm->np);
5819
5820 /* Check observer altitude... */
5821 if (obs->obsz[ir] < zmin)
5823
5824 /* Determine Cartesian coordinates for observer and view point... */
5825 geo2cart(obs->obsz[ir], obs->obslon[ir], obs->obslat[ir], xobs);
5826 geo2cart(obs->vpz[ir], obs->vplon[ir], obs->vplat[ir], xvp);
5827
5828 /* Determine initial tangent vector... */
5829 for (int i = 0; i < 3; i++)
5830 ex0[i] = xvp[i] - xobs[i];
5831 norm = NORM(ex0);
5832 for (int i = 0; i < 3; i++)
5833 ex0[i] /= norm;
5834
5835 /* Observer within atmosphere... */
5836 for (int i = 0; i < 3; i++)
5837 x[i] = xobs[i];
5838
5839 /* Observer above atmosphere (search entry point)... */
5840 if (obs->obsz[ir] > zmax) {
5841 double dmax = norm, dmin = 0;
5842 while (fabs(dmin - dmax) > 0.001) {
5843 const double d = (dmax + dmin) / 2;
5844 for (int i = 0; i < 3; i++)
5845 x[i] = xobs[i] + d * ex0[i];
5846 cart2geo(x, &z, &lon, &lat);
5847 if (z <= zmax && z > zmax - 0.001)
5848 break;
5849 if (z < zmax - 0.0005)
5850 dmax = d;
5851 else
5852 dmin = d;
5853 }
5854 }
5855
5856 /* Ray-tracing... */
5857 while (1) {
5858
5859 /* Set step length... */
5860 double ds = ctl->rayds;
5861 if (ctl->raydz > 0) {
5862 norm = NORM(x);
5863 for (int i = 0; i < 3; i++)
5864 xh[i] = x[i] / norm;
5865 const double cosa = fabs(DOTP(ex0, xh));
5866 if (cosa != 0)
5867 ds = MIN(ctl->rayds, ctl->raydz / cosa);
5868 }
5869
5870 /* Determine geolocation... */
5871 cart2geo(x, &z, &lon, &lat);
5872
5873 /* Check if LOS hits the ground or has left atmosphere... */
5874 if (z < zmin || z > zmax) {
5875 if (los->np == 0)
5877 stop = (z < zmin ? 2 : 1);
5878 const double frac =
5879 ((z <
5880 zmin ? zmin : zmax) - los->z[los->np - 1]) / (z - los->z[los->np -
5881 1]);
5882 geo2cart(los->z[los->np - 1], los->lon[los->np - 1],
5883 los->lat[los->np - 1], xh);
5884 for (int i = 0; i < 3; i++)
5885 x[i] = xh[i] + frac * (x[i] - xh[i]);
5886 cart2geo(x, &z, &lon, &lat);
5887 los->ds[los->np - 1] = ds * frac;
5888 ds = 0;
5889 }
5890
5891 /* Interpolate atmospheric data... */
5892 intpol_atm(ctl, atm, z, &p, &t, q, k);
5893
5894 /* Abort before writing beyond the fixed LOS scratch buffers... */
5895 if (los->np >= NLOS)
5897
5898 /* Save data... */
5899 los->lon[los->np] = lon;
5900 los->lat[los->np] = lat;
5901 los->z[los->np] = z;
5902 los->p[los->np] = p;
5903 los->t[los->np] = t;
5904 for (int ig = 0; ig < ctl->ng; ig++)
5905 los->q[los->np][ig] = q[ig];
5906 for (int id = 0; id < ctl->nd; id++)
5907 los->k[los->np][id] = k[ctl->window[id]];
5908 los->ds[los->np] = ds;
5909
5910 /* Add cloud extinction... */
5911 if (ctl->ncl > 0 && atm->cldz > 0) {
5912 const double aux = exp(-0.5 * POW2((z - atm->clz) / atm->cldz));
5913 for (int id = 0; id < ctl->nd; id++) {
5914 const int icl = locate_irr(ctl->clnu, ctl->ncl, ctl->nu[id]);
5915 los->k[los->np][id]
5916 += aux * LIN(ctl->clnu[icl], atm->clk[icl],
5917 ctl->clnu[icl + 1], atm->clk[icl + 1], ctl->nu[id]);
5918 }
5919 }
5920
5921 /* Increment number of LOS points... */
5922 los->np++;
5923
5924 /* Check stop flag... */
5925 if (stop) {
5926
5927 /* Set surface temperature... */
5928 if (ctl->nsf > 0 && atm->sft > 0)
5929 t = atm->sft;
5930 los->sft = (stop == 2 ? t : -999);
5931
5932 /* Set surface emissivity... */
5933 for (int id = 0; id < ctl->nd; id++) {
5934 los->sfeps[id] = 1.0;
5935 if (ctl->nsf > 0) {
5936 const int isf = locate_irr(ctl->sfnu, ctl->nsf, ctl->nu[id]);
5937 los->sfeps[id] = LIN(ctl->sfnu[isf], atm->sfeps[isf],
5938 ctl->sfnu[isf + 1], atm->sfeps[isf + 1],
5939 ctl->nu[id]);
5940 }
5941 }
5942
5943 /* Leave raytracer... */
5944 break;
5945 }
5946
5947 /* Determine refractivity... */
5948 if (ctl->refrac && z <= zrefrac)
5949 n = 1 + REFRAC_EDLEN(p, t);
5950 else
5951 n = 1;
5952
5953 /* Construct new tangent vector (first term)... */
5954 for (int i = 0; i < 3; i++)
5955 ex1[i] = ex0[i] * n;
5956
5957 /* Compute gradient of refractivity... */
5958 if (ctl->refrac && z <= zrefrac) {
5959 for (int i = 0; i < 3; i++)
5960 xh[i] = x[i] + 0.5 * ds * ex0[i];
5961 cart2geo(xh, &z, &lon, &lat);
5962 intpol_atm(ctl, atm, z, &p, &t, q, k);
5963 n = REFRAC_EDLEN(p, t);
5964 for (int i = 0; i < 3; i++) {
5965 xh[i] += h;
5966 cart2geo(xh, &z, &lon, &lat);
5967 intpol_atm(ctl, atm, z, &p, &t, q, k);
5968 ng[i] = (REFRAC_EDLEN(p, t) - n) / h;
5969 xh[i] -= h;
5970 }
5971 } else
5972 for (int i = 0; i < 3; i++)
5973 ng[i] = 0;
5974
5975 /* Construct new tangent vector (second term)... */
5976 for (int i = 0; i < 3; i++)
5977 ex1[i] += ds * ng[i];
5978
5979 /* Normalize new tangent vector... */
5980 norm = NORM(ex1);
5981 for (int i = 0; i < 3; i++)
5982 ex1[i] /= norm;
5983
5984 /* Determine next point of LOS... */
5985 for (int i = 0; i < 3; i++)
5986 x[i] += 0.5 * ds * (ex0[i] + ex1[i]);
5987
5988 /* Copy tangent vector... */
5989 for (int i = 0; i < 3; i++)
5990 ex0[i] = ex1[i];
5991 }
5992
5993 /* Get tangent point (to be done before changing segment lengths!)... */
5994 tangent_point(los, &obs->tpz[ir], &obs->tplon[ir], &obs->tplat[ir]);
5995
5996 /* Change segment lengths according to trapezoid rule... */
5997 for (int ip = los->np - 1; ip >= 1; ip--)
5998 los->ds[ip] = 0.5 * (los->ds[ip - 1] + los->ds[ip]);
5999 los->ds[0] *= 0.5;
6000
6001 /* Compute column density... */
6002 for (int ip = 0; ip < los->np; ip++)
6003 for (int ig = 0; ig < ctl->ng; ig++)
6004 los->u[ip][ig] = 10 * los->q[ip][ig] * los->p[ip]
6005 / (KB * los->t[ip]) * los->ds[ip];
6006
6007 /* Compute Curtis-Godson means... */
6008 for (int ig = 0; ig < ctl->ng; ig++) {
6009 los->cgu[0][ig] = los->u[0][ig];
6010 los->cgp[0][ig] = los->u[0][ig] * los->p[0];
6011 los->cgt[0][ig] = los->u[0][ig] * los->t[0];
6012 }
6013 for (int ip = 1; ip < los->np; ip++)
6014 for (int ig = 0; ig < ctl->ng; ig++) {
6015 los->cgu[ip][ig] = los->cgu[ip - 1][ig] + los->u[ip][ig];
6016 los->cgp[ip][ig] = los->cgp[ip - 1][ig] + los->u[ip][ig] * los->p[ip];
6017 los->cgt[ip][ig] = los->cgt[ip - 1][ig] + los->u[ip][ig] * los->t[ip];
6018 }
6019 for (int ip = 0; ip < los->np; ip++)
6020 for (int ig = 0; ig < ctl->ng; ig++)
6021 if (los->cgu[ip][ig] != 0) {
6022 los->cgp[ip][ig] /= los->cgu[ip][ig];
6023 los->cgt[ip][ig] /= los->cgu[ip][ig];
6024 }
6025
6026 return FORMOD_STATUS_OK;
6027}
6028
6029/*****************************************************************************/
6030
6032 const char *dirname,
6033 const char *filename,
6034 const ctl_t *ctl,
6035 atm_t *atm,
6036 int profile) {
6037
6038 /* Init... */
6039 atm->np = 0;
6040
6041 /* Set filename... */
6042 char file[LEN];
6043 if (dirname != NULL)
6044 sprintf(file, "%s/%s", dirname, filename);
6045 else
6046 sprintf(file, "%s", filename);
6047
6048 /* Write info... */
6049 LOG(1, "Read atmospheric data: %s", file);
6050
6051 /* Read ASCII data... */
6052 if (ctl->atmfmt == 1)
6053 read_atm_asc(file, ctl, atm);
6054
6055 /* Read binary data... */
6056 else if (ctl->atmfmt == 2)
6057 read_atm_bin(file, ctl, atm);
6058
6059 /* Read netCDF data... */
6060 else if (ctl->atmfmt == 3)
6061 read_atm_nc(file, ctl, atm, profile);
6062
6063 /* Check number of points... */
6064 if (atm->np < 1)
6065 ERRMSG("Could not read any data!");
6066
6067 /* Write info... */
6068 double mini, maxi;
6069 LOG(2, "Number of data points: %d", atm->np);
6070 gsl_stats_minmax(&mini, &maxi, atm->time, 1, (size_t) atm->np);
6071 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
6072 gsl_stats_minmax(&mini, &maxi, atm->z, 1, (size_t) atm->np);
6073 LOG(2, "Altitude range: %g ... %g km", mini, maxi);
6074 gsl_stats_minmax(&mini, &maxi, atm->lon, 1, (size_t) atm->np);
6075 LOG(2, "Longitude range: %g ... %g deg", mini, maxi);
6076 gsl_stats_minmax(&mini, &maxi, atm->lat, 1, (size_t) atm->np);
6077 LOG(2, "Latitude range: %g ... %g deg", mini, maxi);
6078 gsl_stats_minmax(&mini, &maxi, atm->p, 1, (size_t) atm->np);
6079 LOG(2, "Pressure range: %g ... %g hPa", maxi, mini);
6080 gsl_stats_minmax(&mini, &maxi, atm->t, 1, (size_t) atm->np);
6081 LOG(2, "Temperature range: %g ... %g K", mini, maxi);
6082 for (int ig = 0; ig < ctl->ng; ig++) {
6083 gsl_stats_minmax(&mini, &maxi, atm->q[ig], 1, (size_t) atm->np);
6084 LOG(2, "Emitter %s range: %g ... %g ppv", ctl->emitter[ig], mini, maxi);
6085 }
6086 for (int iw = 0; iw < ctl->nw; iw++) {
6087 gsl_stats_minmax(&mini, &maxi, atm->k[iw], 1, (size_t) atm->np);
6088 LOG(2, "Extinction range (window %d): %g ... %g km^-1", iw, mini, maxi);
6089 }
6090 if (ctl->ncl > 0) {
6091 LOG(2, "Cloud layer: z= %g km | dz= %g km | k= %g ... %g km^-1",
6092 atm->clz, atm->cldz, atm->clk[0], atm->clk[ctl->ncl - 1]);
6093 } else
6094 LOG(2, "Cloud layer: none");
6095 if (ctl->nsf > 0) {
6096 LOG(2,
6097 "Surface: T_s = %g K | eps= %g ... %g",
6098 atm->sft, atm->sfeps[0], atm->sfeps[ctl->nsf - 1]);
6099 } else
6100 LOG(2, "Surface: none");
6101}
6102
6103/*****************************************************************************/
6104
6106 const char *filename,
6107 const ctl_t *ctl,
6108 atm_t *atm) {
6109
6110 /* Init... */
6111 atm->np = 0;
6112
6113 /* Open file... */
6114 FILE *in;
6115 if (!(in = fopen(filename, "r")))
6116 ERRMSG("Cannot open file!");
6117
6118 /* Read line... */
6119 char line[LEN], *tok;
6120 while (fgets(line, LEN, in)) {
6121
6122 /* Check capacity before writing a valid data point... */
6123 double time;
6124 TOK(line, tok, "%lg", time);
6125 if (atm->np >= NP)
6126 ERRMSG("Too many data points!");
6127
6128 /* Read data... */
6129 atm->time[atm->np] = time;
6130 TOK(NULL, tok, "%lg", atm->z[atm->np]);
6131 TOK(NULL, tok, "%lg", atm->lon[atm->np]);
6132 TOK(NULL, tok, "%lg", atm->lat[atm->np]);
6133 TOK(NULL, tok, "%lg", atm->p[atm->np]);
6134 TOK(NULL, tok, "%lg", atm->t[atm->np]);
6135 for (int ig = 0; ig < ctl->ng; ig++)
6136 TOK(NULL, tok, "%lg", atm->q[ig][atm->np]);
6137 for (int iw = 0; iw < ctl->nw; iw++)
6138 TOK(NULL, tok, "%lg", atm->k[iw][atm->np]);
6139 if (ctl->ncl > 0 && atm->np == 0) {
6140 TOK(NULL, tok, "%lg", atm->clz);
6141 TOK(NULL, tok, "%lg", atm->cldz);
6142 for (int icl = 0; icl < ctl->ncl; icl++)
6143 TOK(NULL, tok, "%lg", atm->clk[icl]);
6144 }
6145 if (ctl->nsf > 0 && atm->np == 0) {
6146 TOK(NULL, tok, "%lg", atm->sft);
6147 for (int isf = 0; isf < ctl->nsf; isf++)
6148 TOK(NULL, tok, "%lg", atm->sfeps[isf]);
6149 }
6150
6151 /* Increment data point counter... */
6152 ++atm->np;
6153 }
6154
6155 /* Close file... */
6156 fclose(in);
6157}
6158
6159/*****************************************************************************/
6160
6162 const char *filename,
6163 const ctl_t *ctl,
6164 atm_t *atm) {
6165
6166 /* Open file... */
6167 FILE *in;
6168 if (!(in = fopen(filename, "r")))
6169 ERRMSG("Cannot open file!");
6170
6171 /* Read header... */
6172 char magic[4];
6173 FREAD(magic, char,
6174 4,
6175 in);
6176 if (memcmp(magic, "ATM1", 4) != 0)
6177 ERRMSG("Invalid magic string!");
6178
6179 int ng, nw, ncl, nsf;
6180 FREAD(&ng, int,
6181 1,
6182 in);
6183 FREAD(&nw, int,
6184 1,
6185 in);
6186 FREAD(&ncl, int,
6187 1,
6188 in);
6189 FREAD(&nsf, int,
6190 1,
6191 in);
6192 if (ng != ctl->ng || nw != ctl->nw || ncl != ctl->ncl || nsf != ctl->nsf)
6193 ERRMSG("Error reading file header!");
6194
6195 /* Read data... */
6196 size_t np;
6197 FREAD(&np, size_t,
6198 1,
6199 in);
6200 atm->np = (int) np;
6201 if (atm->np > NP)
6202 ERRMSG("Too many data points!");
6203 FREAD(atm->time, double,
6204 np,
6205 in);
6206 FREAD(atm->z, double,
6207 np,
6208 in);
6209 FREAD(atm->lon, double,
6210 np,
6211 in);
6212 FREAD(atm->lat, double,
6213 np,
6214 in);
6215 FREAD(atm->p, double,
6216 np,
6217 in);
6218 FREAD(atm->t, double,
6219 np,
6220 in);
6221 for (int ig = 0; ig < ctl->ng; ig++)
6222 FREAD(atm->q[ig], double,
6223 np,
6224 in);
6225 for (int iw = 0; iw < ctl->nw; iw++)
6226 FREAD(atm->k[iw], double,
6227 np,
6228 in);
6229 if (ctl->ncl > 0) {
6230 FREAD(&atm->clz, double,
6231 1,
6232 in);
6233 FREAD(&atm->cldz, double,
6234 1,
6235 in);
6236 FREAD(atm->clk, double,
6237 (size_t) ctl->ncl,
6238 in);
6239 }
6240 if (ctl->nsf) {
6241 FREAD(&atm->sft, double,
6242 1,
6243 in);
6244 FREAD(atm->sfeps, double,
6245 (size_t) ctl->nsf,
6246 in);
6247 }
6248
6249 /* Close file... */
6250 fclose(in);
6251}
6252
6253/*****************************************************************************/
6254
6256 const char *filename,
6257 const ctl_t *ctl,
6258 atm_t *atm,
6259 int profile) {
6260
6261 int ncid, var_time, var_z, var_lon, var_lat, var_p, var_t, var_q[NG],
6262 var_k[NW], var_cz = -1, var_cdz = -1, var_ck[NCL], var_sft =
6263 -1, var_sfe[NSF], var_nlev = -1;
6264
6265 char varname[LEN];
6266
6267 /* Open file... */
6268 NC(nc_open(filename, NC_NOWRITE, &ncid));
6269
6270 /* Initialize hyperslab... */
6271 size_t start[2] = { (size_t) profile, 0 };
6272 size_t count[2] = { 1, 0 };
6273
6274 /* Determine atm->np... */
6275 NC(nc_inq_varid(ncid, "nlev", &var_nlev));
6276 NC(nc_get_vara_int(ncid, var_nlev, start, count, &atm->np));
6277 if (atm->np < 1 || atm->np > NP)
6278 ERRMSG("Number of level out of range!");
6279
6280 /* Update hyperslab... */
6281 count[1] = (size_t) atm->np;
6282
6283 /* Inquire core variables... */
6284 NC(nc_inq_varid(ncid, "time", &var_time));
6285 NC(nc_inq_varid(ncid, "z", &var_z));
6286 NC(nc_inq_varid(ncid, "lon", &var_lon));
6287 NC(nc_inq_varid(ncid, "lat", &var_lat));
6288 NC(nc_inq_varid(ncid, "p", &var_p));
6289 NC(nc_inq_varid(ncid, "t", &var_t));
6290
6291 /* Inquire emiters... */
6292 for (int ig = 0; ig < ctl->ng; ig++)
6293 NC(nc_inq_varid(ncid, ctl->emitter[ig], &var_q[ig]));
6294
6295 /* Inquire extinctions... */
6296 for (int iw = 0; iw < ctl->nw; iw++) {
6297 sprintf(varname, "ext_win_%d", iw);
6298 NC(nc_inq_varid(ncid, varname, &var_k[iw]));
6299 }
6300
6301 /* Inquire cloud variables... */
6302 if (ctl->ncl > 0) {
6303 NC(nc_inq_varid(ncid, "cld_z", &var_cz));
6304 NC(nc_inq_varid(ncid, "cld_dz", &var_cdz));
6305 for (int icl = 0; icl < ctl->ncl; icl++) {
6306 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
6307 NC(nc_inq_varid(ncid, varname, &var_ck[icl]));
6308 }
6309 }
6310
6311 /* Inquire surface variables... */
6312 if (ctl->nsf > 0) {
6313 NC(nc_inq_varid(ncid, "srf_t", &var_sft));
6314 for (int isf = 0; isf < ctl->nsf; isf++) {
6315 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
6316 NC(nc_inq_varid(ncid, varname, &var_sfe[isf]));
6317 }
6318 }
6319
6320 /* Read core variables... */
6321 NC(nc_get_vara_double(ncid, var_time, start, count, atm->time));
6322 NC(nc_get_vara_double(ncid, var_z, start, count, atm->z));
6323 NC(nc_get_vara_double(ncid, var_lon, start, count, atm->lon));
6324 NC(nc_get_vara_double(ncid, var_lat, start, count, atm->lat));
6325 NC(nc_get_vara_double(ncid, var_p, start, count, atm->p));
6326 NC(nc_get_vara_double(ncid, var_t, start, count, atm->t));
6327
6328 /* Read emitters... */
6329 for (int ig = 0; ig < ctl->ng; ig++)
6330 NC(nc_get_vara_double(ncid, var_q[ig], start, count, atm->q[ig]));
6331
6332 /* Read extinctions... */
6333 for (int iw = 0; iw < ctl->nw; iw++)
6334 NC(nc_get_vara_double(ncid, var_k[iw], start, count, atm->k[iw]));
6335
6336 /* Read cloud variables... */
6337 if (ctl->ncl > 0) {
6338 NC(nc_get_vara_double(ncid, var_cz, start, count, &atm->clz));
6339 NC(nc_get_vara_double(ncid, var_cdz, start, count, &atm->cldz));
6340 for (int icl = 0; icl < ctl->ncl; icl++)
6341 NC(nc_get_vara_double(ncid, var_ck[icl], start, count, &atm->clk[icl]));
6342 }
6343
6344 /* Read surface variables... */
6345 if (ctl->nsf > 0) {
6346 NC(nc_get_vara_double(ncid, var_sft, start, count, &atm->sft));
6347
6348 for (int isf = 0; isf < ctl->nsf; isf++)
6349 NC(nc_get_vara_double
6350 (ncid, var_sfe[isf], start, count, &atm->sfeps[isf]));
6351 }
6352
6353 /* Close file... */
6354 NC(nc_close(ncid));
6355}
6356
6357/*****************************************************************************/
6358
6360 int argc,
6361 char *argv[],
6362 ctl_t *ctl) {
6363
6364 /* Write info... */
6365 LOG(1, "\nJuelich Rapid Spectral Simulation Code (JURASSIC)\n"
6366 "(executable: %s | version: %s | compiled: %s, %s)\n",
6367 argv[0], VERSION, __DATE__, __TIME__);
6368
6369 /* Emitters... */
6370 ctl->ng = (int) scan_ctl(argc, argv, "NG", -1, "0", NULL);
6371 if (ctl->ng < 0 || ctl->ng > NG)
6372 ERRMSG("Set 0 <= NG <= MAX!");
6373 for (int ig = 0; ig < ctl->ng; ig++)
6374 scan_ctl(argc, argv, "EMITTER", ig, "", ctl->emitter[ig]);
6375 ctl->ig_co2 = find_emitter(ctl, "CO2");
6376 ctl->ig_h2o = find_emitter(ctl, "H2O");
6377 ctl->ig_n2 = find_emitter(ctl, "N2");
6378 ctl->ig_o2 = find_emitter(ctl, "O2");
6379
6380 /* Radiance channels... */
6381 ctl->nd = (int) scan_ctl(argc, argv, "ND", -1, "0", NULL);
6382 if (ctl->nd < 0 || ctl->nd > ND)
6383 ERRMSG("Set 0 <= ND <= MAX!");
6384 for (int id = 0; id < ctl->nd; id++)
6385 ctl->nu[id] = scan_ctl(argc, argv, "NU", id, "", NULL);
6386
6387 /* Spectral windows... */
6388 ctl->nw = (int) scan_ctl(argc, argv, "NW", -1, "1", NULL);
6389 if (ctl->nw < 0 || ctl->nw > NW)
6390 ERRMSG("Set 0 <= NW <= MAX!");
6391 if (ctl->nd > 0 && ctl->nw == 0)
6392 ERRMSG("Set NW > 0 when ND > 0!");
6393 for (int id = 0; id < ctl->nd; id++) {
6394 const double window = scan_ctl(argc, argv, "WINDOW", id, "0", NULL);
6395 if (!(window >= 0 && window < ctl->nw) || window != (int) window)
6396 ERRMSG("Set WINDOW[%d] to an integer in [0, NW)!", id);
6397 ctl->window[id] = (int) window;
6398 }
6399
6400 /* Cloud data... */
6401 ctl->ncl = (int) scan_ctl(argc, argv, "NCL", -1, "0", NULL);
6402 if (ctl->ncl < 0 || ctl->ncl > NCL)
6403 ERRMSG("Set 0 <= NCL <= MAX!");
6404 if (ctl->ncl == 1)
6405 ERRMSG("Set NCL > 1!");
6406 for (int icl = 0; icl < ctl->ncl; icl++)
6407 ctl->clnu[icl] = scan_ctl(argc, argv, "CLNU", icl, "", NULL);
6408
6409 /* Surface data... */
6410 ctl->nsf = (int) scan_ctl(argc, argv, "NSF", -1, "0", NULL);
6411 if (ctl->nsf < 0 || ctl->nsf > NSF)
6412 ERRMSG("Set 0 <= NSF <= MAX!");
6413 if (ctl->nsf == 1)
6414 ERRMSG("Set NSF > 1!");
6415 for (int isf = 0; isf < ctl->nsf; isf++)
6416 ctl->sfnu[isf] = scan_ctl(argc, argv, "SFNU", isf, "", NULL);
6417 ctl->sftype = (int) scan_ctl(argc, argv, "SFTYPE", -1, "2", NULL);
6418 if (ctl->sftype < 0 || ctl->sftype > 3)
6419 ERRMSG("Set 0 <= SFTYPE <= 3!");
6420 ctl->sfsza = scan_ctl(argc, argv, "SFSZA", -1, "-999", NULL);
6421
6422 /* Emissivity look-up tables... */
6423 scan_ctl(argc, argv, "TBLBASE", -1, "-", ctl->tblbase);
6424 ctl->tblfmt = (int) scan_ctl(argc, argv, "TBLFMT", -1, "1", NULL);
6425 if (ctl->tblfmt < 1 || ctl->tblfmt > 3)
6426 ERRMSG("Unknown look-up table file format, set TBLFMT to 1, 2, or 3!");
6427
6428 /* Climatological data file... */
6429 scan_ctl(argc, argv, "CLIM_FILE", -1, "-", ctl->climfile);
6430
6431 /* File formats... */
6432 ctl->atmfmt = (int) scan_ctl(argc, argv, "ATMFMT", -1, "1", NULL);
6433 if (ctl->atmfmt < 1 || ctl->atmfmt > 3)
6434 ERRMSG("Unknown atmospheric file format, set ATMFMT to 1, 2, or 3!");
6435 ctl->obsfmt = (int) scan_ctl(argc, argv, "OBSFMT", -1, "1", NULL);
6436 if (ctl->obsfmt < 1 || ctl->obsfmt > 3)
6437 ERRMSG("Unknown observation file format, set OBSFMT to 1, 2, or 3!");
6438 ctl->matrixfmt = (int) scan_ctl(argc, argv, "MATRIXFMT", -1, "1", NULL);
6439 if (ctl->matrixfmt < 1 || ctl->matrixfmt > 3)
6440 ERRMSG("Unknown matrix file format, set MATRIXFMT to 1, 2, or 3!");
6441
6442 /* Hydrostatic equilibrium... */
6443 ctl->hydz = scan_ctl(argc, argv, "HYDZ", -1, "-999", NULL);
6444
6445 /* Continua... */
6446 ctl->ctm_co2 = (int) scan_ctl(argc, argv, "CTM_CO2", -1, "1", NULL);
6447 ctl->ctm_h2o = (int) scan_ctl(argc, argv, "CTM_H2O", -1, "1", NULL);
6448 ctl->ctm_n2 = (int) scan_ctl(argc, argv, "CTM_N2", -1, "1", NULL);
6449 ctl->ctm_o2 = (int) scan_ctl(argc, argv, "CTM_O2", -1, "1", NULL);
6450
6451 /* Ray-tracing... */
6452 ctl->refrac = (int) scan_ctl(argc, argv, "REFRAC", -1, "1", NULL);
6453 ctl->rayds = scan_ctl(argc, argv, "RAYDS", -1, "10", NULL);
6454 ctl->raydz = scan_ctl(argc, argv, "RAYDZ", -1, "0.1", NULL);
6455
6456 /* Field of view... */
6457 scan_ctl(argc, argv, "FOV", -1, "-", ctl->fov);
6458 if (ctl->fov[0] != '-')
6459 read_shape(ctl->fov, ctl->fov_dz, ctl->fov_w, &ctl->fov_n);
6460
6461 /* Retrieval interface... */
6462 ctl->retp_zmin = scan_ctl(argc, argv, "RETP_ZMIN", -1, "-999", NULL);
6463 ctl->retp_zmax = scan_ctl(argc, argv, "RETP_ZMAX", -1, "-999", NULL);
6464 ctl->rett_zmin = scan_ctl(argc, argv, "RETT_ZMIN", -1, "-999", NULL);
6465 ctl->rett_zmax = scan_ctl(argc, argv, "RETT_ZMAX", -1, "-999", NULL);
6466 for (int ig = 0; ig < ctl->ng; ig++) {
6467 ctl->retq_zmin[ig] = scan_ctl(argc, argv, "RETQ_ZMIN", ig, "-999", NULL);
6468 ctl->retq_zmax[ig] = scan_ctl(argc, argv, "RETQ_ZMAX", ig, "-999", NULL);
6469 }
6470 for (int iw = 0; iw < ctl->nw; iw++) {
6471 ctl->retk_zmin[iw] = scan_ctl(argc, argv, "RETK_ZMIN", iw, "-999", NULL);
6472 ctl->retk_zmax[iw] = scan_ctl(argc, argv, "RETK_ZMAX", iw, "-999", NULL);
6473 }
6474 ctl->ret_clz = (int) scan_ctl(argc, argv, "RET_CLZ", -1, "0", NULL);
6475 ctl->ret_cldz = (int) scan_ctl(argc, argv, "RET_CLDZ", -1, "0", NULL);
6476 ctl->ret_clk = (int) scan_ctl(argc, argv, "RET_CLK", -1, "0", NULL);
6477 ctl->ret_sft = (int) scan_ctl(argc, argv, "RET_SFT", -1, "0", NULL);
6478 ctl->ret_sfeps = (int) scan_ctl(argc, argv, "RET_SFEPS", -1, "0", NULL);
6479
6480 /* Output flags... */
6481 ctl->write_bbt = (int) scan_ctl(argc, argv, "WRITE_BBT", -1, "0", NULL);
6482 ctl->write_matrix =
6483 (int) scan_ctl(argc, argv, "WRITE_MATRIX", -1, "0", NULL);
6484
6485 /* External forward models... */
6486 ctl->formod = (int) scan_ctl(argc, argv, "FORMOD", -1, "1", NULL);
6487 scan_ctl(argc, argv, "RFMBIN", -1, "-", ctl->rfmbin);
6488 scan_ctl(argc, argv, "RFMTMP", -1, "-", ctl->rfmtmp);
6489 scan_ctl(argc, argv, "RFMHIT", -1, "-", ctl->rfmhit);
6490 for (int ig = 0; ig < ctl->ng; ig++)
6491 scan_ctl(argc, argv, "RFMXSC", ig, "-", ctl->rfmxsc[ig]);
6492}
6493
6494/*****************************************************************************/
6495
6497 const char *dirname,
6498 const char *filename,
6499 const ctl_t *ctl,
6500 gsl_matrix *matrix,
6501 int dataset) {
6502
6503 /* Read ASCII data... */
6504 if (ctl->matrixfmt == 1)
6505 read_matrix_asc(dirname, filename, matrix);
6506
6507 /* Read binary data... */
6508 else if (ctl->matrixfmt == 2)
6509 read_matrix_bin(dirname, filename, matrix);
6510
6511 /* Read netCDF data... */
6512 else if (ctl->matrixfmt == 3)
6513 read_matrix_nc(dirname, filename, matrix, dataset);
6514
6515 /* Error... */
6516 else
6517 ERRMSG("Unknown matrix file format, check MATRIXFMT!");
6518}
6519
6520/*****************************************************************************/
6521
6523 const char *dirname,
6524 const char *filename,
6525 gsl_matrix *matrix) {
6526
6527 char dum[LEN], file[LEN], line[LEN];
6528
6529 double value;
6530
6531 int i, j;
6532
6533 /* Set filename... */
6534 if (dirname != NULL)
6535 sprintf(file, "%s/%s", dirname, filename);
6536 else
6537 sprintf(file, "%s", filename);
6538
6539 /* Write info... */
6540 LOG(1, "Read matrix: %s", file);
6541
6542 /* Open file... */
6543 FILE *in;
6544 if (!(in = fopen(file, "r")))
6545 ERRMSG("Cannot open file!");
6546
6547 /* Read data... */
6548 gsl_matrix_set_zero(matrix);
6549 while (fgets(line, LEN, in))
6550 if (sscanf(line, "%d %s %s %s %s %s %d %s %s %s %s %s %lg",
6551 &i, dum, dum, dum, dum, dum,
6552 &j, dum, dum, dum, dum, dum, &value) == 13)
6553 gsl_matrix_set(matrix, (size_t) i, (size_t) j, value);
6554
6555 /* Close file... */
6556 fclose(in);
6557}
6558
6559/*****************************************************************************/
6560
6562 const char *dirname,
6563 const char *filename,
6564 gsl_matrix *matrix) {
6565
6566 char file[LEN], magic[4];
6567 size_t nr, nc;
6568
6569 /* Set filename... */
6570 if (dirname != NULL)
6571 sprintf(file, "%s/%s", dirname, filename);
6572 else
6573 sprintf(file, "%s", filename);
6574
6575 /* Write info... */
6576 LOG(1, "Read matrix: %s", file);
6577
6578 /* Open file... */
6579 FILE *in;
6580 if (!(in = fopen(file, "r")))
6581 ERRMSG("Cannot open file!");
6582
6583 /* Read header... */
6584 FREAD(magic, char,
6585 4,
6586 in);
6587 if (memcmp(magic, "MAT1", 4) != 0)
6588 ERRMSG("Invalid magic string!");
6589 FREAD(&nr, size_t,
6590 1,
6591 in);
6592 FREAD(&nc, size_t,
6593 1,
6594 in);
6595 if (nr != matrix->size1 || nc != matrix->size2)
6596 ERRMSG("Error reading file header!");
6597
6598 /* Read data... */
6599 for (size_t i = 0; i < nr; i++)
6600 for (size_t j = 0; j < nc; j++) {
6601 double value;
6602 FREAD(&value, double,
6603 1,
6604 in);
6605 gsl_matrix_set(matrix, i, j, value);
6606 }
6607
6608 /* Close file... */
6609 fclose(in);
6610}
6611
6612/*****************************************************************************/
6613
6615 const char *dirname,
6616 const char *filename,
6617 gsl_matrix *matrix,
6618 int dataset) {
6619
6620 char file[LEN];
6621
6622 int ncid, dimid_row, dimid_col, varid;
6623
6624 size_t nr, nc;
6625
6626 /* Set filename... */
6627 if (dirname != NULL)
6628 sprintf(file, "%s/%s", dirname, filename);
6629 else
6630 sprintf(file, "%s", filename);
6631
6632 /* Write info... */
6633 LOG(1, "Read matrix: %s", file);
6634
6635 /* Open file... */
6636 NC(nc_open(file, NC_NOWRITE, &ncid));
6637
6638 /* Read dimensions... */
6639 NC(nc_inq_dimid(ncid, "row", &dimid_row));
6640 NC(nc_inq_dimid(ncid, "col", &dimid_col));
6641 NC(nc_inq_dimlen(ncid, dimid_row, &nr));
6642 NC(nc_inq_dimlen(ncid, dimid_col, &nc));
6643 if (nr != matrix->size1 || nc != matrix->size2)
6644 ERRMSG("Error reading file header!");
6645
6646 /* Read data... */
6647 NC(nc_inq_varid(ncid, "matrix", &varid));
6648 for (size_t i = 0; i < nr; i++)
6649 for (size_t j = 0; j < nc; j++) {
6650 double value;
6651 size_t start[3] = { (size_t) dataset, i, j };
6652 size_t count[3] = { 1, 1, 1 };
6653 NC(nc_get_vara_double(ncid, varid, start, count, &value));
6654 gsl_matrix_set(matrix, i, j, value);
6655 }
6656
6657 /* Close file... */
6658 NC(nc_close(ncid));
6659}
6660
6661/*****************************************************************************/
6662
6664 const char *dirname,
6665 const char *filename,
6666 const ctl_t *ctl,
6667 obs_t *obs,
6668 int profile) {
6669
6670 /* Set filename... */
6671 char file[LEN];
6672 if (dirname != NULL)
6673 sprintf(file, "%s/%s", dirname, filename);
6674 else
6675 sprintf(file, "%s", filename);
6676
6677 /* Write info... */
6678 LOG(1, "Read observation data: %s", file);
6679
6680 /* Read ASCII data... */
6681 if (ctl->obsfmt == 1)
6682 read_obs_asc(file, ctl, obs);
6683
6684 /* Read binary data... */
6685 else if (ctl->obsfmt == 2)
6686 read_obs_bin(file, ctl, obs);
6687
6688 /* Read netCDF data... */
6689 else if (ctl->obsfmt == 3)
6690 read_obs_nc(file, ctl, obs, profile);
6691
6692 /* Check number of points... */
6693 if (obs->nr < 1)
6694 ERRMSG("Could not read any data!");
6695
6696 /* Write info... */
6697 double mini, maxi;
6698 LOG(2, "Number of ray paths: %d", obs->nr);
6699 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
6700 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
6701 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
6702 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
6703 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
6704 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
6705 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
6706 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
6707 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
6708 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
6709 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
6710 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
6711 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
6712 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
6713 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
6714 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
6715 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
6716 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
6717 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
6718 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
6719 for (int id = 0; id < ctl->nd; id++) {
6720 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
6721 if (ctl->write_bbt) {
6722 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
6723 ctl->nu[id], mini, maxi);
6724 } else {
6725 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
6726 ctl->nu[id], mini, maxi);
6727 }
6728 }
6729 for (int id = 0; id < ctl->nd; id++) {
6730 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
6731 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
6732 ctl->nu[id], mini, maxi);
6733 }
6734}
6735
6736/*****************************************************************************/
6737
6739 const char *filename,
6740 const ctl_t *ctl,
6741 obs_t *obs) {
6742
6743 /* Init... */
6744 obs->nr = 0;
6745
6746 /* Open file... */
6747 FILE *in;
6748 if (!(in = fopen(filename, "r")))
6749 ERRMSG("Cannot open file!");
6750
6751 /* Read line... */
6752 char line[LEN], *tok;
6753 while (fgets(line, LEN, in)) {
6754
6755 /* Check capacity before writing a valid ray... */
6756 double time;
6757 TOK(line, tok, "%lg", time);
6758 if (obs->nr >= NR)
6759 ERRMSG("Too many rays!");
6760
6761 /* Read data... */
6762 obs->time[obs->nr] = time;
6763 TOK(NULL, tok, "%lg", obs->obsz[obs->nr]);
6764 TOK(NULL, tok, "%lg", obs->obslon[obs->nr]);
6765 TOK(NULL, tok, "%lg", obs->obslat[obs->nr]);
6766 TOK(NULL, tok, "%lg", obs->vpz[obs->nr]);
6767 TOK(NULL, tok, "%lg", obs->vplon[obs->nr]);
6768 TOK(NULL, tok, "%lg", obs->vplat[obs->nr]);
6769 TOK(NULL, tok, "%lg", obs->tpz[obs->nr]);
6770 TOK(NULL, tok, "%lg", obs->tplon[obs->nr]);
6771 TOK(NULL, tok, "%lg", obs->tplat[obs->nr]);
6772 for (int id = 0; id < ctl->nd; id++)
6773 TOK(NULL, tok, "%lg", obs->rad[id][obs->nr]);
6774 for (int id = 0; id < ctl->nd; id++)
6775 TOK(NULL, tok, "%lg", obs->tau[id][obs->nr]);
6776
6777 /* Increment counter... */
6778 ++obs->nr;
6779 }
6780
6781 /* Close file... */
6782 fclose(in);
6783}
6784
6785/*****************************************************************************/
6786
6788 const char *filename,
6789 const ctl_t *ctl,
6790 obs_t *obs) {
6791
6792 /* Open file... */
6793 FILE *in;
6794 if (!(in = fopen(filename, "r")))
6795 ERRMSG("Cannot open file!");
6796
6797 /* Read header... */
6798 char magic[4];
6799 FREAD(magic, char,
6800 4,
6801 in);
6802 if (memcmp(magic, "OBS1", 4) != 0)
6803 ERRMSG("Invalid magic string!");
6804
6805 int nd;
6806 FREAD(&nd, int,
6807 1,
6808 in);
6809 if (nd != ctl->nd)
6810 ERRMSG("Error reading file header!");
6811
6812 /* Read data... */
6813 size_t nr;
6814 FREAD(&nr, size_t,
6815 1,
6816 in);
6817 obs->nr = (int) nr;
6818 if (obs->nr > NR)
6819 ERRMSG("Too many ray paths!");
6820 FREAD(obs->time, double,
6821 nr,
6822 in);
6823 FREAD(obs->obsz, double,
6824 nr,
6825 in);
6826 FREAD(obs->obslon, double,
6827 nr,
6828 in);
6829 FREAD(obs->obslat, double,
6830 nr,
6831 in);
6832 FREAD(obs->vpz, double,
6833 nr,
6834 in);
6835 FREAD(obs->vplon, double,
6836 nr,
6837 in);
6838 FREAD(obs->vplat, double,
6839 nr,
6840 in);
6841 FREAD(obs->tpz, double,
6842 nr,
6843 in);
6844 FREAD(obs->tplon, double,
6845 nr,
6846 in);
6847 FREAD(obs->tplat, double,
6848 nr,
6849 in);
6850 for (int id = 0; id < ctl->nd; id++)
6851 FREAD(obs->rad[id], double,
6852 nr,
6853 in);
6854 for (int id = 0; id < ctl->nd; id++)
6855 FREAD(obs->tau[id], double,
6856 nr,
6857 in);
6858
6859 /* Close file... */
6860 fclose(in);
6861}
6862
6863/*****************************************************************************/
6864
6866 const char *filename,
6867 const ctl_t *ctl,
6868 obs_t *obs,
6869 const int profile) {
6870
6871 int ncid, var_nray = -1, var_time = -1, var_obsz = -1, var_obslon =
6872 -1, var_obslat = -1, var_vpz = -1, var_vplon = -1, var_vplat =
6873 -1, var_tpz = -1, var_tplon = -1, var_tplat =
6874 -1, var_rad[ND], var_tau[ND];
6875 const char *spec_prefix = ctl->write_bbt ? "bt" : "rad";
6876
6877 /* Open file... */
6878 NC(nc_open(filename, NC_NOWRITE, &ncid));
6879
6880 /* Initialize hyperslab... */
6881 size_t start[2] = { (size_t) profile, 0 };
6882 size_t count[2] = { 1, 0 };
6883
6884 /* Read nray(profile) -> obs->nr */
6885 NC(nc_inq_varid(ncid, "nray", &var_nray));
6886 NC(nc_get_vara_int(ncid, var_nray, start, count, &obs->nr));
6887 if (obs->nr < 1 || obs->nr > NR)
6888 ERRMSG("Number of ray paths out of range!");
6889
6890 /* Update hyperslab... */
6891 count[1] = (size_t) obs->nr;
6892
6893 /* Inquire geometry variables... */
6894 NC(nc_inq_varid(ncid, "time", &var_time));
6895 NC(nc_inq_varid(ncid, "obs_z", &var_obsz));
6896 NC(nc_inq_varid(ncid, "obs_lon", &var_obslon));
6897 NC(nc_inq_varid(ncid, "obs_lat", &var_obslat));
6898
6899 NC(nc_inq_varid(ncid, "vp_z", &var_vpz));
6900 NC(nc_inq_varid(ncid, "vp_lon", &var_vplon));
6901 NC(nc_inq_varid(ncid, "vp_lat", &var_vplat));
6902
6903 NC(nc_inq_varid(ncid, "tp_z", &var_tpz));
6904 NC(nc_inq_varid(ncid, "tp_lon", &var_tplon));
6905 NC(nc_inq_varid(ncid, "tp_lat", &var_tplat));
6906
6907 /* Inquire spectral variables per channel... */
6908 for (int id = 0; id < ctl->nd; id++) {
6909 char varname[LEN];
6910
6911 sprintf(varname, "%s_%.4f", spec_prefix, ctl->nu[id]);
6912 NC(nc_inq_varid(ncid, varname, &var_rad[id]));
6913
6914 sprintf(varname, "tau_%.4f", ctl->nu[id]);
6915 NC(nc_inq_varid(ncid, varname, &var_tau[id]));
6916 }
6917
6918 /* Read geometry... */
6919 NC(nc_get_vara_double(ncid, var_time, start, count, obs->time));
6920 NC(nc_get_vara_double(ncid, var_obsz, start, count, obs->obsz));
6921 NC(nc_get_vara_double(ncid, var_obslon, start, count, obs->obslon));
6922 NC(nc_get_vara_double(ncid, var_obslat, start, count, obs->obslat));
6923
6924 NC(nc_get_vara_double(ncid, var_vpz, start, count, obs->vpz));
6925 NC(nc_get_vara_double(ncid, var_vplon, start, count, obs->vplon));
6926 NC(nc_get_vara_double(ncid, var_vplat, start, count, obs->vplat));
6927
6928 NC(nc_get_vara_double(ncid, var_tpz, start, count, obs->tpz));
6929 NC(nc_get_vara_double(ncid, var_tplon, start, count, obs->tplon));
6930 NC(nc_get_vara_double(ncid, var_tplat, start, count, obs->tplat));
6931
6932 /* Read radiance and transmittance... */
6933 for (int id = 0; id < ctl->nd; id++) {
6934 NC(nc_get_vara_double(ncid, var_rad[id], start, count, obs->rad[id]));
6935 NC(nc_get_vara_double(ncid, var_tau[id], start, count, obs->tau[id]));
6936 }
6937
6938 /* Close file... */
6939 NC(nc_close(ncid));
6940}
6941
6942/*****************************************************************************/
6943
6945 const char *basename,
6946 const double z,
6947 const double *nu,
6948 const double *f,
6949 const int n) {
6950
6951 double *nurfm, *spec;
6952
6953 int npts;
6954
6955 /* Allocate... */
6956 ALLOC(nurfm, double,
6957 RFMNPTS);
6958 ALLOC(spec, double,
6959 RFMNPTS);
6960
6961 /* Search and read RFM spectrum... */
6962 char filename[LEN];
6963 find_rfm_file(filename, sizeof(filename), basename, z);
6964 read_rfm_spec(filename, nurfm, spec, &npts);
6965
6966 /* Convolute... */
6967 const double result = convolve_rfm(nurfm, spec, npts, nu, f, n);
6968
6969 /* Free... */
6970 free(nurfm);
6971 free(spec);
6972
6973 return result;
6974}
6975
6976/*****************************************************************************/
6977
6979 int argc,
6980 char *argv[],
6981 const ctl_t *ctl,
6982 ret_t *ret) {
6983
6984 /* Iteration control... */
6985 ret->kernel_recomp =
6986 (int) scan_ctl(argc, argv, "KERNEL_RECOMP", -1, "3", NULL);
6987 ret->conv_itmax = (int) scan_ctl(argc, argv, "CONV_ITMAX", -1, "30", NULL);
6988 ret->conv_dmin = scan_ctl(argc, argv, "CONV_DMIN", -1, "0.1", NULL);
6989
6990 /* Error analysis... */
6991 ret->err_ana = (int) scan_ctl(argc, argv, "ERR_ANA", -1, "0", NULL);
6992
6993 for (int id = 0; id < ctl->nd; id++)
6994 ret->err_formod[id] = scan_ctl(argc, argv, "ERR_FORMOD", id, "0", NULL);
6995
6996 for (int id = 0; id < ctl->nd; id++)
6997 ret->err_noise[id] = scan_ctl(argc, argv, "ERR_NOISE", id, "0", NULL);
6998
6999 ret->err_press = scan_ctl(argc, argv, "ERR_PRESS", -1, "0", NULL);
7000 ret->err_press_cz = scan_ctl(argc, argv, "ERR_PRESS_CZ", -1, "-999", NULL);
7001 ret->err_press_ch = scan_ctl(argc, argv, "ERR_PRESS_CH", -1, "-999", NULL);
7002
7003 ret->err_temp = scan_ctl(argc, argv, "ERR_TEMP", -1, "0", NULL);
7004 ret->err_temp_cz = scan_ctl(argc, argv, "ERR_TEMP_CZ", -1, "-999", NULL);
7005 ret->err_temp_ch = scan_ctl(argc, argv, "ERR_TEMP_CH", -1, "-999", NULL);
7006
7007 for (int ig = 0; ig < ctl->ng; ig++) {
7008 ret->err_q[ig] = scan_ctl(argc, argv, "ERR_Q", ig, "0", NULL);
7009 ret->err_q_cz[ig] = scan_ctl(argc, argv, "ERR_Q_CZ", ig, "-999", NULL);
7010 ret->err_q_ch[ig] = scan_ctl(argc, argv, "ERR_Q_CH", ig, "-999", NULL);
7011 }
7012
7013 for (int iw = 0; iw < ctl->nw; iw++) {
7014 ret->err_k[iw] = scan_ctl(argc, argv, "ERR_K", iw, "0", NULL);
7015 ret->err_k_cz[iw] = scan_ctl(argc, argv, "ERR_K_CZ", iw, "-999", NULL);
7016 ret->err_k_ch[iw] = scan_ctl(argc, argv, "ERR_K_CH", iw, "-999", NULL);
7017 }
7018
7019 ret->err_clz = scan_ctl(argc, argv, "ERR_CLZ", -1, "0", NULL);
7020 ret->err_cldz = scan_ctl(argc, argv, "ERR_CLDZ", -1, "0", NULL);
7021 for (int icl = 0; icl < ctl->ncl; icl++)
7022 ret->err_clk[icl] = scan_ctl(argc, argv, "ERR_CLK", icl, "0", NULL);
7023
7024 ret->err_sft = scan_ctl(argc, argv, "ERR_SFT", -1, "0", NULL);
7025 for (int isf = 0; isf < ctl->nsf; isf++)
7026 ret->err_sfeps[isf] = scan_ctl(argc, argv, "ERR_SFEPS", isf, "0", NULL);
7027
7028 /* Shared retrieval I/O... */
7029 ret->shared_io_profile = 0;
7030 scan_ctl(argc, argv, "SHARED_IO_PROFLIST", -1, "-",
7031 ret->shared_io_proflist);
7032 scan_ctl(argc, argv, "SHARED_IO_ATM_APR_FILE", -1, "-",
7034 scan_ctl(argc, argv, "SHARED_IO_OBS_MEAS_FILE", -1, "-",
7036 scan_ctl(argc, argv, "SHARED_IO_ATM_FINAL_FILE", -1, "-",
7038 scan_ctl(argc, argv, "SHARED_IO_OBS_FINAL_FILE", -1, "-",
7040 scan_ctl(argc, argv, "SHARED_IO_MATRIX_COV_APR_FILE", -1, "-",
7042 scan_ctl(argc, argv, "SHARED_IO_MATRIX_KERNEL_FILE", -1, "-",
7044 scan_ctl(argc, argv, "SHARED_IO_MATRIX_COV_RET_FILE", -1, "-",
7046 scan_ctl(argc, argv, "SHARED_IO_MATRIX_CORR_FILE", -1, "-",
7048 scan_ctl(argc, argv, "SHARED_IO_MATRIX_GAIN_FILE", -1, "-",
7050 scan_ctl(argc, argv, "SHARED_IO_MATRIX_AVK_FILE", -1, "-",
7052 scan_ctl(argc, argv, "SHARED_IO_ATM_ERR_TOTAL_FILE", -1, "-",
7054 scan_ctl(argc, argv, "SHARED_IO_ATM_ERR_NOISE_FILE", -1, "-",
7056 scan_ctl(argc, argv, "SHARED_IO_ATM_ERR_FORMOD_FILE", -1, "-",
7058 scan_ctl(argc, argv, "SHARED_IO_ATM_CONT_FILE", -1, "-",
7060 scan_ctl(argc, argv, "SHARED_IO_ATM_RES_FILE", -1, "-",
7062}
7063
7064/*****************************************************************************/
7065
7067 const char *filename,
7068 double *nu,
7069 double *rad,
7070 int *npts) {
7071
7072 char *line = NULL, *tok;
7073
7074 size_t line_buf_size = 0;
7075
7076 double dnu, nu0, nu1;
7077
7078 int ipts = 0;
7079
7080 /* Write info... */
7081 LOG(1, "Read RFM data: %s", filename);
7082
7083 /* Open file... */
7084 FILE *in;
7085 if (!(in = fopen(filename, "r")))
7086 ERRMSG("Cannot open file!");
7087
7088 /* Read header... */
7089 for (int i = 0; i < 4; i++)
7090 if (getline(&line, &line_buf_size, in) == -1)
7091 ERRMSG("Error while reading file header!");
7092 if (sscanf(line, "%d %lg %lg %lg", npts, &nu0, &dnu, &nu1) != 4)
7093 ERRMSG("Invalid spectrum header format!");
7094
7095 /* Check number of spectral grid points... */
7096 if (*npts < 2)
7097 ERRMSG("RFM spectrum must contain at least two spectral points!");
7098 if (*npts > RFMNPTS)
7099 ERRMSG("Too many spectral grid points!");
7100
7101 /* Read radiance data... */
7102 while (getline(&line, &line_buf_size, in) != -1 && ipts < *npts) {
7103 tok = strtok(line, " \t\n");
7104 while (tok != NULL && ipts < *npts) {
7105 if (sscanf(tok, "%lg", &rad[ipts]) == 1)
7106 ipts++;
7107 tok = strtok(NULL, " \t\n");
7108 }
7109 }
7110
7111 /* Check number of spectral grid points... */
7112 if (ipts != *npts)
7113 ERRMSG("Error while reading RFM data!");
7114
7115 /* Compute wavenumbers... */
7116 for (ipts = 0; ipts < *npts; ipts++)
7117 nu[ipts] = LIN(0.0, nu0, (double) (*npts - 1), nu1, (double) ipts);
7118
7119 /* Close file... */
7120 fclose(in);
7121
7122 /* Free.. */
7123 free(line);
7124}
7125
7126/*****************************************************************************/
7127
7129 const char *filename,
7130 double *x,
7131 double *y,
7132 int *n) {
7133
7134 char line[LEN];
7135
7136 /* Write info... */
7137 LOG(1, "Read shape function: %s", filename);
7138
7139 /* Open file... */
7140 FILE *in;
7141 if (!(in = fopen(filename, "r")))
7142 ERRMSG("Cannot open file!");
7143
7144 /* Read data... */
7145 *n = 0;
7146 while (fgets(line, LEN, in)) {
7147 double xval, yval;
7148 if (sscanf(line, "%lg %lg", &xval, &yval) == 2) {
7149 if (*n >= NSHAPE)
7150 ERRMSG("Too many data points!");
7151 x[*n] = xval;
7152 y[*n] = yval;
7153 ++(*n);
7154 }
7155 }
7156
7157 /* Close file... */
7158 fclose(in);
7159
7160 /* Check number of data points... */
7161 if (*n < 2)
7162 ERRMSG("Could not read any data!");
7163
7164 /* Write info... */
7165 double mini, maxi;
7166 LOG(2, "Number of data points: %d", *n);
7167 gsl_stats_minmax(&mini, &maxi, x, 1, (size_t) *n);
7168 LOG(2, "Range of x values: %.4f ... %.4f", mini, maxi);
7169 gsl_stats_minmax(&mini, &maxi, y, 1, (size_t) *n);
7170 LOG(2, "Range of y values: %g ... %g", mini, maxi);
7171}
7172
7173/*****************************************************************************/
7174
7176 const ctl_t *ctl) {
7177
7178 /* Allocate... */
7179 tbl_t *tbl;
7180 ALLOC(tbl, tbl_t, 1);
7181
7182 /* Initialize filter function sizes... */
7183 for (int id = 0; id < ctl->nd; id++)
7184 tbl->filt_n[id] = 0;
7185
7186 /* Loop over trace gases... */
7187 for (int ig = 0; ig < ctl->ng; ig++) {
7188
7189 /* Read ASCII look-up tables... */
7190 if (ctl->tblfmt == 1)
7191 for (int id = 0; id < ctl->nd; id++) {
7192 read_tbl_asc(ctl, tbl, id, ig);
7193 TBL_LOG(tbl, id, ig);
7194 }
7195
7196 /* Read binary look-up tables... */
7197 else if (ctl->tblfmt == 2)
7198 for (int id = 0; id < ctl->nd; id++) {
7199 read_tbl_bin(ctl, tbl, id, ig);
7200 TBL_LOG(tbl, id, ig);
7201 }
7202
7203 /* Read netCDF look-up tables... */
7204 else if (ctl->tblfmt == 3) {
7205
7206 /* Open file... */
7207 int ncid;
7208 char filename[2 * LEN];
7209 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
7210 if (nc_open(filename, NC_NOWRITE, &ncid) != NC_NOERR) {
7211 WARN("Missing emissivity table: %s", filename);
7212 continue;
7213 } else
7214 LOG(1, "Read emissivity table: %s", filename);
7215
7216 /* Read channels... */
7217 for (int id = 0; id < ctl->nd; id++) {
7218 read_tbl_nc_channel(ctl, tbl, id, ig, ncid);
7219 TBL_LOG(tbl, id, ig);
7220 }
7221
7222 /* Close file... */
7223 NC(nc_close(ncid));
7224 }
7225 }
7226
7227 /* Calculate log-pressure... */
7228 for (int id = 0; id < ctl->nd; id++)
7229 for (int ig = 0; ig < ctl->ng; ig++)
7230 for (int ip = 0; ip < tbl->np[id][ig]; ip++)
7231 tbl->lnp[id][ig][ip] = log(tbl->p[id][ig][ip]);
7232
7233 /* Read filter functions... */
7234 if (ctl->tblfmt == 1)
7235 for (int id = 0; id < ctl->nd; id++) {
7236 char filename[2 * LEN];
7237 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
7238 read_shape(filename, tbl->filt_nu[id], tbl->filt_f[id],
7239 &tbl->filt_n[id]);
7240 }
7241
7242 /* Initialize source function lookup tables... */
7243 init_srcfunc(ctl, tbl);
7244
7245 /* Return pointer... */
7246 return tbl;
7247}
7248
7249/*****************************************************************************/
7250
7252 const ctl_t *ctl,
7253 tbl_t *tbl,
7254 const int id,
7255 const int ig) {
7256
7257 /* Initialize... */
7258 double eps, eps_old = -999, press, press_old = -999, temp,
7259 temp_old = -999, u, u_old = -999;
7260 int nrange = 0;
7261
7262 /* Set filename... */
7263 char filename[2 * LEN];
7264 sprintf(filename, "%s_%.4f_%s.tab", ctl->tblbase,
7265 ctl->nu[id], ctl->emitter[ig]);
7266
7267 /* Open file... */
7268 FILE *in;
7269 if (!(in = fopen(filename, "r"))) {
7270 WARN("Missing emissivity table: %s", filename);
7271 return;
7272 } else
7273 LOG(1, "Read emissivity table: %s", filename);
7274
7275 /* Init pressure level counter... */
7276 tbl->np[id][ig] = -1;
7277
7278 /* Read data... */
7279 char line[LEN];
7280 while (fgets(line, LEN, in)) {
7281
7282 /* Parse line... */
7283 if (sscanf(line, "%lg %lg %lg %lg", &press, &temp, &u, &eps) != 4)
7284 continue;
7285
7286 /* Check ranges... */
7287 if (u < UMIN || u > UMAX || eps < EPSMIN || eps > EPSMAX) {
7288 nrange++;
7289 continue;
7290 }
7291
7292 /* Determine pressure index... */
7293 if (press != press_old) {
7294 press_old = press;
7295 if ((++tbl->np[id][ig]) >= TBLNP)
7296 ERRMSG("Too many pressure levels!");
7297 tbl->nt[id][ig][tbl->np[id][ig]] = -1;
7298 }
7299
7300 /* Determine temperature index... */
7301 if (temp != temp_old) {
7302 temp_old = temp;
7303 if ((++tbl->nt[id][ig][tbl->np[id][ig]]) >= TBLNT)
7304 ERRMSG("Too many temperatures!");
7305 tbl->nu[id][ig][tbl->np[id][ig]]
7306 [tbl->nt[id][ig][tbl->np[id][ig]]] = -1;
7307
7308 /* Reset dynamic arrays for this (ip,it) node... */
7309 tbl->logu[id][ig][tbl->np[id][ig]]
7310 [tbl->nt[id][ig][tbl->np[id][ig]]] = NULL;
7311 tbl->logeps[id][ig][tbl->np[id][ig]]
7312 [tbl->nt[id][ig][tbl->np[id][ig]]] = NULL;
7313 }
7314
7315 /* Determine column density index... */
7316 if ((eps > eps_old && u > u_old) || tbl->nu[id][ig][tbl->np[id][ig]]
7317 [tbl->nt[id][ig][tbl->np[id][ig]]] < 0) {
7318 eps_old = eps;
7319 u_old = u;
7320 if ((++tbl->nu[id][ig][tbl->np[id][ig]]
7321 [tbl->nt[id][ig][tbl->np[id][ig]]]) >= TBLNU)
7322 ERRMSG("Too many column densities!");
7323
7324 /* Grow dynamic arrays (nu is used as an index during reading). */
7325 const int ip = tbl->np[id][ig];
7326 const int it = tbl->nt[id][ig][ip];
7327 const int iu = tbl->nu[id][ig][ip][it];
7328 const size_t nnew = (size_t) (iu + 1);
7329
7330 float *tmp = (float *) realloc(tbl->logu[id][ig][ip][it],
7331 nnew * sizeof(float));
7332 if (!tmp)
7333 ERRMSG("Out of memory!");
7334 tbl->logu[id][ig][ip][it] = tmp;
7335
7336 tmp =
7337 (float *) realloc(tbl->logeps[id][ig][ip][it], nnew * sizeof(float));
7338 if (!tmp)
7339 ERRMSG("Out of memory!");
7340 tbl->logeps[id][ig][ip][it] = tmp;
7341 }
7342
7343 /* Store data... */
7344 tbl->p[id][ig][tbl->np[id][ig]] = press;
7345 tbl->t[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
7346 = temp;
7347 tbl->logu[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
7348 [tbl->nu[id][ig][tbl->np[id][ig]]
7349 [tbl->nt[id][ig][tbl->np[id][ig]]]] = (float) log(u);
7350 tbl->logeps[id][ig][tbl->np[id][ig]][tbl->nt[id][ig][tbl->np[id][ig]]]
7351 [tbl->nu[id][ig][tbl->np[id][ig]]
7352 [tbl->nt[id][ig][tbl->np[id][ig]]]] = (float) log(eps);
7353 }
7354
7355 /* Increment counters... */
7356 tbl->np[id][ig]++;
7357 for (int ip = 0; ip < tbl->np[id][ig]; ip++) {
7358 tbl->nt[id][ig][ip]++;
7359 for (int it = 0; it < tbl->nt[id][ig][ip]; it++)
7360 tbl->nu[id][ig][ip][it]++;
7361 }
7362
7363 /* Check ranges... */
7364 if (nrange > 0)
7365 WARN("Column density or emissivity out of range (%d data points)!",
7366 nrange);
7367
7368 /* Close file... */
7369 fclose(in);
7370}
7371
7372/*****************************************************************************/
7373
7375 const ctl_t *ctl,
7376 tbl_t *tbl,
7377 const int id,
7378 const int ig) {
7379
7380 /* Set filename... */
7381 char filename[2 * LEN];
7382 sprintf(filename, "%s_%.4f_%s.bin",
7383 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
7384
7385 /* Open file... */
7386 FILE *in = fopen(filename, "rb");
7387 if (!in) {
7388 WARN("Missing emissivity table: %s", filename);
7389 return;
7390 } else
7391 LOG(1, "Read emissivity table: %s", filename);
7392
7393 /* Read length.. */
7394 size_t nbytes;
7395 FREAD(&nbytes, size_t,
7396 1,
7397 in);
7398 if (nbytes <= 0)
7399 ERRMSG("Invalid packed table size!");
7400
7401 /* Read packed blob... */
7402 uint8_t *work = NULL;
7403 ALLOC(work, uint8_t, nbytes);
7404 FREAD(work, uint8_t, nbytes, in);
7405
7406 /* Unpack... */
7407 tbl_unpack(tbl, id, ig, work);
7408
7409 /* Close file... */
7410 fclose(in);
7411
7412 /* Free... */
7413 free(work);
7414}
7415
7416/*****************************************************************************/
7417
7419 const ctl_t *ctl,
7420 tbl_t *tbl,
7421 int id,
7422 int ig,
7423 int ncid) {
7424
7425 char varname[LEN];
7426
7427 int varid, dimid;
7428
7429 size_t nbytes;
7430
7431 /* Inquire variable... */
7432 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
7433 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
7434 WARN("Missing emissivity table: %s", varname);
7435 return;
7436 } else
7437 LOG(1, "Read emissivity table: %s", varname);
7438 NC(nc_inq_vardimid(ncid, varid, &dimid));
7439 NC(nc_inq_dimlen(ncid, dimid, &nbytes));
7440
7441 /* Read variable... */
7442 uint8_t *work = NULL;
7443 ALLOC(work, uint8_t, nbytes);
7444 NC(nc_get_var_uchar(ncid, varid, (unsigned char *) work));
7445
7446 /* Unpack... */
7447 tbl_unpack(tbl, id, ig, work);
7448
7449 /* Free... */
7450 free(work);
7451}
7452
7453/*****************************************************************************/
7454
7456 int argc,
7457 char *argv[],
7458 const char *varname,
7459 const int arridx,
7460 const char *defvalue,
7461 char *value) {
7462
7463 char dummy[LEN], fullname1[LEN], fullname2[LEN], line[LEN],
7464 rvarname[LEN], rval[LEN];
7465
7466 int contain = 0;
7467
7468 /* Open file... */
7469 FILE *in = NULL;
7470 if (argv[1][0] != '-')
7471 if (!(in = fopen(argv[1], "r")))
7472 ERRMSG("Cannot open file!");
7473
7474 /* Set full variable name... */
7475 if (arridx >= 0) {
7476 sprintf(fullname1, "%s[%d]", varname, arridx);
7477 sprintf(fullname2, "%s[*]", varname);
7478 } else {
7479 sprintf(fullname1, "%s", varname);
7480 sprintf(fullname2, "%s", varname);
7481 }
7482
7483 /* Read data... */
7484 if (in != NULL)
7485 while (fgets(line, LEN, in))
7486 if (sscanf(line, "%s %s %s", rvarname, dummy, rval) == 3)
7487 if (strcasecmp(rvarname, fullname1) == 0 ||
7488 strcasecmp(rvarname, fullname2) == 0) {
7489 contain = 1;
7490 break;
7491 }
7492 for (int i = 1; i < argc - 1; i++)
7493 if (strcasecmp(argv[i], fullname1) == 0 ||
7494 strcasecmp(argv[i], fullname2) == 0) {
7495 sprintf(rval, "%s", argv[i + 1]);
7496 contain = 1;
7497 break;
7498 }
7499
7500 /* Close file... */
7501 if (in != NULL)
7502 fclose(in);
7503
7504 /* Check for missing variables... */
7505 if (!contain) {
7506 if (strlen(defvalue) > 0)
7507 sprintf(rval, "%s", defvalue);
7508 else
7509 ERRMSG("Missing variable %s!\n", fullname1);
7510 }
7511
7512 /* Write info... */
7513 LOG(1, "%s = %s", fullname1, rval);
7514
7515 /* Return values... */
7516 if (value != NULL)
7517 sprintf(value, "%s", rval);
7518 return atof(rval);
7519}
7520
7521/*****************************************************************************/
7522
7524 const ret_t *ret,
7525 const ctl_t *ctl,
7526 const atm_t *atm,
7527 const int *iqa,
7528 const int *ipa,
7529 gsl_matrix *s_a) {
7530
7531 /* Get sizes... */
7532 const size_t n = s_a->size1;
7533
7534 /* Allocate... */
7535 gsl_vector *x_a = gsl_vector_alloc(n);
7536
7537 /* Get sigma vector... */
7538 atm2x(ctl, atm, x_a, NULL, NULL);
7539 for (size_t i = 0; i < n; i++) {
7540 if (iqa[i] == IDXP)
7541 gsl_vector_set(x_a, i, ret->err_press / 100 * gsl_vector_get(x_a, i));
7542 if (iqa[i] == IDXT)
7543 gsl_vector_set(x_a, i, ret->err_temp);
7544 for (int ig = 0; ig < ctl->ng; ig++)
7545 if (iqa[i] == IDXQ(ig))
7546 gsl_vector_set(x_a, i, ret->err_q[ig] / 100 * gsl_vector_get(x_a, i));
7547 for (int iw = 0; iw < ctl->nw; iw++)
7548 if (iqa[i] == IDXK(iw))
7549 gsl_vector_set(x_a, i, ret->err_k[iw]);
7550 if (iqa[i] == IDXCLZ)
7551 gsl_vector_set(x_a, i, ret->err_clz);
7552 if (iqa[i] == IDXCLDZ)
7553 gsl_vector_set(x_a, i, ret->err_cldz);
7554 for (int icl = 0; icl < ctl->ncl; icl++)
7555 if (iqa[i] == IDXCLK(icl))
7556 gsl_vector_set(x_a, i, ret->err_clk[icl]);
7557 if (iqa[i] == IDXSFT)
7558 gsl_vector_set(x_a, i, ret->err_sft);
7559 for (int isf = 0; isf < ctl->nsf; isf++)
7560 if (iqa[i] == IDXSFEPS(isf))
7561 gsl_vector_set(x_a, i, ret->err_sfeps[isf]);
7562 }
7563
7564 /* Check standard deviations... */
7565 for (size_t i = 0; i < n; i++)
7566 if (POW2(gsl_vector_get(x_a, i)) <= 0)
7567 ERRMSG("Check a priori data (zero standard deviation)!");
7568
7569 /* Initialize diagonal covariance... */
7570 gsl_matrix_set_zero(s_a);
7571 for (size_t i = 0; i < n; i++)
7572 gsl_matrix_set(s_a, i, i, POW2(gsl_vector_get(x_a, i)));
7573
7574 /* Loop over matrix elements... */
7575 for (size_t i = 0; i < n; i++)
7576 for (size_t j = 0; j < n; j++)
7577 if (i != j && iqa[i] == iqa[j]) {
7578
7579 /* Initialize... */
7580 double cz = 0;
7581 double ch = 0;
7582
7583 /* Set correlation lengths for pressure... */
7584 if (iqa[i] == IDXP) {
7585 cz = ret->err_press_cz;
7586 ch = ret->err_press_ch;
7587 }
7588
7589 /* Set correlation lengths for temperature... */
7590 if (iqa[i] == IDXT) {
7591 cz = ret->err_temp_cz;
7592 ch = ret->err_temp_ch;
7593 }
7594
7595 /* Set correlation lengths for volume mixing ratios... */
7596 for (int ig = 0; ig < ctl->ng; ig++)
7597 if (iqa[i] == IDXQ(ig)) {
7598 cz = ret->err_q_cz[ig];
7599 ch = ret->err_q_ch[ig];
7600 }
7601
7602 /* Set correlation lengths for extinction... */
7603 for (int iw = 0; iw < ctl->nw; iw++)
7604 if (iqa[i] == IDXK(iw)) {
7605 cz = ret->err_k_cz[iw];
7606 ch = ret->err_k_ch[iw];
7607 }
7608
7609 /* Compute correlations... */
7610 if (cz > 0 && ch > 0) {
7611
7612 /* Get Cartesian coordinates... */
7613 double x0[3], x1[3];
7614 geo2cart(0, atm->lon[ipa[i]], atm->lat[ipa[i]], x0);
7615 geo2cart(0, atm->lon[ipa[j]], atm->lat[ipa[j]], x1);
7616
7617 /* Compute correlations... */
7618 const double rho =
7619 exp(-DIST(x0, x1) / ch -
7620 fabs(atm->z[ipa[i]] - atm->z[ipa[j]]) / cz);
7621
7622 /* Set covariance... */
7623 gsl_matrix_set(s_a, i, j, gsl_vector_get(x_a, i)
7624 * gsl_vector_get(x_a, j) * rho);
7625 }
7626 }
7627
7628 /* Free... */
7629 gsl_vector_free(x_a);
7630}
7631
7632/*****************************************************************************/
7633
7635 const ret_t *ret,
7636 const ctl_t *ctl,
7637 const obs_t *obs,
7638 gsl_vector *sig_noise,
7639 gsl_vector *sig_formod,
7640 gsl_vector *sig_eps_inv) {
7641
7642 /* Allocate... */
7643 obs_t *obs_err;
7644 ALLOC(obs_err, obs_t, 1);
7645
7646 /* Get size... */
7647 const size_t m = sig_eps_inv->size;
7648
7649 /* Noise error (always considered in retrieval fit)... */
7650 copy_obs(ctl, obs_err, obs, 1);
7651 for (int ir = 0; ir < obs_err->nr; ir++)
7652 for (int id = 0; id < ctl->nd; id++)
7653 obs_err->rad[id][ir]
7654 = (isfinite(obs->rad[id][ir]) ? ret->err_noise[id] : NAN);
7655 obs2y(ctl, obs_err, sig_noise, NULL, NULL);
7656
7657 /* Forward model error (always considered in retrieval fit)... */
7658 copy_obs(ctl, obs_err, obs, 1);
7659 for (int ir = 0; ir < obs_err->nr; ir++)
7660 for (int id = 0; id < ctl->nd; id++)
7661 obs_err->rad[id][ir]
7662 = fabs(ret->err_formod[id] / 100 * obs->rad[id][ir]);
7663 obs2y(ctl, obs_err, sig_formod, NULL, NULL);
7664
7665 /* Total error... */
7666 for (size_t i = 0; i < m; i++)
7667 gsl_vector_set(sig_eps_inv, i, 1 / sqrt(POW2(gsl_vector_get(sig_noise, i))
7668 +
7669 POW2(gsl_vector_get
7670 (sig_formod, i))));
7671
7672 /* Check standard deviations... */
7673 for (size_t i = 0; i < m; i++)
7674 if (gsl_vector_get(sig_eps_inv, i) <= 0)
7675 ERRMSG("Check measurement errors (zero standard deviation)!");
7676
7677 /* Free... */
7678 free(obs_err);
7679}
7680
7681/*****************************************************************************/
7682
7684 const ret_t *ret,
7685 const char *shared_file,
7686 const char *legacy_file,
7687 const char **dirname,
7688 int *profile) {
7689
7690 if (shared_file[0] != '-') {
7691 *dirname = NULL;
7692 *profile = ret->shared_io_profile;
7693 return shared_file;
7694 }
7695
7696 *dirname = ret->dir;
7697 *profile = 0;
7698 return legacy_file;
7699}
7700
7701/*****************************************************************************/
7702
7704 const ret_t *ret,
7705 const char *shared_file,
7706 const char *legacy_file,
7707 const char **dirname,
7708 int *profile) {
7709
7710 if (shared_file[0] != '-') {
7711 *dirname = NULL;
7712 *profile = ret->shared_io_profile;
7713 return shared_file;
7714 }
7715
7716 *dirname = ret->dir;
7717 *profile = 0;
7718 return legacy_file;
7719}
7720
7721/*****************************************************************************/
7722
7724 const ret_t *ret) {
7725
7726 const char *base = shared_io_output_file(ret);
7727 if (base == NULL)
7728 return -1;
7729
7730 char lockfile[LEN];
7731 if (snprintf(lockfile, LEN, "%s.lock", base) >= LEN)
7732 ERRMSG("Lock file name too long!");
7733 int fd = open(lockfile, O_CREAT | O_RDWR, 0666);
7734 if (fd < 0)
7735 ERRMSG("Cannot open lock file!");
7736
7737 struct flock fl;
7738 fl.l_type = F_WRLCK;
7739 fl.l_whence = SEEK_SET;
7740 fl.l_start = 0;
7741 fl.l_len = 0;
7742 if (fcntl(fd, F_SETLKW, &fl) < 0)
7743 ERRMSG("Cannot lock shared output file!");
7744
7745 return fd;
7746}
7747
7748/*****************************************************************************/
7749
7751 int fd) {
7752
7753 if (fd < 0)
7754 return;
7755
7756 struct flock fl;
7757 fl.l_type = F_UNLCK;
7758 fl.l_whence = SEEK_SET;
7759 fl.l_start = 0;
7760 fl.l_len = 0;
7761 if (fcntl(fd, F_SETLK, &fl) < 0)
7762 ERRMSG("Cannot unlock shared output file!");
7763 close(fd);
7764}
7765
7766/*****************************************************************************/
7767
7769 const ret_t *ret) {
7770
7771 if (ret->shared_io_atm_final_file[0] != '-')
7772 return ret->shared_io_atm_final_file;
7773 if (ret->shared_io_obs_final_file[0] != '-')
7774 return ret->shared_io_obs_final_file;
7775 if (ret->shared_io_matrix_cov_apr_file[0] != '-')
7777 if (ret->shared_io_matrix_kernel_file[0] != '-')
7778 return ret->shared_io_matrix_kernel_file;
7779 if (ret->shared_io_matrix_cov_ret_file[0] != '-')
7781 if (ret->shared_io_matrix_corr_file[0] != '-')
7782 return ret->shared_io_matrix_corr_file;
7783 if (ret->shared_io_matrix_gain_file[0] != '-')
7784 return ret->shared_io_matrix_gain_file;
7785 if (ret->shared_io_matrix_avk_file[0] != '-')
7786 return ret->shared_io_matrix_avk_file;
7787 if (ret->shared_io_atm_err_total_file[0] != '-')
7788 return ret->shared_io_atm_err_total_file;
7789 if (ret->shared_io_atm_err_noise_file[0] != '-')
7790 return ret->shared_io_atm_err_noise_file;
7791 if (ret->shared_io_atm_err_formod_file[0] != '-')
7793 if (ret->shared_io_atm_cont_file[0] != '-')
7794 return ret->shared_io_atm_cont_file;
7795 if (ret->shared_io_atm_res_file[0] != '-')
7796 return ret->shared_io_atm_res_file;
7797 return NULL;
7798}
7799
7800/*****************************************************************************/
7801
7803 const los_t *los,
7804 double *tpz,
7805 double *tplon,
7806 double *tplat) {
7807
7808 /* Find minimum altitude... */
7809 const size_t ip = gsl_stats_min_index(los->z, 1, (size_t) los->np);
7810
7811 /* Nadir or zenith... */
7812 if (ip <= 0 || ip >= (size_t) los->np - 1) {
7813 *tpz = los->z[los->np - 1];
7814 *tplon = los->lon[los->np - 1];
7815 *tplat = los->lat[los->np - 1];
7816 }
7817
7818 /* Limb... */
7819 else {
7820
7821 /* Determine interpolating polynomial y=a*x^2+b*x+c... */
7822 const double yy0 = los->z[ip - 1];
7823 const double yy1 = los->z[ip];
7824 const double yy2 = los->z[ip + 1];
7825 const double x1 = sqrt(POW2(los->ds[ip]) - POW2(yy1 - yy0));
7826 const double x2 = x1 + sqrt(POW2(los->ds[ip + 1]) - POW2(yy2 - yy1));
7827 const double a = 1 / (x1 - x2) * (-(yy0 - yy1) / x1 + (yy0 - yy2) / x2);
7828 const double b = -(yy0 - yy1) / x1 - a * x1;
7829 const double c = yy0;
7830
7831 /* Get tangent point location... */
7832 double dummy, v[3], v0[3], v2[3];
7833 const double x = -b / (2 * a);
7834 *tpz = a * x * x + b * x + c;
7835 geo2cart(los->z[ip - 1], los->lon[ip - 1], los->lat[ip - 1], v0);
7836 geo2cart(los->z[ip + 1], los->lon[ip + 1], los->lat[ip + 1], v2);
7837 for (int i = 0; i < 3; i++)
7838 v[i] = LIN(0.0, v0[i], x2, v2[i], x);
7839 cart2geo(v, &dummy, tplon, tplat);
7840 }
7841}
7842
7843/*****************************************************************************/
7844
7846 const ctl_t *ctl,
7847 tbl_t *tbl) {
7848
7849 /* Check pointer... */
7850 if (!tbl)
7851 return;
7852
7853 /* Loop over channels and emitters... */
7854 for (int id = 0; id < ctl->nd; id++)
7855 for (int ig = 0; ig < ctl->ng; ig++) {
7856
7857 /* Check number of pressure levels... */
7858 const int np = tbl->np[id][ig];
7859 if (np < 0)
7860 continue;
7861
7862 /* Loop over pressure levels... */
7863 for (int ip = 0; ip < np; ip++) {
7864
7865 /* Loop over temperature levels... */
7866 const int nt = tbl->nt[id][ig][ip];
7867 for (int it = 0; it < nt; it++) {
7868
7869 /* Free... */
7870 free(tbl->logu[id][ig][ip][it]);
7871 free(tbl->logeps[id][ig][ip][it]);
7872 tbl->logu[id][ig][ip][it] = NULL;
7873 tbl->logeps[id][ig][ip][it] = NULL;
7874 }
7875 }
7876 }
7877
7878 /* Free... */
7879 free(tbl);
7880}
7881
7882/*****************************************************************************/
7883
7885 const tbl_t *tbl,
7886 int id,
7887 int ig,
7888 uint8_t *buf,
7889 size_t *bytes_used) {
7890
7891 uint8_t *cur = buf;
7892
7893 /* Pack lookup table... */
7894 int np = tbl->np[id][ig];
7895 memcpy(cur, &np, sizeof(np));
7896 cur += sizeof(np);
7897
7898 memcpy(cur, tbl->p[id][ig], (size_t) np * sizeof(double));
7899 cur += ((size_t) np * sizeof(double));
7900
7901 for (int ip = 0; ip < np; ip++) {
7902 int nt = tbl->nt[id][ig][ip];
7903 memcpy(cur, &nt, sizeof(nt));
7904 cur += sizeof(nt);
7905
7906 memcpy(cur, tbl->t[id][ig][ip], (size_t) nt * sizeof(double));
7907 cur += ((size_t) nt * sizeof(double));
7908
7909 for (int it = 0; it < nt; it++) {
7910 int nu = tbl->nu[id][ig][ip][it];
7911 memcpy(cur, &nu, sizeof(nu));
7912 cur += sizeof(nu);
7913
7914 memcpy(cur, tbl->logu[id][ig][ip][it], (size_t) nu * sizeof(float));
7915 cur += ((size_t) nu * sizeof(float));
7916
7917 memcpy(cur, tbl->logeps[id][ig][ip][it], (size_t) nu * sizeof(float));
7918 cur += ((size_t) nu * sizeof(float));
7919 }
7920 }
7921
7922 /* Pack filter function... */
7923 const int n = tbl->filt_n[id];
7924 memcpy(cur, &n, sizeof(n));
7925 cur += sizeof(n);
7926
7927 memcpy(cur, tbl->filt_nu[id], (size_t) n * sizeof(double));
7928 cur += ((size_t) n * sizeof(double));
7929
7930 memcpy(cur, tbl->filt_f[id], (size_t) n * sizeof(double));
7931 cur += ((size_t) n * sizeof(double));
7932
7933 *bytes_used = (size_t) (cur - buf);
7934}
7935
7936/*****************************************************************************/
7937
7939 const tbl_t *tbl,
7940 int id,
7941 int ig) {
7942
7943 size_t bytes = 0;
7944
7945 /* Size of lookup table... */
7946 const int np = tbl->np[id][ig];
7947 bytes += sizeof(int);
7948 bytes += ((size_t) np * sizeof(double));
7949
7950 for (int ip = 0; ip < np; ip++) {
7951 const int nt = tbl->nt[id][ig][ip];
7952 bytes += sizeof(int);
7953 bytes += ((size_t) nt * sizeof(double));
7954
7955 for (int it = 0; it < nt; it++) {
7956 const int nu = tbl->nu[id][ig][ip][it];
7957 bytes += sizeof(int);
7958 bytes += (2 * (size_t) nu * sizeof(float));
7959 }
7960 }
7961
7962 /* Size of filter function... */
7963 const int n = tbl->filt_n[id];
7964 bytes += sizeof(int);
7965 bytes += (2 * (size_t) n * sizeof(double));
7966
7967 return bytes;
7968}
7969
7970/*****************************************************************************/
7971
7973 tbl_t *tbl,
7974 int id,
7975 int ig,
7976 const uint8_t *buf) {
7977
7978 const uint8_t *cur = buf;
7979
7980 /* Unpack lookup table... */
7981 int np;
7982 memcpy(&np, cur, sizeof(np));
7983 cur += sizeof(np);
7984
7985 if (np < 0 || np > TBLNP)
7986 ERRMSG("np out of range!");
7987 tbl->np[id][ig] = np;
7988
7989 memcpy(tbl->p[id][ig], cur, (size_t) np * sizeof(double));
7990 cur += ((size_t) np * sizeof(double));
7991
7992 for (int ip = 0; ip < np; ip++) {
7993
7994 int nt;
7995 memcpy(&nt, cur, sizeof(nt));
7996 cur += sizeof(nt);
7997
7998 if (nt < 0 || nt > TBLNT)
7999 ERRMSG("nt out of range!");
8000 tbl->nt[id][ig][ip] = nt;
8001
8002 memcpy(tbl->t[id][ig][ip], cur, (size_t) nt * sizeof(double));
8003 cur += ((size_t) nt * sizeof(double));
8004
8005 for (int it = 0; it < nt; it++) {
8006
8007 int nu;
8008 memcpy(&nu, cur, sizeof(nu));
8009 cur += sizeof(nu);
8010
8011 if (nu < 0 || nu > TBLNU)
8012 ERRMSG("nu out of range!");
8013 tbl->nu[id][ig][ip][it] = nu;
8014
8015 ALLOC(tbl->logu[id][ig][ip][it], float,
8016 nu);
8017 ALLOC(tbl->logeps[id][ig][ip][it], float,
8018 nu);
8019
8020 memcpy(tbl->logu[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
8021 cur += ((size_t) nu * sizeof(float));
8022
8023 memcpy(tbl->logeps[id][ig][ip][it], cur, (size_t) nu * sizeof(float));
8024 cur += ((size_t) nu * sizeof(float));
8025 }
8026 }
8027
8028 /* Unpack filter function... */
8029 int n;
8030 memcpy(&n, cur, sizeof(n));
8031 cur += sizeof(n);
8032
8033 if (n < 2 || n > NSHAPE)
8034 ERRMSG("Missing or invalid filter function (filt_n) in packed table!");
8035 tbl->filt_n[id] = n;
8036
8037 memcpy(tbl->filt_nu[id], cur, (size_t) n * sizeof(double));
8038 cur += ((size_t) n * sizeof(double));
8039
8040 memcpy(tbl->filt_f[id], cur, (size_t) n * sizeof(double));
8041 cur += ((size_t) n * sizeof(double));
8042
8043 return (size_t) (cur - buf);
8044}
8045
8046/*****************************************************************************/
8047
8049 const int year,
8050 const int mon,
8051 const int day,
8052 const int hour,
8053 const int min,
8054 const int sec,
8055 const double remain,
8056 double *jsec) {
8057
8058 struct tm t0, t1;
8059
8060 t0.tm_year = 100;
8061 t0.tm_mon = 0;
8062 t0.tm_mday = 1;
8063 t0.tm_hour = 0;
8064 t0.tm_min = 0;
8065 t0.tm_sec = 0;
8066
8067 t1.tm_year = year - 1900;
8068 t1.tm_mon = mon - 1;
8069 t1.tm_mday = day;
8070 t1.tm_hour = hour;
8071 t1.tm_min = min;
8072 t1.tm_sec = sec;
8073
8074 *jsec = (double) timegm(&t1) - (double) timegm(&t0) + remain;
8075}
8076
8077/*****************************************************************************/
8078
8080 const char *name,
8081 const char *group,
8082 int output) {
8083
8084 static char names[NTIMER][100], groups[NTIMER][100];
8085 static double rt_name[NTIMER], rt_group[NTIMER], rt_min[NTIMER],
8086 rt_max[NTIMER], rt_sq[NTIMER], t0, t1;
8087 static int ct_name[NTIMER], iname = -1, igroup = -1, nname, ngroup;
8088
8089 /* Get time... */
8090 t1 = omp_get_wtime();
8091 const double dt = t1 - t0;
8092
8093 /* Accumulate runtime for current timer... */
8094 if (iname >= 0) {
8095 rt_name[iname] += dt;
8096 rt_sq[iname] += POW2(dt);
8097 rt_min[iname] = (ct_name[iname] <= 0 ? dt : MIN(rt_min[iname], dt));
8098 rt_max[iname] = (ct_name[iname] <= 0 ? dt : MAX(rt_max[iname], dt));
8099 ct_name[iname]++;
8100 }
8101 if (igroup >= 0)
8102 rt_group[igroup] += dt;
8103
8104 /* Write summary... */
8105 if (output) {
8106 for (int i = 0; i < nname; i++) {
8107 const double mean = rt_name[i] / ct_name[i];
8108 const double variance = MAX(0.0, rt_sq[i] / ct_name[i] - POW2(mean));
8109 LOG(1,
8110 "TIMER_%s = %.3f s (min= %g s, mean= %g s, stddev= %g s, max= %g s, n= %d)",
8111 names[i], rt_name[i], rt_min[i], mean, sqrt(variance), rt_max[i],
8112 ct_name[i]);
8113 }
8114 for (int i = 0; i < ngroup; i++)
8115 LOG(1, "TIMER_GROUP_%s = %.3f s", groups[i], rt_group[i]);
8116 double total = 0.0;
8117 for (int i = 0; i < nname; i++)
8118 total += rt_name[i];
8119 LOG(1, "TIMER_TOTAL = %.3f s", total);
8120 }
8121
8122 /* Identify next timer name... */
8123 for (iname = 0; iname < nname; iname++)
8124 if (strcasecmp(name, names[iname]) == 0)
8125 break;
8126 for (igroup = 0; igroup < ngroup; igroup++)
8127 if (strcasecmp(group, groups[igroup]) == 0)
8128 break;
8129
8130 /* Add new timer name if needed... */
8131 if (iname >= nname) {
8132 sprintf(names[iname], "%s", name);
8133 if ((++nname) >= NTIMER)
8134 ERRMSG("Too many timers!");
8135 }
8136
8137 /* Add new timer group if needed... */
8138 if (igroup >= ngroup) {
8139 sprintf(groups[igroup], "%s", group);
8140 if ((++ngroup) >= NTIMER)
8141 ERRMSG("Too many groups!");
8142 }
8143
8144 /* Save time stamp for next phase... */
8145 t0 = t1;
8146}
8147
8148/*****************************************************************************/
8149
8151 const char *dirname,
8152 const char *filename,
8153 const ctl_t *ctl,
8154 const atm_t *atm,
8155 int profile) {
8156
8157 /* Set filename... */
8158 char file[LEN];
8159 if (dirname != NULL)
8160 sprintf(file, "%s/%s", dirname, filename);
8161 else
8162 sprintf(file, "%s", filename);
8163
8164 /* Write info... */
8165 LOG(1, "Write atmospheric data: %s", file);
8166
8167 /* Write ASCII data... */
8168 if (ctl->atmfmt == 1)
8169 write_atm_asc(file, ctl, atm);
8170
8171 /* Write binary data... */
8172 else if (ctl->atmfmt == 2)
8173 write_atm_bin(file, ctl, atm);
8174
8175 /* Write netCDF data... */
8176 else if (ctl->atmfmt == 3)
8177 write_atm_nc(file, ctl, atm, profile);
8178
8179 /* Error... */
8180 else
8181 ERRMSG("Unknown file format, check ATMFMT!");
8182
8183 /* Write info... */
8184 double mini, maxi;
8185 LOG(2, "Number of data points: %d", atm->np);
8186 gsl_stats_minmax(&mini, &maxi, atm->time, 1, (size_t) atm->np);
8187 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
8188 gsl_stats_minmax(&mini, &maxi, atm->z, 1, (size_t) atm->np);
8189 LOG(2, "Altitude range: %g ... %g km", mini, maxi);
8190 gsl_stats_minmax(&mini, &maxi, atm->lon, 1, (size_t) atm->np);
8191 LOG(2, "Longitude range: %g ... %g deg", mini, maxi);
8192 gsl_stats_minmax(&mini, &maxi, atm->lat, 1, (size_t) atm->np);
8193 LOG(2, "Latitude range: %g ... %g deg", mini, maxi);
8194 gsl_stats_minmax(&mini, &maxi, atm->p, 1, (size_t) atm->np);
8195 LOG(2, "Pressure range: %g ... %g hPa", maxi, mini);
8196 gsl_stats_minmax(&mini, &maxi, atm->t, 1, (size_t) atm->np);
8197 LOG(2, "Temperature range: %g ... %g K", mini, maxi);
8198 for (int ig = 0; ig < ctl->ng; ig++) {
8199 gsl_stats_minmax(&mini, &maxi, atm->q[ig], 1, (size_t) atm->np);
8200 LOG(2, "Emitter %s range: %g ... %g ppv", ctl->emitter[ig], mini, maxi);
8201 }
8202 for (int iw = 0; iw < ctl->nw; iw++) {
8203 gsl_stats_minmax(&mini, &maxi, atm->k[iw], 1, (size_t) atm->np);
8204 LOG(2, "Extinction range (window %d): %g ... %g km^-1", iw, mini, maxi);
8205 }
8206 if (ctl->ncl > 0) {
8207 LOG(2, "Cloud layer: z= %g km | dz= %g km | k= %g ... %g km^-1",
8208 atm->clz, atm->cldz, atm->clk[0], atm->clk[ctl->ncl - 1]);
8209 } else
8210 LOG(2, "Cloud layer: none");
8211 if (ctl->nsf > 0) {
8212 LOG(2,
8213 "Surface: T_s = %g K | eps= %g ... %g",
8214 atm->sft, atm->sfeps[0], atm->sfeps[ctl->nsf - 1]);
8215 } else
8216 LOG(2, "Surface: none");
8217}
8218
8219/*****************************************************************************/
8220
8222 const char *filename,
8223 const ctl_t *ctl,
8224 const atm_t *atm) {
8225
8226 int n = 6;
8227
8228 /* Create file... */
8229 FILE *out;
8230 if (!(out = fopen(filename, "w")))
8231 ERRMSG("Cannot create file!");
8232
8233 /* Write header... */
8234 fprintf(out,
8235 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
8236 "# $2 = altitude [km]\n"
8237 "# $3 = longitude [deg]\n"
8238 "# $4 = latitude [deg]\n"
8239 "# $5 = pressure [hPa]\n" "# $6 = temperature [K]\n");
8240 for (int ig = 0; ig < ctl->ng; ig++)
8241 fprintf(out, "# $%d = %s volume mixing ratio [ppv]\n",
8242 ++n, ctl->emitter[ig]);
8243 for (int iw = 0; iw < ctl->nw; iw++)
8244 fprintf(out, "# $%d = extinction (window %d) [km^-1]\n", ++n, iw);
8245 if (ctl->ncl > 0) {
8246 fprintf(out, "# $%d = cloud layer height [km]\n", ++n);
8247 fprintf(out, "# $%d = cloud layer depth [km]\n", ++n);
8248 for (int icl = 0; icl < ctl->ncl; icl++)
8249 fprintf(out, "# $%d = cloud layer extinction (%.4f cm^-1) [km^-1]\n",
8250 ++n, ctl->clnu[icl]);
8251 }
8252 if (ctl->nsf > 0) {
8253 fprintf(out, "# $%d = surface temperature [K]\n", ++n);
8254 for (int isf = 0; isf < ctl->nsf; isf++)
8255 fprintf(out, "# $%d = surface emissivity (%.4f cm^-1)\n",
8256 ++n, ctl->sfnu[isf]);
8257 }
8258
8259 /* Write data... */
8260 for (int ip = 0; ip < atm->np; ip++) {
8261 if (ip == 0 || atm->time[ip] != atm->time[ip - 1])
8262 fprintf(out, "\n");
8263 fprintf(out, "%.2f %g %g %g %g %g", atm->time[ip], atm->z[ip],
8264 atm->lon[ip], atm->lat[ip], atm->p[ip], atm->t[ip]);
8265 for (int ig = 0; ig < ctl->ng; ig++)
8266 fprintf(out, " %g", atm->q[ig][ip]);
8267 for (int iw = 0; iw < ctl->nw; iw++)
8268 fprintf(out, " %g", atm->k[iw][ip]);
8269 if (ctl->ncl > 0) {
8270 fprintf(out, " %g %g", atm->clz, atm->cldz);
8271 for (int icl = 0; icl < ctl->ncl; icl++)
8272 fprintf(out, " %g", atm->clk[icl]);
8273 }
8274 if (ctl->nsf > 0) {
8275 fprintf(out, " %g", atm->sft);
8276 for (int isf = 0; isf < ctl->nsf; isf++)
8277 fprintf(out, " %g", atm->sfeps[isf]);
8278 }
8279 fprintf(out, "\n");
8280 }
8281
8282 /* Close file... */
8283 fclose(out);
8284}
8285
8286/*****************************************************************************/
8287
8289 const char *filename,
8290 const ctl_t *ctl,
8291 const atm_t *atm) {
8292
8293 /* Create file... */
8294 FILE *out;
8295 if (!(out = fopen(filename, "w")))
8296 ERRMSG("Cannot create file!");
8297
8298 /* Write header... */
8299 FWRITE("ATM1", char,
8300 4,
8301 out);
8302 FWRITE(&ctl->ng, int,
8303 1,
8304 out);
8305 FWRITE(&ctl->nw, int,
8306 1,
8307 out);
8308 FWRITE(&ctl->ncl, int,
8309 1,
8310 out);
8311 FWRITE(&ctl->nsf, int,
8312 1,
8313 out);
8314
8315 /* Write data... */
8316 size_t np = (size_t) atm->np;
8317 FWRITE(&np, size_t,
8318 1,
8319 out);
8320 FWRITE(atm->time, double,
8321 np,
8322 out);
8323 FWRITE(atm->z, double,
8324 np,
8325 out);
8326 FWRITE(atm->lon, double,
8327 np,
8328 out);
8329 FWRITE(atm->lat, double,
8330 np,
8331 out);
8332 FWRITE(atm->p, double,
8333 np,
8334 out);
8335 FWRITE(atm->t, double,
8336 np,
8337 out);
8338 for (int ig = 0; ig < ctl->ng; ig++)
8339 FWRITE(atm->q[ig], double,
8340 np,
8341 out);
8342 for (int iw = 0; iw < ctl->nw; iw++)
8343 FWRITE(atm->k[iw], double,
8344 np,
8345 out);
8346 if (ctl->ncl > 0) {
8347 FWRITE(&atm->clz, double,
8348 1,
8349 out);
8350 FWRITE(&atm->cldz, double,
8351 1,
8352 out);
8353 FWRITE(atm->clk, double,
8354 (size_t) ctl->ncl,
8355 out);
8356 }
8357 if (ctl->nsf > 0) {
8358 FWRITE(&atm->sft, double,
8359 1,
8360 out);
8361 FWRITE(atm->sfeps, double,
8362 (size_t) ctl->nsf,
8363 out);
8364 }
8365
8366 /* Close file... */
8367 fclose(out);
8368}
8369
8370/*****************************************************************************/
8371
8373 const char *filename,
8374 const ctl_t *ctl,
8375 const atm_t *atm,
8376 int profile) {
8377
8378 char longname[LEN], varname[LEN];
8379
8380 int ncid, varid, dim_profile, dim_level;
8381
8382 size_t level_max;
8383
8384 /* Check number of levels... */
8385 if (atm->np < 1 || atm->np > NP)
8386 ERRMSG("Number of levels out of range!");
8387
8388 /* Open or create file... */
8389 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR)
8390 NC(nc_create(filename, NC_NETCDF4, &ncid));
8391
8392 /* Enter define mode... */
8393 int r = nc_redef(ncid);
8394 if (r != NC_NOERR && r != NC_EINDEFINE)
8395 NC(r);
8396
8397 /* Define profile dimension (unlimited)... */
8398 if (nc_inq_dimid(ncid, "profile", &dim_profile) != NC_NOERR)
8399 NC(nc_def_dim(ncid, "profile", NC_UNLIMITED, &dim_profile));
8400
8401 /* Define level dimension (fixed)... */
8402 if (nc_inq_dimid(ncid, "level", &dim_level) == NC_NOERR) {
8403 NC(nc_inq_dimlen(ncid, dim_level, &level_max));
8404 if (level_max < 1 || level_max > (size_t) NP)
8405 ERRMSG("netCDF dimension level is out of range!");
8406 if ((size_t) atm->np > level_max)
8407 ERRMSG("profile has too many levels!");
8408 } else {
8409 level_max = (size_t) atm->np;
8410 NC(nc_def_dim(ncid, "level", level_max, &dim_level));
8411 }
8412
8413 /* Set dimension IDs... */
8414 int dimids[2] = { dim_profile, dim_level };
8415
8416 /* Tunables for compression/quantization... */
8417 const int deflate_level = 0;
8418 const int quant_digits = 0;
8419
8420 /* Define nlev (1D)... */
8421 if (nc_inq_varid(ncid, "nlev", &varid) != NC_NOERR)
8422 NC_DEF_VAR("nlev", NC_INT, 1, dimids,
8423 "number of vertical levels", "1", 0, 0);
8424
8425 /* Define core variables (2D)... */
8426 if (nc_inq_varid(ncid, "time", &varid) != NC_NOERR)
8427 NC_DEF_VAR("time", NC_DOUBLE, 2, dimids,
8428 "time in seconds since 2000-01-01, 00:00 UTC", "s",
8429 deflate_level, 0);
8430
8431 if (nc_inq_varid(ncid, "z", &varid) != NC_NOERR)
8432 NC_DEF_VAR("z", NC_DOUBLE, 2, dimids, "altitude", "km", deflate_level, 0);
8433
8434 if (nc_inq_varid(ncid, "lon", &varid) != NC_NOERR)
8435 NC_DEF_VAR("lon", NC_DOUBLE, 2, dimids,
8436 "longitude", "degrees_east", deflate_level, 0);
8437
8438 if (nc_inq_varid(ncid, "lat", &varid) != NC_NOERR)
8439 NC_DEF_VAR("lat", NC_DOUBLE, 2, dimids,
8440 "latitude", "degrees_north", deflate_level, 0);
8441
8442 if (nc_inq_varid(ncid, "p", &varid) != NC_NOERR)
8443 NC_DEF_VAR("p", NC_DOUBLE, 2, dimids,
8444 "pressure", "hPa", deflate_level, quant_digits);
8445
8446 if (nc_inq_varid(ncid, "t", &varid) != NC_NOERR)
8447 NC_DEF_VAR("t", NC_DOUBLE, 2, dimids,
8448 "temperature", "K", deflate_level, quant_digits);
8449
8450 /* Write emitters (2D)... */
8451 for (int ig = 0; ig < ctl->ng; ig++)
8452 if (nc_inq_varid(ncid, ctl->emitter[ig], &varid) != NC_NOERR) {
8453 sprintf(longname, "%s volume mixing ratio", ctl->emitter[ig]);
8454 NC_DEF_VAR(ctl->emitter[ig], NC_DOUBLE, 2, dimids,
8455 longname, "ppv", deflate_level, quant_digits);
8456 }
8457
8458 /* Write extinction (2D)... */
8459 for (int iw = 0; iw < ctl->nw; iw++) {
8460 sprintf(varname, "ext_win_%d", iw);
8461 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
8462 sprintf(longname, "extinction (window %d)", iw);
8463 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids,
8464 longname, "km**-1", deflate_level, quant_digits);
8465 }
8466 }
8467
8468 /* Write cloud variables (1D)... */
8469 if (ctl->ncl > 0) {
8470 if (nc_inq_varid(ncid, "cld_z", &varid) != NC_NOERR)
8471 NC_DEF_VAR("cld_z", NC_DOUBLE, 1, dimids,
8472 "cloud layer height", "km", deflate_level, quant_digits);
8473
8474 if (nc_inq_varid(ncid, "cld_dz", &varid) != NC_NOERR)
8475 NC_DEF_VAR("cld_dz", NC_DOUBLE, 1, dimids,
8476 "cloud layer depth", "km", deflate_level, quant_digits);
8477
8478 for (int icl = 0; icl < ctl->ncl; icl++) {
8479 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
8480 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
8481 sprintf(longname, "cloud layer extinction (%.4f cm^-1)",
8482 ctl->clnu[icl]);
8483 NC_DEF_VAR(varname, NC_DOUBLE, 1, dimids, longname, "km**-1",
8484 deflate_level, quant_digits);
8485 }
8486 }
8487 }
8488
8489 /* Write surface variables (1D)... */
8490 if (ctl->nsf > 0) {
8491 if (nc_inq_varid(ncid, "srf_t", &varid) != NC_NOERR)
8492 NC_DEF_VAR("srf_t", NC_DOUBLE, 1, dimids,
8493 "surface temperature", "K", deflate_level, quant_digits);
8494
8495 for (int isf = 0; isf < ctl->nsf; isf++) {
8496 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
8497 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
8498 sprintf(longname, "surface emissivity (%.4f cm^-1)", ctl->sfnu[isf]);
8499 NC_DEF_VAR(varname, NC_DOUBLE, 1, dimids, longname, "1",
8500 deflate_level, quant_digits);
8501 }
8502 }
8503 }
8504
8505 /* Leave define mode... */
8506 NC(nc_enddef(ncid));
8507
8508 /* Define hyperslabs... */
8509 size_t start[2] = { (size_t) profile, 0 };
8510 size_t count[2] = { 1, (size_t) atm->np };
8511
8512 /* Write nlev... */
8513 NC_PUT_INT("nlev", &atm->np, 1);
8514
8515 /* Write core variables... */
8516 NC_PUT_DOUBLE("time", atm->time, 1);
8517 NC_PUT_DOUBLE("z", atm->z, 1);
8518 NC_PUT_DOUBLE("lon", atm->lon, 1);
8519 NC_PUT_DOUBLE("lat", atm->lat, 1);
8520 NC_PUT_DOUBLE("p", atm->p, 1);
8521 NC_PUT_DOUBLE("t", atm->t, 1);
8522
8523 /* Write emitters... */
8524 for (int ig = 0; ig < ctl->ng; ig++)
8525 NC_PUT_DOUBLE(ctl->emitter[ig], atm->q[ig], 1);
8526
8527 /* Write extinction... */
8528 for (int iw = 0; iw < ctl->nw; iw++) {
8529 sprintf(varname, "ext_win_%d", iw);
8530 NC_PUT_DOUBLE(varname, atm->k[iw], 1);
8531 }
8532
8533 /* Write cloud variables... */
8534 if (ctl->ncl > 0) {
8535 NC_PUT_DOUBLE("cld_z", &atm->clz, 1);
8536 NC_PUT_DOUBLE("cld_dz", &atm->cldz, 1);
8537 for (int icl = 0; icl < ctl->ncl; icl++) {
8538 sprintf(varname, "cld_k_%.4f", ctl->clnu[icl]);
8539 NC_PUT_DOUBLE(varname, &atm->clk[icl], 1);
8540 }
8541 }
8542
8543 /* Write surface variables... */
8544 if (ctl->nsf > 0) {
8545 NC_PUT_DOUBLE("srf_t", &atm->sft, 1);
8546 for (int isf = 0; isf < ctl->nsf; isf++) {
8547 sprintf(varname, "srf_eps_%.4f", ctl->sfnu[isf]);
8548 NC_PUT_DOUBLE(varname, &atm->sfeps[isf], 1);
8549 }
8550 }
8551
8552 /* Close file... */
8553 NC(nc_sync(ncid));
8554 NC(nc_close(ncid));
8555}
8556
8557/*****************************************************************************/
8558
8560 const char *filename,
8561 const ctl_t *ctl,
8562 const atm_t *atm) {
8563
8564 /* Write info... */
8565 LOG(1, "Write RFM data: %s", filename);
8566
8567 /* Create file... */
8568 FILE *out;
8569 if (!(out = fopen(filename, "w")))
8570 ERRMSG("Cannot create file!");
8571
8572 /* Write data... */
8573 fprintf(out, "%d\n", atm->np);
8574 fprintf(out, "*HGT [km]\n");
8575 for (int ip = 0; ip < atm->np; ip++)
8576 fprintf(out, "%g\n", atm->z[ip]);
8577 fprintf(out, "*PRE [mb]\n");
8578 for (int ip = 0; ip < atm->np; ip++)
8579 fprintf(out, "%g\n", atm->p[ip]);
8580 fprintf(out, "*TEM [K]\n");
8581 for (int ip = 0; ip < atm->np; ip++)
8582 fprintf(out, "%g\n", atm->t[ip]);
8583 for (int ig = 0; ig < ctl->ng; ig++) {
8584 fprintf(out, "*%s [ppmv]\n", ctl->emitter[ig]);
8585 for (int ip = 0; ip < atm->np; ip++)
8586 fprintf(out, "%g\n", atm->q[ig][ip] * 1e6);
8587 }
8588 fprintf(out, "*END\n");
8589
8590 /* Close file... */
8591 fclose(out);
8592}
8593
8594/*****************************************************************************/
8595
8597 const char *dirname,
8598 const char *filename,
8599 const ctl_t *ctl,
8600 const gsl_matrix *matrix,
8601 const atm_t *atm,
8602 const obs_t *obs,
8603 const char *rowspace,
8604 const char *colspace,
8605 const char *sort,
8606 int dataset) {
8607
8608 /* Check output flag... */
8609 if (!ctl->write_matrix)
8610 return;
8611
8612 /* Write ASCII data... */
8613 if (ctl->matrixfmt == 1)
8614 write_matrix_asc(dirname, filename, ctl, matrix, atm, obs,
8615 rowspace, colspace, sort);
8616
8617 /* Write binary data... */
8618 else if (ctl->matrixfmt == 2)
8619 write_matrix_bin(dirname, filename, matrix);
8620
8621 /* Write netCDF data... */
8622 else if (ctl->matrixfmt == 3)
8623 write_matrix_nc(dirname, filename, ctl, matrix, atm, obs,
8624 rowspace, colspace, sort, dataset);
8625
8626 /* Error... */
8627 else
8628 ERRMSG("Unknown matrix file format, check MATRIXFMT!");
8629}
8630
8631/*****************************************************************************/
8632
8634 const char *dirname,
8635 const char *filename,
8636 const ctl_t *ctl,
8637 const gsl_matrix *matrix,
8638 const atm_t *atm,
8639 const obs_t *obs,
8640 const char *rowspace,
8641 const char *colspace,
8642 const char *sort) {
8643
8644 char file[LEN], quantity[LEN];
8645
8646 int *cida, *ciqa, *cipa, *cira, *rida, *riqa, *ripa, *rira;
8647
8648 size_t i, j, nc, nr;
8649
8650 /* Allocate... */
8651 ALLOC(cida, int,
8652 M);
8653 ALLOC(ciqa, int,
8654 N);
8655 ALLOC(cipa, int,
8656 N);
8657 ALLOC(cira, int,
8658 M);
8659 ALLOC(rida, int,
8660 M);
8661 ALLOC(riqa, int,
8662 N);
8663 ALLOC(ripa, int,
8664 N);
8665 ALLOC(rira, int,
8666 M);
8667
8668 /* Set filename... */
8669 if (dirname != NULL)
8670 sprintf(file, "%s/%s", dirname, filename);
8671 else
8672 sprintf(file, "%s", filename);
8673
8674 /* Write info... */
8675 LOG(1, "Write matrix: %s", file);
8676
8677 /* Create file... */
8678 FILE *out;
8679 if (!(out = fopen(file, "w")))
8680 ERRMSG("Cannot create file!");
8681
8682 /* Write header (row space)... */
8683 if (rowspace[0] == 'y') {
8684
8685 fprintf(out,
8686 "# $1 = Row: index (measurement space)\n"
8687 "# $2 = Row: channel wavenumber [cm^-1]\n"
8688 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
8689 "# $4 = Row: view point altitude [km]\n"
8690 "# $5 = Row: view point longitude [deg]\n"
8691 "# $6 = Row: view point latitude [deg]\n");
8692
8693 /* Get number of rows... */
8694 nr = obs2y(ctl, obs, NULL, rida, rira);
8695
8696 } else {
8697
8698 fprintf(out,
8699 "# $1 = Row: index (state space)\n"
8700 "# $2 = Row: name of quantity\n"
8701 "# $3 = Row: time (seconds since 2000-01-01T00:00Z)\n"
8702 "# $4 = Row: altitude [km]\n"
8703 "# $5 = Row: longitude [deg]\n" "# $6 = Row: latitude [deg]\n");
8704
8705 /* Get number of rows... */
8706 nr = atm2x(ctl, atm, NULL, riqa, ripa);
8707 }
8708
8709 /* Write header (column space)... */
8710 if (colspace[0] == 'y') {
8711
8712 fprintf(out,
8713 "# $7 = Col: index (measurement space)\n"
8714 "# $8 = Col: channel wavenumber [cm^-1]\n"
8715 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
8716 "# $10 = Col: view point altitude [km]\n"
8717 "# $11 = Col: view point longitude [deg]\n"
8718 "# $12 = Col: view point latitude [deg]\n");
8719
8720 /* Get number of columns... */
8721 nc = obs2y(ctl, obs, NULL, cida, cira);
8722
8723 } else {
8724
8725 fprintf(out,
8726 "# $7 = Col: index (state space)\n"
8727 "# $8 = Col: name of quantity\n"
8728 "# $9 = Col: time (seconds since 2000-01-01T00:00Z)\n"
8729 "# $10 = Col: altitude [km]\n"
8730 "# $11 = Col: longitude [deg]\n" "# $12 = Col: latitude [deg]\n");
8731
8732 /* Get number of columns... */
8733 nc = atm2x(ctl, atm, NULL, ciqa, cipa);
8734 }
8735
8736 /* Write header entry... */
8737 fprintf(out, "# $13 = Matrix element\n\n");
8738
8739 /* Write matrix data... */
8740 i = j = 0;
8741 while (i < nr && j < nc) {
8742
8743 /* Write info about the row... */
8744 if (rowspace[0] == 'y')
8745 fprintf(out, "%d %.4f %.2f %g %g %g",
8746 (int) i, ctl->nu[rida[i]],
8747 obs->time[rira[i]], obs->vpz[rira[i]],
8748 obs->vplon[rira[i]], obs->vplat[rira[i]]);
8749 else {
8750 idx2name(ctl, riqa[i], quantity);
8751 fprintf(out, "%d %s %.2f %g %g %g", (int) i, quantity,
8752 atm->time[ripa[i]], atm->z[ripa[i]],
8753 atm->lon[ripa[i]], atm->lat[ripa[i]]);
8754 }
8755
8756 /* Write info about the column... */
8757 if (colspace[0] == 'y')
8758 fprintf(out, " %d %.4f %.2f %g %g %g",
8759 (int) j, ctl->nu[cida[j]],
8760 obs->time[cira[j]], obs->vpz[cira[j]],
8761 obs->vplon[cira[j]], obs->vplat[cira[j]]);
8762 else {
8763 idx2name(ctl, ciqa[j], quantity);
8764 fprintf(out, " %d %s %.2f %g %g %g", (int) j, quantity,
8765 atm->time[cipa[j]], atm->z[cipa[j]],
8766 atm->lon[cipa[j]], atm->lat[cipa[j]]);
8767 }
8768
8769 /* Write matrix entry... */
8770 fprintf(out, " %g\n", gsl_matrix_get(matrix, i, j));
8771
8772 /* Set matrix indices... */
8773 if (sort[0] == 'r') {
8774 j++;
8775 if (j >= nc) {
8776 j = 0;
8777 i++;
8778 fprintf(out, "\n");
8779 }
8780 } else {
8781 i++;
8782 if (i >= nr) {
8783 i = 0;
8784 j++;
8785 fprintf(out, "\n");
8786 }
8787 }
8788 }
8789
8790 /* Close file... */
8791 fclose(out);
8792
8793 /* Free... */
8794 free(cida);
8795 free(ciqa);
8796 free(cipa);
8797 free(cira);
8798 free(rida);
8799 free(riqa);
8800 free(ripa);
8801 free(rira);
8802}
8803
8804/*****************************************************************************/
8805
8807 const char *dirname,
8808 const char *filename,
8809 const gsl_matrix *matrix) {
8810
8811 char file[LEN];
8812 const size_t nr = matrix->size1;
8813 const size_t nc = matrix->size2;
8814
8815 /* Set filename... */
8816 if (dirname != NULL)
8817 sprintf(file, "%s/%s", dirname, filename);
8818 else
8819 sprintf(file, "%s", filename);
8820
8821 /* Write info... */
8822 LOG(1, "Write matrix: %s", file);
8823
8824 /* Create file... */
8825 FILE *out;
8826 if (!(out = fopen(file, "w")))
8827 ERRMSG("Cannot create file!");
8828
8829 /* Write header... */
8830 FWRITE("MAT1", char,
8831 4,
8832 out);
8833 FWRITE(&nr, size_t,
8834 1,
8835 out);
8836 FWRITE(&nc, size_t,
8837 1,
8838 out);
8839
8840 /* Write data... */
8841 for (size_t i = 0; i < nr; i++)
8842 for (size_t j = 0; j < nc; j++) {
8843 double value = gsl_matrix_get(matrix, i, j);
8844 FWRITE(&value, double,
8845 1,
8846 out);
8847 }
8848
8849 /* Close file... */
8850 fclose(out);
8851}
8852
8853/*****************************************************************************/
8854
8856 const char *dirname,
8857 const char *filename,
8858 const ctl_t *ctl,
8859 const gsl_matrix *matrix,
8860 const atm_t *atm,
8861 const obs_t *obs,
8862 const char *rowspace,
8863 const char *colspace,
8864 const char *sort,
8865 int dataset) {
8866
8867 char file[LEN];
8868 char quantity[LEN];
8869 const size_t name_strlen = 100;
8870
8871 int ncid, dimid_dataset, dimid_row, dimid_col, dimid_name, varid;
8872 int *cida, *ciqa, *cipa, *cira, *rida, *riqa, *ripa, *rira;
8873
8874 size_t nr = matrix->size1, nc = matrix->size2, naux;
8875
8876 /* Allocate metadata index arrays... */
8877 ALLOC(cida, int,
8878 M);
8879 ALLOC(ciqa, int,
8880 N);
8881 ALLOC(cipa, int,
8882 N);
8883 ALLOC(cira, int,
8884 M);
8885 ALLOC(rida, int,
8886 M);
8887 ALLOC(riqa, int,
8888 N);
8889 ALLOC(ripa, int,
8890 N);
8891 ALLOC(rira, int,
8892 M);
8893
8894 /* Set filename... */
8895 if (dirname != NULL)
8896 sprintf(file, "%s/%s", dirname, filename);
8897 else
8898 sprintf(file, "%s", filename);
8899
8900 /* Write info... */
8901 LOG(1, "Write matrix: %s", file);
8902
8903 /* Open or create file... */
8904 if (nc_open(file, NC_WRITE, &ncid) != NC_NOERR)
8905 NC(nc_create(file, NC_NETCDF4, &ncid));
8906
8907 /* Enter define mode... */
8908 int r = nc_redef(ncid);
8909 if (r != NC_NOERR && r != NC_EINDEFINE)
8910 NC(r);
8911
8912 /* Define dataset dimension (unlimited)... */
8913 if (nc_inq_dimid(ncid, "dataset", &dimid_dataset) != NC_NOERR)
8914 NC(nc_def_dim(ncid, "dataset", NC_UNLIMITED, &dimid_dataset));
8915
8916 /* Define row dimension (fixed)... */
8917 if (nc_inq_dimid(ncid, "row", &dimid_row) == NC_NOERR) {
8918 NC(nc_inq_dimlen(ncid, dimid_row, &naux));
8919 if (naux != nr)
8920 ERRMSG("matrix row dimension is incompatible!");
8921 } else
8922 NC(nc_def_dim(ncid, "row", nr, &dimid_row));
8923
8924 /* Define col dimension (fixed)... */
8925 if (nc_inq_dimid(ncid, "col", &dimid_col) == NC_NOERR) {
8926 NC(nc_inq_dimlen(ncid, dimid_col, &naux));
8927 if (naux != nc)
8928 ERRMSG("matrix col dimension is incompatible!");
8929 } else
8930 NC(nc_def_dim(ncid, "col", nc, &dimid_col));
8931
8932 /* Define fixed-length name dimension... */
8933 if (nc_inq_dimid(ncid, "name_strlen", &dimid_name) == NC_NOERR) {
8934 NC(nc_inq_dimlen(ncid, dimid_name, &naux));
8935 if (naux != name_strlen)
8936 ERRMSG("matrix name_strlen dimension is incompatible!");
8937 } else
8938 NC(nc_def_dim(ncid, "name_strlen", name_strlen, &dimid_name));
8939
8940 /* Define variables... */
8941 int dimids3[3] = { dimid_dataset, dimid_row, dimid_col };
8942 int dimids1[1] = { dimid_dataset };
8943 int dimids2_row[2] = { dimid_dataset, dimid_row };
8944 int dimids2_col[2] = { dimid_dataset, dimid_col };
8945 int dimids3_rowname[3] = { dimid_dataset, dimid_row, dimid_name };
8946 int dimids3_colname[3] = { dimid_dataset, dimid_col, dimid_name };
8947 if (nc_inq_varid(ncid, "matrix", &varid) != NC_NOERR) {
8948 NC(nc_def_var(ncid, "matrix", NC_DOUBLE, 3, dimids3, &varid));
8949 NC(nc_put_att_text(ncid, varid, "long_name", 14, "matrix element"));
8950 NC(nc_put_att_text(ncid, varid, "units", 1, "1"));
8951 }
8952 if (nc_inq_varid(ncid, "rowspace", &varid) != NC_NOERR)
8953 NC_DEF_VAR("rowspace", NC_CHAR, 1, dimids1,
8954 "row space selector", "1", 0, 0);
8955 if (nc_inq_varid(ncid, "colspace", &varid) != NC_NOERR)
8956 NC_DEF_VAR("colspace", NC_CHAR, 1, dimids1,
8957 "column space selector", "1", 0, 0);
8958 if (nc_inq_varid(ncid, "sort", &varid) != NC_NOERR)
8959 NC_DEF_VAR("sort", NC_CHAR, 1, dimids1,
8960 "matrix sort selector", "1", 0, 0);
8961 if (nc_inq_varid(ncid, "row_nu", &varid) != NC_NOERR)
8962 NC_DEF_VAR("row_nu", NC_DOUBLE, 2, dimids2_row,
8963 "row channel wavenumber", "cm^-1", 0, 0);
8964 if (nc_inq_varid(ncid, "row_time", &varid) != NC_NOERR)
8965 NC_DEF_VAR("row_time", NC_DOUBLE, 2, dimids2_row,
8966 "row time since 2000-01-01T00:00Z", "s", 0, 0);
8967 if (nc_inq_varid(ncid, "row_z", &varid) != NC_NOERR)
8968 NC_DEF_VAR("row_z", NC_DOUBLE, 2, dimids2_row,
8969 "row altitude", "km", 0, 0);
8970 if (nc_inq_varid(ncid, "row_lon", &varid) != NC_NOERR)
8971 NC_DEF_VAR("row_lon", NC_DOUBLE, 2, dimids2_row,
8972 "row longitude", "degrees_east", 0, 0);
8973 if (nc_inq_varid(ncid, "row_lat", &varid) != NC_NOERR)
8974 NC_DEF_VAR("row_lat", NC_DOUBLE, 2, dimids2_row,
8975 "row latitude", "degrees_north", 0, 0);
8976 if (nc_inq_varid(ncid, "row_quantity", &varid) != NC_NOERR)
8977 NC_DEF_VAR("row_quantity", NC_CHAR, 3, dimids3_rowname,
8978 "row state quantity name", "1", 0, 0);
8979 if (nc_inq_varid(ncid, "col_nu", &varid) != NC_NOERR)
8980 NC_DEF_VAR("col_nu", NC_DOUBLE, 2, dimids2_col,
8981 "column channel wavenumber", "cm^-1", 0, 0);
8982 if (nc_inq_varid(ncid, "col_time", &varid) != NC_NOERR)
8983 NC_DEF_VAR("col_time", NC_DOUBLE, 2, dimids2_col,
8984 "column time since 2000-01-01T00:00Z", "s", 0, 0);
8985 if (nc_inq_varid(ncid, "col_z", &varid) != NC_NOERR)
8986 NC_DEF_VAR("col_z", NC_DOUBLE, 2, dimids2_col,
8987 "column altitude", "km", 0, 0);
8988 if (nc_inq_varid(ncid, "col_lon", &varid) != NC_NOERR)
8989 NC_DEF_VAR("col_lon", NC_DOUBLE, 2, dimids2_col,
8990 "column longitude", "degrees_east", 0, 0);
8991 if (nc_inq_varid(ncid, "col_lat", &varid) != NC_NOERR)
8992 NC_DEF_VAR("col_lat", NC_DOUBLE, 2, dimids2_col,
8993 "column latitude", "degrees_north", 0, 0);
8994 if (nc_inq_varid(ncid, "col_quantity", &varid) != NC_NOERR)
8995 NC_DEF_VAR("col_quantity", NC_CHAR, 3, dimids3_colname,
8996 "column state quantity name", "1", 0, 0);
8997
8998 /* Leave define mode... */
8999 NC(nc_enddef(ncid));
9000
9001 /* Write metadata... */
9002 size_t start1[1] = { (size_t) dataset };
9003 size_t count1[1] = { 1 };
9004 NC(nc_inq_varid(ncid, "rowspace", &varid));
9005 NC(nc_put_vara_text(ncid, varid, start1, count1, rowspace));
9006 NC(nc_inq_varid(ncid, "colspace", &varid));
9007 NC(nc_put_vara_text(ncid, varid, start1, count1, colspace));
9008 NC(nc_inq_varid(ncid, "sort", &varid));
9009 NC(nc_put_vara_text(ncid, varid, start1, count1, sort));
9010
9011 /* Set row and column metadata indices... */
9012 if (rowspace[0] == 'y')
9013 nr = obs2y(ctl, obs, NULL, rida, rira);
9014 else
9015 nr = atm2x(ctl, atm, NULL, riqa, ripa);
9016 if (colspace[0] == 'y')
9017 nc = obs2y(ctl, obs, NULL, cida, cira);
9018 else
9019 nc = atm2x(ctl, atm, NULL, ciqa, cipa);
9020
9021 /* Write row metadata... */
9022 for (size_t i = 0; i < nr; i++) {
9023 const double nu = rowspace[0] == 'y' ? ctl->nu[rida[i]] : GSL_NAN;
9024 const double time =
9025 rowspace[0] == 'y' ? obs->time[rira[i]] : atm->time[ripa[i]];
9026 const double z = rowspace[0] == 'y' ? obs->vpz[rira[i]] : atm->z[ripa[i]];
9027 const double lon =
9028 rowspace[0] == 'y' ? obs->vplon[rira[i]] : atm->lon[ripa[i]];
9029 const double lat =
9030 rowspace[0] == 'y' ? obs->vplat[rira[i]] : atm->lat[ripa[i]];
9031 char qbuf[LEN] = { 0 };
9032 size_t start2[2] = { (size_t) dataset, i };
9033 size_t count2[2] = { 1, 1 };
9034 size_t start3n[3] = { (size_t) dataset, i, 0 };
9035 size_t count3n[3] = { 1, 1, name_strlen };
9036
9037 if (rowspace[0] != 'y') {
9038 idx2name(ctl, riqa[i], quantity);
9039 snprintf(qbuf, LEN, "%s", quantity);
9040 }
9041
9042 NC(nc_inq_varid(ncid, "row_nu", &varid));
9043 NC(nc_put_vara_double(ncid, varid, start2, count2, &nu));
9044 NC(nc_inq_varid(ncid, "row_time", &varid));
9045 NC(nc_put_vara_double(ncid, varid, start2, count2, &time));
9046 NC(nc_inq_varid(ncid, "row_z", &varid));
9047 NC(nc_put_vara_double(ncid, varid, start2, count2, &z));
9048 NC(nc_inq_varid(ncid, "row_lon", &varid));
9049 NC(nc_put_vara_double(ncid, varid, start2, count2, &lon));
9050 NC(nc_inq_varid(ncid, "row_lat", &varid));
9051 NC(nc_put_vara_double(ncid, varid, start2, count2, &lat));
9052 NC(nc_inq_varid(ncid, "row_quantity", &varid));
9053 NC(nc_put_vara_text(ncid, varid, start3n, count3n, qbuf));
9054 }
9055
9056 /* Write column metadata... */
9057 for (size_t j = 0; j < nc; j++) {
9058 const double nu = colspace[0] == 'y' ? ctl->nu[cida[j]] : GSL_NAN;
9059 const double time =
9060 colspace[0] == 'y' ? obs->time[cira[j]] : atm->time[cipa[j]];
9061 const double z = colspace[0] == 'y' ? obs->vpz[cira[j]] : atm->z[cipa[j]];
9062 const double lon =
9063 colspace[0] == 'y' ? obs->vplon[cira[j]] : atm->lon[cipa[j]];
9064 const double lat =
9065 colspace[0] == 'y' ? obs->vplat[cira[j]] : atm->lat[cipa[j]];
9066 char qbuf[LEN] = { 0 };
9067 size_t start2[2] = { (size_t) dataset, j };
9068 size_t count2[2] = { 1, 1 };
9069 size_t start3n[3] = { (size_t) dataset, j, 0 };
9070 size_t count3n[3] = { 1, 1, name_strlen };
9071
9072 if (colspace[0] != 'y') {
9073 idx2name(ctl, ciqa[j], quantity);
9074 snprintf(qbuf, LEN, "%s", quantity);
9075 }
9076
9077 NC(nc_inq_varid(ncid, "col_nu", &varid));
9078 NC(nc_put_vara_double(ncid, varid, start2, count2, &nu));
9079 NC(nc_inq_varid(ncid, "col_time", &varid));
9080 NC(nc_put_vara_double(ncid, varid, start2, count2, &time));
9081 NC(nc_inq_varid(ncid, "col_z", &varid));
9082 NC(nc_put_vara_double(ncid, varid, start2, count2, &z));
9083 NC(nc_inq_varid(ncid, "col_lon", &varid));
9084 NC(nc_put_vara_double(ncid, varid, start2, count2, &lon));
9085 NC(nc_inq_varid(ncid, "col_lat", &varid));
9086 NC(nc_put_vara_double(ncid, varid, start2, count2, &lat));
9087 NC(nc_inq_varid(ncid, "col_quantity", &varid));
9088 NC(nc_put_vara_text(ncid, varid, start3n, count3n, qbuf));
9089 }
9090
9091 /* Write matrix data... */
9092 NC(nc_inq_varid(ncid, "matrix", &varid));
9093 for (size_t i = 0; i < nr; i++)
9094 for (size_t j = 0; j < nc; j++) {
9095 const double value = gsl_matrix_get(matrix, i, j);
9096 size_t start3[3] = { (size_t) dataset, i, j };
9097 size_t count3[3] = { 1, 1, 1 };
9098 NC(nc_put_vara_double(ncid, varid, start3, count3, &value));
9099 }
9100
9101 /* Close file... */
9102 NC(nc_sync(ncid));
9103 NC(nc_close(ncid));
9104
9105 /* Free... */
9106 free(cida);
9107 free(ciqa);
9108 free(cipa);
9109 free(cira);
9110 free(rida);
9111 free(riqa);
9112 free(ripa);
9113 free(rira);
9114}
9115
9116/*****************************************************************************/
9117
9119 const char *dirname,
9120 const char *filename,
9121 const ctl_t *ctl,
9122 const obs_t *obs,
9123 int profile) {
9124
9125 /* Set filename... */
9126 char file[LEN];
9127 if (dirname != NULL)
9128 sprintf(file, "%s/%s", dirname, filename);
9129 else
9130 sprintf(file, "%s", filename);
9131
9132 /* Write info... */
9133 LOG(1, "Write observation data: %s", file);
9134
9135 /* Write ASCII data... */
9136 if (ctl->obsfmt == 1)
9137 write_obs_asc(file, ctl, obs);
9138
9139 /* Write binary data... */
9140 else if (ctl->obsfmt == 2)
9141 write_obs_bin(file, ctl, obs);
9142
9143 /* Write netCDF data... */
9144 else if (ctl->obsfmt == 3)
9145 write_obs_nc(file, ctl, obs, profile);
9146
9147 /* Write info... */
9148 double mini, maxi;
9149 LOG(2, "Number of ray paths: %d", obs->nr);
9150 gsl_stats_minmax(&mini, &maxi, obs->time, 1, (size_t) obs->nr);
9151 LOG(2, "Time range: %.2f ... %.2f s", mini, maxi);
9152 gsl_stats_minmax(&mini, &maxi, obs->obsz, 1, (size_t) obs->nr);
9153 LOG(2, "Observer altitude range: %g ... %g km", mini, maxi);
9154 gsl_stats_minmax(&mini, &maxi, obs->obslon, 1, (size_t) obs->nr);
9155 LOG(2, "Observer longitude range: %g ... %g deg", mini, maxi);
9156 gsl_stats_minmax(&mini, &maxi, obs->obslat, 1, (size_t) obs->nr);
9157 LOG(2, "Observer latitude range: %g ... %g deg", mini, maxi);
9158 gsl_stats_minmax(&mini, &maxi, obs->vpz, 1, (size_t) obs->nr);
9159 LOG(2, "View point altitude range: %g ... %g km", mini, maxi);
9160 gsl_stats_minmax(&mini, &maxi, obs->vplon, 1, (size_t) obs->nr);
9161 LOG(2, "View point longitude range: %g ... %g deg", mini, maxi);
9162 gsl_stats_minmax(&mini, &maxi, obs->vplat, 1, (size_t) obs->nr);
9163 LOG(2, "View point latitude range: %g ... %g deg", mini, maxi);
9164 gsl_stats_minmax(&mini, &maxi, obs->tpz, 1, (size_t) obs->nr);
9165 LOG(2, "Tangent point altitude range: %g ... %g km", mini, maxi);
9166 gsl_stats_minmax(&mini, &maxi, obs->tplon, 1, (size_t) obs->nr);
9167 LOG(2, "Tangent point longitude range: %g ... %g deg", mini, maxi);
9168 gsl_stats_minmax(&mini, &maxi, obs->tplat, 1, (size_t) obs->nr);
9169 LOG(2, "Tangent point latitude range: %g ... %g deg", mini, maxi);
9170 for (int id = 0; id < ctl->nd; id++) {
9171 gsl_stats_minmax(&mini, &maxi, obs->rad[id], 1, (size_t) obs->nr);
9172 if (ctl->write_bbt) {
9173 LOG(2, "Brightness temperature (%.4f cm^-1) range: %g ... %g K",
9174 ctl->nu[id], mini, maxi);
9175 } else {
9176 LOG(2, "Radiance (%.4f cm^-1) range: %g ... %g W/(m^2 sr cm^-1)",
9177 ctl->nu[id], mini, maxi);
9178 }
9179 }
9180 for (int id = 0; id < ctl->nd; id++) {
9181 gsl_stats_minmax(&mini, &maxi, obs->tau[id], 1, (size_t) obs->nr);
9182 LOG(2, "Transmittance (%.4f cm^-1) range: %g ... %g",
9183 ctl->nu[id], mini, maxi);
9184 }
9185}
9186
9187/*****************************************************************************/
9188
9190 const char *filename,
9191 const ctl_t *ctl,
9192 const obs_t *obs) {
9193
9194 int n = 10;
9195
9196 /* Create file... */
9197 FILE *out;
9198 if (!(out = fopen(filename, "w")))
9199 ERRMSG("Cannot create file!");
9200
9201 /* Write header... */
9202 fprintf(out,
9203 "# $1 = time (seconds since 2000-01-01T00:00Z)\n"
9204 "# $2 = observer altitude [km]\n"
9205 "# $3 = observer longitude [deg]\n"
9206 "# $4 = observer latitude [deg]\n"
9207 "# $5 = view point altitude [km]\n"
9208 "# $6 = view point longitude [deg]\n"
9209 "# $7 = view point latitude [deg]\n"
9210 "# $8 = tangent point altitude [km]\n"
9211 "# $9 = tangent point longitude [deg]\n"
9212 "# $10 = tangent point latitude [deg]\n");
9213 for (int id = 0; id < ctl->nd; id++)
9214 if (ctl->write_bbt)
9215 fprintf(out, "# $%d = brightness temperature (%.4f cm^-1) [K]\n",
9216 ++n, ctl->nu[id]);
9217 else
9218 fprintf(out, "# $%d = radiance (%.4f cm^-1) [W/(m^2 sr cm^-1)]\n",
9219 ++n, ctl->nu[id]);
9220 for (int id = 0; id < ctl->nd; id++)
9221 fprintf(out, "# $%d = transmittance (%.4f cm^-1) [-]\n", ++n,
9222 ctl->nu[id]);
9223
9224 /* Write data... */
9225 for (int ir = 0; ir < obs->nr; ir++) {
9226 if (ir == 0 || obs->time[ir] != obs->time[ir - 1])
9227 fprintf(out, "\n");
9228 fprintf(out, "%.2f %g %g %g %g %g %g %g %g %g", obs->time[ir],
9229 obs->obsz[ir], obs->obslon[ir], obs->obslat[ir],
9230 obs->vpz[ir], obs->vplon[ir], obs->vplat[ir],
9231 obs->tpz[ir], obs->tplon[ir], obs->tplat[ir]);
9232 for (int id = 0; id < ctl->nd; id++)
9233 fprintf(out, " %g", obs->rad[id][ir]);
9234 for (int id = 0; id < ctl->nd; id++)
9235 fprintf(out, " %g", obs->tau[id][ir]);
9236 fprintf(out, "\n");
9237 }
9238
9239 /* Close file... */
9240 fclose(out);
9241}
9242
9243/*****************************************************************************/
9244
9246 const char *filename,
9247 const ctl_t *ctl,
9248 const obs_t *obs) {
9249
9250 /* Create file... */
9251 FILE *out;
9252 if (!(out = fopen(filename, "w")))
9253 ERRMSG("Cannot create file!");
9254
9255 /* Write header... */
9256 FWRITE("OBS1", char,
9257 4,
9258 out);
9259 FWRITE(&ctl->nd, int,
9260 1,
9261 out);
9262
9263 /* Write data... */
9264 size_t nr = (size_t) obs->nr;
9265 FWRITE(&nr, size_t,
9266 1,
9267 out);
9268 FWRITE(obs->time, double,
9269 nr,
9270 out);
9271 FWRITE(obs->obsz, double,
9272 nr,
9273 out);
9274 FWRITE(obs->obslon, double,
9275 nr,
9276 out);
9277 FWRITE(obs->obslat, double,
9278 nr,
9279 out);
9280 FWRITE(obs->vpz, double,
9281 nr,
9282 out);
9283 FWRITE(obs->vplon, double,
9284 nr,
9285 out);
9286 FWRITE(obs->vplat, double,
9287 nr,
9288 out);
9289 FWRITE(obs->tpz, double,
9290 nr,
9291 out);
9292 FWRITE(obs->tplon, double,
9293 nr,
9294 out);
9295 FWRITE(obs->tplat, double,
9296 nr,
9297 out);
9298 for (int id = 0; id < ctl->nd; id++)
9299 FWRITE(obs->rad[id], double,
9300 nr,
9301 out);
9302 for (int id = 0; id < ctl->nd; id++)
9303 FWRITE(obs->tau[id], double,
9304 nr,
9305 out);
9306
9307 /* Close file... */
9308 fclose(out);
9309}
9310
9311/*****************************************************************************/
9312
9314 const char *filename,
9315 const ctl_t *ctl,
9316 const obs_t *obs,
9317 const int profile) {
9318
9319 char longname[LEN], varname[LEN];
9320 const char *spec_prefix = ctl->write_bbt ? "bt" : "rad";
9321
9322 int ncid, varid, dim_profile, dim_ray;
9323
9324 size_t ray_max;
9325
9326 /* Check number of rays... */
9327 if (obs->nr < 1 || obs->nr > NR)
9328 ERRMSG("Number of ray paths out of range!");
9329
9330 /* Open or create file... */
9331 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR)
9332 NC(nc_create(filename, NC_NETCDF4, &ncid));
9333
9334 /* Enter define mode... */
9335 int r = nc_redef(ncid);
9336 if (r != NC_NOERR && r != NC_EINDEFINE)
9337 NC(r);
9338
9339 /* Define profile dimension (unlimited)... */
9340 if (nc_inq_dimid(ncid, "profile", &dim_profile) != NC_NOERR)
9341 NC(nc_def_dim(ncid, "profile", NC_UNLIMITED, &dim_profile));
9342
9343 /* Define ray dimension (fixed)... */
9344 if (nc_inq_dimid(ncid, "ray", &dim_ray) == NC_NOERR) {
9345 NC(nc_inq_dimlen(ncid, dim_ray, &ray_max));
9346 if (ray_max < 1 || ray_max > (size_t) NR)
9347 ERRMSG("netCDF dimension ray is out of range!");
9348 if ((size_t) obs->nr > ray_max)
9349 ERRMSG("profile has too many rays!");
9350 } else {
9351 ray_max = (size_t) obs->nr;
9352 NC(nc_def_dim(ncid, "ray", ray_max, &dim_ray));
9353 }
9354
9355 /* Dimension ID array... */
9356 int dimids[2] = { dim_profile, dim_ray };
9357
9358 /* Tunables for compression/quantization... */
9359 const int deflate_level = 0;
9360 const int quant_digits = 0;
9361
9362 /* Define nray (1D over profile)... */
9363 if (nc_inq_varid(ncid, "nray", &varid) != NC_NOERR)
9364 NC_DEF_VAR("nray", NC_INT, 1, dimids, "number of ray paths", "1", 0, 0);
9365
9366 /* Define geometry variables (2D over profile, ray)... */
9367 if (nc_inq_varid(ncid, "time", &varid) != NC_NOERR)
9368 NC_DEF_VAR("time", NC_DOUBLE, 2, dimids,
9369 "time in seconds since 2000-01-01, 00:00 UTC", "s",
9370 deflate_level, 0);
9371
9372 if (nc_inq_varid(ncid, "obs_z", &varid) != NC_NOERR)
9373 NC_DEF_VAR("obs_z", NC_DOUBLE, 2, dimids,
9374 "observer altitude", "km", deflate_level, 0);
9375
9376 if (nc_inq_varid(ncid, "obs_lon", &varid) != NC_NOERR)
9377 NC_DEF_VAR("obs_lon", NC_DOUBLE, 2, dimids,
9378 "observer longitude", "degrees_east", deflate_level, 0);
9379
9380 if (nc_inq_varid(ncid, "obs_lat", &varid) != NC_NOERR)
9381 NC_DEF_VAR("obs_lat", NC_DOUBLE, 2, dimids,
9382 "observer latitude", "degrees_north", deflate_level, 0);
9383
9384 if (nc_inq_varid(ncid, "vp_z", &varid) != NC_NOERR)
9385 NC_DEF_VAR("vp_z", NC_DOUBLE, 2, dimids,
9386 "view point altitude", "km", deflate_level, 0);
9387
9388 if (nc_inq_varid(ncid, "vp_lon", &varid) != NC_NOERR)
9389 NC_DEF_VAR("vp_lon", NC_DOUBLE, 2, dimids,
9390 "view point longitude", "degrees_east", deflate_level, 0);
9391
9392 if (nc_inq_varid(ncid, "vp_lat", &varid) != NC_NOERR)
9393 NC_DEF_VAR("vp_lat", NC_DOUBLE, 2, dimids,
9394 "view point latitude", "degrees_north", deflate_level, 0);
9395
9396 if (nc_inq_varid(ncid, "tp_z", &varid) != NC_NOERR)
9397 NC_DEF_VAR("tp_z", NC_DOUBLE, 2, dimids,
9398 "tangent point altitude", "km", deflate_level, 0);
9399
9400 if (nc_inq_varid(ncid, "tp_lon", &varid) != NC_NOERR)
9401 NC_DEF_VAR("tp_lon", NC_DOUBLE, 2, dimids,
9402 "tangent point longitude", "degrees_east", deflate_level, 0);
9403
9404 if (nc_inq_varid(ncid, "tp_lat", &varid) != NC_NOERR)
9405 NC_DEF_VAR("tp_lat", NC_DOUBLE, 2, dimids,
9406 "tangent point latitude", "degrees_north", deflate_level, 0);
9407
9408 /* Define radiance/transmittance per channel (2D profile,ray)... */
9409 for (int id = 0; id < ctl->nd; id++) {
9410
9411 sprintf(varname, "%s_%.4f", spec_prefix, ctl->nu[id]);
9412 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
9413 if (ctl->write_bbt) {
9414 sprintf(longname, "brightness temperature (%.4f cm^-1)", ctl->nu[id]);
9415 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname, "K",
9416 deflate_level, quant_digits);
9417 } else {
9418 sprintf(longname, "radiance (%.4f cm^-1)", ctl->nu[id]);
9419 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname,
9420 "W/(m^2 sr cm^-1)", deflate_level, quant_digits);
9421 }
9422 }
9423
9424 sprintf(varname, "tau_%.4f", ctl->nu[id]);
9425 if (nc_inq_varid(ncid, varname, &varid) != NC_NOERR) {
9426 sprintf(longname, "transmittance (%.4f cm^-1)", ctl->nu[id]);
9427 NC_DEF_VAR(varname, NC_DOUBLE, 2, dimids, longname, "1",
9428 deflate_level, quant_digits);
9429 }
9430 }
9431
9432 /* Leave define mode... */
9433 NC(nc_enddef(ncid));
9434
9435 /* Hyperslabs... */
9436 size_t start[2] = { (size_t) profile, 0 };
9437 size_t count[2] = { 1, (size_t) obs->nr };
9438
9439 /* Write nray(profile)... */
9440 int nr = obs->nr;
9441 NC(nc_inq_varid(ncid, "nray", &varid));
9442 NC(nc_put_vara_int(ncid, varid, start, count, &nr));
9443
9444 /* Write geometry... */
9445 NC(nc_inq_varid(ncid, "time", &varid));
9446 NC(nc_put_vara_double(ncid, varid, start, count, obs->time));
9447
9448 NC(nc_inq_varid(ncid, "obs_z", &varid));
9449 NC(nc_put_vara_double(ncid, varid, start, count, obs->obsz));
9450
9451 NC(nc_inq_varid(ncid, "obs_lon", &varid));
9452 NC(nc_put_vara_double(ncid, varid, start, count, obs->obslon));
9453
9454 NC(nc_inq_varid(ncid, "obs_lat", &varid));
9455 NC(nc_put_vara_double(ncid, varid, start, count, obs->obslat));
9456
9457 NC(nc_inq_varid(ncid, "vp_z", &varid));
9458 NC(nc_put_vara_double(ncid, varid, start, count, obs->vpz));
9459
9460 NC(nc_inq_varid(ncid, "vp_lon", &varid));
9461 NC(nc_put_vara_double(ncid, varid, start, count, obs->vplon));
9462
9463 NC(nc_inq_varid(ncid, "vp_lat", &varid));
9464 NC(nc_put_vara_double(ncid, varid, start, count, obs->vplat));
9465
9466 NC(nc_inq_varid(ncid, "tp_z", &varid));
9467 NC(nc_put_vara_double(ncid, varid, start, count, obs->tpz));
9468
9469 NC(nc_inq_varid(ncid, "tp_lon", &varid));
9470 NC(nc_put_vara_double(ncid, varid, start, count, obs->tplon));
9471
9472 NC(nc_inq_varid(ncid, "tp_lat", &varid));
9473 NC(nc_put_vara_double(ncid, varid, start, count, obs->tplat));
9474
9475 /* Write spectral variables per channel... */
9476 for (int id = 0; id < ctl->nd; id++) {
9477 sprintf(varname, "%s_%.4f", spec_prefix, ctl->nu[id]);
9478 NC(nc_inq_varid(ncid, varname, &varid));
9479 NC(nc_put_vara_double(ncid, varid, start, count, obs->rad[id]));
9480
9481 sprintf(varname, "tau_%.4f", ctl->nu[id]);
9482 NC(nc_inq_varid(ncid, varname, &varid));
9483 NC(nc_put_vara_double(ncid, varid, start, count, obs->tau[id]));
9484 }
9485
9486 /* Close file... */
9487 NC(nc_sync(ncid));
9488 NC(nc_close(ncid));
9489}
9490
9491/*****************************************************************************/
9492
9494 const char *filename,
9495 const double *x,
9496 const double *y,
9497 const int n) {
9498
9499 /* Write info... */
9500 LOG(1, "Write shape function: %s", filename);
9501
9502 /* Create file... */
9503 FILE *out;
9504 if (!(out = fopen(filename, "w")))
9505 ERRMSG("Cannot create file!");
9506
9507 /* Write header... */
9508 fprintf(out,
9509 "# $1 = shape function x-value [-]\n"
9510 "# $2 = shape function y-value [-]\n\n");
9511
9512 /* Write data... */
9513 for (int i = 0; i < n; i++)
9514 fprintf(out, "%.10g %.10g\n", x[i], y[i]);
9515
9516 /* Close file... */
9517 fclose(out);
9518}
9519
9520/*****************************************************************************/
9521
9523 const char *quantity,
9524 const ret_t *ret,
9525 const ctl_t *ctl,
9526 const atm_t *atm,
9527 const gsl_matrix *s) {
9528
9529 /* Get sizes... */
9530 const size_t n = s->size1;
9531
9532 /* Allocate... */
9533 atm_t *atm_aux;
9534 ALLOC(atm_aux, atm_t, 1);
9535 gsl_vector *x_aux = gsl_vector_alloc(n);
9536
9537 /* Compute standard deviation... */
9538 for (size_t i = 0; i < n; i++)
9539 gsl_vector_set(x_aux, i, sqrt(gsl_matrix_get(s, i, i)));
9540
9541 /* Write to disk... */
9542 char filename[LEN];
9543 const char *dirname;
9544 int profile;
9545 const char *shared_file = "-";
9546 copy_atm(ctl, atm_aux, atm, 1);
9547 x2atm(ctl, x_aux, atm_aux);
9548 if (strcmp(quantity, "total") == 0)
9549 shared_file = ret->shared_io_atm_err_total_file;
9550 else if (strcmp(quantity, "noise") == 0)
9551 shared_file = ret->shared_io_atm_err_noise_file;
9552 else if (strcmp(quantity, "formod") == 0)
9553 shared_file = ret->shared_io_atm_err_formod_file;
9554 sprintf(filename, "atm_err_%s.tab", quantity);
9555 const char *target =
9556 shared_io_output_target(ret, shared_file, filename, &dirname, &profile);
9557 write_atm(dirname, target, ctl, atm_aux, profile);
9558
9559 /* Free... */
9560 gsl_vector_free(x_aux);
9561}
9562
9563/*****************************************************************************/
9564
9566 const ctl_t *ctl,
9567 const tbl_t *tbl) {
9568
9569 /* Loop over emitters and detectors... */
9570 for (int ig = 0; ig < ctl->ng; ig++)
9571 for (int id = 0; id < ctl->nd; id++) {
9572
9573 /* Skip empty tables... */
9574 if (tbl->np[id][ig] <= 0) {
9575 WARN("Skip writing empty emissivity table: emitter=%s, nu=%.4f",
9576 ctl->emitter[ig], ctl->nu[id]);
9577 continue;
9578 }
9579
9580 /* Write ASCII look-up tables... */
9581 if (ctl->tblfmt == 1)
9582 write_tbl_asc(ctl, tbl, id, ig);
9583
9584 /* Write binary look-up tables... */
9585 else if (ctl->tblfmt == 2)
9586 write_tbl_bin(ctl, tbl, id, ig);
9587
9588 /* Write netCDF look-up tables... */
9589 else if (ctl->tblfmt == 3)
9590 write_tbl_nc(ctl, tbl, id, ig);
9591
9592 /* Write info... */
9593 TBL_LOG(tbl, id, ig);
9594 }
9595
9596 /* Write filter functions... */
9597 if (ctl->tblfmt == 1)
9598 for (int id = 0; id < ctl->nd; id++) {
9599 char filename[2 * LEN];
9600 sprintf(filename, "%s_%.4f.filt", ctl->tblbase, ctl->nu[id]);
9601 write_shape(filename, tbl->filt_nu[id], tbl->filt_f[id],
9602 tbl->filt_n[id]);
9603 }
9604}
9605
9606/*****************************************************************************/
9607
9609 const ctl_t *ctl,
9610 const tbl_t *tbl,
9611 const int id,
9612 const int ig) {
9613
9614 /* Set filename... */
9615 char filename[2 * LEN];
9616 sprintf(filename, "%s_%.4f_%s.tab", ctl->tblbase,
9617 ctl->nu[id], ctl->emitter[ig]);
9618
9619 /* Create file... */
9620 FILE *out;
9621 if (!(out = fopen(filename, "w"))) {
9622 ERRMSG("Cannot create emissivity table: %s", filename);
9623 } else
9624 LOG(1, "Write emissivity table: %s", filename);
9625
9626 /* Write header... */
9627 fprintf(out,
9628 "# $1 = pressure [hPa]\n"
9629 "# $2 = temperature [K]\n"
9630 "# $3 = column density [molecules/cm^2]\n"
9631 "# $4 = emissivity [-]\n");
9632
9633 /* Save table file... */
9634 for (int ip = 0; ip < tbl->np[id][ig]; ip++)
9635 for (int it = 0; it < tbl->nt[id][ig][ip]; it++) {
9636 fprintf(out, "\n");
9637 for (int iu = 0; iu < tbl->nu[id][ig][ip][it]; iu++)
9638 fprintf(out, "%g %g %e %e\n",
9639 tbl->p[id][ig][ip], tbl->t[id][ig][ip][it],
9640 exp(tbl->logu[id][ig][ip][it][iu]),
9641 exp(tbl->logeps[id][ig][ip][it][iu]));
9642 }
9643
9644 /* Close file... */
9645 fclose(out);
9646}
9647
9648/*****************************************************************************/
9649
9651 const ctl_t *ctl,
9652 const tbl_t *tbl,
9653 const int id,
9654 const int ig) {
9655
9656 /* Set filename... */
9657 char filename[2 * LEN];
9658 sprintf(filename, "%s_%.4f_%s.bin",
9659 ctl->tblbase, ctl->nu[id], ctl->emitter[ig]);
9660
9661 /* Create file... */
9662 FILE *out;
9663 if (!(out = fopen(filename, "w"))) {
9664 ERRMSG("Cannot create emissivity table: %s", filename);
9665 } else
9666 LOG(1, "Write emissivity table: %s", filename);
9667
9668 /* Pack... */
9669 size_t used = 0;
9670 const size_t need = tbl_packed_size(tbl, id, ig);
9671 uint8_t *work = NULL;
9672 ALLOC(work, uint8_t, need);
9673 tbl_pack(tbl, id, ig, work, &used);
9674 if (used != need)
9675 ERRMSG("Internal error: packed size mismatch!");
9676
9677 /* Write length and packed blob... */
9678 FWRITE(&used, size_t,
9679 1,
9680 out);
9681 FWRITE(work, uint8_t, used, out);
9682
9683 /* Close file... */
9684 fclose(out);
9685
9686 /* Free... */
9687 free(work);
9688}
9689
9690/*****************************************************************************/
9691
9693 const ctl_t *ctl,
9694 const tbl_t *tbl,
9695 const int id,
9696 const int ig) {
9697
9698 /* Set filename... */
9699 char filename[2 * LEN];
9700 sprintf(filename, "%s_%s.nc", ctl->tblbase, ctl->emitter[ig]);
9701
9702 /* Open or create file... */
9703 int ncid;
9704 if (nc_open(filename, NC_WRITE, &ncid) != NC_NOERR) {
9705 if (nc_create(filename, NC_NETCDF4 | NC_CLOBBER, &ncid) != NC_NOERR)
9706 ERRMSG("Cannot open or create emissivity table: %s", filename);
9707 NC_PUT_ATT_GLOBAL("format_version", "1");
9708 NC_PUT_ATT_GLOBAL("emitter", ctl->emitter[ig]);
9709 NC(nc_enddef(ncid));
9710 }
9711
9712 /* Set variable and dimension name... */
9713 char varname[LEN], dimname[LEN];
9714 sprintf(varname, "tbl_%.4f", ctl->nu[id]);
9715 sprintf(dimname, "len_%.4f", ctl->nu[id]);
9716
9717 /* Write info... */
9718 LOG(1, "Write emissivity table: %s in %s", varname, filename);
9719
9720 /* Allocate work space... */
9721 size_t used = 0;
9722 const size_t need = tbl_packed_size(tbl, id, ig);
9723 uint8_t *work = NULL;
9724 ALLOC(work, uint8_t, need);
9725
9726 /* Pack table... */
9727 tbl_pack(tbl, id, ig, work, &used);
9728 if (used != need)
9729 ERRMSG("Internal error: packed size mismatch!");
9730
9731 /* Prevent overwrite... */
9732 int tmp;
9733 if (nc_inq_varid(ncid, varname, &tmp) == NC_NOERR)
9734 ERRMSG("Table already present!");
9735
9736 /* Add dimension and variable... */
9737 int dimid, varid;
9738 NC(nc_redef(ncid));
9739 NC(nc_def_dim(ncid, dimname, used, &dimid));
9740 int dimids[1] = { dimid };
9741 NC_DEF_VAR(varname, NC_UBYTE, 1, dimids,
9742 "Packed lookup table blob", "1", 0, 0);
9743 NC(nc_enddef(ncid));
9744
9745 /* Write data... */
9746 NC(nc_put_var_uchar(ncid, varid, (const unsigned char *) work));
9747
9748 /* Free... */
9749 free(work);
9750
9751 /* Close file... */
9752 NC(nc_close(ncid));
9753}
9754
9755/*****************************************************************************/
9756
9758 const ctl_t *ctl,
9759 const gsl_vector *x,
9760 atm_t *atm) {
9761
9762 size_t n = 0;
9763
9764 /* Get pressure... */
9765 for (int ip = 0; ip < atm->np; ip++)
9766 if (atm->z[ip] >= ctl->retp_zmin && atm->z[ip] <= ctl->retp_zmax)
9767 x2atm_help(&atm->p[ip], x, &n);
9768
9769 /* Get temperature... */
9770 for (int ip = 0; ip < atm->np; ip++)
9771 if (atm->z[ip] >= ctl->rett_zmin && atm->z[ip] <= ctl->rett_zmax)
9772 x2atm_help(&atm->t[ip], x, &n);
9773
9774 /* Get volume mixing ratio... */
9775 for (int ig = 0; ig < ctl->ng; ig++)
9776 for (int ip = 0; ip < atm->np; ip++)
9777 if (atm->z[ip] >= ctl->retq_zmin[ig]
9778 && atm->z[ip] <= ctl->retq_zmax[ig])
9779 x2atm_help(&atm->q[ig][ip], x, &n);
9780
9781 /* Get extinction... */
9782 for (int iw = 0; iw < ctl->nw; iw++)
9783 for (int ip = 0; ip < atm->np; ip++)
9784 if (atm->z[ip] >= ctl->retk_zmin[iw]
9785 && atm->z[ip] <= ctl->retk_zmax[iw])
9786 x2atm_help(&atm->k[iw][ip], x, &n);
9787
9788 /* Get cloud data... */
9789 if (ctl->ret_clz)
9790 x2atm_help(&atm->clz, x, &n);
9791 if (ctl->ret_cldz)
9792 x2atm_help(&atm->cldz, x, &n);
9793 if (ctl->ret_clk)
9794 for (int icl = 0; icl < ctl->ncl; icl++)
9795 x2atm_help(&atm->clk[icl], x, &n);
9796
9797 /* Get surface data... */
9798 if (ctl->ret_sft)
9799 x2atm_help(&atm->sft, x, &n);
9800 if (ctl->ret_sfeps)
9801 for (int isf = 0; isf < ctl->nsf; isf++)
9802 x2atm_help(&atm->sfeps[isf], x, &n);
9803}
9804
9805/*****************************************************************************/
9806
9808 double *value,
9809 const gsl_vector *x,
9810 size_t *n) {
9811
9812 /* Get state vector element... */
9813 *value = gsl_vector_get(x, *n);
9814 (*n)++;
9815}
9816
9817/*****************************************************************************/
9818
9820 const ctl_t *ctl,
9821 const gsl_vector *y,
9822 obs_t *obs) {
9823
9824 size_t m = 0;
9825
9826 /* Decompose measurement vector... */
9827 for (int ir = 0; ir < obs->nr; ir++)
9828 for (int id = 0; id < ctl->nd; id++)
9829 if (isfinite(obs->rad[id][ir])) {
9830 obs->rad[id][ir] = gsl_vector_get(y, m);
9831 m++;
9832 }
9833}
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:5047
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:31
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:7374
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:1641
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:6944
#define CLIM_TRANSITION
Definition jurassic.c:1230
void write_atm(const char *dirname, const char *filename, const ctl_t *ctl, const atm_t *atm, int profile)
Write atmospheric data to a file.
Definition jurassic.c:8150
void read_rfm_spec(const char *filename, double *nu, double *rad, int *npts)
Read a Reference Forward Model (RFM) ASCII spectrum.
Definition jurassic.c:7066
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:7884
void read_matrix_nc(const char *dirname, const char *filename, gsl_matrix *matrix, int dataset)
Read a numerical matrix from a netCDF file.
Definition jurassic.c:6614
double cos_sza(const double sec, const double lon, const double lat)
Calculates the cosine of the solar zenith angle.
Definition jurassic.c:1600
int 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:5795
void read_atm_bin(const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric data in binary format.
Definition jurassic.c:6161
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:9189
void formod_rfm(const ctl_t *ctl, const tbl_t *tbl, const atm_t *atm, obs_t *obs)
Forward-model radiance and transmittance with the Reference Forward Model (RFM).
Definition jurassic.c:4372
int locate_reg(const double *xx, const int n, const double x)
Locate index for interpolation on a regular (uniform) grid.
Definition jurassic.c:5328
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:4945
double ctmo2(const double nu, const double p, const double t)
Compute Oâ‚‚ collision-induced absorption coefficient.
Definition jurassic.c:3774
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:9313
void tbl_free(const ctl_t *ctl, tbl_t *tbl)
Free lookup table and all internally allocated memory.
Definition jurassic.c:7845
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:9608
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:9692
void idx2name(const ctl_t *ctl, const int idx, char *quantity)
Convert a quantity index to a descriptive name string.
Definition jurassic.c:4741
void read_ctl(int argc, char *argv[], ctl_t *ctl)
Read model control parameters from command-line and configuration input.
Definition jurassic.c:6359
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:4082
#define CLIM_TOP_CONSTANT
Definition jurassic.c:1237
void climatology(const ctl_t *ctl, const clim_t *clim, atm_t *atm)
Initializes atmospheric climatology profiles.
Definition jurassic.c:217
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:6787
int shared_io_lock(const ret_t *ret)
Acquire an exclusive lock for shared retrieval output files.
Definition jurassic.c:7723
#define CLIM_TOP_LOG
Definition jurassic.c:1238
void read_obs(const char *dirname, const char *filename, const ctl_t *ctl, obs_t *obs, int profile)
Read observation data from an input file.
Definition jurassic.c:6663
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:5399
int formod_pencil(const ctl_t *ctl, const tbl_t *tbl, const atm_t *atm, obs_t *obs, const int ir, los_t *los)
Compute line-of-sight radiances using the pencil-beam forward model.
Definition jurassic.c:4180
void climatology_external(const ctl_t *ctl, const clim_t *clim, atm_t *atm)
Overwrites the built-in climatology with a JuMACS climatology.
Definition jurassic.c:1580
int locate_irr(const double *xx, const int n, const double x)
Locate index for interpolation on an irregular grid.
Definition jurassic.c:5298
const char * shared_io_input_target(const ret_t *ret, const char *shared_file, const char *legacy_file, const char **dirname, int *profile)
Resolve retrieval input target for legacy-directory and shared-file modes.
Definition jurassic.c:7683
void write_matrix_asc(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 an ASCII file.
Definition jurassic.c:8633
void day2doy(int year, int mon, int day, int *doy)
Convert a calendar date to day-of-year.
Definition jurassic.c:3924
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:8372
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 dataset)
Write a fully annotated matrix (e.g., Jacobian or gain matrix) to file.
Definition jurassic.c:8596
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.
Definition jurassic.c:8048
void x2atm(const ctl_t *ctl, const gsl_vector *x, atm_t *atm)
Map retrieval state vector back to atmospheric structure.
Definition jurassic.c:9757
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:181
double ctmh2o(const double nu, const double p, const double t, const double q, const double u)
Compute the MT_CKD 4.1 water vapor continuum (optical depth).
Definition jurassic.c:2535
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:9650
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:4852
void shared_io_unlock(int fd)
Release a shared retrieval output lock.
Definition jurassic.c:7750
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:8559
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:7634
void write_obs(const char *dirname, const char *filename, const ctl_t *ctl, const obs_t *obs, int profile)
Write observation data to an output file in ASCII or binary format.
Definition jurassic.c:9118
void write_tbl(const ctl_t *ctl, const tbl_t *tbl)
Write emissivity lookup tables to disk.
Definition jurassic.c:9565
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:7972
void read_matrix(const char *dirname, const char *filename, const ctl_t *ctl, gsl_matrix *matrix, int dataset)
Read a numerical matrix from a file.
Definition jurassic.c:6496
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:4827
int find_emitter(const ctl_t *ctl, const char *emitter)
Find gas species index by name.
Definition jurassic.c:3974
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.
Definition jurassic.c:5471
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:5092
void timer_group(const char *name, const char *group, int output)
Aggregate wall-clock timings for named code phases.
Definition jurassic.c:8079
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:7802
double ctmco2(const double nu, const double p, const double t, const double u)
Compute carbon dioxide continuum optical depth.
Definition jurassic.c:1672
void read_atm(const char *dirname, const char *filename, const ctl_t *ctl, atm_t *atm, int profile)
Read atmospheric input data from a file.
Definition jurassic.c:6031
int formod_fov(const ctl_t *ctl, obs_t *obs, obs_t *obs_scratch)
Apply field-of-view (FOV) convolution to modeled radiances.
Definition jurassic.c:4118
void write_matrix_nc(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 dataset)
Write a numerical matrix to a netCDF file.
Definition jurassic.c:8855
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:8221
void write_matrix_bin(const char *dirname, const char *filename, const gsl_matrix *matrix)
Write a numerical matrix to a binary file.
Definition jurassic.c:8806
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:3886
void formod_batch(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs, const int nbatch, int *status, los_t *los_scratch, obs_t *obs_scratch)
Execute the forward model for a batch of independent cases.
Definition jurassic.c:4038
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:9245
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:9807
void cart2geo(const double *x, double *z, double *lon, double *lat)
Converts Cartesian coordinates to geographic coordinates.
Definition jurassic.c:202
void doy2day(int year, int doy, int *mon, int *day)
Convert a day-of-year value to a calendar date.
Definition jurassic.c:3944
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:5171
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:6865
void init_srcfunc(const ctl_t *ctl, tbl_t *tbl)
Initialize source function lookup tables from emissivity data.
Definition jurassic.c:4780
void matrix_invert(gsl_matrix *a)
Invert a square matrix, optimized for diagonal or symmetric positive-definite matrices.
Definition jurassic.c:5369
void read_ret(int argc, char *argv[], const ctl_t *ctl, ret_t *ret)
Read retrieval configuration and error parameters.
Definition jurassic.c:6978
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:7455
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:9493
void read_atm_asc(const char *filename, const ctl_t *ctl, atm_t *atm)
Read atmospheric data in ASCII format.
Definition jurassic.c:6105
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:7251
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:4646
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:103
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.
Definition jurassic.c:5138
void read_matrix_asc(const char *dirname, const char *filename, gsl_matrix *matrix)
Read a numerical matrix from an ASCII file.
Definition jurassic.c:6522
tbl_t * read_tbl(const ctl_t *ctl)
Read emissivity lookup tables from disk.
Definition jurassic.c:7175
void read_matrix_bin(const char *dirname, const char *filename, gsl_matrix *matrix)
Read a numerical matrix from a binary file.
Definition jurassic.c:6561
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:7418
const char * shared_io_output_target(const ret_t *ret, const char *shared_file, const char *legacy_file, const char **dirname, int *profile)
Resolve retrieval output target for legacy-directory and shared-file modes.
Definition jurassic.c:7703
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:6255
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:3836
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:5444
void y2obs(const ctl_t *ctl, const gsl_vector *y, obs_t *obs)
Copy elements from the measurement vector y into the observation structure.
Definition jurassic.c:9819
void hydrostatic(const ctl_t *ctl, atm_t *atm)
Adjust pressure profile using the hydrostatic equation.
Definition jurassic.c:4681
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:7128
double ctmn2(const double nu, const double p, const double t)
Compute Nâ‚‚ collision-induced absorption coefficient.
Definition jurassic.c:3705
void climatology_external_interp(const clim_t *clim, const atm_t *atm, const double field[CT][CZ][CLAT], const int top_policy, double *out)
Interpolates a JuMACS climatology field onto atmospheric profiles.
Definition jurassic.c:1260
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:127
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:4663
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:7523
const char * shared_io_output_file(const ret_t *ret)
Return the primary shared retrieval output file configured for locking.
Definition jurassic.c:7768
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:9522
int formod(const ctl_t *ctl, const tbl_t *tbl, atm_t *atm, obs_t *obs, los_t *los_scratch, obs_t *obs_scratch)
Execute one complete forward-model calculation.
Definition jurassic.c:3987
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:7938
clim_t * read_clim(const ctl_t *ctl)
Reads a JuMACS climatology file into an allocated climatology structure.
Definition jurassic.c:1363
int locate_tbl(const float *xx, const int n, const double x)
Locate index for interpolation within emissivity table grids.
Definition jurassic.c:5347
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:8288
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:6738
int read_clim_field(const char *filename, const char *varname, const int ncid, const int dim_month, const int dim_alt, const int dim_lat, const int nalt, const int nlat, double field[CT][CZ][CLAT], double *vmin, double *vmax)
Reads and validates one JuMACS climatology field.
Definition jurassic.c:1168
JURASSIC library declarations.
#define N
Maximum size of state vector.
Definition jurassic.h:346
#define IDXCLZ
Index for cloud layer height.
Definition jurassic.h:468
#define LEN
Maximum length of ASCII data lines.
Definition jurassic.h:336
#define RE
Mean radius of Earth [km].
Definition jurassic.h:233
#define BRIGHT(rad, nu)
Compute brightness temperature from radiance.
Definition jurassic.h:533
@ FORMOD_STATUS_TOO_MANY_LOS_POINTS
Definition jurassic.h:163
@ FORMOD_STATUS_OK
Definition jurassic.h:159
@ FORMOD_STATUS_FOV_DATA_MISSING
Definition jurassic.h:161
@ FORMOD_STATUS_OBSERVER_BELOW_SURFACE
Definition jurassic.h:162
@ FORMOD_STATUS_NO_ATMOSPHERE_INTERSECTION
Definition jurassic.h:164
#define P0
Standard pressure [hPa].
Definition jurassic.h:228
#define KB
Boltzmann constant [kg m^2/(K s^2)].
Definition jurassic.h:203
#define POW2(x)
Compute the square of a value.
Definition jurassic.h:1144
#define NFOV
Number of ray paths used for FOV calculations.
Definition jurassic.h:361
#define KERNEL_T_ABS
Absolute temperature step [K].
Definition jurassic.h:287
#define FWRITE(ptr, type, size, out)
Write binary data to a file.
Definition jurassic.h:704
#define NC_PUT_ATT_GLOBAL(attname, text)
Add a global text attribute to a NetCDF file.
Definition jurassic.h:1021
#define NC(cmd)
Execute a NetCDF command and check for errors.
Definition jurassic.h:800
#define TBL_LOG(tbl, id, ig)
Log detailed statistics of an emissivity look-up table.
Definition jurassic.h:1250
#define SELECT_TIMER(id, group)
Switch to a named aggregated timer.
Definition jurassic.h:1284
#define DOTP(a, b)
Compute dot product of two 3D vectors.
Definition jurassic.h:643
#define O2
Oxygen concentration.
Definition jurassic.h:223
#define UMAX
Maximum column density [molecules/cm^2].
Definition jurassic.h:268
#define KERNEL_CLZ_ABS
Absolute cloud center altitude step [km].
Definition jurassic.h:307
#define KERNEL_P_MIN
Minimum absolute pressure step [hPa].
Definition jurassic.h:282
#define MIN(a, b)
Determine the minimum of two values.
Definition jurassic.h:787
#define IDXCLDZ
Index for cloud layer depth.
Definition jurassic.h:471
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition jurassic.h:1451
#define NC_PUT_INT(varname, ptr, hyperslab)
Write integer data to a NetCDF variable.
Definition jurassic.h:982
#define CLAMP(v, lo, hi)
Clamp a value to a specified range.
Definition jurassic.h:555
#define RFMNPTS
Maximum number of RFM spectral grid points.
Definition jurassic.h:428
#define IDXK(iw)
Indices for extinction.
Definition jurassic.h:465
#define M
Maximum size of measurement vector.
Definition jurassic.h:341
#define KERNEL_P_REL
Relative pressure step (fraction of pressure).
Definition jurassic.h:277
#define KERNEL_SFT_ABS
Absolute surface temperature step [K].
Definition jurassic.h:322
#define CO2_FIT(TIME)
Climatological CO2 volume mixing ratio as a quadratic function of time.
Definition jurassic.h:570
#define G0
Standard gravity [m/s^2].
Definition jurassic.h:193
#define NQ
Maximum number of quantities.
Definition jurassic.h:398
#define ND
Maximum number of radiance channels.
Definition jurassic.h:356
#define NA
Avogadro's number.
Definition jurassic.h:213
#define LOGY(x0, y0, x1, y1, x)
Compute logarithmic interpolation in y.
Definition jurassic.h:748
#define KERNEL_K_ABS
Absolute atmospheric extinction step [km^-1].
Definition jurassic.h:302
#define NSHAPE
Maximum number of shape function grid points.
Definition jurassic.h:413
#define IDXSFT
Index for surface layer temperature.
Definition jurassic.h:477
#define CT
Maximum number of time steps for climatological data.
Definition jurassic.h:371
#define RI
Ideal gas constant [J/(mol K)].
Definition jurassic.h:238
#define NORM(a)
Compute the norm (magnitude) of a 3D vector.
Definition jurassic.h:1099
#define IDXSFEPS(isf)
Indices for surface layer emissivity.
Definition jurassic.h:480
#define IDXCLK(icl)
Indices for cloud layer extinction.
Definition jurassic.h:474
#define TOK(line, tok, format, var)
Tokenize a string and parse a variable.
Definition jurassic.h:1315
#define WARN(...)
Print a warning message with contextual information.
Definition jurassic.h:1418
#define TBLNU
Maximum number of column densities per emissivity curve.
Definition jurassic.h:448
#define IDXP
Index for pressure.
Definition jurassic.h:456
#define ALLOC(ptr, type, n)
Allocate memory for an array.
Definition jurassic.h:503
#define CLAT
Maximum number of latitudes for climatological data (JuMACS: 36 area-weighted 5-degree bands).
Definition jurassic.h:383
#define DEG2RAD(deg)
Convert degrees to radians.
Definition jurassic.h:590
#define TSUN
Effective temperature of the sun [K].
Definition jurassic.h:258
#define RAD2DEG(rad)
Convert radians to degrees.
Definition jurassic.h:1173
#define TBLNT
Maximum number of temperatures in emissivity tables.
Definition jurassic.h:443
#define NP
Maximum number of atmospheric data points.
Definition jurassic.h:393
#define NTIMER
Maximum number of aggregated timers.
Definition jurassic.h:418
#define PLANCK(T, nu)
Compute spectral radiance using Planck’s law.
Definition jurassic.h:1130
#define KERNEL_Q_REL
Relative gas VMR step (fraction of VMR).
Definition jurassic.h:292
#define KERNEL_CLK_ABS
Absolute cloud extinction step [km^-1].
Definition jurassic.h:317
#define REFRAC_EDLEN(p, T)
Compute dry-air refractivity (n - 1) with an Edlen-type relation.
Definition jurassic.h:1230
#define KERNEL_CLDZ_ABS
Absolute cloud width step [km].
Definition jurassic.h:312
#define NG
Maximum number of emitters.
Definition jurassic.h:366
#define EPSMAX
Maximum emissivity.
Definition jurassic.h:188
#define LOG(level,...)
Print a log message with a specified logging level.
Definition jurassic.h:1381
#define TBLNS
Maximum number of source function temperature levels.
Definition jurassic.h:438
#define NC_DEF_VAR(varname, type, ndims, dims, long_name, units, level, quant)
Define a NetCDF variable with attributes.
Definition jurassic.h:830
#define N2
Nitrogen concentration.
Definition jurassic.h:218
#define CZ
Maximum number of altitudes for climatological data (JuMACS: 0...150 km at 1 km spacing).
Definition jurassic.h:377
#define TBLNP
Maximum number of pressure levels in emissivity tables.
Definition jurassic.h:433
#define NSF
Maximum number of surface layer spectral grid points.
Definition jurassic.h:408
#define NCL
Maximum number of cloud layer spectral grid points.
Definition jurassic.h:351
#define DIST(a, b)
Compute Cartesian distance between two 3D vectors.
Definition jurassic.h:608
#define NC_PUT_DOUBLE(varname, ptr, hyperslab)
Write double precision data to a NetCDF variable.
Definition jurassic.h:935
#define FREAD(ptr, type, size, out)
Read binary data from a file.
Definition jurassic.h:681
#define LIN(x0, y0, x1, y1, x)
Compute linear interpolation.
Definition jurassic.h:727
#define NLOS
Maximum number of LOS points.
Definition jurassic.h:388
#define KERNEL_SFEPS_ABS
Absolute surface emissivity step (dimensionless).
Definition jurassic.h:327
#define NR
Maximum number of ray paths.
Definition jurassic.h:403
#define IDXQ(ig)
Indices for volume mixing ratios.
Definition jurassic.h:462
#define KERNEL_Q_MIN
Minimum absolute gas VMR step (dimensionless).
Definition jurassic.h:297
#define TMAX
Maximum temperature for source function [K].
Definition jurassic.h:248
#define TMIN
Minimum temperature for source function [K].
Definition jurassic.h:253
#define NW
Maximum number of spectral windows.
Definition jurassic.h:423
#define MAX(a, b)
Determine the maximum of two values.
Definition jurassic.h:769
#define IDXT
Index for temperature.
Definition jurassic.h:459
#define FMOD(x, y)
Compute floating-point remainder.
Definition jurassic.h:660
Atmospheric profile data.
Definition jurassic.h:1501
double time[NP]
Time (seconds since 2000-01-01T00:00Z).
Definition jurassic.h:1507
double sfeps[NSF]
Surface emissivity.
Definition jurassic.h:1543
double k[NW][NP]
Extinction [km^-1].
Definition jurassic.h:1528
double lat[NP]
Latitude [deg].
Definition jurassic.h:1516
double lon[NP]
Longitude [deg].
Definition jurassic.h:1513
double t[NP]
Temperature [K].
Definition jurassic.h:1522
double clz
Cloud layer height [km].
Definition jurassic.h:1531
int np
Number of data points.
Definition jurassic.h:1504
double cldz
Cloud layer depth [km].
Definition jurassic.h:1534
double sft
Surface temperature [K].
Definition jurassic.h:1540
double z[NP]
Altitude [km].
Definition jurassic.h:1510
double clk[NCL]
Cloud layer extinction [km^-1].
Definition jurassic.h:1537
double q[NG][NP]
Volume mixing ratio [ppv].
Definition jurassic.h:1525
double p[NP]
Pressure [hPa].
Definition jurassic.h:1519
JuMACS climatology on a fixed grid.
Definition jurassic.h:1553
int has_q[NG]
Set for each emitter with a field read.
Definition jurassic.h:1582
double alt[CZ]
Altitude grid [km].
Definition jurassic.h:1564
int ntime
Number of climatological time coordinates.
Definition jurassic.h:1561
double time[CT]
Climatological time coordinates [s into year].
Definition jurassic.h:1570
double q[NG][CT][CZ][CLAT]
Volume mixing ratio [ppv].
Definition jurassic.h:1576
int has_t
Set if a temperature field was read.
Definition jurassic.h:1579
double t[CT][CZ][CLAT]
Temperature [K].
Definition jurassic.h:1573
int nalt
Number of altitude levels.
Definition jurassic.h:1555
double lat[CLAT]
Latitude grid [deg].
Definition jurassic.h:1567
int nlat
Number of latitude bands.
Definition jurassic.h:1558
Control parameters.
Definition jurassic.h:1593
char rfmtmp[LEN]
Base directory for temporary RFM working directories.
Definition jurassic.h:1749
int write_matrix
Write matrix file (0=no, 1=yes).
Definition jurassic.h:1740
int nw
Number of spectral windows.
Definition jurassic.h:1620
int atmfmt
Atmospheric data file format (1=ASCII, 2=binary, 3=netCDF).
Definition jurassic.h:1653
double retp_zmin
Minimum altitude for pressure retrieval [km].
Definition jurassic.h:1698
double nu[ND]
Centroid wavenumber of each channel [cm^-1].
Definition jurassic.h:1617
int ig_co2
Emitter index of CO2.
Definition jurassic.h:1602
double retk_zmax[NW]
Maximum altitude for extinction retrieval [km].
Definition jurassic.h:1719
char climfile[LEN]
Climatological data file ("-" = built-in climatology).
Definition jurassic.h:1650
double sfnu[NSF]
Surface layer wavenumber [cm^-1].
Definition jurassic.h:1635
char rfmhit[LEN]
HITRAN file for RFM.
Definition jurassic.h:1752
char tblbase[LEN]
Basename for table files and filter function files.
Definition jurassic.h:1644
char rfmbin[LEN]
Path to RFM binary.
Definition jurassic.h:1746
double hydz
Reference height for hydrostatic pressure profile (-999 to skip) [km].
Definition jurassic.h:1662
int ctm_co2
Compute CO2 continuum (0=no, 1=yes).
Definition jurassic.h:1665
double rett_zmax
Maximum altitude for temperature retrieval [km].
Definition jurassic.h:1707
int ret_sfeps
Retrieve surface layer emissivity (0=no, 1=yes).
Definition jurassic.h:1734
int ret_sft
Retrieve surface layer temperature (0=no, 1=yes).
Definition jurassic.h:1731
int ret_clz
Retrieve cloud layer height (0=no, 1=yes).
Definition jurassic.h:1722
int ctm_n2
Compute N2 continuum (0=no, 1=yes).
Definition jurassic.h:1671
char fov[LEN]
Field-of-view data file.
Definition jurassic.h:1686
char rfmxsc[NG][LEN]
Emitter cross-section files for RFM.
Definition jurassic.h:1755
int window[ND]
Window index of each channel.
Definition jurassic.h:1623
int ctm_h2o
Compute H2O continuum (0=no, 1=yes).
Definition jurassic.h:1668
int formod
Forward model (0=CGA, 1=EGA, 2=RFM).
Definition jurassic.h:1743
double retq_zmax[NG]
Maximum altitude for volume mixing ratio retrieval [km].
Definition jurassic.h:1713
double retq_zmin[NG]
Minimum altitude for volume mixing ratio retrieval [km].
Definition jurassic.h:1710
int ng
Number of emitters.
Definition jurassic.h:1596
double clnu[NCL]
Cloud layer wavenumber [cm^-1].
Definition jurassic.h:1629
int refrac
Take into account refractivity (0=no, 1=yes).
Definition jurassic.h:1677
int ig_o2
Emitter index of O2.
Definition jurassic.h:1611
double rett_zmin
Minimum altitude for temperature retrieval [km].
Definition jurassic.h:1704
double sfsza
Solar zenith angle at the surface [deg] (-999=auto).
Definition jurassic.h:1641
int nd
Number of radiance channels.
Definition jurassic.h:1614
int fov_n
Field-of-view number of data points.
Definition jurassic.h:1695
int sftype
Surface treatment (0=none, 1=emissions, 2=downward, 3=solar).
Definition jurassic.h:1638
int matrixfmt
Matrix data file format (1=ASCII, 2=binary, 3=netCDF).
Definition jurassic.h:1659
double retk_zmin[NW]
Minimum altitude for extinction retrieval [km].
Definition jurassic.h:1716
int ncl
Number of cloud layer spectral grid points.
Definition jurassic.h:1626
int ig_n2
Emitter index of N2.
Definition jurassic.h:1608
int obsfmt
Observation data file format (1=ASCII, 2=binary, 3=netCDF).
Definition jurassic.h:1656
double fov_dz[NSHAPE]
Field-of-view vertical distance [km].
Definition jurassic.h:1689
int ctm_o2
Compute O2 continuum (0=no, 1=yes).
Definition jurassic.h:1674
int ret_clk
Retrieve cloud layer extinction (0=no, 1=yes).
Definition jurassic.h:1728
char emitter[NG][LEN]
Name of each emitter.
Definition jurassic.h:1599
int nsf
Number of surface layer spectral grid points.
Definition jurassic.h:1632
double rayds
Maximum step length for raytracing [km].
Definition jurassic.h:1680
int ret_cldz
Retrieve cloud layer depth (0=no, 1=yes).
Definition jurassic.h:1725
int ig_h2o
Emitter index of H2O.
Definition jurassic.h:1605
int tblfmt
Look-up table file format (1=ASCII, 2=binary, 3=netCDF).
Definition jurassic.h:1647
double raydz
Vertical step length for raytracing [km].
Definition jurassic.h:1683
int write_bbt
Use brightness temperature instead of radiance (0=no, 1=yes).
Definition jurassic.h:1737
double fov_w[NSHAPE]
Field-of-view weighting factor.
Definition jurassic.h:1692
double retp_zmax
Maximum altitude for pressure retrieval [km].
Definition jurassic.h:1701
Line-of-sight data.
Definition jurassic.h:1766
double z[NLOS]
Altitude [km].
Definition jurassic.h:1772
double eps[NLOS][ND]
Segment emissivity.
Definition jurassic.h:1814
double cgu[NLOS][NG]
Curtis-Godson column density [molecules/cm^2].
Definition jurassic.h:1811
double q[NLOS][NG]
Volume mixing ratio [ppv].
Definition jurassic.h:1787
double sft
Surface temperature [K].
Definition jurassic.h:1793
double cgt[NLOS][NG]
Curtis-Godson temperature [K].
Definition jurassic.h:1808
double lon[NLOS]
Longitude [deg].
Definition jurassic.h:1775
double ds[NLOS]
Segment length [km].
Definition jurassic.h:1799
int np
Number of LOS points.
Definition jurassic.h:1769
double u[NLOS][NG]
Column density [molecules/cm^2].
Definition jurassic.h:1802
double lat[NLOS]
Latitude [deg].
Definition jurassic.h:1778
double src[NLOS][ND]
Segment source function [W/(m^2 sr cm^-1)].
Definition jurassic.h:1817
double k[NLOS][ND]
Extinction [km^-1].
Definition jurassic.h:1790
double sfeps[ND]
Surface emissivity.
Definition jurassic.h:1796
double cgp[NLOS][NG]
Curtis-Godson pressure [hPa].
Definition jurassic.h:1805
double t[NLOS]
Temperature [K].
Definition jurassic.h:1784
double p[NLOS]
Pressure [hPa].
Definition jurassic.h:1781
Observation geometry and radiance data.
Definition jurassic.h:1828
double tau[ND][NR]
Transmittance of ray path.
Definition jurassic.h:1864
double rad[ND][NR]
Radiance [W/(m^2 sr cm^-1)].
Definition jurassic.h:1867
double tplon[NR]
Tangent point longitude [deg].
Definition jurassic.h:1858
double vpz[NR]
View point altitude [km].
Definition jurassic.h:1846
double vplat[NR]
View point latitude [deg].
Definition jurassic.h:1852
double obslon[NR]
Observer longitude [deg].
Definition jurassic.h:1840
double obslat[NR]
Observer latitude [deg].
Definition jurassic.h:1843
double obsz[NR]
Observer altitude [km].
Definition jurassic.h:1837
double tplat[NR]
Tangent point latitude [deg].
Definition jurassic.h:1861
double vplon[NR]
View point longitude [deg].
Definition jurassic.h:1849
double time[NR]
Time (seconds since 2000-01-01T00:00Z).
Definition jurassic.h:1834
double tpz[NR]
Tangent point altitude [km].
Definition jurassic.h:1855
int nr
Number of ray paths.
Definition jurassic.h:1831
int mask[ND][NR]
Internal observation mask used by the forward model.
Definition jurassic.h:1870
Retrieval control parameters.
Definition jurassic.h:1883
char shared_io_atm_final_file[LEN]
Optional shared retrieved-atmosphere output file.
Definition jurassic.h:1970
double err_press_cz
Vertical correlation length for pressure error [km].
Definition jurassic.h:1910
double err_press
Pressure error [%].
Definition jurassic.h:1907
char shared_io_atm_res_file[LEN]
Optional shared averaging-kernel resolution output file.
Definition jurassic.h:2006
double err_k_cz[NW]
Vertical correlation length for extinction error [km].
Definition jurassic.h:1937
int err_ana
Carry out error analysis (0=no, 1=yes).
Definition jurassic.h:1898
double err_k_ch[NW]
Horizontal correlation length for extinction error [km].
Definition jurassic.h:1940
double err_temp_cz
Vertical correlation length for temperature error [km].
Definition jurassic.h:1919
double err_formod[ND]
Forward model error [%].
Definition jurassic.h:1901
char shared_io_matrix_cov_apr_file[LEN]
Optional shared a priori covariance output file.
Definition jurassic.h:1976
double conv_dmin
Minimum normalized step size in state space.
Definition jurassic.h:1895
double err_temp
Temperature error [K].
Definition jurassic.h:1916
double err_q_cz[NG]
Vertical correlation length for volume mixing ratio error [km].
Definition jurassic.h:1928
char shared_io_proflist[LEN]
Optional file containing retrieval profile indices.
Definition jurassic.h:1961
double err_noise[ND]
Noise error [W/(m^2 sr cm^-1)].
Definition jurassic.h:1904
double err_clz
Cloud height error [km].
Definition jurassic.h:1943
double err_sft
Surface temperature error [K].
Definition jurassic.h:1952
double err_clk[NCL]
Cloud extinction error [km^-1].
Definition jurassic.h:1949
char shared_io_matrix_gain_file[LEN]
Optional shared gain matrix output file.
Definition jurassic.h:1988
char shared_io_obs_meas_file[LEN]
Optional shared measured-observation input file.
Definition jurassic.h:1967
char shared_io_matrix_cov_ret_file[LEN]
Optional shared retrieval covariance output file.
Definition jurassic.h:1982
char shared_io_matrix_kernel_file[LEN]
Optional shared kernel matrix output file.
Definition jurassic.h:1979
char shared_io_atm_apr_file[LEN]
Optional shared atmospheric a priori input file.
Definition jurassic.h:1964
char shared_io_matrix_avk_file[LEN]
Optional shared averaging-kernel matrix output file.
Definition jurassic.h:1991
double err_temp_ch
Horizontal correlation length for temperature error [km].
Definition jurassic.h:1922
int kernel_recomp
Re-computation of kernel matrix (number of iterations).
Definition jurassic.h:1889
int conv_itmax
Maximum number of iterations.
Definition jurassic.h:1892
char shared_io_atm_err_formod_file[LEN]
Optional shared forward-model retrieval-error output file.
Definition jurassic.h:2000
double err_cldz
Cloud depth error [km].
Definition jurassic.h:1946
double err_press_ch
Horizontal correlation length for pressure error [km].
Definition jurassic.h:1913
double err_q_ch[NG]
Horizontal correlation length for volume mixing ratio error [km].
Definition jurassic.h:1931
char shared_io_matrix_corr_file[LEN]
Optional shared correlation matrix output file.
Definition jurassic.h:1985
char shared_io_atm_err_total_file[LEN]
Optional shared total retrieval-error output file.
Definition jurassic.h:1994
double err_q[NG]
Volume mixing ratio error [%].
Definition jurassic.h:1925
char dir[LEN]
Working directory.
Definition jurassic.h:1886
char shared_io_atm_err_noise_file[LEN]
Optional shared noise retrieval-error output file.
Definition jurassic.h:1997
char shared_io_obs_final_file[LEN]
Optional shared retrieved-observation output file.
Definition jurassic.h:1973
double err_sfeps[NSF]
Surface emissivity error.
Definition jurassic.h:1955
char shared_io_atm_cont_file[LEN]
Optional shared averaging-kernel contribution output file.
Definition jurassic.h:2003
int shared_io_profile
Profile index used for shared netCDF retrieval inputs and outputs.
Definition jurassic.h:1958
double err_k[NW]
Extinction error [km^-1].
Definition jurassic.h:1934
Emissivity look-up tables.
Definition jurassic.h:2016
float * logu[ND][NG][TBLNP][TBLNT]
Logarithm of column density [molecules/cm^2].
Definition jurassic.h:2037
double sr[TBLNS][ND]
Source function radiance [W/(m^2 sr cm^-1)].
Definition jurassic.h:2055
double p[ND][NG][TBLNP]
Pressure [hPa].
Definition jurassic.h:2028
int nu[ND][NG][TBLNP][TBLNT]
Number of column densities.
Definition jurassic.h:2025
int filt_n[ND]
Filter function number of spectral grid points.
Definition jurassic.h:2043
int nt[ND][NG][TBLNP]
Number of temperatures.
Definition jurassic.h:2022
float * logeps[ND][NG][TBLNP][TBLNT]
Logarithm of emissivity.
Definition jurassic.h:2040
double filt_f[ND][NSHAPE]
Filter function values.
Definition jurassic.h:2049
double t[ND][NG][TBLNP][TBLNT]
Temperature [K].
Definition jurassic.h:2034
double lnp[ND][NG][TBLNP]
Log-pressure [hPa].
Definition jurassic.h:2031
double st[TBLNS]
Source function temperature [K].
Definition jurassic.h:2052
double filt_nu[ND][NSHAPE]
Filter function spectral grid points [cm^-1].
Definition jurassic.h:2046
int np[ND][NG]
Number of pressure levels.
Definition jurassic.h:2019