JURASSIC
filter.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
27/* ------------------------------------------------------------
28 Functions...
29 ------------------------------------------------------------ */
30
32double ails(
33 int apo,
34 double opl,
35 double dnu);
36
38static void usage(
39 void);
40
41/* ------------------------------------------------------------
42 Main...
43 ------------------------------------------------------------ */
44
45int main(
46 int argc,
47 char *argv[]) {
48
49 static ctl_t ctl;
50
51 static double ff[NSHAPE], fnu[NSHAPE];
52
53 double fsum = 0.0;
54
55 int fn = 0;
56
57 /* Print usage information... */
58 USAGE;
59
60 /* Write info... */
61 if (argc < 3)
62 ERRMSG("Missing or invalid command-line arguments.\n\n"
63 "Usage: filter <ctl> <filter> [KEY VALUE ...]\n\n"
64 "Use -h for full help.");
65
66 /* Read control parameters... */
67 read_ctl(argc, argv, &ctl);
68 const int type = (int) scan_ctl(argc, argv, "FILTER_TYPE", -1, "1", NULL);
69 const double opd = scan_ctl(argc, argv, "FILTER_OPD", -1, "10.0", NULL);
70 const double fwhm = scan_ctl(argc, argv, "FILTER_FWHM", -1, "1.0", NULL);
71 const double center =
72 scan_ctl(argc, argv, "FILTER_CENTER", -1, "1000.0", NULL);
73 const double width = scan_ctl(argc, argv, "FILTER_WIDTH", -1, "2.1", NULL);
74 const double samp = scan_ctl(argc, argv, "FILTER_SAMP", -1, "0.0005", NULL);
75
76 /* Compute filter function... */
77 for (double nu = center - 0.5 * width;
78 nu <= center + 0.5 * width; nu += samp) {
79
80 /* Set frequency... */
81 fnu[fn] = nu;
82
83 /* Boxcar... */
84 if (type == 0)
85 ff[fn] = (fabs(nu - center) <= 0.5 * fwhm ? 1.0 : 0.0);
86
87 /* Triangle... */
88 else if (type == 1) {
89 ff[fn] = 1.0 - fabs(nu - center) / fwhm;
90 ff[fn] = MAX(ff[fn], 0.0);
91 }
92
93 /* Gaussian... */
94 else if (type == 2) {
95 double sigma = fwhm / 2.355;
96 ff[fn] = exp(-0.5 * POW2((nu - center) / sigma));
97 }
98
99 /* Sinc function... */
100 else if (type == 3)
101 ff[fn] = ails(0, opd, nu - center);
102
103 /* Norton-Beer strong apodization... */
104 else if (type == 4)
105 ff[fn] = ails(1, opd, nu - center);
106
107 /* Error message... */
108 else
109 ERRMSG("Filter function type unknown!");
110
111 /* Count spectral grid points... */
112 if ((++fn) >= NSHAPE)
113 ERRMSG("Too many filter function data points!");
114 }
115
116 /* Normalize filter function... */
117 for (int i = 0; i < fn; i++)
118 fsum += ff[i];
119 for (int i = 0; i < fn; i++)
120 ff[i] /= (fsum * samp);
121
122 /* Write to file... */
123 write_shape(argv[2], fnu, ff, fn);
124
125 return (EXIT_SUCCESS);
126}
127
128/*****************************************************************************/
129
130static void usage(
131 void) {
132 printf("\nJURASSIC filter generator.\n\n");
133 printf("Create a radiometric filter function from the filter settings\n");
134 printf("in the control file and write it to disk.\n\n");
135 printf("Usage:\n");
136 printf(" filter <ctl> <filter> [KEY VALUE ...]\n\n");
137 printf("Arguments:\n");
138 printf(" <ctl> Control file.\n");
139 printf(" <filter> Output filter-function file.\n");
140 printf(" [KEY VALUE] Optional control parameters.\n\n");
141 printf("Tool-specific control parameters:\n");
142 printf(" FILTER_TYPE Filter shape identifier.\n");
143 printf
144 (" FILTER_OPD Optical path difference for sinc-based filters.\n");
145 printf(" FILTER_FWHM Full width at half maximum.\n");
146 printf(" FILTER_CENTER Center wavenumber.\n");
147 printf(" FILTER_WIDTH Total spectral width.\n");
148 printf(" FILTER_SAMP Spectral sampling interval.\n\n");
149 printf("Further information:\n");
150 printf(" Manual: https://slcs-jsc.github.io/jurassic/\n");
151}
152
153/*****************************************************************************/
154
155double ails(
156 int apo,
157 double opl,
158 double dnu) {
159
160 /* Auxiliary quantities... */
161 const double a = 2 * M_PI * dnu * opl;
162 const double a2 = a * a;
163 const double a4 = a2 * a2;
164 const double a6 = a4 * a2;
165 const double a8 = a4 * a4;
166
167 /* Sinc function... */
168 if (apo == 0) {
169 if (fabs(a) < 0.7)
170 return 1 - a2 / 6 + a4 / 120 - a6 / 5040 + a8 / 362880;
171 else
172 return sin(a) / a;
173 }
174
175 /* Norton-Beer strong apodization... */
176 else if (apo == 1) {
177 double q0, q2, q4;
178 if (fabs(a) < 0.7) {
179 q0 = 1 - a2 / 6 + a4 / 120 - a6 / 5040 + a8 / 362880;
180 q2 = 1 - a2 / 14 + a4 / 504 - a6 / 33264 + a8 / 3459456;
181 q4 = 1 - a2 / 22 + a4 / 1144 - a6 / 102960 + a8 / 14002560;
182 } else {
183 const double sinca = sin(a) / a;
184 const double cosa = cos(a);
185 q0 = sinca;
186 q2 = -15 / a2 * ((1 - 3 / a2) * sinca + (3 / a2) * cosa);
187 q4 =
188 945 / a4 * ((1 - 45 / a2 + 105 / a4) * sinca +
189 5 / a2 * (2 - 21 / a2) * cosa);
190 }
191 return 0.045335 * q0 + 0.554883 * q2 * 8. / 15. +
192 0.399782 * q4 * 384. / 945.;
193 }
194
195 /* Error message.... */
196 else
197 ERRMSG("Unknown apodization!");
198}
int main(int argc, char *argv[])
Definition: filter.c:45
double ails(int apo, double opl, double dnu)
Compute apodized instrument line shape.
Definition: filter.c:155
void read_ctl(int argc, char *argv[], ctl_t *ctl)
Read model control parameters from command-line and configuration input.
Definition: jurassic.c:5516
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
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:8650
JURASSIC library declarations.
#define POW2(x)
Compute the square of a value.
Definition: jurassic.h:1018
#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 NSHAPE
Maximum number of shape function grid points.
Definition: jurassic.h:328
#define MAX(a, b)
Determine the maximum of two values.
Definition: jurassic.h:666
Control parameters.
Definition: jurassic.h:1428