CRIRES Pipeline Reference Manual 2.3.19
crires_spec_dark.c
1/* $Id: crires_spec_dark.c,v 1.32 2011-02-09 10:45:01 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: 2011-02-09 10:45:01 $
24 * $Revision: 1.32 $
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#include "irplib_utils.h"
38
39/*-----------------------------------------------------------------------------
40 Define
41 -----------------------------------------------------------------------------*/
42
43#define RECIPE_STRING "crires_spec_dark"
44
45/*-----------------------------------------------------------------------------
46 Functions prototypes
47 -----------------------------------------------------------------------------*/
48
49static double crires_spec_dark_ron(const cpl_image *, const cpl_image *, int) ;
50static int crires_spec_dark_save(const cpl_imagelist *,
51 const cpl_parameterlist *, cpl_frameset *) ;
52
53static char crires_spec_dark_description[] =
54"crires_spec_dark -- Dark recipe\n"
55"The files listed in the Set Of Frames (sof-file) must be tagged:\n"
56"raw-file.fits "CRIRES_SPEC_DARK_RAW".\n" ;
57
58CRIRES_RECIPE_DEFINE(crires_spec_dark,
59 CRIRES_PARAM_RON_SAMPLES |
60 CRIRES_PARAM_RON_SZ,
61 "Dark recipe",
62 crires_spec_dark_description) ;
63
64/*-----------------------------------------------------------------------------
65 Static variables
66 -----------------------------------------------------------------------------*/
67
68static struct {
69 /* Inputs */
70 int hsize ;
71 int nsamples ;
72 /* Outputs */
73 crires_illum_period period ;
74 double dark_med[CRIRES_NB_DETECTORS] ;
75 double dark_stdev[CRIRES_NB_DETECTORS] ;
76 double ron1[CRIRES_NB_DETECTORS] ;
77 double ron2[CRIRES_NB_DETECTORS] ;
78} crires_spec_dark_config ;
79
80/*-----------------------------------------------------------------------------
81 Functions code
82 -----------------------------------------------------------------------------*/
83
84/*----------------------------------------------------------------------------*/
91/*----------------------------------------------------------------------------*/
92static int crires_spec_dark(
93 cpl_frameset * frameset,
94 const cpl_parameterlist * parlist)
95{
96 cpl_frameset * rawframes ;
97 cpl_frame * ref_frame ;
98 cpl_propertylist * plist ;
99 double dit ;
100 int ndit, ly, uy, ysize ;
101 cpl_imagelist * darks ;
102 cpl_imagelist * darks_chip ;
103 cpl_image * tmp_dark ;
104 cpl_vector * medians ;
105 double med ;
106 int i, j ;
107
108 /* Initialise */
109 rawframes = NULL ;
110 uy = ly = -1 ;
111 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
112 crires_spec_dark_config.ron1[i] = -1.0 ;
113 crires_spec_dark_config.ron2[i] = -1.0 ;
114 crires_spec_dark_config.dark_med[i] = -1.0 ;
115 crires_spec_dark_config.dark_stdev[i] = -1.0 ;
116 }
117
118 /* Retrieve input parameters */
119 crires_spec_dark_config.hsize = crires_parameterlist_get_int(parlist,
120 RECIPE_STRING, CRIRES_PARAM_RON_SZ) ;
121 crires_spec_dark_config.nsamples = crires_parameterlist_get_int(parlist,
122 RECIPE_STRING, CRIRES_PARAM_RON_SAMPLES) ;
123
124 /* Identify the RAW and CALIB frames in the input frameset */
125 if (crires_dfs_set_groups(frameset, "crires_spec_dark")) {
126 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
127 return -1 ;
128 }
129
130 /* Retrieve raw frames */
131 if ((rawframes = crires_extract_frameset(frameset,
132 CRIRES_SPEC_DARK_RAW)) == NULL) {
133 cpl_msg_error(__func__, "No raw frame in input") ;
134 return -1 ;
135 }
136
137 /* At least 3 frames */
138 if (cpl_frameset_get_size(rawframes) < 3) {
139 cpl_msg_error(__func__, "Not enough input frames");
140 cpl_frameset_delete(rawframes) ;
141 return -1 ;
142 }
143
144 /* Get the detector illumination period */
145 crires_spec_dark_config.period =
146 crires_get_detector_illum_period(
147 cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ;
148 if (crires_spec_dark_config.period == CRIRES_ILLUM_UNKNOWN) {
149 cpl_msg_error(__func__,
150 "Cannot determine the detector illumination period") ;
151 cpl_frameset_delete(rawframes) ;
152 return -1 ;
153 } else {
154 crires_display_detector_illum(crires_spec_dark_config.period) ;
155 }
156
157 /* Get DIT / NDIT from the header */
158 ref_frame = cpl_frameset_get_position(rawframes, 0) ;
159 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
160 0)) == NULL) {
161 cpl_msg_error(__func__, "Cannot get header from frame");
162 cpl_msg_indent_less() ;
163 cpl_frameset_delete(rawframes) ;
164 return -1 ;
165 }
166 dit = crires_pfits_get_dit(plist) ;
167 ndit = crires_pfits_get_ndit(plist) ;
168 cpl_propertylist_delete(plist) ;
169 if (cpl_error_get_code() != CPL_ERROR_NONE) {
170 cpl_msg_error(__func__, "Cannot get the DIT/NDIT from the header") ;
171 cpl_msg_indent_less() ;
172 cpl_frameset_delete(rawframes) ;
173 return -1 ;
174 }
175 cpl_msg_info(__func__, "DIT value: %g sec.", dit) ;
176 cpl_msg_info(__func__, "NDIT value: %d", ndit) ;
177
178 /* Loop on the chips */
179 darks = cpl_imagelist_new() ;
180 cpl_msg_info(__func__, "Dark computation") ;
181 cpl_msg_indent_more() ;
182 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
183 /* Get the illumination zone */
184 if (i==0) {
185 ly=crires_get_detector_ly1(crires_spec_dark_config.period);
186 uy=crires_get_detector_uy1(crires_spec_dark_config.period);
187 } else if (i==1) {
188 ly=crires_get_detector_ly2(crires_spec_dark_config.period);
189 uy=crires_get_detector_uy2(crires_spec_dark_config.period);
190 } else if (i==2) {
191 ly=crires_get_detector_ly3(crires_spec_dark_config.period);
192 uy=crires_get_detector_uy3(crires_spec_dark_config.period);
193 } else if (i==3) {
194 ly=crires_get_detector_ly4(crires_spec_dark_config.period);
195 uy=crires_get_detector_uy4(crires_spec_dark_config.period);
196 }
197 ysize = uy - ly + 1;
198 if (128-ly <= 0) ly = 1 ;
199 else ly = 128-ly+1 ;
200 if (ly+256 >= ysize) uy = ysize ;
201 else uy = ly+256 ;
202
203 /* Load the chips */
204 cpl_msg_info(__func__, "Load chip number %d", i+1) ;
205 if ((darks_chip = crires_load_frameset(rawframes,
206 crires_spec_dark_config.period, i+1,
207 CPL_TYPE_FLOAT)) == NULL) {
208 cpl_msg_error(__func__, "Cannot load chip number %d", i+1) ;
209 cpl_msg_indent_less() ;
210 cpl_imagelist_delete(darks) ;
211 cpl_frameset_delete(rawframes) ;
212 return -1 ;
213 }
214 /* Compute the current dark */
215 cpl_msg_info(__func__, "Collapse images for chip number %d", i+1) ;
216 if ((tmp_dark = cpl_imagelist_collapse_create(darks_chip)) == NULL) {
217 cpl_msg_error(__func__, "Cannot average for chip number %d", i+1) ;
218 cpl_msg_indent_less() ;
219 cpl_imagelist_delete(darks) ;
220 cpl_frameset_delete(rawframes) ;
221 cpl_imagelist_delete(darks_chip) ;
222 return -1 ;
223 }
224 /* Put the result in the image list */
225 cpl_imagelist_set(darks, tmp_dark, i) ;
226
227 /* Compute the dark_med and stdev */
228 medians = cpl_vector_new(cpl_imagelist_get_size(darks_chip));
229 for (j=0 ; j<cpl_imagelist_get_size(darks_chip) ; j++) {
230 med = cpl_image_get_median_window(cpl_imagelist_get(darks_chip, j),
231 256, ly, 768, uy) ;
232 cpl_vector_set(medians, j, med) ;
233 }
234 crires_spec_dark_config.dark_med[i] = cpl_vector_get_mean(medians) ;
235 crires_spec_dark_config.dark_stdev[i] = cpl_vector_get_stdev(medians) ;
236 cpl_vector_delete(medians) ;
237
238 /* Compute the RONs */
239 crires_spec_dark_config.ron1[i] = crires_spec_dark_ron(
240 cpl_imagelist_get(darks_chip, 0),
241 cpl_imagelist_get(darks_chip, 1),
242 ndit) ;
243 crires_spec_dark_config.ron2[i] = crires_spec_dark_ron(
244 cpl_imagelist_get(darks_chip, 1),
245 cpl_imagelist_get(darks_chip, 2),
246 ndit) ;
247 cpl_imagelist_delete(darks_chip) ;
248 }
249 cpl_frameset_delete(rawframes) ;
250 cpl_msg_indent_less() ;
251
252 /* Divide by DIT */
253 cpl_msg_info(__func__, "Division by DIT") ;
254 cpl_imagelist_divide_scalar(darks, dit) ;
255
256 /* Save the product */
257 cpl_msg_info(__func__, "Save the product") ;
258 cpl_msg_indent_more() ;
259 if (crires_spec_dark_save(darks, parlist, frameset)) {
260 cpl_msg_error(__func__, "Cannot save the product") ;
261 cpl_imagelist_delete(darks) ;
262 cpl_msg_indent_less() ;
263 return -1 ;
264 }
265 cpl_imagelist_delete(darks) ;
266 cpl_msg_indent_less() ;
267
268 /* Return */
269 if (cpl_error_get_code()) return -1 ;
270 else return 0 ;
271}
272
273/*----------------------------------------------------------------------------*/
281/*----------------------------------------------------------------------------*/
282static double crires_spec_dark_ron(
283 const cpl_image * ima1,
284 const cpl_image * ima2,
285 int ndit)
286{
287 cpl_image * ima ;
288 double norm ;
289 double ron ;
290
291 /* Test entries */
292 if (ima1 == NULL) return -1.0 ;
293 if (ima2 == NULL) return -1.0 ;
294 if (ndit < 1) return -1.0 ;
295
296 /* Compute norm */
297 norm = 0.5 * ndit ;
298 norm = sqrt(norm) ;
299
300 /* Subtraction */
301 if ((ima = cpl_image_subtract_create(ima2, ima1)) == NULL) return -1.0 ;
302
303 /* RON measurement */
304 cpl_flux_get_noise_window(ima, NULL, crires_spec_dark_config.hsize,
305 crires_spec_dark_config.nsamples, &ron, NULL) ;
306 cpl_image_delete(ima) ;
307 return norm*ron ;
308}
309
310/*----------------------------------------------------------------------------*/
318/*----------------------------------------------------------------------------*/
319static int crires_spec_dark_save(
320 const cpl_imagelist * dark,
321 const cpl_parameterlist * parlist,
322 cpl_frameset * set)
323{
324 cpl_propertylist ** qclists ;
325 const cpl_frame * ref_frame ;
326 cpl_propertylist * inputlist ;
327 const char * recipe_name = "crires_spec_dark" ;
328 int i ;
329
330 /* Get the reference frame */
331 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
332
333 /* Create the QC lists */
334 qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
335 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
336 qclists[i] = cpl_propertylist_new() ;
337 cpl_propertylist_append_double(qclists[i], "ESO QC RON1",
338 crires_spec_dark_config.ron1[i]) ;
339 cpl_propertylist_append_double(qclists[i], "ESO QC RON2",
340 crires_spec_dark_config.ron2[i]) ;
341 cpl_propertylist_append_double(qclists[i], "ESO QC DARKMED",
342 crires_spec_dark_config.dark_med[i]) ;
343 cpl_propertylist_append_double(qclists[i], "ESO QC DARKSTDEV",
344 crires_spec_dark_config.dark_stdev[i]) ;
345
346 /* Propagate some keywords from input raw frame extensions */
347 inputlist = cpl_propertylist_load_regexp(
348 cpl_frame_get_filename(ref_frame), i+1,
349 CRIRES_HEADER_EXT_FORWARD, 0) ;
350 cpl_propertylist_copy_property_regexp(qclists[i], inputlist,
351 CRIRES_HEADER_EXT_FORWARD, 0) ;
352 cpl_propertylist_delete(inputlist) ;
353 }
354
355 /* Write the combined image */
356 crires_image_save(set,
357 parlist,
358 set,
359 dark,
360 recipe_name,
361 CRIRES_CALPRO_DARK,
362 CRIRES_PROTYPE_DARK,
363 crires_spec_dark_config.period,
364 NULL,
365 (const cpl_propertylist**)qclists,
366 PACKAGE "/" PACKAGE_VERSION,
367 "crires_spec_dark.fits") ;
368
369 /* Remove the keywords for the FITS extensions */
370 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
371 cpl_propertylist_erase_regexp(qclists[i], CRIRES_HEADER_EXT_FORWARD, 0);
372 }
373
374 /* Free and return */
375 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
376 cpl_propertylist_delete(qclists[i]) ;
377 }
378 cpl_free(qclists) ;
379 return 0;
380}
381