CR2RE Pipeline Reference Manual 1.6.7
cr2res_util_genlines.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 <cpl.h>
29#include "hdrl.h"
30
31#include "cr2res_utils.h"
32#include "cr2res_pfits.h"
33#include "cr2res_dfs.h"
34#include "cr2res_io.h"
35
36/*-----------------------------------------------------------------------------
37 Define
38 -----------------------------------------------------------------------------*/
39
40#define RECIPE_STRING "cr2res_util_genlines"
41
42/*-----------------------------------------------------------------------------
43 Plugin registration
44 -----------------------------------------------------------------------------*/
45
46int cpl_plugin_get_info(cpl_pluginlist * list);
47
48/*-----------------------------------------------------------------------------
49 Private function prototypes
50 -----------------------------------------------------------------------------*/
51
52static int cr2res_util_genlines_create(cpl_plugin *);
53static int cr2res_util_genlines_exec(cpl_plugin *);
54static int cr2res_util_genlines_destroy(cpl_plugin *);
55static int cr2res_util_genlines(cpl_frameset *, const cpl_parameterlist *);
56
57/*-----------------------------------------------------------------------------
58 Static variables
59 -----------------------------------------------------------------------------*/
60
61static char cr2res_util_genlines_description[] = " \
62Generate Lines calibration tables \n\
63 \n\
64 Inputs \n\
65 raw1.txt " CR2RES_EMISSION_LINES_TXT_RAW" [1] \n\
66 raw2.txt " CR2RES_LINES_SELECTION_TXT_RAW" [0 to 1] \n\
67 The ASCII file raw1.txt must contain two columns: \n\
68 1st: Wavelengths in increasing order (the unit is corrected by \n\
69 the factor option to obtain nanometers). \n\
70 2nd: The atmospheric emission. \n\
71 The file is in the catalogs/ directory of the CR2RES distribution.\n\
72 The optional ASCII files raw2.txt contain a list of wavelength \n\
73 ranges (1 per line) of type: 1632.25,1632.70 \n\
74 The files are in the catalogs/selection/ directory of the CR2RES \n\
75 distribution. They are called XXX.dat, where XXX \n\
76 identifies the setting [L3244, L3340, ...]. \n\
77 \n\
78 Output \n\
79 cr2res_util_genlines.fits "CR2RES_EMISSION_LINES_PROCATG" \n\
80 cr2res_util_genlines_XXX.fits "CR2RES_EMISSION_LINES_PROCATG" \n\
81 \n\
82 Algorithm \n\
83 Parse and load the 2 columns raw1.txt file \n\
84 Apply the --wl_factor correction \n\
85 if (--display) plot it \n\
86 Create the CPL table \n\
87 Save the table with all lines \n\
88 Loop on the selection files \n\
89 Only keep the lines that fall in the selection ranges (if any) \n\
90 Save the table with the selected lines \n\
91 \n\
92 Library functions used \n\
93 cr2res_io_save_EMISSION_LINES() \n\
94" ;
95
96/*-----------------------------------------------------------------------------
97 Function code
98 -----------------------------------------------------------------------------*/
99
100/*----------------------------------------------------------------------------*/
110/*----------------------------------------------------------------------------*/
111int cpl_plugin_get_info(cpl_pluginlist * list)
112{
113 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
114 cpl_plugin * plugin = &recipe->interface;
115
116 if (cpl_plugin_init(plugin,
117 CPL_PLUGIN_API,
118 CR2RES_BINARY_VERSION,
119 CPL_PLUGIN_TYPE_RECIPE,
120 RECIPE_STRING,
121 "Generate spectrum calibration FITS tables",
122 cr2res_util_genlines_description,
123 CR2RES_PIPELINE_AUTHORS,
124 PACKAGE_BUGREPORT,
126 cr2res_util_genlines_create,
127 cr2res_util_genlines_exec,
128 cr2res_util_genlines_destroy)) {
129 cpl_msg_error(cpl_func, "Plugin initialization failed");
130 (void)cpl_error_set_where(cpl_func);
131 return 1;
132 }
133
134 if (cpl_pluginlist_append(list, plugin)) {
135 cpl_msg_error(cpl_func, "Error adding plugin to list");
136 (void)cpl_error_set_where(cpl_func);
137 return 1;
138 }
139
140 return 0;
141}
142
143/*----------------------------------------------------------------------------*/
151/*----------------------------------------------------------------------------*/
152static int cr2res_util_genlines_create(cpl_plugin * plugin)
153{
154 cpl_recipe * recipe ;
155 cpl_parameter * p ;
156
157 /* Check that the plugin is part of a valid recipe */
158 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
159 recipe = (cpl_recipe *)plugin;
160 else
161 return -1;
162
163 /* Create the parameters list in the cpl_recipe object */
164 recipe->parameters = cpl_parameterlist_new();
165
166 /* Fill the parameters list */
167 p = cpl_parameter_new_value("cr2res_util_genlines.wl_factor",
168 CPL_TYPE_DOUBLE, "The factor used to multiply the wl",
169 RECIPE_STRING, 1.0);
170 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wl_factor");
171 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
172 cpl_parameterlist_append(recipe->parameters, p);
173
174 p = cpl_parameter_new_value("cr2res_util_genlines.display",
175 CPL_TYPE_BOOL, "Flag to plot", RECIPE_STRING, FALSE);
176 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "display");
177 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
178 cpl_parameterlist_append(recipe->parameters, p);
179
180 return 0;
181}
182
183/*----------------------------------------------------------------------------*/
189/*----------------------------------------------------------------------------*/
190static int cr2res_util_genlines_exec(cpl_plugin * plugin)
191{
192 cpl_recipe *recipe;
193
194 /* Get the recipe out of the plugin */
195 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
196 recipe = (cpl_recipe *)plugin;
197 else return -1;
198
199 return cr2res_util_genlines(recipe->frames, recipe->parameters);
200}
201
202/*----------------------------------------------------------------------------*/
208/*----------------------------------------------------------------------------*/
209static int cr2res_util_genlines_destroy(cpl_plugin * plugin)
210{
211 cpl_recipe *recipe;
212
213 /* Get the recipe out of the plugin */
214 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
215 recipe = (cpl_recipe *)plugin;
216 else return -1 ;
217
218 cpl_parameterlist_delete(recipe->parameters);
219 return 0 ;
220}
221
222/*----------------------------------------------------------------------------*/
229/*----------------------------------------------------------------------------*/
230static int cr2res_util_genlines(
231 cpl_frameset * frameset,
232 const cpl_parameterlist * parlist)
233{
234 const cpl_parameter * par ;
235 cpl_frameset * lines_list_frames ;
236 cpl_frame * lines_list_frame ;
237 const char * lines_list_fname ;
238 cpl_frameset * selection_frames ;
239 char * out_file;
240 double wl_fac ;
241 int display ;
242 cpl_bivector * bivec ;
243 cpl_bivector * bivec_sorted ;
244 double * pbivec_x ;
245 double * pbivec_y ;
246 double * pbivec_selec_x ;
247 double * pbivec_selec_y ;
248 double * pbivec_selected_x ;
249 double * pbivec_selected_y ;
250 int nvals ;
251 cpl_table * tab ;
252 char * setting ;
253 int i, j, k ;
254
255 /* Retrieve input parameters */
256 par=cpl_parameterlist_find_const(parlist, "cr2res_util_genlines.display");
257 display = cpl_parameter_get_bool(par);
258 par=cpl_parameterlist_find_const(parlist, "cr2res_util_genlines.wl_factor");
259 wl_fac = cpl_parameter_get_double(par);
260
261 /* Identify the RAW and CALIB frames in the input frameset */
262 if (cr2res_dfs_set_groups(frameset)) {
263 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
264 return -1 ;
265 }
266
267 /* Get Calibration frames */
268 selection_frames = cr2res_extract_frameset(frameset,
269 CR2RES_LINES_SELECTION_TXT_RAW) ;
270
271 /* Get the rawframes */
272 lines_list_frames = cr2res_extract_frameset(frameset,
273 CR2RES_EMISSION_LINES_TXT_RAW) ;
274 if (lines_list_frames==NULL ||
275 cpl_frameset_get_size(lines_list_frames) != 1) {
276 cpl_msg_error(__func__, "Please provide 1 and only 1 Lines list file") ;
277 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
278 if (selection_frames != NULL) cpl_frameset_delete(selection_frames) ;
279 if (lines_list_frames != NULL) cpl_frameset_delete(lines_list_frames) ;
280 return -1 ;
281 }
282 lines_list_frame = cpl_frameset_get_position(lines_list_frames, 0);
283 lines_list_fname = cpl_frame_get_filename(lines_list_frame) ;
284
285 cpl_msg_info(__func__, "Process Lines List %s", lines_list_fname) ;
286 cpl_msg_indent_more() ;
287
288 /* Load the file */
289 if ((bivec=cpl_bivector_read(lines_list_fname))==NULL){
290 cpl_msg_error(__func__, "Cannot load the lines in the bivector") ;
291 cpl_msg_indent_less() ;
292 if (selection_frames != NULL) cpl_frameset_delete(selection_frames) ;
293 cpl_frameset_delete(lines_list_frames) ;
294 return -1 ;
295 }
296
297 /* Use wl_factor */
298 cpl_vector_multiply_scalar(cpl_bivector_get_x(bivec), wl_fac) ;
299
300 /* Sort if needed */
301 //int sort = 1 ;
302 //if (sort) {
303 bivec_sorted = cpl_bivector_duplicate(bivec);
304 cpl_bivector_sort(bivec_sorted, bivec, CPL_SORT_ASCENDING, CPL_SORT_BY_X);
305 cpl_bivector_delete(bivec);
306 bivec = bivec_sorted;
307 bivec_sorted = NULL;
308 //}
309
310 /* Display if requested */
311 if (display) {
312 cpl_plot_bivector(
313 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Emission';",
314 "t 'Catalog lines' w lines", "", bivec);
315 }
316
317 /* Allocate the data container */
318 nvals = cpl_bivector_get_size(bivec) ;
319 tab = cpl_table_new(nvals) ;
320 cpl_table_wrap_double(tab, cpl_bivector_get_x_data(bivec),
321 CR2RES_COL_WAVELENGTH) ;
322 cpl_table_wrap_double(tab, cpl_bivector_get_y_data(bivec),
323 CR2RES_COL_EMISSION) ;
324
325 /* Save the table */
326 cpl_msg_info(__func__, "Saving the table with %d rows", nvals) ;
327 out_file = cpl_sprintf("%s.fits",
328 cr2res_get_base_name(cr2res_get_root_name(lines_list_fname)));
329 if (cr2res_io_save_EMISSION_LINES(out_file, tab, parlist, frameset,
330 RECIPE_STRING, NULL) == -1) {
331 cpl_msg_error(__func__, "Cannot write the table") ;
332 cpl_table_unwrap(tab, CR2RES_COL_WAVELENGTH) ;
333 cpl_table_unwrap(tab, CR2RES_COL_EMISSION) ;
334 cpl_table_delete(tab) ;
335 cpl_free(out_file);
336 if (selection_frames != NULL) cpl_frameset_delete(selection_frames) ;
337 cpl_frameset_delete(lines_list_frames) ;
338 cpl_bivector_delete(bivec) ;
339 cpl_msg_indent_less() ;
340 return -1 ;
341 }
342 cpl_free(out_file);
343 cpl_table_unwrap(tab, CR2RES_COL_WAVELENGTH) ;
344 cpl_table_unwrap(tab, CR2RES_COL_EMISSION) ;
345 cpl_table_delete(tab) ;
346
347 /* Loop on the selection frames */
348 for (i = 0; i < cpl_frameset_get_size(selection_frames); i++) {
349 cpl_frame *selection_frame;
350 const char *selection_fname;
351 cpl_bivector *bivec_selec;
352 cpl_bivector *bivec_selected;
353 /* Get the Current Frame */
354 selection_frame = cpl_frameset_get_position(selection_frames, i) ;
355 selection_fname = cpl_frame_get_filename(selection_frame) ;
356 bivec_selected = NULL ;
357
358 /* Apply the selection */
359 bivec_selec = cpl_bivector_read(selection_fname) ;
360 if (bivec_selec != NULL) {
361 pbivec_x = cpl_bivector_get_x_data(bivec) ;
362 pbivec_y = cpl_bivector_get_y_data(bivec) ;
363 pbivec_selec_x = cpl_bivector_get_x_data(bivec_selec) ;
364 pbivec_selec_y = cpl_bivector_get_y_data(bivec_selec) ;
365 /* Count the selected lines */
366 nvals = 0 ;
367 for (j=0 ; j<cpl_bivector_get_size(bivec) ; j++) {
368 /* Loop on the selected ranges */
369 for (k=0 ; k<cpl_bivector_get_size(bivec_selec) ; k++) {
370 /* Check if the line is in one of the ranges */
371 if (pbivec_x[j] >= pbivec_selec_x[k] &&
372 pbivec_x[j] <= pbivec_selec_y[k]) {
373 nvals++ ;
374 /* Next line */
375 break ;
376 }
377 }
378 }
379
380 if (nvals > 0) {
381 /* Apply selection */
382 bivec_selected = cpl_bivector_new(nvals) ;
383 pbivec_selected_x = cpl_bivector_get_x_data(bivec_selected);
384 pbivec_selected_y = cpl_bivector_get_y_data(bivec_selected);
385 nvals = 0 ;
386 for (j=0 ; j<cpl_bivector_get_size(bivec) ; j++) {
387 /* Loop on the selected ranges */
388 for (k=0 ; k<cpl_bivector_get_size(bivec_selec) ; k++) {
389 /* Check if the line is in one of the ranges */
390 if (pbivec_x[j] >= pbivec_selec_x[k] &&
391 pbivec_x[j] <= pbivec_selec_y[k]) {
392 pbivec_selected_x[nvals] = pbivec_x[j] ;
393 pbivec_selected_y[nvals] = pbivec_y[j] ;
394 nvals++ ;
395 /* Next line */
396 break ;
397 }
398 }
399 }
400 } else {
401 bivec_selected = NULL ;
402 }
403 cpl_bivector_delete(bivec_selec) ;
404 }
405
406 /* Save the selection */
407 if (bivec_selected != NULL) {
408 /* Allocate the data container */
409 nvals = cpl_bivector_get_size(bivec_selected) ;
410 tab = cpl_table_new(nvals) ;
411 cpl_table_wrap_double(tab, cpl_bivector_get_x_data(bivec_selected),
412 CR2RES_COL_WAVELENGTH) ;
413 cpl_table_wrap_double(tab, cpl_bivector_get_y_data(bivec_selected),
414 CR2RES_COL_EMISSION) ;
415
416 /* Save the table */
417 cpl_msg_info(__func__, "Saving the table with %d rows", nvals) ;
418
419 /* Format the setting */
420 setting = cpl_strdup(
421 cr2res_get_base_name(cr2res_get_root_name(selection_fname))) ;
422 out_file = cpl_sprintf("%s_%s.fits",
424 setting);
425 cr2res_format_setting2(setting) ;
426 if (cr2res_io_save_EMISSION_LINES(out_file, tab, parlist, frameset,
427 RECIPE_STRING, setting) == -1) {
428 cpl_msg_error(__func__, "Cannot write the table") ;
429 cpl_table_unwrap(tab, CR2RES_COL_WAVELENGTH) ;
430 cpl_table_unwrap(tab, CR2RES_COL_EMISSION) ;
431 cpl_table_delete(tab) ;
432 cpl_free(out_file);
433 if (selection_frames != NULL)
434 cpl_frameset_delete(selection_frames) ;
435 cpl_frameset_delete(lines_list_frames) ;
436 cpl_bivector_delete(bivec_selected) ;
437 cpl_bivector_delete(bivec) ;
438 cpl_free(setting) ;
439 cpl_msg_indent_less() ;
440 return -1 ;
441 }
442 cpl_free(setting) ;
443 cpl_free(out_file);
444 cpl_table_unwrap(tab, CR2RES_COL_WAVELENGTH) ;
445 cpl_table_unwrap(tab, CR2RES_COL_EMISSION) ;
446 cpl_table_delete(tab) ;
447 cpl_bivector_delete(bivec_selected) ;
448 }
449 }
450 cpl_msg_indent_less() ;
451 if (selection_frames != NULL) cpl_frameset_delete(selection_frames) ;
452 cpl_frameset_delete(lines_list_frames) ;
453 cpl_bivector_delete(bivec) ;
454 return 0 ;
455}
456
457
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_EMISSION_LINES(const char *filename, cpl_table *out_table, const cpl_parameterlist *parlist, cpl_frameset *set, const char *recipe, const char *setting_string)
Save EMISSION_LINES file.
Definition: cr2res_io.c:1435
int cr2res_format_setting2(char *setting_id)
Format the setting.
Definition: cr2res_utils.c:190
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.