JURASSIC
tblrdc.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) 2013-2026 Forschungszentrum Juelich GmbH
18*/
19
25#include "jurassic.h"
26
27/* ------------------------------------------------------------
28 Functions...
29 ------------------------------------------------------------ */
30
32static void copy_density(
33 tbl_t * tbl,
34 int id,
35 int ig,
36 int ip,
37 int it,
38 int dst,
39 int src);
40
42static void reduction(
43 tbl_t * tbl,
44 int id,
45 int ig,
46 int ip,
47 int it,
48 int left,
49 int right,
50 int *write_idx,
51 double atol,
52 double rtol);
53
55static void usage(
56 void);
57
58/* ------------------------------------------------------------
59 Main...
60 ------------------------------------------------------------ */
61
62int main(
63 int argc,
64 char *argv[]) {
65 ctl_t ctl;
66
67 /* Print usage information... */
68 USAGE;
69
70 /* Check arguments... */
71 if (argc < 6)
72 ERRMSG("Missing or invalid command-line arguments.\n\n"
73 "Usage: tblrdc <ctl> <tblbase_in> <tblfmt_in> <tblbase_out> <tblfmt_out> [KEY VALUE ...]\n\n"
74 "Use -h for full help.");
75
76 /* Read control parameters... */
77 read_ctl(argc, argv, &ctl);
78 const double atol = scan_ctl(argc, argv, "ATOL", -1, "1e-9", NULL);
79 const double rtol = scan_ctl(argc, argv, "RTOL", -1, "0.01", NULL);
80
81 /* Read tables... */
82 sprintf(ctl.tblbase, "%s", argv[2]);
83 ctl.tblfmt = atoi(argv[3]);
84 tbl_t *tbl = read_tbl(&ctl);
85
86 /* Loop over trace gases and channels... */
87 for (int id = 0; id < ctl.nd; id++)
88 for (int ig = 0; ig < ctl.ng; ig++) {
89
90 /* Init counters... */
91 int total_input = 0;
92 int total_output = 0;
93
94 /* Loop over (p, T) combinations... */
95 for (int ip = 0; ip < tbl->np[id][ig]; ip++) {
96 for (int it = 0; it < tbl->nt[id][ig][ip]; it++) {
97
98 const int num_points = tbl->nu[id][ig][ip][it];
99
100 /* First entry is implicitly kept (in-place reduction)... */
101 int write_idx = 1;
102
103 /* Reduce Middle-Entries if more than 2 entries... */
104 if (num_points > 2)
105 reduction(tbl, id, ig, ip, it, 0, num_points - 1, &write_idx,
106 atol, rtol);
107
108 /* Keep last entry if more than 1 entry... */
109 if (num_points > 1) {
110 copy_density(tbl, id, ig, ip, it, write_idx, num_points - 1);
111 write_idx++;
112 }
113
114 /* Update number of kept points... */
115 tbl->nu[id][ig][ip][it] = write_idx;
116 total_input += num_points;
117 total_output += write_idx;
118 }
119 }
120
121 /* Write info... */
122 LOG(1, "Reduction: %s | %.4f cm^-1 | n= %d | CR= %g", ctl.emitter[ig],
123 ctl.nu[id], total_input,
124 total_output > 0 ? (double) total_input / total_output : NAN);
125
126 }
127
128 /* Write tables... */
129 sprintf(ctl.tblbase, "%s", argv[4]);
130 ctl.tblfmt = atoi(argv[5]);
131 write_tbl(&ctl, tbl);
132
133 /* Free... */
134 tbl_free(&ctl, tbl);
135
136 return EXIT_SUCCESS;
137}
138
139/*****************************************************************************/
140
141static void usage(
142 void) {
143 printf("\nJURASSIC lookup-table reduction tool.\n\n");
144 printf("Reduce look-up table size by adaptive interpolation with\n");
145 printf("absolute and relative error thresholds.\n\n");
146 printf("Usage:\n");
147 printf
148 (" tblrdc <ctl> <tblbase_in> <tblfmt_in> <tblbase_out> <tblfmt_out>\n");
149 printf(" [KEY VALUE ...]\n\n");
150 printf("Arguments:\n");
151 printf(" <ctl> Control file.\n");
152 printf(" <tblbase_in> Input table base name.\n");
153 printf(" <tblfmt_in> Input table format identifier.\n");
154 printf(" <tblbase_out> Output table base name.\n");
155 printf(" <tblfmt_out> Output table format identifier.\n");
156 printf(" [KEY VALUE] Optional control parameters.\n\n");
157 printf("Tool-specific control parameters:\n");
158 printf(" ATOL <x> Absolute interpolation-error threshold.\n");
159 printf(" RTOL <x> Relative interpolation-error threshold.\n\n");
160 printf("Common control parameters:\n");
161 printf(" NG, EMITTER[i] Active emitters.\n");
162 printf(" ND, NU[i] Spectral channels.\n\n");
163 printf("Further information:\n");
164 printf(" Manual: https://slcs-jsc.github.io/jurassic/\n");
165}
166
167/*****************************************************************************/
168
169static void copy_density(
170 tbl_t *tbl,
171 int id,
172 int ig,
173 int ip,
174 int it,
175 int dst,
176 int src) {
177
178 tbl->logu[id][ig][ip][it][dst] = tbl->logu[id][ig][ip][it][src];
179 tbl->logeps[id][ig][ip][it][dst] = tbl->logeps[id][ig][ip][it][src];
180}
181
182/*****************************************************************************/
183
184static void reduction(
185 tbl_t *tbl,
186 int id,
187 int ig,
188 int ip,
189 int it,
190 int left,
191 int right,
192 int *write_idx,
193 double atol,
194 double rtol) {
195
196 int worstindex = -1;
197 double max_err = 0.0;
198
199 /* Scan interior points and find the largest interpolation error... */
200 for (int iu = left + 1; iu < right; iu++) {
201
202 /* Linear interpolation in log-log space: interpolate log(eps) linearly over log(u)... */
203 const double interp_logeps =
204 LIN(tbl->logu[id][ig][ip][it][left], tbl->logeps[id][ig][ip][it][left],
205 tbl->logu[id][ig][ip][it][right],
206 tbl->logeps[id][ig][ip][it][right],
207 tbl->logu[id][ig][ip][it][iu]);
208
209 /* Compute relative error in linear eps (eps = exp(logeps)) */
210 const double eps_i = exp((double) tbl->logeps[id][ig][ip][it][iu]);
211 const double interp_eps = exp(interp_logeps);
212 const double diff = fabs(eps_i - interp_eps);
213
214 /* Check interpolation errors and find maximum error... */
215 if (diff > atol + rtol * fabs(eps_i) && diff > max_err) {
216 max_err = diff;
217 worstindex = iu;
218 }
219 }
220
221 /* Check whether any point violated the error threshold... */
222 if (worstindex != -1) {
223
224 /* Recursion on left segment... */
225 if (worstindex - left > 1)
226 reduction(tbl, id, ig, ip, it, left, worstindex, write_idx, atol, rtol);
227
228 /* Keep worst entry... */
229 copy_density(tbl, id, ig, ip, it, *write_idx, worstindex);
230 (*write_idx)++;
231
232 /* Recursion on right segment... */
233 if (right - worstindex > 1)
234 reduction(tbl, id, ig, ip, it, worstindex, right, write_idx, atol,
235 rtol);
236 }
237}
void usage(void)
Print command-line help.
Definition: formod.c:163
void tbl_free(const ctl_t *ctl, tbl_t *tbl)
Free lookup table and all internally allocated memory.
Definition: jurassic.c:7002
void read_ctl(int argc, char *argv[], ctl_t *ctl)
Read model control parameters from command-line and configuration input.
Definition: jurassic.c:5516
void write_tbl(const ctl_t *ctl, const tbl_t *tbl)
Write emissivity lookup tables to disk.
Definition: jurassic.c:8722
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:6612
tbl_t * read_tbl(const ctl_t *ctl)
Read emissivity lookup tables from disk.
Definition: jurassic.c:6332
JURASSIC library declarations.
#define ERRMSG(...)
Print an error message with contextual information and terminate the program.
Definition: jurassic.h:1325
#define USAGE
Print usage information on -h or --help.
Definition: jurassic.h:1206
#define LOG(level,...)
Print a log message with a specified logging level.
Definition: jurassic.h:1255
#define LIN(x0, y0, x1, y1, x)
Compute linear interpolation.
Definition: jurassic.h:624
Control parameters.
Definition: jurassic.h:1428
double nu[ND]
Centroid wavenumber of each channel [cm^-1].
Definition: jurassic.h:1452
char tblbase[LEN]
Basename for table files and filter function files.
Definition: jurassic.h:1479
int ng
Number of emitters.
Definition: jurassic.h:1431
int nd
Number of radiance channels.
Definition: jurassic.h:1449
char emitter[NG][LEN]
Name of each emitter.
Definition: jurassic.h:1434
int tblfmt
Look-up table file format (1=ASCII, 2=binary, 3=netCDF).
Definition: jurassic.h:1482
Emissivity look-up tables.
Definition: jurassic.h:1842
float * logu[ND][NG][TBLNP][TBLNT]
Logarithm of column density [molecules/cm^2].
Definition: jurassic.h:1863
int nu[ND][NG][TBLNP][TBLNT]
Number of column densities.
Definition: jurassic.h:1851
int nt[ND][NG][TBLNP]
Number of temperatures.
Definition: jurassic.h:1848
float * logeps[ND][NG][TBLNP][TBLNT]
Logarithm of emissivity.
Definition: jurassic.h:1866
int np[ND][NG]
Number of pressure levels.
Definition: jurassic.h:1845
int main(int argc, char *argv[])
Definition: tblrdc.c:62