VISIR Pipeline Reference Manual  4.1.7
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 _XOPEN_SOURCE
30 #define _XOPEN_SOURCE 600 /* setenv */
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 
42 int visir_util_repack_get_info(cpl_pluginlist *);
43 int visir_util_undistort_get_info(cpl_pluginlist *);
44 int visir_old_util_destripe_get_info(cpl_pluginlist *);
45 int 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 
59 static cpl_error_code visir_spc_reduce_fill_parameterlist(cpl_parameterlist *);
60 static int visir_spc_reduce(cpl_frameset *, const cpl_parameterlist *);
61 
62 static 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 /*----------------------------------------------------------------------------*/
90 static 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 (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 */
112 static 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 
119 int 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 /*
155 cpl_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 /*----------------------------------------------------------------------------*/
184 static cpl_error_code
185 visir_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  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
226  }
227 
228  skip_if(0);
229 
230  for (cpl_parameter * p = cpl_parameterlist_get_first(undist_par);
231  p != NULL; p = cpl_parameterlist_get_next(undist_par)) {
232  const char * name = cpl_parameter_get_name(p);
233  if (strstr(name, "bkgcorrect"))
234  continue;
235  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
236  }
237 
238  skip_if(0);
239 
240  for (cpl_parameter * p = cpl_parameterlist_get_first(destripe_par);
241  p != NULL; p = cpl_parameterlist_get_next(destripe_par)) {
242  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
243  }
244 
245  skip_if(0);
246 
247  for (cpl_parameter * p = cpl_parameterlist_get_first(spcobs_par);
248  p != NULL; p = cpl_parameterlist_get_next(spcobs_par)) {
249  const char * name = cpl_parameter_get_name(p);
250  if (strstr(name, "auto_bpm") ||
251  strstr(name, "rem_glitch") ||
252  strstr(name, "purge_bad") ||
253  strstr(name, "union") ||
254  strstr(name, "refine") ||
255  strstr(name, "xcorr") ||
256  strstr(name, "objects") ||
257  strstr(name, "nodding") ||
258  strstr(name, "offsets")) {
259  continue;
260  }
261  cpl_parameterlist_append(self, visir_parameter_duplicate(p));
262  }
263 
264  skip_if(0);
265 
266 
267  skip_if(irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
268  "delete-temp", CPL_TRUE, NULL,
269  context, "Delete temporary files "
270  "created during processing"));
271 
272  skip_if(irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
273  "destripe", CPL_FALSE, NULL, context,
274  "Attempt to remove stripes"));
275 
276  end_skip;
277 
278  cpl_parameterlist_delete(repack->parameters);
279  cpl_parameterlist_delete(undist->parameters);
280  cpl_parameterlist_delete(destripe->parameters);
281  cpl_parameterlist_delete(spcobs->parameters);
282  cpl_plugin_delete(&repack->interface);
283  cpl_plugin_delete(&undist->interface);
284  cpl_plugin_delete(&destripe->interface);
285  cpl_plugin_delete(&spcobs->interface);
286  cpl_pluginlist_delete(plugins);
287 
288  return cpl_error_get_code();
289 }
290 
291 static cpl_error_code
292 util_repack_set_parameters(cpl_parameterlist * rec_pars,
293  const cpl_parameterlist * chain_pars)
294 {
295  cpl_parameter * par;
296 
297  skip_if(visir_copy_parameters(rec_pars, chain_pars));
298 
299  par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.bkgcorrect");
300 
301  if (par)
302  cpl_parameter_set_string(par, "none");
303 
304  par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.normalize");
305 
306  if (par)
307  cpl_parameter_set_bool(par, CPL_TRUE);
308 
309  par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.compress");
310 
311  if (par)
312  cpl_parameter_set_bool(par, CPL_TRUE);
313 
314  end_skip;
315 
316  return cpl_error_get_code();
317 }
318 
319 static cpl_error_code
320 util_undistort_set_parameters(cpl_parameterlist * rec_pars,
321  const cpl_parameterlist * chain_pars)
322 {
323  cpl_parameter * par;
324 
325  skip_if(visir_copy_parameters(rec_pars, chain_pars));
326 
327  par = cpl_parameterlist_find(rec_pars, PACKAGE".visir_util_repack.bkgcorrect");
328 
329  if (par)
330  cpl_parameter_set_bool(par, CPL_TRUE);
331 
332  end_skip;
333 
334  return cpl_error_get_code();
335 }
336 
337 /*----------------------------------------------------------------------------*/
344 /*----------------------------------------------------------------------------*/
345 static int visir_spc_reduce(cpl_frameset * framelist,
346  const cpl_parameterlist * parlist)
347 {
348  cpl_pluginlist * plugins = cpl_pluginlist_new();
349  cpl_frameset * usedframes = cpl_frameset_new();
350 
351  cpl_recipe * repack = visir_init_recipe("visir_util_repack",
352  &visir_util_repack_get_info,
353  plugins);
354  cpl_recipe * undist = visir_init_recipe("visir_util_undistort",
355  &visir_util_undistort_get_info,
356  plugins);
357  cpl_recipe * destripe = visir_init_recipe("visir_old_util_destripe",
358  &visir_old_util_destripe_get_info,
359  plugins);
360  cpl_recipe * spcobs = visir_init_recipe("visir_old_spc_obs",
361  &visir_old_spc_obs_get_info,
362  plugins);
363  const cpl_boolean do_destripe =
364  irplib_parameterlist_get_bool(parlist, PACKAGE,
365  RECIPE_STRING, "destripe");
366 
367  cpl_frameset * repackset = cpl_frameset_new();
368  cpl_frameset * obsset = cpl_frameset_new();
369  cpl_size nrep;
370  const char * input_tag;
371 
372  visir_dfs_set_groups(framelist);
373  FOR_EACH_FRAMESET(frame_, framelist) {
374  cpl_frame * frame = cpl_frame_duplicate(frame_);
375  cpl_frameset_insert(usedframes, cpl_frame_duplicate(frame));
376  if (!strcmp(cpl_frame_get_tag(frame), VISIR_SPEC_STD_CAT_PROCATG) ||
377  !strcmp(cpl_frame_get_tag(frame), VISIR_SPEC_CAL_LINES_PROCATG) ||
378  !strcmp(cpl_frame_get_tag(frame), VISIR_SPEC_CAL_QEFF_PROCATG))
379  cpl_frameset_insert(obsset, frame);
380  else
381  cpl_frameset_insert(repackset, frame);
382  }
383  nrep = cpl_frameset_get_size(repackset);
384  if (cpl_frameset_find(repackset, VISIR_CALIB_LIN)) {
385  nrep--;
386  }
387  if (cpl_frameset_find(repackset, VISIR_CALIB_STATIC_MASK)) {
388  nrep--;
389  }
390  if (cpl_frameset_find(repackset, VISIR_CALIB_STATIC_MASK_SPC)) {
391  nrep--;
392  }
393  if (cpl_frameset_count_tags(repackset, VISIR_SPC_OBS_ECH_RAW) == nrep) {
394  input_tag = VISIR_SPC_OBS_ECH_PP;
395  }
396  else if (cpl_frameset_count_tags(repackset,
397  VISIR_SPC_PHOT_ECH_RAW) == nrep) {
398  input_tag = VISIR_SPC_PHOT_ECH_PP;
399  }
400  else if (cpl_frameset_count_tags(repackset, VISIR_SPC_OBS_RAW) == nrep) {
401  input_tag = VISIR_SPC_OBS_PP;
402  }
403  else if (cpl_frameset_count_tags(repackset, VISIR_SPC_PHOT_RAW) == nrep) {
404  input_tag = VISIR_SPC_PHOT_PP;
405  }
406  else {
407  error_if(1, CPL_ERROR_ILLEGAL_INPUT, "Invalid input tags");
408  }
409  cpl_msg_info(cpl_func, "Working on %s", input_tag);
410  skip_if(visir_run_recipe(repack, repackset, parlist,
411  &util_repack_set_parameters));
412 
413  cpl_frameset * undistset = visir_prepare_frameset(repackset, NULL, 0,
414  CPL_TRUE);
415  /* jitter correction modifies input calib file and adds a new one
416  * to the recipe output, so drop the original one from the frameset */
417  undistset = visir_remove_modified_calib(undistset);
418  cpl_frameset_delete(repackset);
419  repackset = NULL;
420  skip_if(visir_run_recipe(undist, undistset, parlist,
421  &util_undistort_set_parameters));
422 
423  cpl_frameset * destripeset = undistset;
424  if (do_destripe) {
425  const char * tagmap[] = {"UNDISTORTED", VISIR_UTIL_CORRECTED};
426  destripeset =
427  visir_prepare_frameset(undistset, tagmap, ARRAY_LEN(tagmap),
428  CPL_FALSE);
429  skip_if(visir_run_recipe(destripe, destripeset, parlist,
430  &visir_copy_parameters));
431  }
432 
433  const char * obstagmap[] = {do_destripe ? "DESTRIPED" : "UNDISTORTED",
434  input_tag};
435  cpl_frameset * tmp_obs =
436  visir_prepare_frameset(destripeset, obstagmap, ARRAY_LEN(obstagmap),
437  CPL_FALSE);
438 
439  FOR_EACH_FRAMESET_C(frm, tmp_obs)
440  cpl_frameset_insert(obsset, cpl_frame_duplicate(frm));
441  cpl_frameset_delete(tmp_obs);
442 
443  cpl_frame * sky = cpl_frameset_find(undistset, "SPEC_OBS_LMR_SKYFRAME");
444  skip_if(sky == NULL);
445  sky = cpl_frame_duplicate(sky);
446  cpl_frame_set_group(sky, CPL_FRAME_GROUP_CALIB);
447  cpl_frameset_insert(obsset, sky);
448 
449  cpl_frameset_delete(undistset);
450 
451  skip_if(visir_run_recipe(spcobs, obsset, parlist,
452  &visir_copy_parameters));
453 
454  FOR_EACH_FRAMESET(frm, obsset)
455  if (cpl_frame_get_group(frm) == CPL_FRAME_GROUP_PRODUCT)
456  cpl_frameset_insert(framelist, cpl_frame_duplicate(frm));
457  skip_if(0);
458 
459  end_skip;
460  {
461  cpl_recipe * recipes[] = {repack, undist, destripe, spcobs};
462  for (size_t i = 0; i < ARRAY_LEN(recipes); i++)
463  if (recipes[i])
464  cpl_plugin_delete(&(recipes[i]->interface));
465  }
466  cpl_pluginlist_delete(plugins);
467 
468  cpl_frameset_delete(obsset);
469  cpl_frameset_delete(usedframes);
470 
471  return cpl_error_get_code();
472 }
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72