CRIRES Pipeline Reference Manual  2.3.15
crires_util_combine.c
1 /* $Id: crires_util_combine.c,v 1.41 2012-09-19 14:10:27 yjung Exp $
2  *
3  * This file is part of the CRIRES Pipeline
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: yjung $
23  * $Date: 2012-09-19 14:10:27 $
24  * $Revision: 1.41 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include "crires_recipe.h"
37 
38 #include "crires_combine.h"
39 #include "crires_wlcalib.h"
40 #include "crires_extract.h"
41 #include "crires_photom.h"
42 
43 /*-----------------------------------------------------------------------------
44  Define
45  -----------------------------------------------------------------------------*/
46 
47 #define RECIPE_STRING "crires_util_combine"
48 
49 /*-----------------------------------------------------------------------------
50  Functions prototypes
51  -----------------------------------------------------------------------------*/
52 
53 static int crires_util_combine_save(const cpl_imagelist **,
54  const cpl_parameterlist *, cpl_frameset *) ;
55 
56 static char crires_util_combine_description[] =
57 "crires_util_combine -- Images Combination tool\n"
58 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
59 "raw-file.fits "CRIRES_SPEC_JITTER_RAW" or\n"
60 "raw-file.fits "CRIRES_SPEC_JITTER_J_RAW" or\n"
61 "raw-file.fits "CRIRES_SPEC_JITTER_STD_RAW" or\n"
62 "raw-file.fits "CRIRES_SPEC_JITTER_J_STD_RAW" or\n"
63 "raw-file.fits "CRIRES_SPEC_NODDING_OBJECT_RAW" or\n"
64 "raw-file.fits "CRIRES_SPEC_NODDING_SKY_RAW" or\n"
65 "raw-file.fits "CRIRES_SPEC_GENERIC_OBJECT_RAW" or\n"
66 "raw-file.fits "CRIRES_SPEC_GENERIC_SKY_RAW" or\n"
67 "raw-file.fits "CRIRES_SPEC_NODDING_RAW" or\n"
68 "raw-file.fits "CRIRES_SPEC_NODDING_J_RAW" or\n"
69 "raw-file.fits "CRIRES_SPEC_NODDING_STD_RAW" or\n"
70 "raw-file.fits "CRIRES_SPEC_NODDING_J_STD_RAW" or\n"
71 "raw-file.fits "CRIRES_WIN_NODDING_OBJECT_RAW" or\n"
72 "raw-file.fits "CRIRES_WIN_NODDING_SKY_RAW" or\n"
73 "raw-file.fits "CRIRES_WIN_NODDING_RAW" or\n"
74 "raw-file.fits "CRIRES_WIN_NODDING_J_RAW" or\n"
75 "raw-file.fits "CRIRES_WIN_NODDING_STD_RAW" or\n"
76 "raw-file.fits "CRIRES_WIN_NODDING_J_STD_RAW" or\n"
77 "flat-file.fits "CRIRES_CALPRO_FLAT" or\n"
78 "flat-file.fits "CRIRES_CALPRO_FLAT_WIN" or\n"
79 "bpm-file.fits "CRIRES_CALPRO_BPM" or\n"
80 "bpm-file.fits "CRIRES_CALPRO_BPM_WIN" or\n"
81 "dark-file.fits "CRIRES_CALPRO_DARK" or\n"
82 "dark-file.fits "CRIRES_CALPRO_DARK_WIN" or\n"
83 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n"
84 "\n"
85 "In the case of a nodding observation, in order not to degrade the \n"
86 " instrument high resolution, the combined images using only NODA\n"
87 " or NODB nodding positions can be produced on request. (see --onlyA/B)\n"
88 "\n"
89 "This recipe produces 2 files:\n"
90 "First product: the combined image\n"
91 " (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
92 "Second product: the contribution map\n"
93 " (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n" ;
94 
95 CRIRES_RECIPE_DEFINE(crires_util_combine,
96  CRIRES_PARAM_REFINE |
97  CRIRES_PARAM_ONLYA |
98  CRIRES_PARAM_ONLYB |
99  CRIRES_PARAM_BLIND,
100  "Images Combination tool",
101  crires_util_combine_description) ;
102 
103 /*-----------------------------------------------------------------------------
104  Static variables
105  -----------------------------------------------------------------------------*/
106 
107 static struct {
108  /* Inputs */
109  int blind ;
110  int refine ;
111  int onlyA ;
112  int onlyB ;
113  int nodding ;
114  /* Outputs */
115  int win_mode ;
116  crires_illum_period period ;
117 } crires_util_combine_config ;
118 
119 /*-----------------------------------------------------------------------------
120  Functions code
121  -----------------------------------------------------------------------------*/
122 
123 /*----------------------------------------------------------------------------*/
130 /*----------------------------------------------------------------------------*/
131 static int crires_util_combine(
132  cpl_frameset * frameset,
133  const cpl_parameterlist * parlist)
134 {
135  cpl_frameset * rawframes ;
136  cpl_frameset * skyframes ;
137  const char * fname ;
138  const char * flat ;
139  const char * dark ;
140  const char * bpm ;
141  const char * flat_win ;
142  const char * dark_win ;
143  const char * bpm_win ;
144  const char * detlin ;
145  cpl_imagelist ** comblist ;
146  cpl_propertylist * plist ;
147  const char * sval ;
148 
149  /* Initialise */
150  rawframes = NULL ;
151  skyframes = NULL ;
152 
153  /* Retrieve input parameters */
154  crires_util_combine_config.refine = crires_parameterlist_get_bool(
155  parlist, RECIPE_STRING, CRIRES_PARAM_REFINE) ;
156  crires_util_combine_config.onlyA = crires_parameterlist_get_bool(
157  parlist, RECIPE_STRING, CRIRES_PARAM_ONLYA) ;
158  crires_util_combine_config.onlyB = crires_parameterlist_get_bool(
159  parlist, RECIPE_STRING, CRIRES_PARAM_ONLYB) ;
160  crires_util_combine_config.blind = crires_parameterlist_get_bool(
161  parlist, RECIPE_STRING, CRIRES_PARAM_BLIND) ;
162 
163  /* Identify the RAW and CALIB frames in the input frameset */
164  if (crires_dfs_set_groups(frameset, NULL)) {
165  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
166  return -1 ;
167  }
168 
169  /* Retrieve calibration data */
170  flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
171  dark = crires_extract_filename(frameset, CRIRES_CALPRO_DARK) ;
172  bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
173  flat_win = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT_WIN) ;
174  dark_win = crires_extract_filename(frameset, CRIRES_CALPRO_DARK_WIN) ;
175  bpm_win = crires_extract_filename(frameset, CRIRES_CALPRO_BPM_WIN) ;
176  detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
177 
178  /* Retrieve raw frames */
179  if ((rawframes = crires_extract_frameset(frameset,
180  CRIRES_SPEC_JITTER_RAW)) != NULL) {
181  crires_util_combine_config.nodding = 0 ;
182  } else if ((rawframes = crires_extract_frameset(frameset,
183  CRIRES_SPEC_JITTER_J_RAW)) != NULL) {
184  crires_util_combine_config.nodding = 0 ;
185  } else if ((rawframes = crires_extract_frameset(frameset,
186  CRIRES_SPEC_NODDING_RAW)) != NULL) {
187  crires_util_combine_config.nodding = 1 ;
188  } else if ((rawframes = crires_extract_frameset(frameset,
189  CRIRES_SPEC_NODDING_OBJECT_RAW)) != NULL) {
190  crires_util_combine_config.nodding = 1 ;
191  } else if ((rawframes = crires_extract_frameset(frameset,
192  CRIRES_SPEC_NODDING_J_RAW)) != NULL) {
193  crires_util_combine_config.nodding = 1 ;
194  } else if ((rawframes = crires_extract_frameset(frameset,
195  CRIRES_SPEC_GENERIC_OBJECT_RAW)) != NULL) {
196  crires_util_combine_config.nodding = 0 ;
197  } else if ((rawframes = crires_extract_frameset(frameset,
198  CRIRES_SPEC_JITTER_STD_RAW)) != NULL) {
199  crires_util_combine_config.nodding = 0 ;
200  } else if ((rawframes = crires_extract_frameset(frameset,
201  CRIRES_SPEC_JITTER_J_STD_RAW)) != NULL) {
202  crires_util_combine_config.nodding = 0 ;
203  } else if ((rawframes = crires_extract_frameset(frameset,
204  CRIRES_SPEC_NODDING_STD_RAW)) != NULL) {
205  crires_util_combine_config.nodding = 1 ;
206  } else if ((rawframes = crires_extract_frameset(frameset,
207  CRIRES_SPEC_NODDING_J_STD_RAW)) != NULL) {
208  crires_util_combine_config.nodding = 1 ;
209  } else if ((rawframes = crires_extract_frameset(frameset,
210  CRIRES_WIN_NODDING_OBJECT_RAW)) != NULL) {
211  crires_util_combine_config.nodding = 1 ;
212  } else if ((rawframes = crires_extract_frameset(frameset,
213  CRIRES_WIN_NODDING_RAW)) != NULL) {
214  crires_util_combine_config.nodding = 1 ;
215  } else if ((rawframes = crires_extract_frameset(frameset,
216  CRIRES_WIN_NODDING_J_RAW)) != NULL) {
217  crires_util_combine_config.nodding = 1 ;
218  } else if ((rawframes = crires_extract_frameset(frameset,
219  CRIRES_WIN_NODDING_STD_RAW)) != NULL) {
220  crires_util_combine_config.nodding = 1 ;
221  } else if ((rawframes = crires_extract_frameset(frameset,
222  CRIRES_WIN_NODDING_J_STD_RAW)) != NULL) {
223  crires_util_combine_config.nodding = 1 ;
224  } else {
225  cpl_msg_error(__func__, "No raw frame in input") ;
226  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
227  return -1 ;
228  }
229 
230  /* OnlyA and OnlyB are only possible in nodding mode */
231  if (crires_util_combine_config.nodding == 0) {
232  if (crires_util_combine_config.onlyA) {
233  cpl_msg_warning(__func__, "onlyA only possible in nodding mode") ;
234  crires_util_combine_config.onlyA = 0 ;
235  }
236  if (crires_util_combine_config.onlyB) {
237  cpl_msg_warning(__func__, "onlyB only possible in nodding mode") ;
238  crires_util_combine_config.onlyB = 0 ;
239  }
240  }
241 
242  /* Retrieve sky frames if any */
243  skyframes = crires_extract_frameset(frameset, CRIRES_SPEC_NODDING_SKY_RAW) ;
244  if (skyframes == NULL) {
245  skyframes = crires_extract_frameset(frameset,
246  CRIRES_WIN_NODDING_SKY_RAW) ;
247  }
248  if (skyframes == NULL) {
249  skyframes = crires_extract_frameset(frameset,
250  CRIRES_SPEC_GENERIC_SKY_RAW) ;
251  }
252 
253  /* Get the detector illumination period */
254  crires_util_combine_config.period =
255  crires_get_detector_illum_period(cpl_frame_get_filename(
256  cpl_frameset_get_position(rawframes, 0))) ;
257  if (crires_util_combine_config.period == CRIRES_ILLUM_UNKNOWN) {
258  cpl_msg_error(__func__,
259  "Cannot determine the detector illumination period") ;
260  cpl_frameset_delete(rawframes) ;
261  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
262  return -1 ;
263  }
264 
265  /* Windowing mode ? */
266  if ((plist=cpl_propertylist_load(cpl_frame_get_filename(
267  cpl_frameset_get_position(rawframes, 0)), 0)) == NULL)
268  return -1 ;
269  sval = crires_pfits_get_ncorrs(plist) ;
270  if (!strcmp(sval, "FowlerNsampGRstWin")) {
271  crires_util_combine_config.period = CRIRES_ILLUM_FULL_DETECTOR ;
272  crires_util_combine_config.win_mode = 1 ;
273  } else {
274  crires_util_combine_config.win_mode = 0 ;
275  }
276  cpl_propertylist_delete(plist) ;
277 
278  /* Display the Detector illumination */
279  crires_display_detector_illum(crires_util_combine_config.period) ;
280 
281  /* Verify the STRIPE keys conformity */
282  if (crires_util_combine_config.win_mode == 1) {
283  fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
284  if (flat_win != NULL) {
285  if (crire_stripe_keys_mismatch(fname, flat_win)) {
286  cpl_msg_error(__func__,
287  "Mismatch of STRIPE keys with the flat frame") ;
288  cpl_frameset_delete(rawframes) ;
289  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
290  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
291  return -1 ;
292  }
293  }
294  if (bpm_win != NULL) {
295  if (crire_stripe_keys_mismatch(fname, bpm_win)) {
296  cpl_msg_error(__func__,
297  "Mismatch of STRIPE keys with the bpm frame") ;
298  cpl_frameset_delete(rawframes) ;
299  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
300  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
301  return -1 ;
302  }
303  }
304  if (dark_win != NULL) {
305  if (crire_stripe_keys_mismatch(fname, dark_win)) {
306  cpl_msg_error(__func__,
307  "Mismatch of STRIPE keys with the dark frame") ;
308  cpl_frameset_delete(rawframes) ;
309  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
310  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
311  return -1 ;
312  }
313  }
314  }
315 
316  /* Images recombination */
317  cpl_msg_info(__func__, "Images combination") ;
318  cpl_msg_indent_more() ;
319  if (crires_util_combine_config.win_mode == 0) {
320  comblist = crires_combine_imagelist(rawframes, skyframes,
321  crires_util_combine_config.period,
322  flat, dark, bpm, detlin,
323  crires_util_combine_config.nodding,
324  crires_util_combine_config.blind,
325  crires_util_combine_config.refine,
326  crires_util_combine_config.onlyA,
327  crires_util_combine_config.onlyB) ;
328  } else {
329  comblist = crires_combine_imagelist_win(rawframes,
330  flat_win, dark_win, bpm_win, detlin,
331  crires_util_combine_config.refine,
332  crires_util_combine_config.onlyA,
333  crires_util_combine_config.onlyB) ;
334  }
335  if (comblist == NULL) {
336  cpl_msg_error(__func__, "Cannot combine the images") ;
337  cpl_frameset_delete(rawframes) ;
338  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
339  cpl_msg_indent_less() ;
340  return -1 ;
341  }
342  cpl_frameset_delete(rawframes) ;
343  if (skyframes != NULL) cpl_frameset_delete(skyframes) ;
344  cpl_msg_indent_less() ;
345 
346  /* Save the product */
347  cpl_msg_info(__func__, "Save the product") ;
348  cpl_msg_indent_more() ;
349  if (crires_util_combine_save((const cpl_imagelist **)comblist, parlist,
350  frameset)) {
351  cpl_msg_error(__func__, "Cannot save the product") ;
352  cpl_imagelist_delete(comblist[0]) ;
353  cpl_imagelist_delete(comblist[1]) ;
354  if (crires_util_combine_config.onlyA) {
355  cpl_imagelist_delete(comblist[2]) ;
356  cpl_imagelist_delete(comblist[3]) ;
357  }
358  if (crires_util_combine_config.onlyB) {
359  cpl_imagelist_delete(comblist[4]) ;
360  cpl_imagelist_delete(comblist[5]) ;
361  }
362  cpl_free(comblist) ;
363  cpl_msg_indent_less() ;
364  return -1 ;
365  }
366  cpl_imagelist_delete(comblist[0]) ;
367  cpl_imagelist_delete(comblist[1]) ;
368  if (crires_util_combine_config.onlyA) {
369  cpl_imagelist_delete(comblist[2]) ;
370  cpl_imagelist_delete(comblist[3]) ;
371  }
372  if (crires_util_combine_config.onlyB) {
373  cpl_imagelist_delete(comblist[4]) ;
374  cpl_imagelist_delete(comblist[5]) ;
375  }
376  cpl_free(comblist) ;
377  cpl_msg_indent_less() ;
378 
379  /* Return */
380  if (cpl_error_get_code()) return -1 ;
381  else return 0 ;
382 }
383 
384 /*----------------------------------------------------------------------------*/
393 /*----------------------------------------------------------------------------*/
394 static int crires_util_combine_save(
395  const cpl_imagelist ** images,
396  const cpl_parameterlist * parlist,
397  cpl_frameset * set)
398 {
399  const char * recipe_name = "crires_util_combine" ;
400 
401  /* Write the combined image */
402  crires_image_save(set,
403  parlist,
404  set,
405  images[0],
406  recipe_name,
407  CRIRES_OBS_COMBINED_IMA,
408  CRIRES_PROTYPE_COMBINED,
409  crires_util_combine_config.period,
410  NULL,
411  NULL,
412  PACKAGE "/" PACKAGE_VERSION,
413  "crires_util_combine_comb.fits") ;
414 
415  /* Write the contribution map */
416  crires_image_save(set,
417  parlist,
418  set,
419  images[1],
420  recipe_name,
421  CRIRES_OBS_CONTRIBUTION_IMA,
422  CRIRES_PROTYPE_CONTRIB,
423  crires_util_combine_config.period,
424  NULL,
425  NULL,
426  PACKAGE "/" PACKAGE_VERSION,
427  "crires_util_combine_contrib.fits") ;
428 
429  /* Nodded A support */
430  if (crires_util_combine_config.onlyA) {
431  /* Write the combined Nodded A image */
432  crires_image_save(set,
433  parlist,
434  set,
435  images[2],
436  recipe_name,
437  CRIRES_OBS_COMBINED_NA_IMA,
438  CRIRES_PROTYPE_COMBINED,
439  crires_util_combine_config.period,
440  NULL,
441  NULL,
442  PACKAGE "/" PACKAGE_VERSION,
443  "crires_util_combine_comb_noddedA.fits") ;
444 
445  /* Write the contribution Nodded A image */
446  crires_image_save(set,
447  parlist,
448  set,
449  images[3],
450  recipe_name,
451  CRIRES_OBS_CONTRIBUTION_NA_IMA,
452  CRIRES_PROTYPE_CONTRIB,
453  crires_util_combine_config.period,
454  NULL,
455  NULL,
456  PACKAGE "/" PACKAGE_VERSION,
457  "crires_util_combine_contrib_noddedA.fits") ;
458  }
459 
460  /* Nodded B support */
461  if (crires_util_combine_config.onlyB) {
462  /* Write the combined Nodded B image */
463  crires_image_save(set,
464  parlist,
465  set,
466  images[4],
467  recipe_name,
468  CRIRES_OBS_COMBINED_NB_IMA,
469  CRIRES_PROTYPE_COMBINED,
470  crires_util_combine_config.period,
471  NULL,
472  NULL,
473  PACKAGE "/" PACKAGE_VERSION,
474  "crires_util_combine_comb_noddedB.fits") ;
475 
476  /* Write the contribution Nodded B image */
477  crires_image_save(set,
478  parlist,
479  set,
480  images[5],
481  recipe_name,
482  CRIRES_OBS_CONTRIBUTION_NB_IMA,
483  CRIRES_PROTYPE_CONTRIB,
484  crires_util_combine_config.period,
485  NULL,
486  NULL,
487  PACKAGE "/" PACKAGE_VERSION,
488  "crires_util_combine_contrib_noddedB.fits") ;
489  }
490  return 0;
491 }
492