CRIRES Pipeline Reference Manual  2.3.15
crires_spec_jitter.c
1 /*
2  * This file is part of the CRIRES Pipeline
3  * Copyright (C) 2002,2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 /*-----------------------------------------------------------------------------
25  Includes
26  -----------------------------------------------------------------------------*/
27 
28 #include <locale.h>
29 #include "crires_recipe.h"
30 
31 #include "crires_model_kernel.h"
32 #include "crires_combine.h"
33 #include "crires_extract.h"
34 #include "crires_photom.h"
35 #include "crires_wlcalib.h"
36 #include "irplib_utils.h"
37 
38 /*-----------------------------------------------------------------------------
39  Define
40  -----------------------------------------------------------------------------*/
41 
42 #define RECIPE_STRING "crires_spec_jitter"
43 
44 /*-----------------------------------------------------------------------------
45  Functions prototypes
46  -----------------------------------------------------------------------------*/
47 
48 static int crires_spec_jitter_save(const cpl_imagelist **,
49  const cpl_imagelist *, const cpl_imagelist *, const cpl_table **,
50  const cpl_imagelist *, const cpl_imagelist *,
51  const cpl_parameterlist *, cpl_frameset *) ;
52 
53 static char crires_spec_jitter_description[] =
54 "crires_spec_jitter -- Observation recipe with or without nodding/jittering\n"
55 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
56 " raw-file.fits "CRIRES_SPEC_JITTER_RAW" or\n"
57 " raw-file.fits "CRIRES_SPEC_JITTER_J_RAW" or\n"
58 " raw-file.fits "CRIRES_SPEC_JITTER_STD_RAW" or\n"
59 " raw-file.fits "CRIRES_SPEC_JITTER_J_STD_RAW" or\n"
60 " raw-file.fits "CRIRES_SPEC_NODDING_OBJECT_RAW" or\n"
61 " raw-file.fits "CRIRES_SPEC_NODDING_SKY_RAW" or\n"
62 " raw-file.fits "CRIRES_SPEC_GENERIC_OBJECT_RAW" or\n"
63 " raw-file.fits "CRIRES_SPEC_GENERIC_SKY_RAW" or\n"
64 " raw-file.fits "CRIRES_SPEC_NODDING_RAW" or\n"
65 " raw-file.fits "CRIRES_SPEC_NODDING_J_RAW" or\n"
66 " raw-file.fits "CRIRES_SPEC_NODDING_STD_RAW" or\n"
67 " raw-file.fits "CRIRES_SPEC_NODDING_J_STD_RAW" or\n"
68 " flat-file.fits "CRIRES_CALPRO_FLAT" or\n"
69 " bpm-file.fits "CRIRES_CALPRO_BPM" or\n"
70 " dark-file.fits "CRIRES_CALPRO_DARK" or\n"
71 " detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n"
72 " wavecal-file.fits "CRIRES_CALPRO_WAVE" or\n"
73 " catalog-file.fits "CRIRES_CALPRO_OH_CAT" or\n"
74 " catalog-file.fits "CRIRES_CALPRO_HITRAN_CAT" or\n"
75 " stdstar-file.fits "CRIRES_CALPRO_STD_PHOTOFLUX" or\n"
76 " model-config-file.fits "CRIRES_CALPRO_MODEL_CONFIG".\n"
77 "\n"
78 "In the case of a nodding observation, in order not to degrade the \n"
79 " instrument high resolution, the combined images using only NODA\n"
80 " or NODB nodding positions can be produced on request. (see --onlyA/B)\n"
81 " In this case, the following spectrum extraction can be applied \n"
82 " either on the usual combined image or on those NODA/B combined\n"
83 " images (see --comb_used).\n"
84 "\n"
85 "This recipe produces 6 to 11 files:\n"
86 " The combined image (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
87 " The contribution map (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
88 " The combined image using only Nodding A frames (optional)\n"
89 " (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
90 " The contribution map using only Nodding A frames (optional)\n"
91 " (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
92 " The combined image using only Nodding B frames (optional)\n"
93 " (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
94 " The contribution map using only Nodding B frames (optional)\n"
95 " (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
96 " The table with the extracted spectrum\n"
97 " (PRO TYPE = "CRIRES_PROTYPE_SPEC_WL") or\n"
98 " (PRO TYPE = "CRIRES_PROTYPE_SENSIT") or\n"
99 " (PRO TYPE = "CRIRES_PROTYPE_CONVERS")\n"
100 " The profile image (PRO TYPE = "CRIRES_PROTYPE_PROFILE")\n"
101 " The background map (PRO TYPE = "CRIRES_PROTYPE_BGD_MAP")\n"
102 " The wavelength map (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n"
103 " The wavelength map from the model (optional)\n"
104 " (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n" ;
105 
106 CRIRES_RECIPE_DEFINE(crires_spec_jitter,
107  CRIRES_PARAM_WAVES |
108  CRIRES_PARAM_DISPLAY |
109  CRIRES_PARAM_REFINE |
110  CRIRES_PARAM_ONLYA |
111  CRIRES_PARAM_ONLYB |
112  CRIRES_PARAM_COMB_USED |
113  CRIRES_PARAM_BLIND |
114  CRIRES_PARAM_HOR_SIZE |
115  CRIRES_PARAM_SPEC_HSIZE |
116  CRIRES_PARAM_KAPPA |
117  CRIRES_PARAM_CLOSING_HSIZE |
118  CRIRES_PARAM_CLEAN_RATE |
119  CRIRES_PARAM_REJECT |
120  CRIRES_PARAM_Y_SPEC_ZONE_CHIP1 |
121  CRIRES_PARAM_Y_SPEC_ZONE_CHIP2 |
122  CRIRES_PARAM_Y_SPEC_ZONE_CHIP3 |
123  CRIRES_PARAM_Y_SPEC_ZONE_CHIP4 |
124  CRIRES_PARAM_WL_ERROR |
125  CRIRES_PARAM_XC_LIMIT |
126  CRIRES_PARAM_WL_LOG |
127  CRIRES_PARAM_WL_NOLIMIT |
128  CRIRES_PARAM_WL_NBSAMPLES |
129  CRIRES_PARAM_Y_POS_CHIP1 |
130  CRIRES_PARAM_Y_POS_CHIP2 |
131  CRIRES_PARAM_Y_POS_CHIP3 |
132  CRIRES_PARAM_Y_POS_CHIP4 |
133  CRIRES_PARAM_Y_WIDTH |
134  CRIRES_PARAM_DEGREE |
135  CRIRES_PARAM_WL_CLEAN,
136  "Observation recipe",
137  crires_spec_jitter_description) ;
138 
139 /*-----------------------------------------------------------------------------
140  Static variables
141  -----------------------------------------------------------------------------*/
142 
143 static struct {
144  /* Inputs */
145  int comb_blind ;
146  int comb_refine ;
147  int comb_onlyA ;
148  int comb_onlyB ;
149  crires_comb_method comb_used ;
150  double wstart[CRIRES_NB_DETECTORS] ;
151  double wstop[CRIRES_NB_DETECTORS] ;
152  int wl_nolimit ;
153  int wl_log ;
154  const char * wl_ypos_c1 ;
155  const char * wl_ypos_c2 ;
156  const char * wl_ypos_c3 ;
157  const char * wl_ypos_c4 ;
158  int wl_width ;
159  double wl_fwhm ;
160  double wl_slitw ;
161  int wl_degree ;
162  double wl_err ;
163  int wl_samples ;
164  int wl_clean ;
165  double wl_xclimit ;
166  int wl_ppm ;
167  int extr_box_hor_size ;
168  int extr_spec_hsize ;
169  double extr_kappa ;
170  int extr_closing_hs ;
171  int extr_clean_rate ;
172  int extr_rej_left ;
173  int extr_rej_right ;
174  const char * extr_y_spec_zone_c1 ;
175  const char * extr_y_spec_zone_c2 ;
176  const char * extr_y_spec_zone_c3 ;
177  const char * extr_y_spec_zone_c4 ;
178  int display ;
179  /* Outputs */
180  crires_illum_period period ;
181  int std_mode ;
182  int nodding ;
183  int qc_specpos[CRIRES_NB_DETECTORS] ;
184  int qc_specwrec[CRIRES_NB_DETECTORS] ;
185  int qc_specwopt[CRIRES_NB_DETECTORS] ;
186  double qc_specoptmed[CRIRES_NB_DETECTORS] ;
187  double qc_s2nmed[CRIRES_NB_DETECTORS] ;
188  double qc_wlxc[CRIRES_NB_DETECTORS] ;
189  double qc_wlcent[CRIRES_NB_DETECTORS] ;
190  double qc_wldisp[CRIRES_NB_DETECTORS] ;
191  double qc_sensmed[CRIRES_NB_DETECTORS] ;
192  double qc_convmed[CRIRES_NB_DETECTORS] ;
193  double qc_thromed[CRIRES_NB_DETECTORS] ;
194  double qc_fwhm_comb_pix[CRIRES_NB_DETECTORS] ;
195  double qc_fwhm_comb_as[CRIRES_NB_DETECTORS] ;
196  double qc_fwhm_prof_pix[CRIRES_NB_DETECTORS] ;
197  double qc_fwhm_prof_as[CRIRES_NB_DETECTORS] ;
198  double qc_fwhm_diff[CRIRES_NB_DETECTORS] ;
199 } crires_spec_jitter_config ;
200 
201 /*-----------------------------------------------------------------------------
202  Functions code
203  -----------------------------------------------------------------------------*/
204 
205 /*----------------------------------------------------------------------------*/
212 /*----------------------------------------------------------------------------*/
213 static int crires_spec_jitter(
214  cpl_frameset * frameset,
215  const cpl_parameterlist * parlist)
216 {
217  const char * sval ;
218  const char * wl_ypos ;
219  const char * y_pos ;
220  cpl_frameset * rawframes ;
221  cpl_frameset * skyframes ;
222  const char * fname ;
223  cpl_frame * fr ;
224  double tot_ndit ;
225  const char * flat ;
226  const char * dark ;
227  const char * bpm ;
228  const char * detlin ;
229  const char * wavecal ;
230  const char * oh_cat ;
231  const char * hitran_cat ;
232  const char * std_star ;
233  const char * cfg_model ;
234  cpl_propertylist * plist ;
235  double wmin, wmax ;
236  cpl_table * std_star_tab ;
237  cpl_bivector * std_star_biv ;
238  cpl_imagelist ** comblist ;
239  int comblist_offset ;
240  cpl_table * wave_tab[CRIRES_NB_DETECTORS] ;
241  cpl_table * extr_tab[CRIRES_NB_DETECTORS] ;
242  cpl_image * profiles[CRIRES_NB_DETECTORS] ;
243  cpl_image * bg_maps[CRIRES_NB_DETECTORS] ;
244  cpl_imagelist * prof_list ;
245  cpl_imagelist * bgmap_list ;
246  cpl_imagelist * wl_map_loc ;
247  cpl_imagelist * wl_map_model_loc ;
248  cpl_vector ** wavelengths ;
249  cpl_vector * wave_ypos ;
250  int pix, extr_spec_starty, extr_spec_stopy ;
251  int i, j ;
252 
253  /* Needed for sscanf() */
254  setlocale(LC_NUMERIC, "C");
255 
256  /* Initialise */
257  rawframes = NULL ;
258  skyframes = NULL ;
259  comblist_offset = -1 ;
260  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
261  crires_spec_jitter_config.qc_specpos[i] = -1 ;
262  crires_spec_jitter_config.qc_specwrec[i] = -1 ;
263  crires_spec_jitter_config.qc_specwopt[i] = -1 ;
264  crires_spec_jitter_config.qc_specoptmed[i] = -1.0 ;
265  crires_spec_jitter_config.qc_s2nmed[i] = -1.0 ;
266  crires_spec_jitter_config.qc_wlxc[i] = -1.0 ;
267  crires_spec_jitter_config.qc_wlcent[i] = -1.0 ;
268  crires_spec_jitter_config.qc_wldisp[i] = -1.0 ;
269  crires_spec_jitter_config.qc_sensmed[i] = -1.0 ;
270  crires_spec_jitter_config.qc_convmed[i] = -1.0 ;
271  crires_spec_jitter_config.qc_thromed[i] = -1.0 ;
272  crires_spec_jitter_config.qc_fwhm_comb_pix[i] = -1.0 ;
273  crires_spec_jitter_config.qc_fwhm_comb_as[i] = -1.0 ;
274  crires_spec_jitter_config.qc_fwhm_prof_pix[i] = -1.0 ;
275  crires_spec_jitter_config.qc_fwhm_prof_as[i] = -1.0 ;
276  crires_spec_jitter_config.qc_fwhm_diff[i] = -1.0 ;
277  }
278  crires_spec_jitter_config.wl_ppm = 0 ;
279  crires_spec_jitter_config.wl_slitw = 2.0 ;
280  crires_spec_jitter_config.wl_fwhm = 2.0 ;
281 
282  /* Retrieve input parameters */
283  crires_spec_jitter_config.display = crires_parameterlist_get_int(parlist,
284  RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
285  crires_spec_jitter_config.comb_refine = crires_parameterlist_get_bool(
286  parlist, RECIPE_STRING, CRIRES_PARAM_REFINE) ;
287  crires_spec_jitter_config.comb_onlyA = crires_parameterlist_get_bool(
288  parlist, RECIPE_STRING, CRIRES_PARAM_ONLYA) ;
289  crires_spec_jitter_config.comb_onlyB = crires_parameterlist_get_bool(
290  parlist, RECIPE_STRING, CRIRES_PARAM_ONLYB) ;
291  sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
292  CRIRES_PARAM_COMB_USED) ;
293  if (!strcmp(sval, "NODA"))
294  crires_spec_jitter_config.comb_used = CRIRES_COMB_METHOD_NODA ;
295  else if (!strcmp(sval, "NODB"))
296  crires_spec_jitter_config.comb_used = CRIRES_COMB_METHOD_NODB ;
297  else if (!strcmp(sval, "COMB"))
298  crires_spec_jitter_config.comb_used = CRIRES_COMB_METHOD_COMB ;
299  else {
300  cpl_msg_error(__func__, "Invalid combination method specified");
301  return -1;
302  }
303  crires_spec_jitter_config.comb_blind = crires_parameterlist_get_bool(
304  parlist, RECIPE_STRING, CRIRES_PARAM_BLIND) ;
305  sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
306  CRIRES_PARAM_WAVES) ;
307  if (sscanf(sval, "%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg",
308  &crires_spec_jitter_config.wstart[0],
309  &crires_spec_jitter_config.wstop[0],
310  &crires_spec_jitter_config.wstart[1],
311  &crires_spec_jitter_config.wstop[1],
312  &crires_spec_jitter_config.wstart[2],
313  &crires_spec_jitter_config.wstop[2],
314  &crires_spec_jitter_config.wstart[3],
315  &crires_spec_jitter_config.wstop[3])!=2*CRIRES_NB_DETECTORS){
316  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
317  return -1 ;
318  }
319  crires_spec_jitter_config.wl_log = crires_parameterlist_get_bool(parlist,
320  RECIPE_STRING, CRIRES_PARAM_WL_LOG) ;
321  crires_spec_jitter_config.wl_nolimit = crires_parameterlist_get_bool(
322  parlist, RECIPE_STRING, CRIRES_PARAM_WL_NOLIMIT) ;
323  crires_spec_jitter_config.wl_degree = crires_parameterlist_get_int(parlist,
324  RECIPE_STRING, CRIRES_PARAM_DEGREE) ;
325  crires_spec_jitter_config.wl_err = crires_parameterlist_get_double(parlist,
326  RECIPE_STRING, CRIRES_PARAM_WL_ERROR) ;
327  crires_spec_jitter_config.wl_xclimit = crires_parameterlist_get_double(
328  parlist, RECIPE_STRING, CRIRES_PARAM_XC_LIMIT) ;
329  crires_spec_jitter_config.wl_samples = crires_parameterlist_get_int(parlist,
330  RECIPE_STRING, CRIRES_PARAM_WL_NBSAMPLES) ;
331  crires_spec_jitter_config.wl_clean = crires_parameterlist_get_bool(parlist,
332  RECIPE_STRING, CRIRES_PARAM_WL_CLEAN) ;
333  crires_spec_jitter_config.wl_ypos_c1 = crires_parameterlist_get_string(
334  parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP1) ;
335  crires_spec_jitter_config.wl_ypos_c2 = crires_parameterlist_get_string(
336  parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP2) ;
337  crires_spec_jitter_config.wl_ypos_c3 = crires_parameterlist_get_string(
338  parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP3) ;
339  crires_spec_jitter_config.wl_ypos_c4 = crires_parameterlist_get_string(
340  parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP4) ;
341  crires_spec_jitter_config.wl_width= crires_parameterlist_get_int(parlist,
342  RECIPE_STRING, CRIRES_PARAM_Y_WIDTH) ;
343  crires_spec_jitter_config.extr_box_hor_size = crires_parameterlist_get_int(
344  parlist, RECIPE_STRING, CRIRES_PARAM_HOR_SIZE) ;
345  crires_spec_jitter_config.extr_spec_hsize = crires_parameterlist_get_int(
346  parlist, RECIPE_STRING, CRIRES_PARAM_SPEC_HSIZE) ;
347  crires_spec_jitter_config.extr_kappa = crires_parameterlist_get_double(
348  parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA) ;
349  crires_spec_jitter_config.extr_closing_hs = crires_parameterlist_get_int(
350  parlist, RECIPE_STRING, CRIRES_PARAM_CLOSING_HSIZE) ;
351  crires_spec_jitter_config.extr_clean_rate = crires_parameterlist_get_double(
352  parlist, RECIPE_STRING, CRIRES_PARAM_CLEAN_RATE) ;
353  sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
354  CRIRES_PARAM_REJECT) ;
355  if (sscanf(sval, "%d,%d",
356  &crires_spec_jitter_config.extr_rej_left,
357  &crires_spec_jitter_config.extr_rej_right)!=2) {
358  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
359  return -1 ;
360  }
361  crires_spec_jitter_config.extr_y_spec_zone_c1 =
362  crires_parameterlist_get_string(parlist, RECIPE_STRING,
363  CRIRES_PARAM_Y_SPEC_ZONE_CHIP1) ;
364  crires_spec_jitter_config.extr_y_spec_zone_c2 =
365  crires_parameterlist_get_string(parlist, RECIPE_STRING,
366  CRIRES_PARAM_Y_SPEC_ZONE_CHIP2) ;
367  crires_spec_jitter_config.extr_y_spec_zone_c3 =
368  crires_parameterlist_get_string(parlist, RECIPE_STRING,
369  CRIRES_PARAM_Y_SPEC_ZONE_CHIP3) ;
370  crires_spec_jitter_config.extr_y_spec_zone_c4 =
371  crires_parameterlist_get_string(parlist, RECIPE_STRING,
372  CRIRES_PARAM_Y_SPEC_ZONE_CHIP4) ;
373 
374  /* Identify the RAW and CALIB frames in the input frameset */
375  if (crires_dfs_set_groups(frameset, "crires_spec_jitter")) {
376  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
377  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
378  return -1 ;
379  }
380 
381  /* Retrieve calibration data */
382  flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
383  dark = crires_extract_filename(frameset, CRIRES_CALPRO_DARK) ;
384  bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
385  detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
386  wavecal = crires_extract_filename(frameset, CRIRES_CALPRO_WAVE) ;
387  oh_cat = crires_extract_filename(frameset, CRIRES_CALPRO_OH_CAT) ;
388  hitran_cat = crires_extract_filename(frameset, CRIRES_CALPRO_HITRAN_CAT) ;
389  std_star = crires_extract_filename(frameset,CRIRES_CALPRO_STD_PHOTOFLUX);
390  cfg_model = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_CONFIG);
391 
392  /* Retrieve raw frames */
393  if ((rawframes = crires_extract_frameset(frameset,
394  CRIRES_SPEC_JITTER_RAW)) != NULL) {
395  crires_spec_jitter_config.nodding = 0 ;
396  crires_spec_jitter_config.std_mode = 0 ;
397  } else if ((rawframes = crires_extract_frameset(frameset,
398  CRIRES_SPEC_JITTER_J_RAW)) != NULL) {
399  crires_spec_jitter_config.nodding = 0 ;
400  crires_spec_jitter_config.std_mode = 0 ;
401  } else if ((rawframes = crires_extract_frameset(frameset,
402  CRIRES_SPEC_NODDING_OBJECT_RAW)) != NULL) {
403  crires_spec_jitter_config.nodding = 1 ;
404  crires_spec_jitter_config.std_mode = 0 ;
405  } else if ((rawframes = crires_extract_frameset(frameset,
406  CRIRES_SPEC_GENERIC_OBJECT_RAW)) != NULL) {
407  crires_spec_jitter_config.nodding = 0 ;
408  crires_spec_jitter_config.std_mode = 0 ;
409  } else if ((rawframes = crires_extract_frameset(frameset,
410  CRIRES_SPEC_NODDING_RAW)) != NULL) {
411  crires_spec_jitter_config.nodding = 1 ;
412  crires_spec_jitter_config.std_mode = 0 ;
413  } else if ((rawframes = crires_extract_frameset(frameset,
414  CRIRES_SPEC_NODDING_J_RAW)) != NULL) {
415  crires_spec_jitter_config.nodding = 1 ;
416  crires_spec_jitter_config.std_mode = 0 ;
417  } else if ((rawframes = crires_extract_frameset(frameset,
418  CRIRES_SPEC_JITTER_STD_RAW)) != NULL) {
419  crires_spec_jitter_config.nodding = 0 ;
420  crires_spec_jitter_config.std_mode = 1 ;
421  } else if ((rawframes = crires_extract_frameset(frameset,
422  CRIRES_SPEC_JITTER_J_STD_RAW)) != NULL) {
423  crires_spec_jitter_config.nodding = 0 ;
424  crires_spec_jitter_config.std_mode = 1 ;
425  } else if ((rawframes = crires_extract_frameset(frameset,
426  CRIRES_SPEC_NODDING_STD_RAW)) != NULL) {
427  crires_spec_jitter_config.nodding = 1 ;
428  crires_spec_jitter_config.std_mode = 1 ;
429  } else if ((rawframes = crires_extract_frameset(frameset,
430  CRIRES_SPEC_NODDING_J_STD_RAW)) != NULL) {
431  crires_spec_jitter_config.nodding = 1 ;
432  crires_spec_jitter_config.std_mode = 1 ;
433  } else {
434  cpl_msg_error(__func__, "No raw frame in input") ;
435  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
436  return -1 ;
437  }
438 
439  /* Checks on the parameters validity */
440  if (crires_spec_jitter_config.nodding == 0) {
441  /* Only the COMBINED image makes sense */
442  if (crires_spec_jitter_config.comb_used != CRIRES_COMB_METHOD_COMB) {
443  cpl_msg_warning(__func__,
444  "NODA or NODB can only be used in nodding mode") ;
445  crires_spec_jitter_config.comb_used = CRIRES_COMB_METHOD_COMB ;
446  }
447 
448  /* OnlyA and OnlyB are only possible in nodding mode */
449  if (crires_spec_jitter_config.comb_onlyA) {
450  cpl_msg_warning(__func__, "onlyA only possible in nodding mode") ;
451  crires_spec_jitter_config.comb_onlyA = 0 ;
452  }
453  if (crires_spec_jitter_config.comb_onlyB) {
454  cpl_msg_warning(__func__, "onlyB only possible in nodding mode") ;
455  crires_spec_jitter_config.comb_onlyB = 0 ;
456  }
457  }
458  if ((crires_spec_jitter_config.comb_used == CRIRES_COMB_METHOD_NODA)
459  && (crires_spec_jitter_config.comb_onlyA == 0)) {
460  cpl_msg_warning(__func__,
461  "You forgot to require the NODA image to be produced !") ;
462  crires_spec_jitter_config.comb_onlyA = 1 ;
463  }
464  if ((crires_spec_jitter_config.comb_used == CRIRES_COMB_METHOD_NODB)
465  && (crires_spec_jitter_config.comb_onlyB == 0)) {
466  cpl_msg_warning(__func__,
467  "You forgot to require the NODB image to be produced !") ;
468  crires_spec_jitter_config.comb_onlyB = 1 ;
469  }
470 
471  /* Set comblist_offset */
472  if (crires_spec_jitter_config.comb_used == CRIRES_COMB_METHOD_COMB)
473  comblist_offset = 0 ;
474  else if (crires_spec_jitter_config.comb_used == CRIRES_COMB_METHOD_NODA)
475  comblist_offset = 1 ;
476  else if (crires_spec_jitter_config.comb_used == CRIRES_COMB_METHOD_NODB)
477  comblist_offset = 2 ;
478 
479  /* Retrieve sky frames if any */
480  skyframes = crires_extract_frameset(frameset, CRIRES_SPEC_NODDING_SKY_RAW) ;
481  if (skyframes == NULL) {
482  skyframes = crires_extract_frameset(frameset,
483  CRIRES_SPEC_GENERIC_SKY_RAW) ;
484  }
485 
486  /* Get the detector illumination period */
487  crires_spec_jitter_config.period =
488  crires_get_detector_illum_period(
489  cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ;
490  if (crires_spec_jitter_config.period == CRIRES_ILLUM_UNKNOWN) {
491  cpl_msg_error(__func__,
492  "Cannot determine the detector illumination period") ;
493  cpl_frameset_delete(rawframes) ;
494  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
495  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
496  return -1 ;
497  } else {
498  crires_display_detector_illum(crires_spec_jitter_config.period) ;
499  }
500 
501  /* Get the total number of NDIT */
502  fr = cpl_frameset_get_position(rawframes, 0);
503  tot_ndit = crires_get_totndit(cpl_frame_get_filename(fr)) ;
504  if (tot_ndit < 0) {
505  cpl_msg_error(__func__, "Cannot get the total number of NDIT") ;
506  cpl_frameset_delete(rawframes) ;
507  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
508  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
509  return -1 ;
510  }
511  tot_ndit *= cpl_frameset_get_size(rawframes) ;
512 
513  /* Images recombination */
514  cpl_msg_info(__func__, "Images combination") ;
515  cpl_msg_indent_more() ;
516  if ((comblist = crires_combine_imagelist(rawframes, skyframes,
517  crires_spec_jitter_config.period,
518  flat, dark, bpm, detlin,
519  crires_spec_jitter_config.nodding,
520  crires_spec_jitter_config.comb_blind,
521  crires_spec_jitter_config.comb_refine,
522  crires_spec_jitter_config.comb_onlyA,
523  crires_spec_jitter_config.comb_onlyB)) == NULL) {
524  cpl_msg_error(__func__, "Cannot combine the images") ;
525  cpl_frameset_delete(rawframes) ;
526  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
527  cpl_msg_indent_less() ;
528  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
529  return -1 ;
530  }
531  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
532  cpl_msg_indent_less() ;
533 
534  /* Spectrum extraction */
535  cpl_msg_info(__func__, "Spectrum extraction") ;
536  cpl_msg_indent_more() ;
537  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
538  cpl_msg_info(__func__, "Chip number %d extraction", i+1) ;
539  cpl_msg_indent_more() ;
540 
541  /* Where is the spectrum extraction zone ? */
542  y_pos = "" ;
543  if (i+1 == 1) y_pos = crires_spec_jitter_config.extr_y_spec_zone_c1 ;
544  if (i+1 == 2) y_pos = crires_spec_jitter_config.extr_y_spec_zone_c2 ;
545  if (i+1 == 3) y_pos = crires_spec_jitter_config.extr_y_spec_zone_c3 ;
546  if (i+1 == 4) y_pos = crires_spec_jitter_config.extr_y_spec_zone_c4 ;
547  if (sscanf(y_pos,"%d,%d", &extr_spec_starty, &extr_spec_stopy)!=2) {
548  cpl_msg_warning(__func__, "Wrong Spectral Zone specified: %s",
549  y_pos) ;
550  extr_spec_starty = extr_spec_stopy = -1 ;
551  }
552 
553  if ((extr_tab[i] = crires_extract_spectrum(
554  cpl_imagelist_get(comblist[0+2*comblist_offset], i),
555  cpl_imagelist_get(comblist[1+2*comblist_offset], i),
556  crires_spec_jitter_config.extr_box_hor_size,
557  crires_spec_jitter_config.extr_spec_hsize,
558  crires_spec_jitter_config.extr_kappa,
559  crires_spec_jitter_config.extr_closing_hs,
560  crires_spec_jitter_config.extr_clean_rate,
561  crires_spec_jitter_config.extr_rej_left,
562  crires_spec_jitter_config.extr_rej_right,
563  extr_spec_starty, extr_spec_stopy, i+1, tot_ndit,
564  crires_spec_jitter_config.period,
565  &(crires_spec_jitter_config.qc_specpos[i]),
566  &(crires_spec_jitter_config.qc_specwrec[i]),
567  &(crires_spec_jitter_config.qc_specwopt[i]),
568  &(crires_spec_jitter_config.qc_specoptmed[i]),
569  &(crires_spec_jitter_config.qc_s2nmed[i]),
570  &(profiles[i]),
571  &(bg_maps[i]))) == NULL) {
572  cpl_msg_error(__func__, "Cannot extract the spectrum") ;
573  cpl_msg_indent_less() ;
574  cpl_msg_indent_less() ;
575  for (j=0 ; j<i ; j++)
576  cpl_table_delete(extr_tab[j]) ;
577  for (j=0 ; j<i ; j++)
578  cpl_image_delete(profiles[j]) ;
579  for (j=0 ; j<i ; j++)
580  cpl_image_delete(bg_maps[j]) ;
581  cpl_imagelist_delete(comblist[0]) ;
582  cpl_imagelist_delete(comblist[1]) ;
583  if (crires_spec_jitter_config.comb_onlyA) {
584  cpl_imagelist_delete(comblist[2]) ;
585  cpl_imagelist_delete(comblist[3]) ;
586  }
587  if (crires_spec_jitter_config.comb_onlyB) {
588  cpl_imagelist_delete(comblist[4]) ;
589  cpl_imagelist_delete(comblist[5]) ;
590  }
591  cpl_free(comblist) ;
592  cpl_frameset_delete(rawframes) ;
593  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
594  return -1 ;
595  }
596  cpl_msg_info(__func__, "Chip number %d FWHM Computation", i+1) ;
597  if (crires_extract_qc_fwhm(
598  cpl_imagelist_get(comblist[0+2*comblist_offset], i),
599  profiles[i],
600  &(crires_spec_jitter_config.qc_fwhm_comb_pix[i]),
601  &(crires_spec_jitter_config.qc_fwhm_comb_as[i]),
602  &(crires_spec_jitter_config.qc_fwhm_prof_pix[i]),
603  &(crires_spec_jitter_config.qc_fwhm_prof_as[i]),
604  &(crires_spec_jitter_config.qc_fwhm_diff[i])) == -1) {
605  cpl_msg_warning(__func__, "Failed for FWHM computation") ;
606  crires_spec_jitter_config.qc_fwhm_comb_pix[i] = -1.0 ;
607  crires_spec_jitter_config.qc_fwhm_comb_as[i] = -1.0 ;
608  crires_spec_jitter_config.qc_fwhm_prof_pix[i] = -1.0 ;
609  crires_spec_jitter_config.qc_fwhm_prof_as[i] = -1.0 ;
610  crires_spec_jitter_config.qc_fwhm_diff[i] = -1.0 ;
611  }
612  cpl_msg_indent_less() ;
613  }
614 
615  /* Create the profile and bg maps */
616  prof_list = cpl_imagelist_new() ;
617  bgmap_list = cpl_imagelist_new() ;
618  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
619  cpl_imagelist_set(prof_list, profiles[i], i) ;
620  cpl_imagelist_set(bgmap_list, bg_maps[i], i) ;
621  }
622 
623  /* Test that the spectrum is at the same place in all detectors */
624  for (i=1 ; i<CRIRES_NB_DETECTORS ; i++) {
625  if (crires_spec_jitter_config.qc_specpos[i-1] > 0 &&
626  crires_spec_jitter_config.qc_specpos[i] > 0 &&
627  fabs(crires_spec_jitter_config.qc_specpos[i-1] -
628  crires_spec_jitter_config.qc_specpos[i]) >
629  CRIRES_SPEC_POS_TOLERANCE) {
630  cpl_msg_warning(__func__,
631  "The spectrum positions in chip %d and chip %d are too different: %d -> %d",
632  i, i+1, crires_spec_jitter_config.qc_specpos[i-1],
633  crires_spec_jitter_config.qc_specpos[i]) ;
634  }
635  }
636  cpl_msg_indent_less() ;
637 
638  /* Wavelength calibration */
639  cpl_msg_info(__func__, "Wavelength Calibration") ;
640  cpl_msg_indent_more() ;
641  if (wavecal != NULL) {
642  /* Wavelength solution is provided */
643  cpl_msg_info(__func__, "Use the provided solution") ;
644  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
645  if ((wave_tab[i] = crires_load_table_check(wavecal, i+1,
646  CRIRES_PROTYPE_WL_POLY, -1, -1, 0)) == NULL) {
647  cpl_msg_error(__func__, "Cannot load the wavelength table") ;
648  cpl_msg_indent_less() ;
649  cpl_frameset_delete(rawframes) ;
650  cpl_imagelist_delete(comblist[0]) ;
651  cpl_imagelist_delete(comblist[1]) ;
652  if (crires_spec_jitter_config.comb_onlyA) {
653  cpl_imagelist_delete(comblist[2]) ;
654  cpl_imagelist_delete(comblist[3]) ;
655  }
656  if (crires_spec_jitter_config.comb_onlyB) {
657  cpl_imagelist_delete(comblist[4]) ;
658  cpl_imagelist_delete(comblist[5]) ;
659  }
660  cpl_free(comblist) ;
661  for (j=0 ; j<CRIRES_NB_DETECTORS ; j++)
662  cpl_table_delete(extr_tab[j]) ;
663  cpl_imagelist_delete(prof_list) ;
664  cpl_imagelist_delete(bgmap_list) ;
665  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
666  return -1 ;
667  }
668  }
669  } else {
670  /* Calibrate from the science */
671  cpl_msg_info(__func__, "Use the science frame sky to calibrate") ;
672 
673  /* Reduce the first raw frame */
674  fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
675 
676  /* Get the Minimum and Maximum wavelengths */
677  if (crires_spec_jitter_config.wl_nolimit == 0) {
678  plist = cpl_propertylist_load(fname, 0) ;
679  wmin = crires_pfits_get_wlen_min(plist) ;
680  wmax = crires_pfits_get_wlen_max(plist) ;
681  cpl_propertylist_delete(plist) ;
682  if (cpl_error_get_code()) {
683  wmin = wmax = -1.0 ;
684  cpl_error_reset() ;
685  }
686  } else {
687  wmin = wmax = -1.0 ;
688  }
689 
690  /* Loop on the detectors */
691  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
692  cpl_msg_info(__func__, "Calibrate chip number %d", i+1) ;
693  cpl_msg_indent_more() ;
694 
695  /* Where Compute the wavelength from ? */
696  if (i+1 == 1) wl_ypos = crires_spec_jitter_config.wl_ypos_c1 ;
697  if (i+1 == 2) wl_ypos = crires_spec_jitter_config.wl_ypos_c2 ;
698  if (i+1 == 3) wl_ypos = crires_spec_jitter_config.wl_ypos_c3 ;
699  if (i+1 == 4) wl_ypos = crires_spec_jitter_config.wl_ypos_c4 ;
700 
701  if (!strcmp(wl_ypos, "")) {
702  /* Use the spectrum position for the wavelength calibration */
703  cpl_msg_info(__func__,
704  "Compute the wavelength at the spectrum position: %d",
705  crires_spec_jitter_config.qc_specpos[i]) ;
706  wave_ypos = cpl_vector_new(1) ;
707  cpl_vector_set(wave_ypos, 0,
708  (double)(crires_spec_jitter_config.qc_specpos[i])) ;
709  } else {
710  cpl_msg_info(__func__,
711  "Use the Y positions provided on the command line") ;
712  if ((wave_ypos = crires_parse_y_positions(wl_ypos)) == NULL) {
713  cpl_msg_warning(__func__,
714  "Cannot parse the y_pos value : %s - use %d",
715  wl_ypos, crires_spec_jitter_config.qc_specpos[i]);
716  /* Use the spectrum pos for the wavelength calibration */
717  wave_ypos = cpl_vector_new(1) ;
718  cpl_vector_set(wave_ypos, 0,
719  (double)(crires_spec_jitter_config.qc_specpos[i])) ;
720  }
721  }
722 
723  wave_tab[i] = crires_wlcalib_sky(fname,
724  crires_spec_jitter_config.period,
725  oh_cat, hitran_cat, crires_spec_jitter_config.wl_log,
726  flat, dark, bpm, detlin,
727  crires_spec_jitter_config.wstart[i],
728  crires_spec_jitter_config.wstop[i],
729  wmin, wmax, i+1,
730  wave_ypos,
731  crires_spec_jitter_config.wl_width,
732  crires_spec_jitter_config.wl_degree,
733  crires_spec_jitter_config.wl_slitw,
734  crires_spec_jitter_config.wl_fwhm,
735  crires_spec_jitter_config.wl_err,
736  crires_spec_jitter_config.wl_samples,
737  crires_spec_jitter_config.wl_clean,
738  crires_spec_jitter_config.wl_xclimit,
739  crires_spec_jitter_config.wl_ppm,
740  (i+1==crires_spec_jitter_config.display)) ;
741  cpl_msg_indent_less() ;
742  cpl_vector_delete(wave_ypos) ;
743  }
744  }
745 
746  /* Create the wave map */
747  if ((wl_map_loc = crires_wlcalib_gen_wlmap((const cpl_table **)wave_tab))
748  == NULL) {
749  cpl_msg_error(__func__, "Cannot compute the Wavelength Map") ;
750  cpl_frameset_delete(rawframes) ;
751  cpl_imagelist_delete(comblist[0]) ;
752  cpl_imagelist_delete(comblist[1]) ;
753  if (crires_spec_jitter_config.comb_onlyA) {
754  cpl_imagelist_delete(comblist[2]) ;
755  cpl_imagelist_delete(comblist[3]) ;
756  }
757  if (crires_spec_jitter_config.comb_onlyB) {
758  cpl_imagelist_delete(comblist[4]) ;
759  cpl_imagelist_delete(comblist[5]) ;
760  }
761  cpl_free(comblist) ;
762  cpl_imagelist_delete(prof_list) ;
763  cpl_imagelist_delete(bgmap_list) ;
764  for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) {
765  cpl_table_delete(extr_tab[j]) ;
766  if (wave_tab[j] != NULL) cpl_table_delete(wave_tab[j]);
767  }
768  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
769  return -1 ;
770  }
771 
772  /* Compute the QC parameters */
773  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
774  crires_spec_jitter_config.qc_wlcent[i] =
775  cpl_image_get(cpl_imagelist_get(wl_map_loc, i),
776  512, crires_spec_jitter_config.qc_specpos[i], &pix) ;
777  crires_spec_jitter_config.qc_wldisp[i] =
778  ((cpl_image_get(cpl_imagelist_get(wl_map_loc, i), 1024,
779  crires_spec_jitter_config.qc_specpos[i], &pix)) -
780  (cpl_image_get(cpl_imagelist_get(wl_map_loc, i), 1,
781  crires_spec_jitter_config.qc_specpos[i], &pix)))
782  / 1023 ;
783  crires_spec_jitter_config.qc_wlxc[i] =
784  crires_wlcalib_get_better_xc(wave_tab[i]) ;
785  }
786  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
787  if (wave_tab[i] != NULL) cpl_table_delete(wave_tab[i]);
788 
789  /* Get the wl map from the model */
790  fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
791  if ((cfg_model != NULL) && (!crires_model_off()) &&
792  (crires_model_config_check(cfg_model, fname) == 0)) {
793  cpl_msg_info(__func__, "Call the model to get the wavelength map") ;
794  cpl_msg_indent_more() ;
795  wl_map_model_loc = crires_model_wavpix(fname, cfg_model, -1) ;
796  if (wl_map_model_loc == NULL) {
797  cpl_msg_warning(__func__, "Model function returns NULL") ;
798  cpl_error_reset() ;
799  }
800  cpl_msg_indent_less() ;
801  } else {
802  wl_map_model_loc = NULL ;
803  }
804 
805  /* Apply the wavelength */
806  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
807  cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH,
808  CPL_TYPE_DOUBLE) ;
809  for (j=0 ; j<cpl_table_get_nrow(extr_tab[i]) ; j++) {
810  cpl_table_set_double(extr_tab[i], CRIRES_COL_WAVELENGTH, j,
811  cpl_image_get(cpl_imagelist_get_const(wl_map_loc, i), j+1,
812  crires_spec_jitter_config.qc_specpos[i], &pix));
813  }
814  }
815 
816  /* Add the Model Wavelength and Call the model to fill it */
817  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
818  cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH_MODEL,
819  CPL_TYPE_DOUBLE) ;
820  cpl_table_fill_column_window_double(extr_tab[i],
821  CRIRES_COL_WAVELENGTH_MODEL, 0,
822  cpl_table_get_nrow(extr_tab[i]), -1.0) ;
823  }
824  if ((cfg_model != NULL) && (!crires_model_off()) && (1)) {
825  cpl_msg_info(__func__, "Call the model to get the wavelengths") ;
826  cpl_msg_indent_more() ;
827  wavelengths = crires_model_wavelengths(
828  cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)),
829  cfg_model, -1,
830  (double)(crires_spec_jitter_config.qc_specpos[0]),
831  wl_map_model_loc) ;
832  if (wavelengths != NULL) {
833  /* Loop on the detectors */
834  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
835  /* Loop on the x values */
836  for (j=0 ; j<cpl_vector_get_size(wavelengths[i]) ; j++) {
837  cpl_table_set_double(extr_tab[i],
838  CRIRES_COL_WAVELENGTH_MODEL, j,
839  cpl_vector_get(wavelengths[i], j)) ;
840  }
841  }
842  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
843  cpl_vector_delete(wavelengths[i]) ;
844  cpl_free(wavelengths) ;
845  } else {
846  cpl_msg_warning(__func__, "Model function returns NULL") ;
847  cpl_error_reset() ;
848  }
849  cpl_msg_indent_less() ;
850  }
851 
852  /* Conversion factor / Sensitivity */
853  if (crires_spec_jitter_config.std_mode) {
854  cpl_msg_info(__func__,
855  "Sensitivity / Conversion / Throughput computation") ;
856  cpl_msg_indent_more() ;
857  /* Load std star */
858  if ((std_star_tab = crires_load_table_check(std_star, 1,
859  CRIRES_PROTYPE_PHO_FLUX, -1, -1, 0)) == NULL) {
860  cpl_msg_error(__func__, "Cannot load the std star flux") ;
861  } else {
862  /* Get the wished std star */
863  if ((std_star_biv = crires_photom_conv_get_star(std_star_tab,
864  cpl_frame_get_filename(
865  cpl_frameset_get_position(rawframes,0)))) == NULL) {
866  cpl_msg_error(__func__, "Cannot find the star flux") ;
867  cpl_table_delete(std_star_tab) ;
868  } else {
869  cpl_table_delete(std_star_tab) ;
870  /* Apply the conversion */
871  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
872  if (crires_photom_conv_engine(extr_tab[i], std_star_biv,
873  i+1, (i+1==crires_spec_jitter_config.display))==0){
874  crires_spec_jitter_config.qc_convmed[i] =
875  cpl_table_get_column_median(extr_tab[i],
876  CRIRES_COL_CONVERSION_RECT) ;
877  crires_spec_jitter_config.qc_thromed[i] =
878  cpl_table_get_column_median(extr_tab[i],
879  CRIRES_COL_THROUGHPUT) ;
880  /* Apply the sensitivity */
881  if (crires_photom_sens_engine(extr_tab[i],
882  cpl_frame_get_filename(cpl_frameset_get_position(
883  rawframes,0)), -1.0,
884  (i+1==crires_spec_jitter_config.display))>0) {
885  crires_spec_jitter_config.qc_sensmed[i] =
886  cpl_table_get_column_median(extr_tab[i],
887  CRIRES_COL_SENSITIVITY) ; ;
888  }
889  }
890  }
891  cpl_bivector_delete(std_star_biv) ;
892  }
893  }
894  cpl_msg_indent_less() ;
895  }
896  cpl_frameset_delete(rawframes) ;
897 
898  /* Save the product */
899  cpl_msg_info(__func__, "Save the product") ;
900  cpl_msg_indent_more() ;
901  if (crires_spec_jitter_save((const cpl_imagelist **)comblist,
902  prof_list, bgmap_list,
903  (const cpl_table **)extr_tab, wl_map_loc, wl_map_model_loc,
904  parlist, frameset)) {
905  cpl_msg_error(__func__, "Cannot save the product") ;
906  cpl_imagelist_delete(prof_list) ;
907  cpl_imagelist_delete(bgmap_list) ;
908  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
909  if (extr_tab[i] != NULL) cpl_table_delete(extr_tab[i]) ;
910  cpl_imagelist_delete(comblist[0]) ;
911  cpl_imagelist_delete(comblist[1]) ;
912  if (crires_spec_jitter_config.comb_onlyA) {
913  cpl_imagelist_delete(comblist[2]) ;
914  cpl_imagelist_delete(comblist[3]) ;
915  }
916  if (crires_spec_jitter_config.comb_onlyB) {
917  cpl_imagelist_delete(comblist[4]) ;
918  cpl_imagelist_delete(comblist[5]) ;
919  }
920  cpl_free(comblist) ;
921  cpl_imagelist_delete(wl_map_loc) ;
922  if (wl_map_model_loc) cpl_imagelist_delete(wl_map_model_loc) ;
923  cpl_msg_indent_less() ;
924  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
925  return -1 ;
926  }
927  cpl_imagelist_delete(wl_map_loc) ;
928  if (wl_map_model_loc) cpl_imagelist_delete(wl_map_model_loc) ;
929  cpl_imagelist_delete(comblist[0]) ;
930  cpl_imagelist_delete(comblist[1]) ;
931  if (crires_spec_jitter_config.comb_onlyA) {
932  cpl_imagelist_delete(comblist[2]) ;
933  cpl_imagelist_delete(comblist[3]) ;
934  }
935  if (crires_spec_jitter_config.comb_onlyB) {
936  cpl_imagelist_delete(comblist[4]) ;
937  cpl_imagelist_delete(comblist[5]) ;
938  }
939  cpl_free(comblist) ;
940  cpl_imagelist_delete(prof_list) ;
941  cpl_imagelist_delete(bgmap_list) ;
942  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
943  if (extr_tab[i] != NULL) cpl_table_delete(extr_tab[i]) ;
944  cpl_msg_indent_less() ;
945 
946  /* Return */
947  if (cpl_error_get_code()) return -1 ;
948  else return 0 ;
949 }
950 
951 /*----------------------------------------------------------------------------*/
965 /*----------------------------------------------------------------------------*/
966 static int crires_spec_jitter_save(
967  const cpl_imagelist ** images,
968  const cpl_imagelist * prof,
969  const cpl_imagelist * bgmap,
970  const cpl_table ** extr_tab,
971  const cpl_imagelist * wl_map,
972  const cpl_imagelist * wl_map_model,
973  const cpl_parameterlist * parlist,
974  cpl_frameset * set)
975 {
976  cpl_propertylist ** qclists ;
977  const cpl_frame * ref_frame ;
978  const char * procat ;
979  const char * protype ;
980  cpl_propertylist * inputlist ;
981  const char * recipe_name = "crires_spec_jitter" ;
982  int i ;
983 
984  /* Get the reference frame */
985  ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
986 
987  /* Create the QC lists */
988  qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
989  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
990  qclists[i] = cpl_propertylist_new() ;
991  cpl_propertylist_append_int(qclists[i], "ESO QC SPECPOS",
992  crires_spec_jitter_config.qc_specpos[i]) ;
993  cpl_propertylist_append_int(qclists[i], "ESO QC SPECWREC",
994  crires_spec_jitter_config.qc_specwrec[i]) ;
995  cpl_propertylist_append_int(qclists[i], "ESO QC SPECWOPT",
996  crires_spec_jitter_config.qc_specwopt[i]) ;
997  cpl_propertylist_append_double(qclists[i], "ESO QC SIGNAL MED",
998  crires_spec_jitter_config.qc_specoptmed[i]) ;
999  cpl_propertylist_append_double(qclists[i], "ESO QC S2NMED",
1000  crires_spec_jitter_config.qc_s2nmed[i]) ;
1001  cpl_propertylist_append_double(qclists[i], "ESO QC XCORR",
1002  crires_spec_jitter_config.qc_wlxc[i]) ;
1003  cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL",
1004  crires_spec_jitter_config.qc_wlcent[i]) ;
1005  cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL",
1006  crires_spec_jitter_config.qc_wldisp[i]) ;
1007  cpl_propertylist_append_double(qclists[i], "ESO QC SENSMED",
1008  crires_spec_jitter_config.qc_sensmed[i]) ;
1009  cpl_propertylist_append_double(qclists[i], "ESO QC CONVMED",
1010  crires_spec_jitter_config.qc_convmed[i]) ;
1011  cpl_propertylist_append_double(qclists[i], "ESO QC THROMED",
1012  crires_spec_jitter_config.qc_thromed[i]) ;
1013  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX COMBINED",
1014  crires_spec_jitter_config.qc_fwhm_comb_pix[i]) ;
1015  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC COMBINED",
1016  crires_spec_jitter_config.qc_fwhm_comb_as[i]) ;
1017  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX PROFILE",
1018  crires_spec_jitter_config.qc_fwhm_prof_pix[i]) ;
1019  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC PROFILE",
1020  crires_spec_jitter_config.qc_fwhm_prof_as[i]) ;
1021  cpl_propertylist_append_double(qclists[i], "ESO QC FWHM DIFF",
1022  crires_spec_jitter_config.qc_fwhm_diff[i]) ;
1023  /* Propagate some keywords from input raw frame extensions */
1024  inputlist = cpl_propertylist_load_regexp(
1025  cpl_frame_get_filename(ref_frame), i+1,
1026  CRIRES_HEADER_EXT_FORWARD, 0) ;
1027  cpl_propertylist_copy_property_regexp(qclists[i], inputlist,
1028  CRIRES_HEADER_EXT_FORWARD, 0) ;
1029  cpl_propertylist_delete(inputlist) ;
1030  }
1031 
1032  /* PRO.CATG */
1033  if (crires_spec_jitter_config.std_mode == 1) {
1034  procat = CRIRES_STD_COMBINED_IMA ;
1035  } else {
1036  procat = CRIRES_OBS_COMBINED_IMA ;
1037  }
1038 
1039  /* Write the combined image */
1040  crires_image_save(set,
1041  parlist,
1042  set,
1043  images[0],
1044  recipe_name,
1045  procat,
1046  CRIRES_PROTYPE_COMBINED,
1047  crires_spec_jitter_config.period,
1048  NULL,
1049  (const cpl_propertylist **)qclists,
1050  PACKAGE "/" PACKAGE_VERSION,
1051  "crires_spec_jitter_comb.fits") ;
1052 
1053  /* PRO.CATG */
1054  if (crires_spec_jitter_config.std_mode == 1) {
1055  procat = CRIRES_STD_CONTRIBUTION_IMA ;
1056  } else {
1057  procat = CRIRES_OBS_CONTRIBUTION_IMA ;
1058  }
1059 
1060  /* Write the contribution map */
1061  crires_image_save(set,
1062  parlist,
1063  set,
1064  images[1],
1065  recipe_name,
1066  procat,
1067  CRIRES_PROTYPE_CONTRIB,
1068  crires_spec_jitter_config.period,
1069  NULL,
1070  (const cpl_propertylist **)qclists,
1071  PACKAGE "/" PACKAGE_VERSION,
1072  "crires_spec_jitter_contrib.fits") ;
1073 
1074  /* Nodded A support */
1075  if (crires_spec_jitter_config.comb_onlyA) {
1076  /* PRO.CATG */
1077  if (crires_spec_jitter_config.std_mode == 1) {
1078  procat = CRIRES_STD_COMBINED_NA_IMA ;
1079  } else {
1080  procat = CRIRES_OBS_COMBINED_NA_IMA ;
1081  }
1082 
1083  /* Write the combined Nodded A image */
1084  crires_image_save(set,
1085  parlist,
1086  set,
1087  images[2],
1088  recipe_name,
1089  procat,
1090  CRIRES_PROTYPE_COMBINED,
1091  crires_spec_jitter_config.period,
1092  NULL,
1093  (const cpl_propertylist **)qclists,
1094  PACKAGE "/" PACKAGE_VERSION,
1095  "crires_spec_jitter_comb_noddedA.fits") ;
1096 
1097  /* PRO.CATG */
1098  if (crires_spec_jitter_config.std_mode == 1) {
1099  procat = CRIRES_STD_CONTRIBUTION_NA_IMA ;
1100  } else {
1101  procat = CRIRES_OBS_CONTRIBUTION_NA_IMA ;
1102  }
1103 
1104  /* Write the contribution Nodded A image */
1105  crires_image_save(set,
1106  parlist,
1107  set,
1108  images[3],
1109  recipe_name,
1110  procat,
1111  CRIRES_PROTYPE_CONTRIB,
1112  crires_spec_jitter_config.period,
1113  NULL,
1114  (const cpl_propertylist **)qclists,
1115  PACKAGE "/" PACKAGE_VERSION,
1116  "crires_spec_jitter_contrib_noddedA.fits") ;
1117  }
1118 
1119  /* Nodded B support */
1120  if (crires_spec_jitter_config.comb_onlyB) {
1121  /* PRO.CATG */
1122  if (crires_spec_jitter_config.std_mode == 1) {
1123  procat = CRIRES_STD_COMBINED_NB_IMA ;
1124  } else {
1125  procat = CRIRES_OBS_COMBINED_NB_IMA ;
1126  }
1127 
1128  /* Write the combined Nodded B image */
1129  crires_image_save(set,
1130  parlist,
1131  set,
1132  images[4],
1133  recipe_name,
1134  procat,
1135  CRIRES_PROTYPE_COMBINED,
1136  crires_spec_jitter_config.period,
1137  NULL,
1138  (const cpl_propertylist **)qclists,
1139  PACKAGE "/" PACKAGE_VERSION,
1140  "crires_spec_jitter_comb_noddedB.fits") ;
1141 
1142  /* PRO.CATG */
1143  if (crires_spec_jitter_config.std_mode == 1) {
1144  procat = CRIRES_STD_CONTRIBUTION_NB_IMA ;
1145  } else {
1146  procat = CRIRES_OBS_CONTRIBUTION_NB_IMA ;
1147  }
1148 
1149  /* Write the contribution Nodded B image */
1150  crires_image_save(set,
1151  parlist,
1152  set,
1153  images[5],
1154  recipe_name,
1155  procat,
1156  CRIRES_PROTYPE_CONTRIB,
1157  crires_spec_jitter_config.period,
1158  NULL,
1159  (const cpl_propertylist **)qclists,
1160  PACKAGE "/" PACKAGE_VERSION,
1161  "crires_spec_jitter_contrib_noddedB.fits") ;
1162  }
1163 
1164  /* PRO.CATG */
1165  if (crires_spec_jitter_config.std_mode == 1) {
1166  procat = CRIRES_STD_EXTRACT_PROFILE_IMA ;
1167  } else {
1168  procat = CRIRES_OBS_EXTRACT_PROFILE_IMA ;
1169  }
1170 
1171  /* Write the profile image */
1172  crires_image_save(set,
1173  parlist,
1174  set,
1175  prof,
1176  recipe_name,
1177  procat,
1178  CRIRES_PROTYPE_PROFILE,
1179  crires_spec_jitter_config.period,
1180  NULL,
1181  (const cpl_propertylist **)qclists,
1182  PACKAGE "/" PACKAGE_VERSION,
1183  "crires_spec_jitter_prof.fits") ;
1184 
1185  /* PRO.CATG */
1186  if (crires_spec_jitter_config.std_mode == 1) {
1187  procat = CRIRES_STD_EXTRACT_BGMAP_IMA ;
1188  } else {
1189  procat = CRIRES_OBS_EXTRACT_BGMAP_IMA ;
1190  }
1191 
1192  /* Write the background image */
1193  crires_image_save(set,
1194  parlist,
1195  set,
1196  bgmap,
1197  recipe_name,
1198  procat,
1199  CRIRES_PROTYPE_BGD_MAP,
1200  crires_spec_jitter_config.period,
1201  NULL,
1202  (const cpl_propertylist **)qclists,
1203  PACKAGE "/" PACKAGE_VERSION,
1204  "crires_spec_jitter_bgmap.fits") ;
1205 
1206  /* PRO.CATG */
1207  if (crires_spec_jitter_config.std_mode == 1) {
1208  procat = CRIRES_STD_WL_MAP_IMA ;
1209  } else {
1210  procat = CRIRES_OBS_WL_MAP_IMA ;
1211  }
1212 
1213  /* Write the map */
1214  crires_image_save(set,
1215  parlist,
1216  set,
1217  wl_map,
1218  recipe_name,
1219  procat,
1220  CRIRES_PROTYPE_WL_MAP,
1221  crires_spec_jitter_config.period,
1222  NULL,
1223  (const cpl_propertylist **)qclists,
1224  PACKAGE "/" PACKAGE_VERSION,
1225  "crires_spec_jitter_wlmap.fits") ;
1226 
1227  if (wl_map_model != NULL) {
1228  /* PRO.CATG */
1229  if (crires_spec_jitter_config.std_mode == 1) {
1230  procat = CRIRES_STD_WL_MAP_MODEL_IMA ;
1231  } else {
1232  procat = CRIRES_OBS_WL_MAP_MODEL_IMA ;
1233  }
1234 
1235  /* Write the model map */
1236  crires_image_save(set,
1237  parlist,
1238  set,
1239  wl_map_model,
1240  recipe_name,
1241  procat,
1242  CRIRES_PROTYPE_WL_MAP,
1243  crires_spec_jitter_config.period,
1244  NULL,
1245  (const cpl_propertylist **)qclists,
1246  PACKAGE "/" PACKAGE_VERSION,
1247  "crires_spec_jitter_wlmap_model.fits") ;
1248  }
1249 
1250  /* Write the extracted spectra */
1251  /* Get the PRO.CATG */
1252  if (cpl_table_has_column(extr_tab[0], CRIRES_COL_SENSITIVITY)) {
1253  procat = CRIRES_EXTRACT_SENS_TAB ;
1254  protype = CRIRES_PROTYPE_SENSIT ;
1255  } else if (cpl_table_has_column(extr_tab[0],CRIRES_COL_CONVERSION_OPT)){
1256  procat = CRIRES_EXTRACT_CONV_TAB ;
1257  protype = CRIRES_PROTYPE_CONVERS ;
1258  } else if (crires_spec_jitter_config.std_mode == 1) {
1259  procat = CRIRES_STD_EXTRACT_WL_TAB ;
1260  protype = CRIRES_PROTYPE_SPEC_WL ;
1261  } else {
1262  procat = CRIRES_OBS_EXTRACT_WL_TAB ;
1263  protype = CRIRES_PROTYPE_SPEC_WL ;
1264  }
1265  crires_table_save(set,
1266  parlist,
1267  set,
1268  extr_tab,
1269  recipe_name,
1270  procat,
1271  protype,
1272  NULL,
1273  (const cpl_propertylist **)qclists,
1274  PACKAGE "/" PACKAGE_VERSION,
1275  "crires_spec_jitter_extracted.fits") ;
1276 
1277  /* Free and return */
1278  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
1279  cpl_propertylist_delete(qclists[i]) ;
1280  }
1281  cpl_free(qclists) ;
1282  return 0;
1283 }
1284