CRIRES Pipeline Reference Manual  2.3.15
crires_win_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 "crires_wlestimate.h"
37 #include "irplib_utils.h"
38 
39 /*-----------------------------------------------------------------------------
40  Define
41  -----------------------------------------------------------------------------*/
42 
43 #define RECIPE_STRING "crires_win_jitter"
44 
45 /*-----------------------------------------------------------------------------
46  Functions prototypes
47  -----------------------------------------------------------------------------*/
48 
49 static int crires_win_jitter_save(const cpl_imagelist **,
50  const cpl_imagelist *, const cpl_imagelist *, const cpl_table **,
51  const cpl_imagelist *, const cpl_imagelist *,
52  const cpl_parameterlist *, cpl_frameset *) ;
53 
54 static char crires_win_jitter_description[] =
55 "crires_win_jitter -- Observation recipe in Windowing mode\n"
56 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
57 " raw-file.fits "CRIRES_WIN_NODDING_OBJECT_RAW" or\n"
58 " raw-file.fits "CRIRES_WIN_NODDING_SKY_RAW" or\n"
59 " raw-file.fits "CRIRES_WIN_NODDING_RAW" or\n"
60 " raw-file.fits "CRIRES_WIN_NODDING_J_RAW" or\n"
61 " raw-file.fits "CRIRES_WIN_NODDING_STD_RAW" or\n"
62 " raw-file.fits "CRIRES_WIN_NODDING_J_STD_RAW" or\n"
63 " flat-file.fits "CRIRES_CALPRO_FLAT_WIN" or\n"
64 " bpm-file.fits "CRIRES_CALPRO_BPM_WIN" or\n"
65 " detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n"
66 " dark-file.fits "CRIRES_CALPRO_DARK_WIN" or\n"
67 " wavecal-file.fits "CRIRES_CALPRO_WAVE" or\n"
68 " stdstar-file.fits "CRIRES_CALPRO_STD_PHOTOFLUX" or\n"
69 " model-config-file.fits "CRIRES_CALPRO_MODEL_CONFIG".\n"
70 "\n"
71 "In the case of a nodding observation (currently, this recipe only\n"
72 " supports nodding observations), in order not to degrade the \n"
73 " instrument high resolution, the combined images using only NODA\n"
74 " or NODB nodding positions can be produced on request. (see --onlyA/B)\n"
75 " In this case, the following spectrum extraction can be applied \n"
76 " either on the usual combined image or on those NODA/B combined\n"
77 " images (see --comb_used).\n"
78 "\n"
79 "This recipe produces 6 to 11 files:\n"
80 " The combined image (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
81 " The contribution map (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
82 " The combined image using only Nodding A frames (optional)\n"
83 " (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
84 " The contribution map using only Nodding A frames (optional)\n"
85 " (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
86 " The combined image using only Nodding B frames (optional)\n"
87 " (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
88 " The contribution map using only Nodding B frames (optional)\n"
89 " (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
90 " The table with the extracted spectrum\n"
91 " (PRO TYPE = "CRIRES_PROTYPE_SPEC_WL") or\n"
92 " (PRO TYPE = "CRIRES_PROTYPE_SENSIT") or\n"
93 " (PRO TYPE = "CRIRES_PROTYPE_CONVERS")\n"
94 " The profile image (PRO TYPE = "CRIRES_PROTYPE_PROFILE")\n"
95 " The background map (PRO TYPE = "CRIRES_PROTYPE_BGD_MAP")\n"
96 " The wavelength map (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n"
97 " The wavelength map from the model (optional)\n"
98 " (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n" ;
99 
100 CRIRES_RECIPE_DEFINE(crires_win_jitter,
101  CRIRES_PARAM_DISPLAY |
102  CRIRES_PARAM_REFINE |
103  CRIRES_PARAM_ONLYA |
104  CRIRES_PARAM_ONLYB |
105  CRIRES_PARAM_COMB_USED |
106  CRIRES_PARAM_HOR_SIZE |
107  CRIRES_PARAM_SPEC_HSIZE |
108  CRIRES_PARAM_KAPPA |
109  CRIRES_PARAM_CLOSING_HSIZE |
110  CRIRES_PARAM_CLEAN_RATE |
111  CRIRES_PARAM_REJECT |
112  CRIRES_PARAM_Y_SPEC_ZONE_CHIP1 |
113  CRIRES_PARAM_Y_SPEC_ZONE_CHIP2 |
114  CRIRES_PARAM_Y_SPEC_ZONE_CHIP3 |
115  CRIRES_PARAM_Y_SPEC_ZONE_CHIP4 |
116  CRIRES_PARAM_DEGREE,
117  "Observation recipe in Windowing mode",
118  crires_win_jitter_description) ;
119 
120 /*-----------------------------------------------------------------------------
121  Static variables
122  -----------------------------------------------------------------------------*/
123 
124 static struct {
125  /* Inputs */
126  int comb_refine ;
127  int comb_onlyA ;
128  int comb_onlyB ;
129  crires_comb_method comb_used ;
130  int extr_box_hor_size ;
131  int extr_spec_hsize ;
132  double extr_kappa ;
133  int extr_closing_hs ;
134  int extr_clean_rate ;
135  int extr_rej_left ;
136  int extr_rej_right ;
137  const char * extr_y_spec_zone_c1 ;
138  const char * extr_y_spec_zone_c2 ;
139  const char * extr_y_spec_zone_c3 ;
140  const char * extr_y_spec_zone_c4 ;
141  int display ;
142  /* Outputs */
143  int std_mode ;
144  double qc_wlcent[CRIRES_NB_DETECTORS] ;
145  double qc_wldisp[CRIRES_NB_DETECTORS] ;
146  int qc_specpos[CRIRES_NB_DETECTORS] ;
147  int qc_specwrec[CRIRES_NB_DETECTORS] ;
148  int qc_specwopt[CRIRES_NB_DETECTORS] ;
149  double qc_specoptmed[CRIRES_NB_DETECTORS] ;
150  double qc_s2nmed[CRIRES_NB_DETECTORS] ;
151  double qc_sensmed[CRIRES_NB_DETECTORS] ;
152  double qc_convmed[CRIRES_NB_DETECTORS] ;
153  double qc_thromed[CRIRES_NB_DETECTORS] ;
154  double qc_fwhm_comb_pix[CRIRES_NB_DETECTORS] ;
155  double qc_fwhm_comb_as[CRIRES_NB_DETECTORS] ;
156  double qc_fwhm_prof_pix[CRIRES_NB_DETECTORS] ;
157  double qc_fwhm_prof_as[CRIRES_NB_DETECTORS] ;
158  double qc_fwhm_diff[CRIRES_NB_DETECTORS] ;
159 } crires_win_jitter_config ;
160 
161 /*-----------------------------------------------------------------------------
162  Functions code
163  -----------------------------------------------------------------------------*/
164 
165 /*----------------------------------------------------------------------------*/
172 /*----------------------------------------------------------------------------*/
173 static int crires_win_jitter(
174  cpl_frameset * frameset,
175  const cpl_parameterlist * parlist)
176 {
177  const char * sval ;
178  const char * y_pos ;
179  cpl_frameset * rawframes ;
180  const char * fname ;
181  cpl_frame * fr ;
182  double tot_ndit ;
183  const char * flat ;
184  const char * dark ;
185  const char * bpm ;
186  const char * detlin ;
187  const char * wavecal ;
188  const char * std_star ;
189  const char * cfg_model ;
190  cpl_table * std_star_tab ;
191  cpl_bivector * std_star_biv ;
192  cpl_imagelist ** comblist ;
193  int comblist_offset ;
194  int pix, extr_spec_starty, extr_spec_stopy ;
195  cpl_polynomial * wave_poly ;
196  cpl_table * wave_tab[CRIRES_NB_DETECTORS] ;
197  cpl_table * extr_tab[CRIRES_NB_DETECTORS] ;
198  cpl_image * profiles[CRIRES_NB_DETECTORS] ;
199  cpl_image * bg_maps[CRIRES_NB_DETECTORS] ;
200  cpl_imagelist * prof_list ;
201  cpl_imagelist * bgmap_list ;
202  cpl_image * profile_empty ;
203  cpl_image * bgmap_empty ;
204  cpl_table * extr_tab_empty ;
205  cpl_imagelist * wl_map ;
206  cpl_imagelist * wl_map_model ;
207  cpl_vector ** wavelengths ;
208  int i, j ;
209 
210  /* Needed for sscanf() */
211  setlocale(LC_NUMERIC, "C");
212 
213  /* Initialise */
214  rawframes = NULL ;
215  comblist_offset = -1 ;
216  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
217  crires_win_jitter_config.qc_wlcent[i] = -1 ;
218  crires_win_jitter_config.qc_wldisp[i] = -1 ;
219  crires_win_jitter_config.qc_specpos[i] = -1 ;
220  crires_win_jitter_config.qc_specwrec[i] = -1 ;
221  crires_win_jitter_config.qc_specwopt[i] = -1 ;
222  crires_win_jitter_config.qc_specoptmed[i] = -1.0 ;
223  crires_win_jitter_config.qc_s2nmed[i] = -1.0 ;
224  crires_win_jitter_config.qc_sensmed[i] = -1.0 ;
225  crires_win_jitter_config.qc_convmed[i] = -1.0 ;
226  crires_win_jitter_config.qc_thromed[i] = -1.0 ;
227  crires_win_jitter_config.qc_fwhm_comb_pix[i] = -1.0 ;
228  crires_win_jitter_config.qc_fwhm_comb_as[i] = -1.0 ;
229  crires_win_jitter_config.qc_fwhm_prof_pix[i] = -1.0 ;
230  crires_win_jitter_config.qc_fwhm_prof_as[i] = -1.0 ;
231  crires_win_jitter_config.qc_fwhm_diff[i] = -1.0 ;
232  }
233 
234  /* Retrieve input parameters */
235  crires_win_jitter_config.display = crires_parameterlist_get_int(parlist,
236  RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
237  crires_win_jitter_config.comb_refine = crires_parameterlist_get_bool(
238  parlist, RECIPE_STRING, CRIRES_PARAM_REFINE) ;
239  crires_win_jitter_config.comb_onlyA = crires_parameterlist_get_bool(
240  parlist, RECIPE_STRING, CRIRES_PARAM_ONLYA) ;
241  crires_win_jitter_config.comb_onlyB = crires_parameterlist_get_bool(
242  parlist, RECIPE_STRING, CRIRES_PARAM_ONLYB) ;
243  sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
244  CRIRES_PARAM_COMB_USED) ;
245  if (!strcmp(sval, "NODA"))
246  crires_win_jitter_config.comb_used = CRIRES_COMB_METHOD_NODA ;
247  else if (!strcmp(sval, "NODB"))
248  crires_win_jitter_config.comb_used = CRIRES_COMB_METHOD_NODB ;
249  else if (!strcmp(sval, "COMB"))
250  crires_win_jitter_config.comb_used = CRIRES_COMB_METHOD_COMB ;
251  else {
252  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
253  cpl_msg_error(__func__, "Invalid combination method specified");
254  return -1;
255  }
256  crires_win_jitter_config.extr_box_hor_size = crires_parameterlist_get_int(
257  parlist, RECIPE_STRING, CRIRES_PARAM_HOR_SIZE) ;
258  crires_win_jitter_config.extr_spec_hsize = crires_parameterlist_get_int(
259  parlist, RECIPE_STRING, CRIRES_PARAM_SPEC_HSIZE) ;
260  crires_win_jitter_config.extr_kappa = crires_parameterlist_get_double(
261  parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA) ;
262  crires_win_jitter_config.extr_closing_hs = crires_parameterlist_get_int(
263  parlist, RECIPE_STRING, CRIRES_PARAM_CLOSING_HSIZE) ;
264  crires_win_jitter_config.extr_clean_rate = crires_parameterlist_get_double(
265  parlist, RECIPE_STRING, CRIRES_PARAM_CLEAN_RATE) ;
266  sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
267  CRIRES_PARAM_REJECT) ;
268  if (sscanf(sval, "%d,%d",
269  &crires_win_jitter_config.extr_rej_left,
270  &crires_win_jitter_config.extr_rej_right)!=2) {
271  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
272  return -1 ;
273  }
274  crires_win_jitter_config.extr_y_spec_zone_c1 =
275  crires_parameterlist_get_string(parlist, RECIPE_STRING,
276  CRIRES_PARAM_Y_SPEC_ZONE_CHIP1) ;
277  crires_win_jitter_config.extr_y_spec_zone_c2 =
278  crires_parameterlist_get_string(parlist, RECIPE_STRING,
279  CRIRES_PARAM_Y_SPEC_ZONE_CHIP2) ;
280  crires_win_jitter_config.extr_y_spec_zone_c3 =
281  crires_parameterlist_get_string(parlist, RECIPE_STRING,
282  CRIRES_PARAM_Y_SPEC_ZONE_CHIP3) ;
283  crires_win_jitter_config.extr_y_spec_zone_c4 =
284  crires_parameterlist_get_string(parlist, RECIPE_STRING,
285  CRIRES_PARAM_Y_SPEC_ZONE_CHIP4) ;
286 
287  /* Identify the RAW and CALIB frames in the input frameset */
288  if (crires_dfs_set_groups(frameset, "crires_win_jitter")) {
289  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
290  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
291  return -1 ;
292  }
293 
294  /* Retrieve calibration data */
295  flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT_WIN) ;
296  dark = crires_extract_filename(frameset, CRIRES_CALPRO_DARK_WIN) ;
297  bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM_WIN) ;
298  detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
299  wavecal = crires_extract_filename(frameset, CRIRES_CALPRO_WAVE) ;
300  std_star = crires_extract_filename(frameset,CRIRES_CALPRO_STD_PHOTOFLUX);
301  cfg_model = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_CONFIG);
302 
303  /* Retrieve raw frames */
304  if ((rawframes = crires_extract_frameset(frameset,
305  CRIRES_WIN_NODDING_OBJECT_RAW)) != NULL) {
306  crires_win_jitter_config.std_mode = 0 ;
307  } else if ((rawframes = crires_extract_frameset(frameset,
308  CRIRES_WIN_NODDING_RAW)) != NULL) {
309  crires_win_jitter_config.std_mode = 0 ;
310  } else if ((rawframes = crires_extract_frameset(frameset,
311  CRIRES_WIN_NODDING_J_RAW)) != NULL) {
312  crires_win_jitter_config.std_mode = 0 ;
313  } else if ((rawframes = crires_extract_frameset(frameset,
314  CRIRES_WIN_NODDING_STD_RAW)) != NULL) {
315  crires_win_jitter_config.std_mode = 1 ;
316  } else if ((rawframes = crires_extract_frameset(frameset,
317  CRIRES_WIN_NODDING_J_STD_RAW)) != NULL) {
318  crires_win_jitter_config.std_mode = 1 ;
319  } else {
320  cpl_msg_error(__func__, "No raw frame in input") ;
321  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
322  return -1 ;
323  }
324 
325  /* Verify the STRIPE keys conformity */
326  fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
327  if (flat != NULL) {
328  if (crire_stripe_keys_mismatch(fname, flat)) {
329  cpl_msg_error(__func__,
330  "Mismatch of STRIPE keys with the flat frame") ;
331  cpl_frameset_delete(rawframes) ;
332  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
333  return -1 ;
334  }
335  }
336  if (bpm != NULL) {
337  if (crire_stripe_keys_mismatch(fname, bpm)) {
338  cpl_msg_error(__func__,
339  "Mismatch of STRIPE keys with the bpm frame") ;
340  cpl_frameset_delete(rawframes) ;
341  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
342  return -1 ;
343  }
344  }
345  if (dark != NULL) {
346  if (crire_stripe_keys_mismatch(fname, dark)) {
347  cpl_msg_error(__func__,
348  "Mismatch of STRIPE keys with the dark frame") ;
349  cpl_frameset_delete(rawframes) ;
350  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
351  return -1 ;
352  }
353  }
354 
355  /* Checks on the parameters validity */
356  if ((crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODA)
357  && (crires_win_jitter_config.comb_onlyA == 0)) {
358  cpl_msg_warning(__func__,
359  "You forgot to require the NODA image to be produced !") ;
360  crires_win_jitter_config.comb_onlyA = 1 ;
361  }
362  if ((crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODB)
363  && (crires_win_jitter_config.comb_onlyB == 0)) {
364  cpl_msg_warning(__func__,
365  "You forgot to require the NODB image to be produced !") ;
366  crires_win_jitter_config.comb_onlyB = 1 ;
367  }
368 
369  /* Set comblist_offset */
370  if (crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_COMB)
371  comblist_offset = 0 ;
372  else if (crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODA)
373  comblist_offset = 1 ;
374  else if (crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODB)
375  comblist_offset = 2 ;
376 
377  /* Get the total number of NDIT */
378  fr = cpl_frameset_get_position(rawframes, 0);
379  tot_ndit = crires_get_totndit(cpl_frame_get_filename(fr)) ;
380  if (tot_ndit < 0) {
381  cpl_msg_error(__func__, "Cannot get the total number of NDIT") ;
382  cpl_frameset_delete(rawframes) ;
383  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
384  return -1 ;
385  }
386  tot_ndit *= cpl_frameset_get_size(rawframes) ;
387 
388  /* Images recombination */
389  cpl_msg_info(__func__, "Images combination") ;
390  cpl_msg_indent_more() ;
391  if ((comblist = crires_combine_imagelist_win(rawframes,
392  flat, dark, bpm, detlin,
393  crires_win_jitter_config.comb_refine,
394  crires_win_jitter_config.comb_onlyA,
395  crires_win_jitter_config.comb_onlyB)) == NULL) {
396  cpl_msg_error(__func__, "Cannot combine the images") ;
397  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
398  cpl_frameset_delete(rawframes) ;
399  cpl_msg_indent_less() ;
400  return -1 ;
401  }
402  cpl_msg_indent_less() ;
403 
404  /* Spectrum extraction */
405  cpl_msg_info(__func__, "Spectrum extraction") ;
406  cpl_msg_indent_more() ;
407  for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
408  cpl_msg_info(__func__, "Chip number %d extraction", i+1) ;
409  cpl_msg_indent_more() ;
410 
411  /* Where is the spectrum extraction zone ? */
412  y_pos = "" ;
413  if (i == 1) y_pos = crires_win_jitter_config.extr_y_spec_zone_c1 ;
414  if (i == 2) y_pos = crires_win_jitter_config.extr_y_spec_zone_c2 ;
415  if (i == 3) y_pos = crires_win_jitter_config.extr_y_spec_zone_c3 ;
416  if (i == 4) y_pos = crires_win_jitter_config.extr_y_spec_zone_c4 ;
417  if (sscanf(y_pos,"%d,%d", &extr_spec_starty, &extr_spec_stopy)!=2) {
418  cpl_msg_warning(__func__, "Wrong Spectral Zone specified: %s",
419  y_pos) ;
420  extr_spec_starty = extr_spec_stopy = -1 ;
421  }
422  if ((extr_tab[i] = crires_extract_spectrum(
423  cpl_imagelist_get(comblist[0+2*comblist_offset], i),
424  cpl_imagelist_get(comblist[1+2*comblist_offset], i),
425  crires_win_jitter_config.extr_box_hor_size,
426  crires_win_jitter_config.extr_spec_hsize,
427  crires_win_jitter_config.extr_kappa,
428  crires_win_jitter_config.extr_closing_hs,
429  crires_win_jitter_config.extr_clean_rate,
430  crires_win_jitter_config.extr_rej_left,
431  crires_win_jitter_config.extr_rej_right,
432  extr_spec_starty, extr_spec_stopy, i+1, tot_ndit,
433  CRIRES_ILLUM_FULL_DETECTOR,
434  &(crires_win_jitter_config.qc_specpos[i]),
435  &(crires_win_jitter_config.qc_specwrec[i]),
436  &(crires_win_jitter_config.qc_specwopt[i]),
437  &(crires_win_jitter_config.qc_specoptmed[i]),
438  &(crires_win_jitter_config.qc_s2nmed[i]),
439  &(profiles[i]),
440  &(bg_maps[i]))) == NULL) {
441  cpl_msg_error(__func__, "Cannot extract the spectrum") ;
442  cpl_msg_indent_less() ;
443  cpl_msg_indent_less() ;
444  for (j=1 ; j<i ; j++)
445  cpl_table_delete(extr_tab[j]) ;
446  for (j=1 ; j<i ; j++)
447  cpl_image_delete(profiles[j]) ;
448  for (j=1 ; j<i ; j++)
449  cpl_image_delete(bg_maps[j]) ;
450  cpl_imagelist_delete(comblist[0]) ;
451  cpl_imagelist_delete(comblist[1]) ;
452  if (crires_win_jitter_config.comb_onlyA) {
453  cpl_imagelist_delete(comblist[2]) ;
454  cpl_imagelist_delete(comblist[3]) ;
455  }
456  if (crires_win_jitter_config.comb_onlyB) {
457  cpl_imagelist_delete(comblist[4]) ;
458  cpl_imagelist_delete(comblist[5]) ;
459  }
460  cpl_free(comblist) ;
461  cpl_frameset_delete(rawframes) ;
462  return -1 ;
463  }
464  cpl_msg_info(__func__, "Chip number %d FWHM Computation", i+1) ;
465  if (crires_extract_qc_fwhm(
466  cpl_imagelist_get(comblist[0+2*comblist_offset], i),
467  profiles[i],
468  &(crires_win_jitter_config.qc_fwhm_comb_pix[i]),
469  &(crires_win_jitter_config.qc_fwhm_comb_as[i]),
470  &(crires_win_jitter_config.qc_fwhm_prof_pix[i]),
471  &(crires_win_jitter_config.qc_fwhm_prof_as[i]),
472  &(crires_win_jitter_config.qc_fwhm_diff[i])) == -1) {
473  cpl_msg_warning(__func__, "Failed for FWHM computation") ;
474  crires_win_jitter_config.qc_fwhm_comb_pix[i] = -1.0 ;
475  crires_win_jitter_config.qc_fwhm_comb_as[i] = -1.0 ;
476  crires_win_jitter_config.qc_fwhm_prof_pix[i] = -1.0 ;
477  crires_win_jitter_config.qc_fwhm_prof_as[i] = -1.0 ;
478  crires_win_jitter_config.qc_fwhm_diff[i] = -1.0 ;
479  }
480  cpl_msg_indent_less() ;
481  }
482 
483  /* Create the profile and bg maps */
484  prof_list = cpl_imagelist_new() ;
485  bgmap_list = cpl_imagelist_new() ;
486  profile_empty = cpl_image_duplicate(profiles[1]) ;
487  bgmap_empty = cpl_image_duplicate(bg_maps[1]) ;
488  cpl_image_multiply_scalar(profile_empty, 0.0) ;
489  cpl_image_multiply_scalar(bgmap_empty, 0.0) ;
490  cpl_imagelist_set(prof_list, cpl_image_duplicate(profile_empty), 0) ;
491  cpl_imagelist_set(bgmap_list, cpl_image_duplicate(bgmap_empty), 0) ;
492  for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
493  cpl_imagelist_set(prof_list, profiles[i], i) ;
494  cpl_imagelist_set(bgmap_list, bg_maps[i], i) ;
495  }
496  cpl_imagelist_set(prof_list, cpl_image_duplicate(profile_empty),
497  CRIRES_NB_DETECTORS-1) ;
498  cpl_imagelist_set(bgmap_list, cpl_image_duplicate(bgmap_empty),
499  CRIRES_NB_DETECTORS-1) ;
500  cpl_image_delete(profile_empty) ;
501  cpl_image_delete(bgmap_empty) ;
502 
503  /* Test that the spectrum is at the same place in all detectors */
504  if (crires_win_jitter_config.qc_specpos[1] > 0 &&
505  crires_win_jitter_config.qc_specpos[2] > 0 &&
506  fabs(crires_win_jitter_config.qc_specpos[1] -
507  crires_win_jitter_config.qc_specpos[2]) >
508  CRIRES_SPEC_POS_TOLERANCE) {
509  cpl_msg_warning(__func__,
510 "The spectrum positions in chip 1 and chip 2 are too different: %d -> %d",
511  crires_win_jitter_config.qc_specpos[1],
512  crires_win_jitter_config.qc_specpos[2]) ;
513  }
514  cpl_msg_indent_less() ;
515 
516  /* Wavelength calibration */
517  cpl_msg_info(__func__, "Wavelength Calibration") ;
518  cpl_msg_indent_more() ;
519  if (wavecal != NULL) {
520  /* Wavelength solution is provided */
521  cpl_msg_info(__func__, "Use the provided solution") ;
522  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
523  if ((wave_tab[i] = crires_load_table_check(wavecal, i+1,
524  CRIRES_PROTYPE_WL_POLY, -1, -1, 0)) == NULL) {
525  cpl_msg_error(__func__, "Cannot load the wavelength table") ;
526  cpl_msg_indent_less() ;
527  cpl_frameset_delete(rawframes) ;
528  cpl_imagelist_delete(comblist[0]) ;
529  cpl_imagelist_delete(comblist[1]) ;
530  if (crires_win_jitter_config.comb_onlyA) {
531  cpl_imagelist_delete(comblist[2]) ;
532  cpl_imagelist_delete(comblist[3]) ;
533  }
534  if (crires_win_jitter_config.comb_onlyB) {
535  cpl_imagelist_delete(comblist[4]) ;
536  cpl_imagelist_delete(comblist[5]) ;
537  }
538  cpl_free(comblist) ;
539  for (j=1 ; j<CRIRES_NB_DETECTORS-1 ; j++)
540  cpl_table_delete(extr_tab[j]) ;
541  cpl_imagelist_delete(prof_list) ;
542  cpl_imagelist_delete(bgmap_list) ;
543  return -1 ;
544  }
545  }
546  } else {
547  /* Calibrate from the keywords */
548  cpl_msg_info(__func__, "Use the keywords for the wavelength") ;
549 
550  /* Reduce the first raw frame */
551  fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
552 
553  /* Loop on the detectors */
554  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
555  cpl_msg_info(__func__, "Calibrate chip number %d", i+1) ;
556  cpl_msg_indent_more() ;
557  wave_poly = crires_wlestimate_get(fname, i+1) ;
558  wave_tab[i] = crires_wlcalib_gen_wltab_one(wave_poly, -1, -1.0) ;
559  cpl_polynomial_delete(wave_poly) ;
560  cpl_msg_indent_less() ;
561  }
562  }
563 
564  /* Create the wave map */
565  if ((wl_map = crires_wlcalib_gen_wlmap((const cpl_table **)wave_tab))
566  == NULL) {
567  cpl_msg_error(__func__, "Cannot compute the Wavelength Map") ;
568  cpl_frameset_delete(rawframes) ;
569  cpl_imagelist_delete(comblist[0]) ;
570  cpl_imagelist_delete(comblist[1]) ;
571  if (crires_win_jitter_config.comb_onlyA) {
572  cpl_imagelist_delete(comblist[2]) ;
573  cpl_imagelist_delete(comblist[3]) ;
574  }
575  if (crires_win_jitter_config.comb_onlyB) {
576  cpl_imagelist_delete(comblist[4]) ;
577  cpl_imagelist_delete(comblist[5]) ;
578  }
579  cpl_free(comblist) ;
580  cpl_imagelist_delete(prof_list) ;
581  cpl_imagelist_delete(bgmap_list) ;
582  for (j=1 ; j<CRIRES_NB_DETECTORS-1 ; j++)
583  cpl_table_delete(extr_tab[j]) ;
584  for (j=0 ; j<CRIRES_NB_DETECTORS ; j++)
585  if (wave_tab[j] != NULL) cpl_table_delete(wave_tab[j]);
586  return -1 ;
587  }
588  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
589  if (wave_tab[i] != NULL) cpl_table_delete(wave_tab[i]);
590 
591  /* Compute the QC parameters */
592  for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
593  crires_win_jitter_config.qc_wlcent[i] =
594  cpl_image_get(cpl_imagelist_get(wl_map, i),
595  512, crires_win_jitter_config.qc_specpos[i], &pix) ;
596  crires_win_jitter_config.qc_wldisp[i] =
597  ((cpl_image_get(cpl_imagelist_get(wl_map, i), 1024,
598  crires_win_jitter_config.qc_specpos[i], &pix)) -
599  (cpl_image_get(cpl_imagelist_get(wl_map, i), 1,
600  crires_win_jitter_config.qc_specpos[i], &pix)))
601  / 1023 ;
602  }
603 
604  /* Get the wl map from the model */
605  fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
606  if ((cfg_model != NULL) && (!crires_model_off()) &&
607  (crires_model_config_check(cfg_model, fname) == 0)) {
608  cpl_msg_info(__func__, "Call the model to get the wavelength map") ;
609  cpl_msg_indent_more() ;
610  wl_map_model = crires_model_wavpix(fname, cfg_model, -1) ;
611  if (wl_map_model == NULL) {
612  cpl_msg_warning(__func__, "Model function returns NULL") ;
613  cpl_error_reset() ;
614  }
615  cpl_msg_indent_less() ;
616  } else {
617  wl_map_model = NULL ;
618  }
619 
620  /* Apply the wavelength */
621  for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
622  cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH,
623  CPL_TYPE_DOUBLE) ;
624  for (j=0 ; j<cpl_table_get_nrow(extr_tab[i]) ; j++) {
625  cpl_table_set_double(extr_tab[i], CRIRES_COL_WAVELENGTH, j,
626  cpl_image_get(cpl_imagelist_get_const(wl_map, i), j+1,
627  crires_win_jitter_config.qc_specpos[i], &pix));
628  }
629  }
630 
631  /* Add the Model Wavelength and Call the model to fill it */
632  for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
633  cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH_MODEL,
634  CPL_TYPE_DOUBLE) ;
635  cpl_table_fill_column_window_double(extr_tab[i],
636  CRIRES_COL_WAVELENGTH_MODEL, 0,
637  cpl_table_get_nrow(extr_tab[i]), -1.0) ;
638  }
639  if ((cfg_model != NULL) && (!crires_model_off()) && (1)) {
640  cpl_msg_info(__func__, "Call the model to get the wavelengths") ;
641  cpl_msg_indent_more() ;
642  wavelengths = crires_model_wavelengths(
643  cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)),
644  cfg_model, -1,
645  (double)(crires_win_jitter_config.qc_specpos[0]),
646  wl_map_model) ;
647  if (wavelengths != NULL) {
648  /* Loop on the detectors */
649  for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
650  /* Loop on the x values */
651  for (j=0 ; j<cpl_vector_get_size(wavelengths[i]) ; j++) {
652  cpl_table_set_double(extr_tab[i],
653  CRIRES_COL_WAVELENGTH_MODEL, j,
654  cpl_vector_get(wavelengths[i], j)) ;
655  }
656  }
657  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
658  cpl_vector_delete(wavelengths[i]) ;
659  cpl_free(wavelengths) ;
660  } else {
661  cpl_msg_warning(__func__, "Model function returns NULL") ;
662  cpl_error_reset() ;
663  }
664  cpl_msg_indent_less() ;
665  }
666 
667  /* Conversion factor / Sensitivity */
668  if (crires_win_jitter_config.std_mode) {
669  cpl_msg_info(__func__,
670  "Sensitivity / Conversion / Throughput computation") ;
671  cpl_msg_indent_more() ;
672  /* Load std star */
673  if ((std_star_tab = crires_load_table_check(std_star, 1,
674  CRIRES_PROTYPE_PHO_FLUX, -1, -1, 0)) == NULL) {
675  cpl_msg_error(__func__, "Cannot load the std star flux") ;
676  } else {
677  /* Get the wished std star */
678  if ((std_star_biv = crires_photom_conv_get_star(std_star_tab,
679  cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0))))
680  == NULL) {
681  cpl_msg_error(__func__, "Cannot find the star flux") ;
682  cpl_table_delete(std_star_tab) ;
683  } else {
684  cpl_table_delete(std_star_tab) ;
685  /* Apply the conversion */
686  for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
687  if (crires_photom_conv_engine(extr_tab[i], std_star_biv,
688  i+1, (i+1==crires_win_jitter_config.display))==0){
689  crires_win_jitter_config.qc_convmed[i] =
690  cpl_table_get_column_median(extr_tab[i],
691  CRIRES_COL_CONVERSION_RECT) ;
692  crires_win_jitter_config.qc_thromed[i] =
693  cpl_table_get_column_median(extr_tab[i],
694  CRIRES_COL_THROUGHPUT) ;
695  /* Apply the sensitivity */
696  if (crires_photom_sens_engine(extr_tab[i],
697  cpl_frame_get_filename(cpl_frameset_get_position(
698  rawframes,0)), -1.0,
699  (i+1==crires_win_jitter_config.display))>0) {
700  crires_win_jitter_config.qc_sensmed[i] =
701  cpl_table_get_column_median(extr_tab[i],
702  CRIRES_COL_SENSITIVITY) ; ;
703  }
704  }
705  }
706  cpl_bivector_delete(std_star_biv) ;
707  }
708  }
709  cpl_msg_indent_less() ;
710  }
711  cpl_frameset_delete(rawframes) ;
712 
713  /* Create empty extr_tab for non-processed chips */
714  extr_tab_empty = cpl_table_duplicate(extr_tab[1]) ;
715  cpl_table_set_size(extr_tab_empty, 0) ;
716  extr_tab[0] = cpl_table_duplicate(extr_tab_empty) ;
717  extr_tab[CRIRES_NB_DETECTORS-1] = cpl_table_duplicate(extr_tab_empty) ;
718  cpl_table_delete(extr_tab_empty) ;
719 
720  /* Save the product */
721  cpl_msg_info(__func__, "Save the product") ;
722  cpl_msg_indent_more() ;
723  if (crires_win_jitter_save((const cpl_imagelist **)comblist,
724  prof_list, bgmap_list,
725  (const cpl_table **)extr_tab, wl_map, wl_map_model, parlist,
726  frameset)) {
727  cpl_msg_error(__func__, "Cannot save the product") ;
728  cpl_imagelist_delete(prof_list) ;
729  cpl_imagelist_delete(bgmap_list) ;
730  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
731  if (extr_tab[i] != NULL) cpl_table_delete(extr_tab[i]) ;
732  cpl_imagelist_delete(comblist[0]) ;
733  cpl_imagelist_delete(comblist[1]) ;
734  if (crires_win_jitter_config.comb_onlyA) {
735  cpl_imagelist_delete(comblist[2]) ;
736  cpl_imagelist_delete(comblist[3]) ;
737  }
738  if (crires_win_jitter_config.comb_onlyB) {
739  cpl_imagelist_delete(comblist[4]) ;
740  cpl_imagelist_delete(comblist[5]) ;
741  }
742  cpl_free(comblist) ;
743  cpl_imagelist_delete(wl_map) ;
744  if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
745  cpl_msg_indent_less() ;
746  return -1 ;
747  }
748  cpl_imagelist_delete(wl_map) ;
749  if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
750  cpl_imagelist_delete(comblist[0]) ;
751  cpl_imagelist_delete(comblist[1]) ;
752  if (crires_win_jitter_config.comb_onlyA) {
753  cpl_imagelist_delete(comblist[2]) ;
754  cpl_imagelist_delete(comblist[3]) ;
755  }
756  if (crires_win_jitter_config.comb_onlyB) {
757  cpl_imagelist_delete(comblist[4]) ;
758  cpl_imagelist_delete(comblist[5]) ;
759  }
760  cpl_free(comblist) ;
761  cpl_imagelist_delete(prof_list) ;
762  cpl_imagelist_delete(bgmap_list) ;
763  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
764  if (extr_tab[i] != NULL) cpl_table_delete(extr_tab[i]) ;
765  cpl_msg_indent_less() ;
766 
767  /* Return */
768  if (cpl_error_get_code()) return -1 ;
769  else return 0 ;
770 }
771 
772 /*----------------------------------------------------------------------------*/
786 /*----------------------------------------------------------------------------*/
787 static int crires_win_jitter_save(
788  const cpl_imagelist ** images,
789  const cpl_imagelist * prof,
790  const cpl_imagelist * bgmap,
791  const cpl_table ** extr_tab,
792  const cpl_imagelist * wl_map,
793  const cpl_imagelist * wl_map_model,
794  const cpl_parameterlist * parlist,
795  cpl_frameset * set)
796 {
797  cpl_propertylist ** qclists ;
798  const cpl_frame * ref_frame ;
799  const char * procat ;
800  const char * protype ;
801  cpl_propertylist * inputlist ;
802  const char * recipe_name = "crires_win_jitter" ;
803  int i ;
804 
805  /* Get the reference frame */
806  ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
807 
808  /* Create the QC lists */
809  qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
810  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
811  qclists[i] = cpl_propertylist_new() ;
812  cpl_propertylist_append_int(qclists[i], "ESO QC SPECPOS",
813  crires_win_jitter_config.qc_specpos[i]) ;
814  cpl_propertylist_append_int(qclists[i], "ESO QC SPECWREC",
815  crires_win_jitter_config.qc_specwrec[i]) ;
816  cpl_propertylist_append_int(qclists[i], "ESO QC SPECWOPT",
817  crires_win_jitter_config.qc_specwopt[i]) ;
818  cpl_propertylist_append_double(qclists[i], "ESO QC SIGNAL MED",
819  crires_win_jitter_config.qc_specoptmed[i]) ;
820  cpl_propertylist_append_double(qclists[i], "ESO QC S2NMED",
821  crires_win_jitter_config.qc_s2nmed[i]) ;
822  cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL",
823  crires_win_jitter_config.qc_wlcent[i]) ;
824  cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL",
825  crires_win_jitter_config.qc_wldisp[i]) ;
826  cpl_propertylist_append_double(qclists[i], "ESO QC SENSMED",
827  crires_win_jitter_config.qc_sensmed[i]) ;
828  cpl_propertylist_append_double(qclists[i], "ESO QC CONVMED",
829  crires_win_jitter_config.qc_convmed[i]) ;
830  cpl_propertylist_append_double(qclists[i], "ESO QC THROMED",
831  crires_win_jitter_config.qc_thromed[i]) ;
832  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX COMBINED",
833  crires_win_jitter_config.qc_fwhm_comb_pix[i]) ;
834  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC COMBINED",
835  crires_win_jitter_config.qc_fwhm_comb_as[i]) ;
836  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX PROFILE",
837  crires_win_jitter_config.qc_fwhm_prof_pix[i]) ;
838  cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC PROFILE",
839  crires_win_jitter_config.qc_fwhm_prof_as[i]) ;
840  cpl_propertylist_append_double(qclists[i], "ESO QC FWHM DIFF",
841  crires_win_jitter_config.qc_fwhm_diff[i]) ;
842  /* Propagate some keywords from input raw frame extensions */
843  inputlist = cpl_propertylist_load_regexp(
844  cpl_frame_get_filename(ref_frame), i+1,
845  CRIRES_HEADER_EXT_FORWARD, 0) ;
846  cpl_propertylist_copy_property_regexp(qclists[i], inputlist,
847  CRIRES_HEADER_EXT_FORWARD, 0) ;
848  cpl_propertylist_delete(inputlist) ;
849  }
850 
851  /* PRO.CATG */
852  if (crires_win_jitter_config.std_mode == 1) {
853  procat = CRIRES_STD_WIN_COMBINED_IMA ;
854  } else {
855  procat = CRIRES_OBS_WIN_COMBINED_IMA ;
856  }
857 
858  /* Write the combined image */
859  crires_image_save(set,
860  parlist,
861  set,
862  images[0],
863  recipe_name,
864  procat,
865  CRIRES_PROTYPE_COMBINED,
866  CRIRES_ILLUM_FULL_DETECTOR,
867  NULL,
868  (const cpl_propertylist **)qclists,
869  PACKAGE "/" PACKAGE_VERSION,
870  "crires_win_jitter_comb.fits") ;
871 
872  /* PRO.CATG */
873  if (crires_win_jitter_config.std_mode == 1) {
874  procat = CRIRES_STD_WIN_CONTRIBUTION_IMA ;
875  } else {
876  procat = CRIRES_OBS_WIN_CONTRIBUTION_IMA ;
877  }
878 
879  /* Write the contribution map */
880  crires_image_save(set,
881  parlist,
882  set,
883  images[1],
884  recipe_name,
885  procat,
886  CRIRES_PROTYPE_CONTRIB,
887  CRIRES_ILLUM_FULL_DETECTOR,
888  NULL,
889  (const cpl_propertylist **)qclists,
890  PACKAGE "/" PACKAGE_VERSION,
891  "crires_win_jitter_contrib.fits") ;
892 
893  /* Nodded A support */
894  if (crires_win_jitter_config.comb_onlyA) {
895  /* PRO.CATG */
896  if (crires_win_jitter_config.std_mode == 1) {
897  procat = CRIRES_STD_WIN_COMBINED_NA_IMA ;
898  } else {
899  procat = CRIRES_OBS_WIN_COMBINED_NA_IMA ;
900  }
901 
902  /* Write the combined Nodded A image */
903  crires_image_save(set,
904  parlist,
905  set,
906  images[2],
907  recipe_name,
908  procat,
909  CRIRES_PROTYPE_COMBINED,
910  CRIRES_ILLUM_FULL_DETECTOR,
911  NULL,
912  (const cpl_propertylist **)qclists,
913  PACKAGE "/" PACKAGE_VERSION,
914  "crires_win_jitter_comb_noddedA.fits") ;
915 
916  /* PRO.CATG */
917  if (crires_win_jitter_config.std_mode == 1) {
918  procat = CRIRES_STD_WIN_CONTRIBUTION_NA_IMA ;
919  } else {
920  procat = CRIRES_OBS_WIN_CONTRIBUTION_NA_IMA ;
921  }
922 
923  /* Write the contribution Nodded A image */
924  crires_image_save(set,
925  parlist,
926  set,
927  images[3],
928  recipe_name,
929  procat,
930  CRIRES_PROTYPE_CONTRIB,
931  CRIRES_ILLUM_FULL_DETECTOR,
932  NULL,
933  (const cpl_propertylist **)qclists,
934  PACKAGE "/" PACKAGE_VERSION,
935  "crires_win_jitter_contrib_noddedA.fits") ;
936  }
937 
938  /* Nodded B support */
939  if (crires_win_jitter_config.comb_onlyB) {
940  /* PRO.CATG */
941  if (crires_win_jitter_config.std_mode == 1) {
942  procat = CRIRES_STD_WIN_COMBINED_NB_IMA ;
943  } else {
944  procat = CRIRES_OBS_WIN_COMBINED_NB_IMA ;
945  }
946 
947  /* Write the combined Nodded B image */
948  crires_image_save(set,
949  parlist,
950  set,
951  images[4],
952  recipe_name,
953  procat,
954  CRIRES_PROTYPE_COMBINED,
955  CRIRES_ILLUM_FULL_DETECTOR,
956  NULL,
957  (const cpl_propertylist **)qclists,
958  PACKAGE "/" PACKAGE_VERSION,
959  "crires_win_jitter_comb_noddedB.fits") ;
960 
961  /* PRO.CATG */
962  if (crires_win_jitter_config.std_mode == 1) {
963  procat = CRIRES_STD_WIN_CONTRIBUTION_NB_IMA ;
964  } else {
965  procat = CRIRES_OBS_WIN_CONTRIBUTION_NB_IMA ;
966  }
967 
968  /* Write the contribution Nodded B image */
969  crires_image_save(set,
970  parlist,
971  set,
972  images[5],
973  recipe_name,
974  procat,
975  CRIRES_PROTYPE_CONTRIB,
976  CRIRES_ILLUM_FULL_DETECTOR,
977  NULL,
978  (const cpl_propertylist **)qclists,
979  PACKAGE "/" PACKAGE_VERSION,
980  "crires_win_jitter_contrib_noddedB.fits") ;
981  }
982 
983  /* PRO.CATG */
984  if (crires_win_jitter_config.std_mode == 1) {
985  procat = CRIRES_STD_WIN_EXTRACT_PROFILE_IMA ;
986  } else {
987  procat = CRIRES_OBS_WIN_EXTRACT_PROFILE_IMA ;
988  }
989 
990  /* Write the profile image */
991  crires_image_save(set,
992  parlist,
993  set,
994  prof,
995  recipe_name,
996  procat,
997  CRIRES_PROTYPE_PROFILE,
998  CRIRES_ILLUM_FULL_DETECTOR,
999  NULL,
1000  (const cpl_propertylist **)qclists,
1001  PACKAGE "/" PACKAGE_VERSION,
1002  "crires_win_jitter_prof.fits") ;
1003 
1004  /* PRO.CATG */
1005  if (crires_win_jitter_config.std_mode == 1) {
1006  procat = CRIRES_STD_WIN_EXTRACT_BGMAP_IMA ;
1007  } else {
1008  procat = CRIRES_OBS_WIN_EXTRACT_BGMAP_IMA ;
1009  }
1010 
1011  /* Write the background image */
1012  crires_image_save(set,
1013  parlist,
1014  set,
1015  bgmap,
1016  recipe_name,
1017  procat,
1018  CRIRES_PROTYPE_BGD_MAP,
1019  CRIRES_ILLUM_FULL_DETECTOR,
1020  NULL,
1021  (const cpl_propertylist **)qclists,
1022  PACKAGE "/" PACKAGE_VERSION,
1023  "crires_win_jitter_bgmap.fits") ;
1024 
1025  /* PRO.CATG */
1026  if (crires_win_jitter_config.std_mode == 1) {
1027  procat = CRIRES_STD_WIN_WL_MAP_IMA ;
1028  } else {
1029  procat = CRIRES_OBS_WIN_WL_MAP_IMA ;
1030  }
1031 
1032  /* Write the map */
1033  crires_image_save(set,
1034  parlist,
1035  set,
1036  wl_map,
1037  recipe_name,
1038  procat,
1039  CRIRES_PROTYPE_WL_MAP,
1040  CRIRES_ILLUM_FULL_DETECTOR,
1041  NULL,
1042  (const cpl_propertylist **)qclists,
1043  PACKAGE "/" PACKAGE_VERSION,
1044  "crires_win_jitter_wlmap.fits") ;
1045 
1046  if (wl_map_model != NULL) {
1047  /* PRO.CATG */
1048  if (crires_win_jitter_config.std_mode == 1) {
1049  procat = CRIRES_STD_WIN_WL_MAP_MODEL_IMA ;
1050  } else {
1051  procat = CRIRES_OBS_WIN_WL_MAP_MODEL_IMA ;
1052  }
1053 
1054  /* Write the model map */
1055  crires_image_save(set,
1056  parlist,
1057  set,
1058  wl_map_model,
1059  recipe_name,
1060  procat,
1061  CRIRES_PROTYPE_WL_MAP,
1062  CRIRES_ILLUM_FULL_DETECTOR,
1063  NULL,
1064  (const cpl_propertylist **)qclists,
1065  PACKAGE "/" PACKAGE_VERSION,
1066  "crires_win_jitter_wlmap_model.fits") ;
1067  }
1068 
1069  /* Write the extracted spectra */
1070  /* Get the PRO.CATG */
1071  if (cpl_table_has_column(extr_tab[0], CRIRES_COL_SENSITIVITY)) {
1072  procat = CRIRES_WIN_EXTRACT_SENS_TAB ;
1073  protype = CRIRES_PROTYPE_SENSIT ;
1074  } else if (cpl_table_has_column(extr_tab[0],CRIRES_COL_CONVERSION_OPT)){
1075  procat = CRIRES_WIN_EXTRACT_CONV_TAB ;
1076  protype = CRIRES_PROTYPE_CONVERS ;
1077  } else if (crires_win_jitter_config.std_mode == 1) {
1078  procat = CRIRES_STD_WIN_EXTRACT_WL_TAB ;
1079  protype = CRIRES_PROTYPE_SPEC_WL ;
1080  } else {
1081  procat = CRIRES_OBS_WIN_EXTRACT_WL_TAB ;
1082  protype = CRIRES_PROTYPE_SPEC_WL ;
1083  }
1084  crires_table_save(set,
1085  parlist,
1086  set,
1087  extr_tab,
1088  recipe_name,
1089  procat,
1090  protype,
1091  NULL,
1092  (const cpl_propertylist **)qclists,
1093  PACKAGE "/" PACKAGE_VERSION,
1094  "crires_win_jitter_extracted.fits") ;
1095 
1096  /* Free and return */
1097  for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
1098  cpl_propertylist_delete(qclists[i]) ;
1099  }
1100  cpl_free(qclists) ;
1101  return 0;
1102 }
1103