IIINSTRUMENT Pipeline Reference Manual 4.4.3
visir_spc_chain.c
1/*
2 * This file is part of the VISIR Pipeline
3 * Copyright (C) 2012,2013,2014,2015 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18 */
19
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25/*-----------------------------------------------------------------------------
26 Includes
27 -----------------------------------------------------------------------------*/
28
29#ifndef ESO_COVERAGE_BUILD
30#define ESO_COVERAGE_BUILD 0
31#endif
32
33#include "visir_recipe.h"
34
35#include "visir_utils.h"
36#include "irplib_utils.h"
37#include <cxlist.h>
38#include <string.h>
39#include <stdio.h>
40#include <stdlib.h>
41
42int visir_util_repack_get_info(cpl_pluginlist *);
43int visir_util_undistort_get_info(cpl_pluginlist *);
44int visir_old_util_destripe_get_info(cpl_pluginlist *);
45int visir_old_spc_obs_get_info(cpl_pluginlist *);
46
47/*-----------------------------------------------------------------------------
48 Defines
49 -----------------------------------------------------------------------------*/
50
51#define RECIPE_STRING "visir_spc_reduce"
52
53/*-----------------------------------------------------------------------------
54 Private Functions prototypes
55 -----------------------------------------------------------------------------*/
56
57/* FIXME: this code is littered with many unimportant memory leaks */
58
59static cpl_error_code visir_spc_reduce_fill_parameterlist(cpl_parameterlist *);
60static int visir_spc_reduce(cpl_frameset *, const cpl_parameterlist *);
61
62static int visir_spc_reduce_create(cpl_plugin * plugin)
63{
64 cpl_recipe * recipe = (cpl_recipe *)plugin; /* Needed for the fill */
65 cpl_errorstate prestate = cpl_errorstate_get(); /* To check the fill */
66
67 /* Propagate error, if any */
68 /* - Need two function calls to ensure plugin validity before the fill */
69 return cpl_recipedefine_create(plugin)
70 || cpl_recipedefine_create_is_ok(prestate,
71 visir_spc_reduce_fill_parameterlist(recipe->parameters))
72 ? (int)cpl_error_set_where(cpl_func) : 0;
73}
74
75
76/*----------------------------------------------------------------------------*/
89/*----------------------------------------------------------------------------*/
90static int visir_spc_reduce_exec(cpl_plugin * plugin)
91{
92 char * progname = getenv("_");
93 char * classpath = getenv("CLASSPATH");
94 cpl_msg_debug(cpl_func, "Program name: %s", progname);
95 cpl_msg_debug(cpl_func, "CLASSPATH: %s", classpath);
96 if ((progname && strstr(progname, "gasgano")) ||
97 (classpath && strstr(classpath, "gasgano.jar"))) {
98 cpl_msg_info(cpl_func, "Running under gasgano, disabling OpenMP");
99 setenv("OMP_NUM_THREADS", "0", 1);
100 return visir_tmpdir_exec(RECIPE_STRING, plugin, visir_spc_reduce);
101 }
102 else if (ESO_COVERAGE_BUILD || getenv("VISIR_NO_FORK") != NULL) {
103 /* debugging and coverage is better without fork */
104 return cpl_recipedefine_exec(plugin, visir_spc_reduce)
105 ? (int)cpl_error_set_where(cpl_func) : 0;
106 }
107 else
108 return visir_forking_exec(RECIPE_STRING, plugin, visir_spc_reduce);
109}
110
111/* The definition of the recipe destroy function */
112static int visir_spc_reduce_destroy(cpl_plugin * plugin)
113{
114 /* Propagate error, if any */
115 return cpl_recipedefine_destroy(plugin)
116 ? (int)cpl_error_set_where(cpl_func) : 0;
117}
118
119int cpl_plugin_get_info(cpl_pluginlist * list)
120{
121 /* Propagate error, if any. Return 1 on failure */
122 return cpl_recipedefine_init(list, CPL_VERSION_CODE,
123 VISIR_BINARY_VERSION,
124 "visir_spc_reduce",
125 "Spectroscopic Observation recipe",
126 "This recipe performs a wavelength calibration "
127 "followed by spectrum extraction from a combined image. "
128 "It can also compute sensitivities for standard star "
129 "observations.\n"
130 "It works for low and high resolution including echelle "
131 "mode.\n"
132
133 "The files listed in the Set Of Frames (sof-file) "
134 "must be tagged:\n"
135 "VISIR-Long-Slit-Spectroscopy-file.fits "
136 VISIR_SPC_OBS_RAW "\n"
137 "VISIR-Quantum-Efficiency-Calibration-file.fits "
138 VISIR_CALIB_QEFF_SPC "\n"
139 "VISIR-Atmospheric-Emission-Lines-Calibration-file.fits "
140 VISIR_CALIB_LINES_SPC "\n"
141 "VISIR-Standard-Star-Flux-Catalog.fits (optional)"
142 VISIR_CALIB_STDSTAR_SPC"\n"
143 "VISIR-linearty-table.fits "VISIR_CALIB_LIN" (optional)"
144 MAN_VISIR_CALIB_BPM_IMG,
145 "Julian Taylor",
146 "jtaylor@partner.eso.org",
147 cpl_get_license(PACKAGE_NAME, "2015"),
148 visir_spc_reduce_create,
149 visir_spc_reduce_exec,
150 visir_spc_reduce_destroy)
151 ? ((void)cpl_error_set_where(cpl_func), 1) : 0;
152}
153
154/*
155cpl_recipe_define(visir_spc_reduce, VISIR_BINARY_VERSION,
156 "Julian Taylor", PACKAGE_BUGREPORT, "2012",
157 "Attempt to remove stripes in spectral data",
158 "The files listed in the Set Of Frames (sof-file) "
159 "must be tagged:\n"
160 "VISIR-chopnod-corrected-file.fits "
161 "\nThe product(s) will have a FITS card\n"
162 "'HIERARCH ESO PRO CATG' with a value of:\n");
163 */
164
165/*----------------------------------------------------------------------------*/
169/*----------------------------------------------------------------------------*/
170
171/*-----------------------------------------------------------------------------
172 Functions code
173 -----------------------------------------------------------------------------*/
174
175/*----------------------------------------------------------------------------*/
183/*----------------------------------------------------------------------------*/
184static cpl_error_code
185visir_spc_reduce_fill_parameterlist(cpl_parameterlist * self)
186{
187 cpl_pluginlist * plugins = cpl_pluginlist_new();
188 const char * context = PACKAGE ".visir_spc_reduce";
189
190 cpl_recipe * repack = visir_init_recipe("visir_util_repack",
191 &visir_util_repack_get_info,
192 plugins);
193
194 cpl_recipe * undist = visir_init_recipe("visir_util_undistort",
195 &visir_util_undistort_get_info,
196 plugins);
197
198 cpl_recipe * destripe = visir_init_recipe("visir_old_util_destripe",
199 &visir_old_util_destripe_get_info,
200 plugins);
201
202 cpl_recipe * spcobs = visir_init_recipe("visir_old_spc_obs",
203 &visir_old_spc_obs_get_info,
204 plugins);
205
206 cpl_plugin_get_init(&repack->interface)(&repack->interface);
207 cpl_plugin_get_init(&undist->interface)(&undist->interface);
208 cpl_plugin_get_init(&destripe->interface)(&destripe->interface);
209 cpl_plugin_get_init(&spcobs->interface)(&spcobs->interface);
210 cpl_parameterlist * repack_par = repack->parameters;
211 cpl_parameterlist * undist_par = undist->parameters;
212 cpl_parameterlist * destripe_par = destripe->parameters;
213 cpl_parameterlist * spcobs_par = spcobs->parameters;
214 skip_if(0);
215
216 for (cpl_parameter * p = cpl_parameterlist_get_first(repack_par);
217 p != NULL; p = cpl_parameterlist_get_next(repack_par)) {
218 const char * name = cpl_parameter_get_name(p);
219 if (strstr(name, "bkgcorrect"))
220 continue;
221 if (strstr(name, "normalize"))
222 continue;
223 if (strstr(name, "compress"))
224 continue;
225 if (strstr(name, "ncycles"))
226 continue;
227 cpl_parameterlist_append(self, visir_parameter_duplicate(p));
228 }
229
230 skip_if(0);
231
232 for (cpl_parameter * p = cpl_parameterlist_get_first(undist_par);
233 p != NULL; p = cpl_parameterlist_get_next(undist_par)) {
234 const char * name = cpl_parameter_get_name(p);
235 if (strstr(name, "bkgcorrect"))
236 continue;
237 cpl_parameterlist_append(self, visir_parameter_duplicate(p));
238 }
239
240 skip_if(0);
241
242 for (cpl_parameter * p = cpl_parameterlist_get_first(destripe_par);
243 p != NULL; p = cpl_parameterlist_get_next(destripe_par)) {
244 cpl_parameterlist_append(self, visir_parameter_duplicate(p));
245 }
246
247 skip_if(0);
248
249 for (cpl_parameter * p = cpl_parameterlist_get_first(spcobs_par);
250 p != NULL; p = cpl_parameterlist_get_next(spcobs_par)) {
251 const char * name = cpl_parameter_get_name(p);
252 if (strstr(name, "auto_bpm") ||
253 strstr(name, "rem_glitch") ||
254 strstr(name, "purge_bad") ||
255 strstr(name, "union") ||
256 strstr(name, "refine") ||
257 strstr(name, "xcorr") ||
258 strstr(name, "objects") ||
259 strstr(name, "nodding") ||
260 strstr(name, "offsets")) {
261 continue;
262 }
263 cpl_parameterlist_append(self, visir_parameter_duplicate(p));
264 }
265
266 skip_if(0);
267
268
269 skip_if(irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
270 "delete-temp", CPL_TRUE, NULL,
271 context, "Delete temporary files "
272 "created during processing"));
273
274 skip_if(irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
275 "destripe", CPL_FALSE, NULL, context,
276 "Attempt to remove stripes"));
277
278 end_skip;
279
280 cpl_parameterlist_delete(repack->parameters);
281 cpl_parameterlist_delete(undist->parameters);
282 cpl_parameterlist_delete(destripe->parameters);
283 cpl_parameterlist_delete(spcobs->parameters);
284 cpl_plugin_delete(&repack->interface);
285 cpl_plugin_delete(&undist->interface);
286 cpl_plugin_delete(&destripe->interface);
287 cpl_plugin_delete(&spcobs->interface);
288 cpl_pluginlist_delete(plugins);
289
290 return cpl_error_get_code();
291}
292
293static cpl_error_code
294util_repack_set_parameters(cpl_parameterlist * rec_pars,
295 const cpl_parameterlist * chain_pars)
296{
297 cpl_parameter * par;
298
299 skip_if(visir_copy_parameters(rec_pars, chain_pars));
300
301 par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.bkgcorrect");
302
303 if (par)
304 cpl_parameter_set_string(par, "none");
305
306 par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.normalize");
307
308 if (par)
309 cpl_parameter_set_bool(par, CPL_TRUE);
310
311 par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.compress");
312
313 if (par)
314 cpl_parameter_set_bool(par, CPL_TRUE);
315
316 end_skip;
317
318 return cpl_error_get_code();
319}
320
321static cpl_error_code
322util_undistort_set_parameters(cpl_parameterlist * rec_pars,
323 const cpl_parameterlist * chain_pars)
324{
325 cpl_parameter * par;
326
327 skip_if(visir_copy_parameters(rec_pars, chain_pars));
328
329 par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.bkgcorrect");
330
331 if (par)
332 cpl_parameter_set_bool(par, CPL_TRUE);
333
334 end_skip;
335
336 return cpl_error_get_code();
337}
338
339/*----------------------------------------------------------------------------*/
346/*----------------------------------------------------------------------------*/
347static int visir_spc_reduce(cpl_frameset * framelist,
348 const cpl_parameterlist * parlist)
349{
350 cpl_pluginlist * plugins = cpl_pluginlist_new();
351 cpl_frameset * usedframes = cpl_frameset_new();
352
353 cpl_recipe * repack = visir_init_recipe("visir_util_repack",
354 &visir_util_repack_get_info,
355 plugins);
356 cpl_recipe * undist = visir_init_recipe("visir_util_undistort",
357 &visir_util_undistort_get_info,
358 plugins);
359 cpl_recipe * destripe = visir_init_recipe("visir_old_util_destripe",
360 &visir_old_util_destripe_get_info,
361 plugins);
362 cpl_recipe * spcobs = visir_init_recipe("visir_old_spc_obs",
363 &visir_old_spc_obs_get_info,
364 plugins);
365 const cpl_boolean do_destripe =
366 irplib_parameterlist_get_bool(parlist, PACKAGE,
367 RECIPE_STRING, "destripe");
368
369 cpl_frameset * repackset = cpl_frameset_new();
370 cpl_frameset * obsset = cpl_frameset_new();
371 cpl_size nrep;
372 const char * input_tag;
373
374 visir_dfs_set_groups(framelist);
375 cpl_frame * linframe = NULL;
376 FOR_EACH_FRAMESET(frame_, framelist) {
377 cpl_frame * frame = cpl_frame_duplicate(frame_);
378 cpl_frameset_insert(usedframes, cpl_frame_duplicate(frame));
379 if (!strcmp(cpl_frame_get_tag(frame), VISIR_SPEC_STD_CAT_PROCATG) ||
380 !strcmp(cpl_frame_get_tag(frame), VISIR_SPEC_CAL_LINES_PROCATG) ||
381 !strcmp(cpl_frame_get_tag(frame), VISIR_SPEC_CAL_QEFF_PROCATG))
382 cpl_frameset_insert(obsset, frame);
383 else {
384 /* linearity correction also passed to undistort */
385 if (!strcmp(cpl_frame_get_tag(frame), VISIR_CALIB_LIN)) {
386 linframe = cpl_frame_duplicate(frame);
387 }
388 cpl_frameset_insert(repackset, frame);
389 }
390 }
391 nrep = cpl_frameset_get_size(repackset);
392 if (cpl_frameset_find(repackset, VISIR_CALIB_LIN)) {
393 nrep--;
394 }
395 if (cpl_frameset_find(repackset, VISIR_CALIB_STATIC_MASK)) {
396 nrep--;
397 }
398 if (cpl_frameset_count_tags(repackset, VISIR_SPC_OBS_ECH_RAW) == nrep) {
399 input_tag = VISIR_SPC_OBS_ECH_PP;
400 }
401 else if (cpl_frameset_count_tags(repackset,
402 VISIR_SPC_PHOT_ECH_RAW) == nrep) {
403 input_tag = VISIR_SPC_PHOT_ECH_PP;
404 }
405 else if (cpl_frameset_count_tags(repackset, VISIR_SPC_OBS_RAW) == nrep) {
406 input_tag = VISIR_SPC_OBS_PP;
407 }
408 else if (cpl_frameset_count_tags(repackset, VISIR_SPC_PHOT_RAW) == nrep) {
409 input_tag = VISIR_SPC_PHOT_PP;
410 }
411 else {
412 error_if(1, CPL_ERROR_ILLEGAL_INPUT, "Invalid input tags");
413 }
414 cpl_msg_info(cpl_func, "Working on %s", input_tag);
415 skip_if(visir_run_recipe(repack, repackset, parlist,
416 &util_repack_set_parameters));
417
418 cpl_frameset * undistset = visir_prepare_frameset(repackset, NULL, 0,
419 CPL_TRUE);
420 /* jitter correction modifies input calib file and adds a new one
421 * to the recipe output, so drop the original one from the frameset */
422 undistset = visir_remove_modified_calib(undistset);
423 /* insert linearity table for skyframe*/
424 if (linframe) {
425 cpl_frameset_insert(undistset, linframe);
426 }
427 cpl_frameset_delete(repackset);
428 repackset = NULL;
429 skip_if(visir_run_recipe(undist, undistset, parlist,
430 &util_undistort_set_parameters));
431
432 cpl_frameset * destripeset = undistset;
433 if (do_destripe) {
434 const char * tagmap[] = {"UNDISTORTED", VISIR_UTIL_CORRECTED};
435 destripeset =
436 visir_prepare_frameset(undistset, tagmap, ARRAY_LEN(tagmap),
437 CPL_FALSE);
438 skip_if(visir_run_recipe(destripe, destripeset, parlist,
439 &visir_copy_parameters));
440 }
441
442 const char * obstagmap[] = {do_destripe ? "DESTRIPED" : "UNDISTORTED",
443 input_tag};
444 cpl_frameset * tmp_obs =
445 visir_prepare_frameset(destripeset, obstagmap, ARRAY_LEN(obstagmap),
446 CPL_FALSE);
447
448 FOR_EACH_FRAMESET_C(frm, tmp_obs)
449 cpl_frameset_insert(obsset, cpl_frame_duplicate(frm));
450 cpl_frameset_delete(tmp_obs);
451
452 cpl_frame * sky = cpl_frameset_find(undistset, "SPEC_OBS_LMR_SKYFRAME");
453 skip_if(sky == NULL);
454 sky = cpl_frame_duplicate(sky);
455 cpl_frame_set_group(sky, CPL_FRAME_GROUP_CALIB);
456 cpl_frameset_insert(obsset, sky);
457
458 cpl_frameset_delete(undistset);
459
460 skip_if(visir_run_recipe(spcobs, obsset, parlist,
461 &visir_copy_parameters));
462
463 FOR_EACH_FRAMESET(frm, obsset)
464 if (cpl_frame_get_group(frm) == CPL_FRAME_GROUP_PRODUCT)
465 cpl_frameset_insert(framelist, cpl_frame_duplicate(frm));
466 skip_if(0);
467
468 end_skip;
469 {
470 cpl_recipe * recipes[] = {repack, undist, destripe, spcobs};
471 for (size_t i = 0; i < ARRAY_LEN(recipes); i++)
472 if (recipes[i])
473 cpl_plugin_delete(&(recipes[i]->interface));
474 }
475 cpl_pluginlist_delete(plugins);
476
477 cpl_frameset_delete(obsset);
478 cpl_frameset_delete(usedframes);
479
480 return cpl_error_get_code();
481}
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72