CR2RE Pipeline Reference Manual 1.6.8
cr2res_util_splice.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#include <locale.h>
28#include <string.h>
29
30#include <cpl.h>
31#include "hdrl.h"
32
33#include "cr2res_pfits.h"
34#include "cr2res_dfs.h"
35#include "cr2res_io.h"
36#include "cr2res_splice.h"
37
38/*-----------------------------------------------------------------------------
39 Define
40 -----------------------------------------------------------------------------*/
41
42#define RECIPE_STRING "cr2res_util_splice"
43
44/*-----------------------------------------------------------------------------
45 Plugin registration
46 -----------------------------------------------------------------------------*/
47
48int cpl_plugin_get_info(cpl_pluginlist * list);
49
50/*-----------------------------------------------------------------------------
51 Private function prototypes
52 -----------------------------------------------------------------------------*/
53
54static int cr2res_util_splice_create(cpl_plugin *);
55static int cr2res_util_splice_exec(cpl_plugin *);
56static int cr2res_util_splice_destroy(cpl_plugin *);
57static int cr2res_util_splice(cpl_frameset *, const cpl_parameterlist *);
58
59/*-----------------------------------------------------------------------------
60 Static variables
61 -----------------------------------------------------------------------------*/
62
63static char cr2res_util_splice_description[] = "\
64Continuum normalization and splicing together spectra. \n\
65 \n\
66 \n\
67 Inputs \n\
68 blaze.fits " CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG " [1] \n\
69 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG " [1] \n\
70 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG " \n\
71 or " CR2RES_UTIL_TRACE_TW_PROCATG " \n\
72 or " CR2RES_UTIL_WAVE_TW_PROCATG " \n\
73 or " CR2RES_CAL_WAVE_TW_PROCATG " \n\
74 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG " \n\
75 extracted.fits " CR2RES_UTIL_EXTRACT_1D_PROCATG " [1] \n\
76 \n\
77 Outputs \n\
78 \n\
79 Algorithm \n\
80 \n\
81 Library functions used: \n\
82";
83
84/*-----------------------------------------------------------------------------
85 Function code
86 -----------------------------------------------------------------------------*/
87
88/*----------------------------------------------------------------------------*/
98/*----------------------------------------------------------------------------*/
99int cpl_plugin_get_info(cpl_pluginlist * list)
100{
101 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
102 cpl_plugin * plugin = &recipe->interface;
103
104 if (cpl_plugin_init(plugin,
105 CPL_PLUGIN_API,
106 CR2RES_BINARY_VERSION,
107 CPL_PLUGIN_TYPE_RECIPE,
108 RECIPE_STRING,
109 "Splicing utility",
110 cr2res_util_splice_description,
111 CR2RES_PIPELINE_AUTHORS,
112 PACKAGE_BUGREPORT,
114 cr2res_util_splice_create,
115 cr2res_util_splice_exec,
116 cr2res_util_splice_destroy)) {
117 cpl_msg_error(cpl_func, "Plugin initialization failed");
118 (void)cpl_error_set_where(cpl_func);
119 return 1;
120 }
121
122 if (cpl_pluginlist_append(list, plugin)) {
123 cpl_msg_error(cpl_func, "Error adding plugin to list");
124 (void)cpl_error_set_where(cpl_func);
125 return 1;
126 }
127
128 return 0;
129}
130
131/*----------------------------------------------------------------------------*/
139/*----------------------------------------------------------------------------*/
140static int cr2res_util_splice_create(cpl_plugin * plugin)
141{
142 cpl_recipe * recipe;
143 cpl_parameter * p;
144
145 /* Check that the plugin is part of a valid recipe */
146 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
147 recipe = (cpl_recipe *)plugin;
148 else
149 return -1;
150
151 /* Create the parameters list in the cpl_recipe object */
152 recipe->parameters = cpl_parameterlist_new();
153
154 /* Fill the parameters list */
155 p = cpl_parameter_new_value("cr2res.cr2res_util_splice.detector",
156 CPL_TYPE_INT, "Only reduce the specified detector",
157 "cr2res.cr2res_util_splice", 0);
158 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detector");
159 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
160 cpl_parameterlist_append(recipe->parameters, p);
161
162 return 0;
163}
164
165/*----------------------------------------------------------------------------*/
171/*----------------------------------------------------------------------------*/
172static int cr2res_util_splice_exec(cpl_plugin * plugin)
173{
174 cpl_recipe *recipe;
175
176 /* Get the recipe out of the plugin */
177 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
178 recipe = (cpl_recipe *)plugin;
179 else return -1;
180
181 return cr2res_util_splice(recipe->frames, recipe->parameters);
182}
183
184/*----------------------------------------------------------------------------*/
190/*----------------------------------------------------------------------------*/
191static int cr2res_util_splice_destroy(cpl_plugin * plugin)
192{
193 cpl_recipe *recipe;
194
195 /* Get the recipe out of the plugin */
196 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
197 recipe = (cpl_recipe *)plugin;
198 else return -1 ;
199
200 cpl_parameterlist_delete(recipe->parameters);
201 return 0 ;
202}
203
204/*----------------------------------------------------------------------------*/
211/*----------------------------------------------------------------------------*/
212static int cr2res_util_splice(
213 cpl_frameset * frameset,
214 const cpl_parameterlist * parlist)
215{
216 cpl_frameset * trace_fset ;
217 cpl_frameset * extracted_fset ;
218 cpl_frameset * blaze_fset ;
219 const char * trace_file ;
220 const char * extracted_file ;
221 const char * blaze_file ;
222 cpl_table * trace_table ;
223 cpl_table * extracted_table ;
224 cpl_table * blaze_table ;
225 cpl_table ** trace_tables ;
226 cpl_table ** blaze_tables ;
227 cpl_table ** extracted_tables ;
228 cpl_bivector * spliced ;
229 cpl_bivector * spliced_err ;
230 cpl_table * spliced_table ;
231 cpl_error_code ret ;
232 cpl_size nframes, i ;
233 int ext_nr_trace, ext_nr_blaze, ext_nr_extracted,
234 det_nr, nb_det ;
235
236 /* RETRIEVE INPUT PARAMETERS */
237
238 /* Check Parameters */
239
240 /* Identify the RAW and CALIB frames in the input frameset */
241 if (cr2res_dfs_set_groups(frameset) != CPL_ERROR_NONE) {
242 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
243 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
244 return -1 ;
245 }
246
247 /* Get Inputs */
248 trace_fset = cr2res_io_find_TRACE_WAVE_all(frameset) ;
249 extracted_fset = cr2res_extract_frameset(frameset,
250 CR2RES_UTIL_EXTRACT_1D_PROCATG) ;
251 blaze_fset = cr2res_extract_frameset(frameset,
252 CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG) ;
253
254 /* Tests the Inputs */
255 if (trace_fset==NULL || extracted_fset==NULL || blaze_fset==NULL) {
256 cpl_msg_error(__func__, "Missing Inputs") ;
257 if (trace_fset != NULL) cpl_frameset_delete(trace_fset) ;
258 if (extracted_fset != NULL) cpl_frameset_delete(extracted_fset) ;
259 if (blaze_fset != NULL) cpl_frameset_delete(blaze_fset) ;
260 return -1 ;
261 }
262 nframes = cpl_frameset_get_size(trace_fset) ;
263 if (cpl_frameset_get_size(extracted_fset) != nframes ||
264 cpl_frameset_get_size(blaze_fset) != nframes) {
265 cpl_msg_error(__func__, "Inconsistent Inputs") ;
266 cpl_frameset_delete(trace_fset) ;
267 cpl_frameset_delete(extracted_fset) ;
268 cpl_frameset_delete(blaze_fset) ;
269 return -1 ;
270 }
271
272 if (nframes < 1) {
273 cpl_msg_error(__func__, "No valid frames could be found") ;
274 cpl_frameset_delete(trace_fset) ;
275 cpl_frameset_delete(extracted_fset) ;
276 cpl_frameset_delete(blaze_fset) ;
277 return -1 ;
278 }
279
280 cpl_msg_info(__func__,
281 "Detected %"CPL_SIZE_FORMAT" BLAZE/EXTRACTED/TRACE triplet(s)",
282 nframes) ;
283
284 /* Count the number of detector to process */
285
286 /* Loop over the Frames */
287 nb_det = 0 ;
288 for (i=0 ; i<nframes; i++) {
289
290 /* Get the File names */
291 trace_file = cpl_frame_get_filename(
292 cpl_frameset_get_position(trace_fset, i)) ;
293 extracted_file = cpl_frame_get_filename(
294 cpl_frameset_get_position(extracted_fset, i)) ;
295 blaze_file = cpl_frame_get_filename(
296 cpl_frameset_get_position(blaze_fset, i)) ;
297
298 /* Loop over the detectors */
299 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
300
301 /* Get Extension Numbers */
302 ext_nr_trace = cr2res_io_get_ext_idx(trace_file, det_nr, 1) ;
303 ext_nr_extracted = cr2res_io_get_ext_idx(extracted_file, det_nr, 1);
304 ext_nr_blaze = cr2res_io_get_ext_idx(blaze_file, det_nr, 1) ;
305
306
307 /* Skip if any detector is missing */
308 if (ext_nr_trace<0 || ext_nr_extracted<0 || ext_nr_blaze<0)
309 continue ;
310
311 /* Try loading */
312 trace_table = cr2res_io_load_TRACE_WAVE(trace_file, det_nr);
313 blaze_table = cr2res_io_load_EXTRACT_1D(blaze_file, det_nr);
314 extracted_table = cr2res_io_load_EXTRACT_1D(extracted_file, det_nr);
315
316 /* Increase counter if ok */
317 if (trace_table != NULL && blaze_table != NULL &&
318 extracted_table != NULL) {
319 nb_det++ ;
320 } else {
321 cpl_error_reset() ;
322 }
323
324 if (trace_table!= NULL) cpl_table_delete(trace_table);
325 if (blaze_table!= NULL) cpl_table_delete(blaze_table);
326 if (extracted_table!= NULL) cpl_table_delete(extracted_table);
327 }
328 }
329
330 if (nb_det == 0) {
331 cpl_msg_error(__func__, "No valid data could be found") ;
332 cpl_frameset_delete(trace_fset) ;
333 cpl_frameset_delete(extracted_fset) ;
334 cpl_frameset_delete(blaze_fset) ;
335 return -1 ;
336 }
337
338 cpl_msg_info(__func__, "Loading %d Detector(s) for splicing", nb_det) ;
339
340 /* Allocate Data containers */
341 blaze_tables = cpl_malloc(nb_det * sizeof(cpl_table*)) ;
342 extracted_tables = cpl_malloc(nb_det * sizeof(cpl_table*)) ;
343 trace_tables = cpl_malloc(nb_det * sizeof(cpl_table*)) ;
344
345 /* Load the inputs */
346 /* Loop over the Frames */
347 nb_det = 0 ;
348 for (i=0 ; i<nframes; i++) {
349 /* Get the File names */
350 trace_file = cpl_frame_get_filename(
351 cpl_frameset_get_position(trace_fset, i)) ;
352 extracted_file = cpl_frame_get_filename(
353 cpl_frameset_get_position(extracted_fset, i)) ;
354 blaze_file = cpl_frame_get_filename(
355 cpl_frameset_get_position(blaze_fset, i)) ;
356
357 /* Loop over the detectors */
358 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
359
360 /* Get Extension Numbers */
361 ext_nr_trace = cr2res_io_get_ext_idx(trace_file, det_nr, 1) ;
362 ext_nr_extracted = cr2res_io_get_ext_idx(extracted_file, det_nr, 1);
363 ext_nr_blaze = cr2res_io_get_ext_idx(blaze_file, det_nr, 1) ;
364
365 /* Skip if any detector is missing */
366 if (ext_nr_trace<0 || ext_nr_extracted<0 || ext_nr_blaze<0)
367 continue ;
368
369 /* Load */
370 trace_table = cr2res_io_load_TRACE_WAVE(trace_file, det_nr);
371 blaze_table = cr2res_io_load_EXTRACT_1D(blaze_file, det_nr);
372 extracted_table = cr2res_io_load_EXTRACT_1D(extracted_file, det_nr);
373
374 /* Increase counter if ok */
375 if (trace_table!=NULL && blaze_table!=NULL &&
376 extracted_table!=NULL) {
377 trace_tables[nb_det] = trace_table;
378 extracted_tables[nb_det] = extracted_table;
379 blaze_tables[nb_det] = blaze_table;
380 nb_det++ ;
381 } else {
382 cpl_error_reset() ;
383 if (trace_table!= NULL) cpl_table_delete(trace_table);
384 if (blaze_table!= NULL) cpl_table_delete(blaze_table);
385 if (extracted_table!= NULL) cpl_table_delete(extracted_table);
386 }
387 }
388 }
389 cpl_frameset_delete(trace_fset) ;
390 cpl_frameset_delete(blaze_fset) ;
391
392 /* Call the splicing */
393
394 ret = cr2res_splice(extracted_tables, blaze_tables, trace_tables,
395 nb_det, &spliced, &spliced_err) ;
396
397
398 /* Deallocate */
399 for (i=0 ; i<nb_det ; i++) {
400 cpl_table_delete(blaze_tables[i]) ;
401 cpl_table_delete(extracted_tables[i]) ;
402 cpl_table_delete(trace_tables[i]) ;
403 }
404 cpl_free(blaze_tables) ;
405 cpl_free(extracted_tables) ;
406 cpl_free(trace_tables) ;
407
408 if (ret) {
409 cpl_msg_error(__func__, "Splicing Error");
410 spliced_table = NULL ;
411 } else {
412 /* Store the spliced in a SPLICED table */
413 spliced_table = cr2res_splice_SPLICED_1D_create(spliced, spliced_err) ;
414
415 /* Free the bivectors */
416 cpl_bivector_delete(spliced) ;
417 cpl_bivector_delete(spliced_err) ;
418
419 /* Save the table */
420 if (spliced_table == NULL) {
421 cpl_msg_error(__func__, "Failed to create the SPLICED table");
422 }
423 else {
424 cpl_propertylist *ext_plist;
425 char *out_file;
426 extracted_file = cpl_frame_get_filename(
427 cpl_frameset_get_position(extracted_fset, 0)) ;
428 ext_plist = cpl_propertylist_load(extracted_file, 1) ;
429 out_file = cpl_sprintf("%s_spliced.fits",
431 cr2res_io_save_SPLICED_1D(out_file, frameset, frameset, parlist,
432 spliced_table, NULL, ext_plist,
433 CR2RES_UTIL_SPLICE_SPLICED_1D_PROCATG, RECIPE_STRING) ;
434 cpl_free(out_file);
435 cpl_propertylist_delete(ext_plist);
436 cpl_table_delete(spliced_table) ;
437 }
438 }
439
440 /* Free and return */
441 cpl_frameset_delete(extracted_fset) ;
442 return (int)cpl_error_get_code();
443}
444
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
cpl_table * cr2res_io_load_EXTRACT_1D(const char *filename, int detector)
Load a table from a EXTRACT_1D.
Definition: cr2res_io.c:1296
int cr2res_io_save_SPLICED_1D(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table *spliced_1d, const cpl_propertylist *qc_list, cpl_propertylist *ext_plist, const char *procatg, const char *recipe)
Save a SPLICED_1D.
Definition: cr2res_io.c:1978
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
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
Definition: cr2res_io.c:1109
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.