CR2RE Pipeline Reference Manual 1.6.8
cr2res_util_slit_curv.c
1/*
2 * This file is part of the CR2RES 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., 51 Franklin St, Fifth Floor, 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 <string.h>
29
30#include <cpl.h>
31#include "hdrl.h"
32
33#include "cr2res_slit_curv.h"
34#include "cr2res_utils.h"
35#include "cr2res_pfits.h"
36#include "cr2res_dfs.h"
37#include "cr2res_io.h"
38#include "cr2res_trace.h"
39
40/*-----------------------------------------------------------------------------
41 Define
42 -----------------------------------------------------------------------------*/
43
44#define RECIPE_STRING "cr2res_util_slit_curv"
45
46/*-----------------------------------------------------------------------------
47 Plugin registration
48 -----------------------------------------------------------------------------*/
49
50int cpl_plugin_get_info(cpl_pluginlist * list);
51
52/*-----------------------------------------------------------------------------
53 Private function prototypes
54 -----------------------------------------------------------------------------*/
55
56static int cr2res_util_slit_curv_create(cpl_plugin *);
57static int cr2res_util_slit_curv_exec(cpl_plugin *);
58static int cr2res_util_slit_curv_destroy(cpl_plugin *);
59static int cr2res_util_slit_curv(cpl_frameset *, const cpl_parameterlist *);
60
61/*-----------------------------------------------------------------------------
62 Static variables
63 -----------------------------------------------------------------------------*/
64
65static char cr2res_util_slit_curv_description[] = "\
66Slit curvature computation \n\
67 For each input trace_wave file, the slit curvature is derived. \n\
68 \n\
69 Inputs \n\
70 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG " [1 to n] \n\
71 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG " \n\
72 or " CR2RES_UTIL_TRACE_TW_PROCATG " \n\
73 or " CR2RES_UTIL_WAVE_TW_PROCATG " \n\
74 or " CR2RES_CAL_WAVE_TW_PROCATG " \n\
75 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG " \n\
76 lamp.fits " CR2RES_WAVE_FPET_RAW " [1 to n] \n\
77 \n\
78 Outputs \n\
79 <input_lamp_name>_map.fits " CR2RES_UTIL_SLIT_CURV_MAP_PROCATG" \n\
80 <input_lamp_name>_tw.fits " CR2RES_UTIL_SLIT_CURV_TW_PROCATG" \n\
81 \n\
82 Algorithm \n\
83 loop on input raw files pairs (t,l): \n\
84 loop on detectors d: \n\
85 Load the TRACE_WAVE table for the current detector \n\
86 Loop over the traces t: \n\
87 Call cr2res_slit_curv_compute_order_trace() to get the \n\
88 current trace curvatures \n\
89 Update the slit curvature in the TRACE_WAVE table \n\
90 Generate a slit curve map \n\
91 Save the TRACE_WAVE \n\
92 Save the SLIT_CURVE_MAP \n\
93 \n\
94 Library functions used \n\
95 cr2res_io_load_TRACE_WAVE() \n\
96 cr2res_slit_curv_compute_order_trace() \n\
97 cr2res_slit_curv_gen_map() \n\
98 cr2res_io_save_SLIT_CURV_MAP() \n\
99 cr2res_io_save_TRACE_WAVE() \n\
100";
101
102/*-----------------------------------------------------------------------------
103 Function code
104 -----------------------------------------------------------------------------*/
105
106/*----------------------------------------------------------------------------*/
116/*----------------------------------------------------------------------------*/
117int cpl_plugin_get_info(cpl_pluginlist * list)
118{
119 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
120 cpl_plugin * plugin = &recipe->interface;
121
122 if (cpl_plugin_init(plugin,
123 CPL_PLUGIN_API,
124 CR2RES_BINARY_VERSION,
125 CPL_PLUGIN_TYPE_RECIPE,
126 RECIPE_STRING,
127 "Slit Curvature utility",
128 cr2res_util_slit_curv_description,
129 CR2RES_PIPELINE_AUTHORS,
130 PACKAGE_BUGREPORT,
132 cr2res_util_slit_curv_create,
133 cr2res_util_slit_curv_exec,
134 cr2res_util_slit_curv_destroy)) {
135 cpl_msg_error(cpl_func, "Plugin initialization failed");
136 (void)cpl_error_set_where(cpl_func);
137 return 1;
138 }
139
140 if (cpl_pluginlist_append(list, plugin)) {
141 cpl_msg_error(cpl_func, "Error adding plugin to list");
142 (void)cpl_error_set_where(cpl_func);
143 return 1;
144 }
145
146 return 0;
147}
148
149/*----------------------------------------------------------------------------*/
157/*----------------------------------------------------------------------------*/
158static int cr2res_util_slit_curv_create(cpl_plugin * plugin)
159{
160 cpl_recipe * recipe;
161 cpl_parameter * p;
162
163 /* Check that the plugin is part of a valid recipe */
164 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
165 recipe = (cpl_recipe *)plugin;
166 else
167 return -1;
168
169 /* Create the parameters list in the cpl_recipe object */
170 recipe->parameters = cpl_parameterlist_new();
171
172 /* Fill the parameters list */
173 p = cpl_parameter_new_value("cr2res.cr2res_util_slit_curv.detector",
174 CPL_TYPE_INT, "Only reduce the specified detector",
175 "cr2res.cr2res_util_slit_curv", 0);
176 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detector");
177 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
178 cpl_parameterlist_append(recipe->parameters, p);
179
180 p = cpl_parameter_new_value("cr2res.cr2res_util_slit_curv.order",
181 CPL_TYPE_INT, "Only reduce the specified order",
182 "cr2res.cr2res_util_slit_curv", -1);
183 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "order");
184 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
185 cpl_parameterlist_append(recipe->parameters, p);
186
187 p = cpl_parameter_new_value("cr2res.cr2res_util_slit_curv.trace_nb",
188 CPL_TYPE_INT, "Only reduce the specified trace number",
189 "cr2res.cr2res_util_slit_curv", -1);
190 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "trace_nb");
191 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
192 cpl_parameterlist_append(recipe->parameters, p);
193
194 p = cpl_parameter_new_value("cr2res.cr2res_util_slit_curv.degree",
195 CPL_TYPE_INT, "Polynomial degree for the fit (1 or 2)",
196 "cr2res.cr2res_util_slit_curv", 2);
197 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "degree");
198 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
199 cpl_parameterlist_append(recipe->parameters, p);
200
201 p = cpl_parameter_new_value("cr2res.cr2res_util_slit_curv.display",
202 CPL_TYPE_INT, "X value to display (1->2048)",
203 "cr2res.cr2res_util_slit_curv", 0);
204 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "display");
205 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
206 cpl_parameterlist_append(recipe->parameters, p);
207 return 0;
208}
209
210/*----------------------------------------------------------------------------*/
216/*----------------------------------------------------------------------------*/
217static int cr2res_util_slit_curv_exec(cpl_plugin * plugin)
218{
219 cpl_recipe *recipe;
220
221 /* Get the recipe out of the plugin */
222 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
223 recipe = (cpl_recipe *)plugin;
224 else return -1;
225
226 return cr2res_util_slit_curv(recipe->frames, recipe->parameters);
227}
228
229/*----------------------------------------------------------------------------*/
235/*----------------------------------------------------------------------------*/
236static int cr2res_util_slit_curv_destroy(cpl_plugin * plugin)
237{
238 cpl_recipe *recipe;
239
240 /* Get the recipe out of the plugin */
241 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
242 recipe = (cpl_recipe *)plugin;
243 else return -1 ;
244
245 cpl_parameterlist_delete(recipe->parameters);
246 return 0 ;
247}
248
249/*----------------------------------------------------------------------------*/
256/*----------------------------------------------------------------------------*/
257static int cr2res_util_slit_curv(
258 cpl_frameset * frameset,
259 const cpl_parameterlist * parlist)
260{
261 const cpl_parameter * param;
262 int reduce_det, reduce_order, reduce_trace;
263 cpl_frameset * rawframes_tw ;
264 cpl_frameset * rawframes_lamp ;
265 cpl_table * trace_wave[CR2RES_NB_DETECTORS] ;
266 hdrl_image * lamp_image[CR2RES_NB_DETECTORS] ;
267 hdrl_image * slit_curv_map[CR2RES_NB_DETECTORS] ;
268 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
269 cpl_polynomial * slit_polya ;
270 cpl_polynomial * slit_polyb ;
271 cpl_polynomial * slit_polyc ;
272 cpl_array * slit_array ;
273 int det_nr, order, trace_id, nb_traces, slit_degree ;
274 char * out_file;
275 int i, j, k ;
276
277 /* RETRIEVE INPUT PARAMETERS */
278 param = cpl_parameterlist_find_const(parlist,
279 "cr2res.cr2res_util_slit_curv.detector");
280 reduce_det = cpl_parameter_get_int(param);
281 param = cpl_parameterlist_find_const(parlist,
282 "cr2res.cr2res_util_slit_curv.order");
283 reduce_order = cpl_parameter_get_int(param);
284 param = cpl_parameterlist_find_const(parlist,
285 "cr2res.cr2res_util_slit_curv.trace_nb");
286 reduce_trace = cpl_parameter_get_int(param);
287 param = cpl_parameterlist_find_const(parlist,
288 "cr2res.cr2res_util_slit_curv.degree");
289 slit_degree = cpl_parameter_get_int(param);
290 /*param = cpl_parameterlist_find_const(parlist,
291 "cr2res.cr2res_util_slit_curv.display");
292 display = cpl_parameter_get_int(param) ;*/
293
294 /* Identify the RAW and CALIB frames in the input frameset */
295 if (cr2res_dfs_set_groups(frameset) != CPL_ERROR_NONE) {
296 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
297 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
298 return -1 ;
299 }
300
301 /* Get Calibration frames */
302
303 /* Get the rawframes */
304 rawframes_tw = cr2res_io_find_TRACE_WAVE_all(frameset);
305 rawframes_lamp = cr2res_extract_frameset(frameset, CR2RES_WAVE_FPET_RAW) ;
306 if (rawframes_tw == NULL || rawframes_lamp == NULL ||
307 cpl_frameset_get_size(rawframes_lamp) <= 0 ||
308 cpl_frameset_get_size(rawframes_tw) <= 0 ||
309 cpl_frameset_get_size(rawframes_lamp) !=
310 cpl_frameset_get_size(rawframes_tw)) {
311 cpl_msg_error(__func__, "Input files not consistent") ;
312 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
313 if (rawframes_tw != NULL) cpl_frameset_delete(rawframes_tw) ;
314 if (rawframes_lamp != NULL) cpl_frameset_delete(rawframes_lamp) ;
315 return -1 ;
316 }
317
318 /* Loop on the RAW frames */
319 for (i = 0; i < cpl_frameset_get_size(rawframes_tw); i++) {
320 const cpl_frame *cur_frame_tw;
321 const char *cur_fname_tw;
322 const cpl_frame *cur_frame_lamp;
323 const char *cur_fname_lamp;
324 /* Get the Current Frame */
325 cur_frame_tw = cpl_frameset_get_position(rawframes_tw, i) ;
326 cur_fname_tw = cpl_frame_get_filename(cur_frame_tw) ;
327 cur_frame_lamp = cpl_frameset_get_position(rawframes_lamp, i) ;
328 cur_fname_lamp = cpl_frame_get_filename(cur_frame_lamp) ;
329 cpl_msg_info(__func__, "Reduce Frames %s (%s) ",
330 cr2res_get_base_name(cur_fname_lamp),
331 cr2res_get_base_name(cur_fname_tw)) ;
332 cpl_msg_indent_more() ;
333
334 /* Loop over the detectors */
335 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
336
337 /* Initialise */
338 slit_curv_map[det_nr-1] = NULL ;
339 trace_wave[det_nr-1] = NULL ;
340 lamp_image[det_nr-1] = NULL ;
341
342 /* Store the extension header for product saving */
343 ext_plist[det_nr-1] = cpl_propertylist_load(cur_fname_tw,
344 cr2res_io_get_ext_idx(cur_fname_tw, det_nr, 1)) ;
345
346 /* Compute only one detector */
347 if (reduce_det != 0 && det_nr != reduce_det) continue ;
348
349 cpl_msg_info(__func__, "Process detector number %d", det_nr) ;
350 cpl_msg_indent_more() ;
351
352 /* Load the TRACE_WAVE table of this detector */
353 cpl_msg_info(__func__, "Load the TRACE_WAVE table") ;
354 if ((trace_wave[det_nr-1] = cr2res_io_load_TRACE_WAVE(cur_fname_tw,
355 det_nr)) == NULL) {
356 cpl_msg_error(__func__,"Failed to load table - skip detector");
357 cpl_error_reset() ;
358 cpl_msg_indent_less() ;
359 continue ;
360 }
361 nb_traces = cpl_table_get_nrow(trace_wave[det_nr-1]) ;
362
363 /* Load the lamp image of this detector */
364 cpl_msg_info(__func__, "Load the LAMP image") ;
365 if ((lamp_image[det_nr-1] = cr2res_io_load_image(cur_fname_lamp,
366 det_nr)) == NULL) {
367 cpl_msg_error(__func__,"Failed to load image - skip detector");
368 cpl_error_reset() ;
369 cpl_msg_indent_less() ;
370 continue ;
371 }
372
373 /* Loop over the traces and get the slit curvature */
374 for (j=0 ; j<nb_traces ; j++) {
375 /* Get Order and trace id */
376 order = cpl_table_get(trace_wave[det_nr-1],
377 CR2RES_COL_ORDER, j, NULL) ;
378 trace_id = cpl_table_get(trace_wave[det_nr-1],
379 CR2RES_COL_TRACENB, j, NULL) ;
380
381 /* Check if this order needs to be skipped */
382 if (reduce_order > -1 && order != reduce_order) continue ;
383
384 /* Check if this trace needs to be skipped */
385 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
386
387 cpl_msg_info(__func__, "Process Order %d/Trace %d",
388 order, trace_id) ;
389 cpl_msg_indent_more() ;
390
391 /* Call the Slit Curvature Computation */
392 /* TODO : Should those become parameters ? */
393 int height = 165 ;
394 int window = 15 ;
395 int change_degree = 1;
396 if (cr2res_slit_curv_compute_order_trace(lamp_image[det_nr-1],
397 trace_wave[det_nr-1], order, trace_id,
398 height, window, change_degree, slit_degree ,
399 &slit_polya, &slit_polyb, &slit_polyc)) {
400 cpl_msg_warning(__func__,
401 "Cannot Compute Slit curvature for Order %d",
402 order);
403 cpl_error_reset() ;
404 cpl_msg_indent_less() ;
405 continue ;
406 }
407
408 /* Fill the SLIT_CURVE_A/B/C for the current trace */
409 slit_array = cr2res_convert_poly_to_array(slit_polya, 3) ;
410 cpl_polynomial_delete(slit_polya) ;
411 cpl_table_set_array(trace_wave[det_nr-1],
412 CR2RES_COL_SLIT_CURV_A, j, slit_array) ;
413 cpl_array_delete(slit_array) ;
414 slit_array = cr2res_convert_poly_to_array(slit_polyb, 3) ;
415 cpl_polynomial_delete(slit_polyb) ;
416 cpl_table_set_array(trace_wave[det_nr-1],
417 CR2RES_COL_SLIT_CURV_B, j, slit_array) ;
418 cpl_array_delete(slit_array) ;
419 slit_array = cr2res_convert_poly_to_array(slit_polyc, 3) ;
420 cpl_polynomial_delete(slit_polyc) ;
421 cpl_table_set_array(trace_wave[det_nr-1],
422 CR2RES_COL_SLIT_CURV_C, j, slit_array) ;
423 cpl_array_delete(slit_array) ;
424
425 // Correct the wavelength solution for the curvature
426 cr2res_trace_shift_wavelength(trace_wave[det_nr-1], 0.5,
427 order, trace_id);
428
429 cpl_msg_indent_less() ;
430 }
431
432 /* Generate the SLIT CURV Map */
433 slit_curv_map[det_nr-1] =
434 cr2res_slit_curv_gen_map(trace_wave[det_nr-1], reduce_order,
435 reduce_trace, 50, 0) ;
436 cpl_msg_indent_less() ;
437 }
438
439 /* Save the SLIT_CURV_MAP */
440 out_file = cpl_sprintf("%s_map.fits",
442 cr2res_io_save_SLIT_CURV_MAP(out_file, frameset, frameset, parlist,
443 slit_curv_map, NULL, ext_plist,
444 CR2RES_UTIL_SLIT_CURV_MAP_PROCATG, RECIPE_STRING) ;
445 cpl_free(out_file);
446
447 /* Save the new TRACE_WAVE table */
448 out_file=cpl_sprintf("%s_tw.fits",
450 cr2res_io_save_TRACE_WAVE(out_file, frameset, frameset, parlist,
451 trace_wave, NULL, ext_plist, CR2RES_UTIL_SLIT_CURV_TW_PROCATG,
452 RECIPE_STRING) ;
453 cpl_free(out_file);
454
455 /* Free and return */
456 for (k=0 ; k<CR2RES_NB_DETECTORS ; k++) {
457 if (trace_wave[k] != NULL) cpl_table_delete(trace_wave[k]) ;
458 if (lamp_image[k] != NULL) hdrl_image_delete(lamp_image[k]) ;
459 if (slit_curv_map[k] != NULL)
460 hdrl_image_delete(slit_curv_map[k]) ;
461 if (ext_plist[k] != NULL)
462 cpl_propertylist_delete(ext_plist[k]) ;
463 }
464 }
465 cpl_frameset_delete(rawframes_lamp) ;
466 cpl_frameset_delete(rawframes_tw) ;
467 return (int)cpl_error_get_code();
468}
469
cpl_error_code cr2res_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: cr2res_dfs.c:53
int cr2res_io_save_TRACE_WAVE(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table **tables, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a TRACE_WAVE.
Definition: cr2res_io.c:1670
cpl_frameset * cr2res_io_find_TRACE_WAVE_all(const cpl_frameset *in)
Get the CR2RES_TW_DRSTYPE frames from a frameset.
Definition: cr2res_io.c:293
int cr2res_io_get_ext_idx(const char *filename, int detector, int data)
Get the wished extension number for a detector.
Definition: cr2res_io.c:644
int cr2res_io_save_SLIT_CURV_MAP(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **data, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a SLIT_CURV_MAP.
Definition: cr2res_io.c:1947
hdrl_image * cr2res_io_load_image(const char *in, int detector)
Load an hdrl image from a image file.
Definition: cr2res_io.c:704
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
Definition: cr2res_io.c:1109
int cr2res_slit_curv_compute_order_trace(const hdrl_image *img, const cpl_table *trace_wave, const int order, const int trace, const int height, const int window, const cpl_size change_degree, const int slit_degree, cpl_polynomial **slit_poly_a, cpl_polynomial **slit_poly_b, cpl_polynomial **slit_poly_c)
Get the slit curvature directly from the image.
hdrl_image * cr2res_slit_curv_gen_map(const cpl_table *trace_wave, int order, int trace_id, int spacing_pixels, int full_trace)
Compute the slit_curv map from the trace_wave table.
cpl_array * cr2res_convert_poly_to_array(const cpl_polynomial *poly, int size)
Convert a polynomial to array.
char * cr2res_get_root_name(const char *filename)
Find out the root part of a basename (name without extension).
cpl_frameset * cr2res_extract_frameset(const cpl_frameset *in, const char *tag)
Extract the frames with the given tag from a frameset.
char * cr2res_get_base_name(const char *filename)
Find out the base name of a file (i.e. without prefix path)
const char * cr2res_get_license(void)
Get the pipeline copyright and license.
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379