CR2RE Pipeline Reference Manual 1.6.10
cr2res_idp.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#include <math.h>
30
31#include <cpl.h>
32
33#include "cr2res_idp.h"
34#include "cr2res_pfits.h"
35#include "cr2res_utils.h"
36#include "cr2res_dfs.h"
37#include "cr2res_io.h"
38#include "cr2res_qc.h"
39
40/*-----------------------------------------------------------------------------
41 Functions prototypes
42 -----------------------------------------------------------------------------*/
43
44static int cr2res_idp_copy_spec(
45 cpl_table * out,
46 const cpl_table * in,
47 cpl_size out_start_idx,
48 int det_nr,
49 int order,
50 int tracenb,
51 const char * setting,
52 int error_method,
53 int nab) ;
54static int cr2res_idp_copy_pol(
55 cpl_table * out,
56 const cpl_table * in,
57 cpl_size out_start_idx,
58 int det_nr,
59 int order,
60 const char * setting) ;
61
62/*-----------------------------------------------------------------------------
63 Utility functions
64 -----------------------------------------------------------------------------*/
65
66static void replace_spaces_with_underscores(char *str)
67{
68
69 for (int i = 0; str[i] != '\0'; i++) {
70 if (str[i] == ' ') {
71 str[i] = '_'; // Replace space with an underscore
72 }
73 }
74}
75
76/*----------------------------------------------------------------------------*/
80/*----------------------------------------------------------------------------*/
81
84/*----------------------------------------------------------------------------*/
97/*----------------------------------------------------------------------------*/
99 const char * filename,
100 cpl_frameset * allframes,
101 cpl_frameset * rawframes,
102 const cpl_parameterlist * parlist,
103 cpl_table ** tables,
104 cpl_propertylist * main_qc_plist,
105 cpl_propertylist ** ext_plist,
106 const char * procatg,
107 const char * recipe)
108{
109 cpl_table * idp_tab ;
110 const cpl_array * wlen_arr;
111 cpl_array * tmp_arr;
112 char * idp_filename ;
113 cpl_frame * out_frame ;
114 const cpl_frame * ref_frame ;
115 const char * ref_fname ;
116 cpl_propertylist * pri_head ;
117 cpl_propertylist * ext_head ;
118 double dit, exptime, texptime, mjd_start, mjd_end,
119 wmin, wmax, resol, spec_bin ;
120 const char * progid ;
121 const char * slitname ;
122 const char * setting ;
123 const char * poltype ;
124 int err, i, ndit, nframes, nraw, obid, nrows, ord ;
125 char * keyname;
126 char * tmp_string;
127 const cpl_parameter * param ;
128 int error_method = -1;
129 int nab;
130
131 const char *nod_catg = "OBS_NODDING_EXTRACT";
132
133 poltype = NULL;
134
135 cpl_msg_info(__func__, "Create IDPs for %s", filename) ;
136 /* Output file name */
137 idp_filename = cpl_sprintf("idp_%s", filename) ;
138
139 /* Create the Primary header */
140 ref_frame = cpl_frameset_get_position_const(rawframes, 0) ;
141 ref_fname = cpl_frame_get_filename(ref_frame) ;
142 pri_head = cpl_propertylist_load(ref_fname, 0);
143
144
145 cr2res_qc_dup_mtrlgy_key(rawframes, pri_head);
146
147 /* Create the first EXTENSION header */
148 ext_head = cpl_propertylist_new() ;
149
150 /* Read spectral setting because we need it to make the table*/
151 setting = cpl_propertylist_get_string(pri_head, "ESO INS WLEN ID");
152
153 /* Create the big table */
154 // NEED TO PASS ERRMETHOD AND NABCYCLES, ERRMETHOD IS IN THE PARLIST, NAB IS IN THE MAIN HEADER
155
156 if (strncmp(procatg, nod_catg, strlen(nod_catg)) == 0)
157 {
158
159 param = cpl_parameterlist_find_const(parlist,
160 "cr2res.cr2res_obs_nodding.error_method");
161 if (strcmp(cpl_parameter_get_string(param), "Horne") == 0)
162 error_method = CR2RES_EXTRACT_ERROR_HORNE;
163 else
164 error_method = CR2RES_EXTRACT_ERROR_POISSON;
165 //nab = cpl_frameset_count_tags(rawframes,CR2RES_OBS_NODDING_JITTER_RAW) / 2;
166 nab = 1;
167 if (strcmp(procatg, CR2RES_OBS_NODDING_EXTRACTC_IDP_PROCATG) == 0)
168 nab = nab * 2;
169 }
170 else
171 nab = 0;
172
173 idp_tab = cr2res_idp_create_table(tables, recipe, setting, error_method, nab);
174
175 /* Get wmin / wmax */
176 wlen_arr = cpl_table_get_array(idp_tab, CR2RES_IDP_COL_WAVE, 0);
177 nrows = cpl_array_get_size(wlen_arr);
178 wmin = cpl_array_get_double(wlen_arr, 0, &err) ;
179 wmax = cpl_array_get_double(wlen_arr, nrows-1, &err) ;
180
181 /* Prepare frame */
182 out_frame = cpl_frame_new();
183 cpl_frame_set_filename(out_frame, idp_filename);
184 cpl_frame_set_type(out_frame, CPL_FRAME_TYPE_ANY);
185 cpl_frame_set_group(out_frame, CPL_FRAME_GROUP_PRODUCT);
186 cpl_frame_set_level(out_frame, CPL_FRAME_LEVEL_FINAL);
187
188 // Set the PRO.CATG
189 cpl_frame_set_tag(out_frame, procatg);
190 cpl_propertylist_append_string(pri_head, CPL_DFS_PRO_CATG, procatg);
191
192 // TODO: split this type by recipe
193 cpl_propertylist_append_string(pri_head, CR2RES_HEADER_DRS_TYPE,
194 CR2RES_EXTRACT_1D_IDP_DRSTYPE) ;
195
196 if (!strcmp(recipe, "cr2res_obs_nodding")) {
197 cpl_propertylist_update_string(pri_head, "OBSTECH", "NODDING") ;
198 }
199 else if (!strcmp(recipe, "cr2res_obs_staring")) {
200 cpl_propertylist_update_string(pri_head, "OBSTECH", "STARING") ;
201 }
202 else if (!strcmp(recipe, "cr2res_obs_2d")) {
203 cpl_propertylist_update_string(pri_head, "OBSTECH", "GENERIC_OFFSET") ;
204 }
205 else if (!strcmp(recipe, "cr2res_obs_pol")) {
206 cpl_propertylist_update_string(pri_head, "OBSTECH", "POLARIMETRY") ;
207 }
208 cpl_propertylist_set_comment(pri_head, "OBSTECH",
209 "Technique of observation") ;
210
211 /* RADECSYS renamed to RADESYS */
212 if (cpl_propertylist_has(pri_head, "RADECSYS")) {
213 if (!cpl_propertylist_has(pri_head, "RADESYS")) {
214 const cpl_property *_property =
215 cpl_propertylist_get_property_const(pri_head, "RADECSYS");
216 cpl_property *property = cpl_property_duplicate(_property);
217 cpl_property_set_name(property, "RADESYS");
218 cpl_propertylist_append_property(pri_head, property);
219 cpl_property_delete(property);
220 }
221 cpl_propertylist_erase(pri_head, "RADECSYS");
222 }
223
224 cpl_dfs_setup_product_header(pri_head, out_frame, allframes,
225 parlist, recipe, VERSION, "PRO-1.16", ref_frame);
226
227 /* Add Keywords to primary header */
228 // ESO INS FILT1 NAME ---> FILTER
229 if (cpl_propertylist_has(pri_head, "ESO INS FILT1 NAME")) {
230 cpl_propertylist_update_string(pri_head, "FILTER",
231 cpl_propertylist_get_string(pri_head, "ESO INS FILT1 ID")) ;
232 cpl_propertylist_set_comment(pri_head, "FILTER",
233 "");
234 }
235
236 /* Collect data from main header */
237 dit = cr2res_pfits_get_dit(pri_head);
238 ndit = cr2res_pfits_get_ndit(pri_head) ;
239
240 nframes = cpl_frameset_get_size(rawframes);
241 nraw = 0;
242
243 cpl_errorstate tempes = cpl_errorstate_get();
244
245 for (i = 1; i <= nframes; i++) {
246 const char *fname;
247 keyname = cpl_sprintf("ESO PRO REC1 RAW%d NAME", i);
248 fname = cpl_propertylist_get_string(pri_head, keyname);
249 cpl_free(keyname);
250 if (fname != NULL){
251 keyname = cpl_sprintf("PROV%d", i);
252 cpl_propertylist_update_string(pri_head, keyname, fname);
253 cpl_free(keyname);
254 nraw++;
255 }
256 }
257
258 cpl_errorstate_set(tempes);
259
260 /* Add QC from the first Extension ext_plist[0] */
261 if (ext_plist[0] != NULL)
262 cpl_propertylist_copy_property_regexp(ext_head, ext_plist[0], "QC*", 0);
263
264 cpl_propertylist_update_int(pri_head, "NCOMBINE", nraw);
265 exptime = dit * ndit * nraw;
266 cpl_propertylist_update_double(pri_head, "EXPTIME", exptime);
267 cpl_propertylist_set_comment(pri_head, "EXPTIME",
268 "[s] Total integration time per pixel");
269
270 texptime = exptime ;
271 cpl_propertylist_update_double(pri_head, "TEXPTIME", texptime);
272 cpl_propertylist_set_comment(pri_head, "TEXPTIME",
273 "[s] Total integration time of exposures");
274
275 cr2res_idp_compute_mjd(rawframes, &mjd_start, &mjd_end) ;
276 if (mjd_start > 0.0) {
277 cpl_propertylist_update_double(pri_head, "MJD-OBS", mjd_start) ;
278 cpl_propertylist_set_comment(pri_head, "MJD-OBS",
279 "[d] Start of observations (days)");
280 }
281 if (mjd_end > 0.0) {
282 cpl_propertylist_update_double(pri_head, "MJD-END", mjd_end) ;
283 cpl_propertylist_set_comment(pri_head, "MJD-END",
284 "[d] End of observations (days)");
285 }
286
287 if (mjd_end > 0 && mjd_start > 0) {
288 cpl_propertylist_update_double(ext_head, "TELAPSE",
289 (mjd_end-mjd_start)*24*3600) ;
290 cpl_propertylist_set_comment(ext_head, "TELAPSE",
291 "Total elapsed time in seconds [s]") ;
292
293 cpl_propertylist_update_double(ext_head, "TMID",
294 (mjd_end+mjd_start)/2.0) ;
295 cpl_propertylist_set_comment(ext_head, "TMID",
296 "Exposure midpoint [MJD]") ;
297 }
298
299 progid = cr2res_pfits_get_progid(pri_head) ;
300 cpl_propertylist_update_string(pri_head, "PROG_ID", progid) ;
301 cpl_propertylist_set_comment(pri_head, "PROG_ID",
302 "ESO programme identification");
303
304 obid = cr2res_pfits_get_obs_id(pri_head) ;
305 cpl_propertylist_update_int(pri_head, "OBID1", obid);
306 cpl_propertylist_set_comment(pri_head, "OBID1", "Observation block ID");
307
308 if (!strcmp(recipe, "cr2res_obs_2d"))
309 cpl_propertylist_update_bool(pri_head, "EXT_OBJ", 1) ;
310 else
311 cpl_propertylist_update_bool(pri_head, "EXT_OBJ", 0) ;
312 cpl_propertylist_set_comment(pri_head, "EXT_OBJ",
313 "True for extended objects, cr2res_obs_2d was used") ;
314
315 cpl_propertylist_update_string(pri_head, "FLUXCAL", "UNCALIBRATED") ;
316 cpl_propertylist_set_comment(pri_head, "FLUXCAL",
317 "Type of flux calibration");
318
319 cpl_propertylist_update_int(pri_head, "FLUXERR", -1) ;
320 cpl_propertylist_set_comment(pri_head, "FLUXERR",
321 "Fractional uncertainty [%%] on the flux scale");
322
323 cpl_propertylist_update_bool(pri_head, "TOT_FLUX", 0) ;
324 cpl_propertylist_set_comment(pri_head, "TOT_FLUX",
325 "True if flux data represent the total source flux.");
326
327 /* Find blaze to decide if continuum normalized or not,
328 * but set false anyway for now, code left in case this
329 * changes again.*/
330 if ( cpl_frameset_find_const(allframes,
331 CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG) != NULL) {
332 cpl_propertylist_update_bool(pri_head, "CONTNORM", 0) ;
333 } else {
334 cpl_propertylist_update_bool(pri_head, "CONTNORM", 0) ;
335 }
336 cpl_propertylist_set_comment(pri_head, "CONTNORM",
337 "TRUE if the spectrum has been divided by the blaze") ;
338
339
340 cpl_propertylist_update_string(pri_head, "SPECSYS", "TOPOCENT") ;
341 cpl_propertylist_set_comment(pri_head, "SPECSYS",
342 "Frame of reference for spectral coordinates");
343
344 cpl_propertylist_update_string(pri_head, "PROCSOFT",
345 PACKAGE "/" PACKAGE_VERSION) ;
346 cpl_propertylist_set_comment(pri_head, "PROCSOFT", "ESO pipeline version");
347
348 cpl_propertylist_update_string(pri_head, "REFERENC", "") ;
349 cpl_propertylist_set_comment(pri_head, "REFERENC", "Reference publication");
350
351 cpl_propertylist_update_string(pri_head, "PRODCATG", "SCIENCE.SPECTRUM") ;
352 cpl_propertylist_set_comment(pri_head, "PRODCATG", "Data product category");
353
354
355 cpl_propertylist_update_double(pri_head, "WAVELMIN", wmin) ;
356 cpl_propertylist_set_comment(pri_head, "WAVELMIN",
357 "Minimum Wavelength [nm]") ;
358
359 cpl_propertylist_update_double(pri_head, "WAVELMAX", wmax) ;
360 cpl_propertylist_set_comment(pri_head, "WAVELMAX",
361 "Maximum Wavelength [nm]") ;
362
363 cpl_propertylist_update_double(pri_head, "SPEC_VAL", (wmax+wmin)/2.0) ;
364 cpl_propertylist_set_comment(pri_head, "SPEC_VAL",
365 "Characteristic spectral coordinate value [nm]") ;
366
367 cpl_propertylist_update_double(pri_head, "SPEC_BW", wmax-wmin) ;
368 cpl_propertylist_set_comment(pri_head, "SPEC_BW",
369 "Width of the spectrum [nm]") ;
370
371 cpl_propertylist_update_string(pri_head, "SPECSYS", "TOPOCENT") ;
372 cpl_propertylist_set_comment(pri_head, "SPECSYS",
373 "") ;
374
375 tmp_arr = cpl_array_new(cpl_array_get_size(wlen_arr)-1, CPL_TYPE_DOUBLE);
376 for (i=1; i<cpl_array_get_size(wlen_arr);i++){
377 cpl_array_set_double(tmp_arr, i-1,
378 cpl_array_get_double(wlen_arr,i, NULL)-
379 cpl_array_get_double(wlen_arr,i-1, NULL)
380 );
381 }
382 spec_bin = cpl_array_get_median(tmp_arr);
383 cpl_array_delete(tmp_arr);
384 cpl_propertylist_update_double(pri_head, "SPEC_BIN", spec_bin) ;
385 cpl_propertylist_set_comment(pri_head, "SPEC_BIN",
386 "Median spectral bin width [nm]") ;
387
388 slitname = cpl_propertylist_get_string(pri_head,"ESO INS SLIT1 ID");
389 if (!strcmp(slitname,"w_0.2")) {
390 cpl_propertylist_update_double(ext_head, "APERTURE", 5.5555555E-5) ;
391 cpl_propertylist_update_double(pri_head, "SPEC_RES", SPEC_RESOL_SLIT02);
392 }
393 else if (!strcmp(slitname,"w_0.4")) {
394
395 cpl_propertylist_update_double(ext_head, "APERTURE", 1.1111111E-4) ;
396 cpl_propertylist_update_double(pri_head, "SPEC_RES", SPEC_RESOL_SLIT04);
397 }
398 cpl_propertylist_set_comment(ext_head, "APERTURE",
399 "Slit width in deg") ;
400 cpl_propertylist_set_comment(pri_head, "SPEC_RES",
401 "Nominal resolving power for the given slit");
402
403 /* Get some keys from the extension headers*/
404 tmp_arr = cpl_array_new(12*CR2RES_NB_DETECTORS, CPL_TYPE_DOUBLE);
405 cpl_array * tmp_arr_sig = cpl_array_new(CR2RES_NB_DETECTORS, CPL_TYPE_DOUBLE);
406 for (i=0; i<CR2RES_NB_DETECTORS; i++){
407 resol = cpl_propertylist_get_double(ext_plist[i], CR2RES_HEADER_QC_SIGNAL);
408 if (resol==0){
409 cpl_error_reset();
410 } else {
411 cpl_array_set_double(tmp_arr_sig, i, resol);
412 }
413 for (ord=0; ord < 12; ord++){
414 keyname = cpl_sprintf(CR2RES_HEADER_QC_SNR, ord+1);
415 resol = cpl_propertylist_get_double(ext_plist[i], keyname);
416 if (resol==0){
417 cpl_error_reset();
418 } else {
419 /* FIXME: The error propagation is not correct. PIPE-11912
420 * Correction_factor = <Error_propagated_corrected> / <Error_propagated>
421 * where
422 * <Error_propagated_corrected> = [((a*<Error_propagated>)**2 + b**2)**0.5]
423 * where a=2.12 and b=26.1, as above.
424 */
425 double perr = cpl_array_get_double(tmp_arr_sig, i, NULL) / resol;
426 double corr = sqrt(pow(2.08*perr,2) + nab*25.2*25.2) / perr;
427 cpl_array_set_double(tmp_arr, ord + (i*12),resol/corr);
428 if(i==0){
429 cpl_propertylist_update_double(ext_head, keyname, resol/corr) ;
430 }
431 }
432 cpl_free(keyname);
433 }
434 }
435 cpl_propertylist_update_double(pri_head, "SNR",
436 cpl_array_get_median(tmp_arr)) ;
437 cpl_propertylist_set_comment(pri_head, "SNR",
438 "Median signal-to-noise in all detector-orders");
439 cpl_array_delete(tmp_arr);
440
441 if (!strcmp(recipe,"cr2res_obs_pol")) {
442 /* Find Pol.TYPE */
443 poltype = cr2res_pfits_get_poltype(pri_head);
444 tmp_string = cpl_sprintf("/I/%s/",poltype);
445 cpl_propertylist_update_string(pri_head, "STOKES", tmp_string);
446 cpl_free(tmp_string);
447 }
448
449 /* Remove the ASSON keywords */
450 cpl_propertylist_erase_regexp(pri_head, "ASSO*", 0);
451
452 /* Add QC from the main Extension */
453 if (main_qc_plist != NULL) {
454 cpl_propertylist_copy_property_regexp(pri_head, main_qc_plist, "QC*",
455 0);
456 }
457
458 /* Save the main header */
459 cpl_propertylist_save(pri_head, idp_filename, CPL_IO_CREATE);
460
461
462 /* Add Keywords to extension header */
463 cpl_propertylist_update_string(ext_head, "EXTNAME", "SPECTRUM") ;
464
465 cpl_propertylist_update_double(ext_head, "RA",
466 cpl_propertylist_get_double(pri_head, "RA"));
467 cpl_propertylist_set_comment(ext_head, "RA",
468 cpl_propertylist_get_comment(pri_head, "RA"));
469 cpl_propertylist_update_double(ext_head, "DEC",
470 cpl_propertylist_get_double(pri_head, "DEC"));
471 cpl_propertylist_set_comment(ext_head, "DEC",
472 cpl_propertylist_get_comment(pri_head, "DEC"));
473 cpl_propertylist_update_string(ext_head, "OBJECT",
474 cpl_propertylist_get_string(pri_head, "OBJECT"));
475 cpl_propertylist_set_comment(ext_head, "OBJECT",
476 cpl_propertylist_get_comment(pri_head, "OBJECT"));
477 tmp_string = cpl_sprintf("%s_%d_%s",
478 cpl_propertylist_get_string(pri_head, "OBJECT"),
479 cr2res_pfits_get_obs_id(pri_head),
480 cpl_propertylist_get_string(pri_head, "DATE-OBS"));
481
482 replace_spaces_with_underscores(tmp_string);
483
484 cpl_propertylist_update_string(ext_head, "TITLE", tmp_string);
485 cpl_free(tmp_string);
486 cpl_propertylist_set_comment(ext_head, "TITLE",
487 "IDP title");
488
489 cpl_propertylist_update_double(ext_head, "SPEC_VAL", (wmax+wmin)/2.0) ;
490 cpl_propertylist_set_comment(ext_head, "SPEC_VAL",
491 "Characteristic spectral coordinate value [nm]") ;
492 cpl_propertylist_update_double(ext_head, "SPEC_BW", wmax-wmin) ;
493 cpl_propertylist_set_comment(ext_head, "SPEC_BW",
494 "Width of the spectrum [nm]") ;
495
496 cpl_propertylist_update_string(ext_head, "VOPUB", "ESO/SAF") ;
497 cpl_propertylist_set_comment(ext_head, "VOPUB", "VO Publishing Authority") ;
498 cpl_propertylist_update_string(ext_head, "VOCLASS", "SPECTRUM V1.0") ;
499 cpl_propertylist_set_comment(ext_head, "VOCLASS",
500 "Data Model name and version") ;
501 cpl_propertylist_update_int(ext_head, "NELEM", nrows) ;
502 cpl_propertylist_set_comment(ext_head, "NELEM", "Length of the data array");
503
504 cpl_propertylist_update_string(ext_head, "TUTYP1",
505 "spec:Data.SpectralAxis.Value");
506 cpl_propertylist_update_string(ext_head, "TUCD1", "em.wl");
507 cpl_propertylist_update_double(ext_head, "TDMIN1", wmin);
508 cpl_propertylist_update_double(ext_head, "TDMAX1", wmax);
509
510 cpl_propertylist_update_string(ext_head, "TUTYP2",
511 "spec:Data.FluxAxis.Value");
512 cpl_propertylist_update_string(ext_head, "TUCD2",
513 "phot.flux.density;em.wl;stat.uncalib");
514
515 cpl_propertylist_update_string(ext_head, "TUTYP3",
516 "spec:Data.FluxAxis.Accuracy.StatError");
517 cpl_propertylist_update_string(ext_head, "TUCD3",
518 "stat.error;phot.flux.density;em.wl;stat.uncalib");
519
520 cpl_propertylist_update_string(ext_head, "TUTYP4",
521 "spec:Data.FluxAxis.Accuracy.QualityStatus");
522 cpl_propertylist_update_string(ext_head, "TUCD4",
523 "meta.code.qual");
524
525 cpl_propertylist_update_string(ext_head, "TUTYP5",
526 "");
527 cpl_propertylist_update_string(ext_head, "TUCD5",
528 "instr.order");
529
530 cpl_propertylist_update_string(ext_head, "TUTYP6",
531 "");
532 cpl_propertylist_update_string(ext_head, "TUCD6",
533 "meta.number;instr.det");
534
535 if (!strcmp(recipe,"cr2res_obs_pol")) { // POL
536 cpl_propertylist_update_string(ext_head, "TUTYP7", "");
537 tmp_string = cpl_sprintf("phot.count;phys.polarization.stokes.%s",
538 poltype);
539 cpl_propertylist_update_string(ext_head, "TUCD7", tmp_string);
540 cpl_free(tmp_string);
541
542 cpl_propertylist_update_string(ext_head, "TUTYP8", "");
543 tmp_string = cpl_sprintf("stat.error;phys.polarization.stokes.%s",
544 poltype);
545 cpl_propertylist_update_string(ext_head, "TUCD8", tmp_string);
546 cpl_free(tmp_string);
547 } else { // Nodding and staring
548 cpl_propertylist_update_string(ext_head, "TUTYP7",
549 "");
550 cpl_propertylist_update_string(ext_head, "TUCD7",
551 "pos.cartesian.x;instr.det");
552
553 cpl_propertylist_update_string(ext_head, "TUTYP8",
554 "");
555 cpl_propertylist_update_string(ext_head, "TUCD8",
556 "meta.number"); // TraceNb
557
558 }
559 /* For Y pixel coordinate in OBS_2D
560 TUCDi = pos.cartesian.y;instr.det
561
562 for pol
563 phot.count;phys.polarization.stokes.I
564 */
565
566 /* Remove keywords */
567 cpl_propertylist_erase(ext_head, "CRDER3");
568 cpl_propertylist_erase(ext_head, "CUNIT3");
569 cpl_propertylist_erase(ext_head, "BUNIT");
570 cpl_propertylist_erase(ext_head, "CTYPE1");
571 cpl_propertylist_erase(ext_head, "CUNIT2");
572 cpl_propertylist_erase(ext_head, "CSYER1");
573 cpl_propertylist_erase(ext_head, "CSYER2");
574 cpl_propertylist_erase(ext_head, "CDELT1");
575 cpl_propertylist_erase(ext_head, "CRPIX1");
576 cpl_propertylist_erase(ext_head, "CRVAL1");
577 cpl_propertylist_erase(ext_head, "CUNIT1");
578
579
580 /* Save the table */
581 cpl_table_save(idp_tab, NULL, ext_head, idp_filename, CPL_IO_EXTEND) ;
582
583 /* Insert it in the Frameset */
584 cpl_frameset_insert(allframes, out_frame);
585
586 /* Clean */
587 cpl_free(idp_filename) ;
588 cpl_table_delete(idp_tab) ;
589 cpl_propertylist_delete(pri_head) ;
590 cpl_propertylist_delete(ext_head) ;
591
592 return 0 ;
593}
594
595/*----------------------------------------------------------------------------*/
601/*----------------------------------------------------------------------------*/
603 cpl_table ** tables,
604 const char * recipe,
605 const char * setting,
606 int error_method,
607 int nab)
608{
609 cpl_table * idp_tab ;
610 cpl_table * tmp_tab ;
611 cpl_array * col_names ;
612 const char * col_name ;
613 char * col_kind ;
614 cpl_type col_type;
615 cpl_propertylist * sort_list ;
616 int order, trace_nb ;
617 cpl_size i, j, ntot, ncols, nrows, nb_selected ;
618
619 /* Check Inputs */
620 if (tables == NULL) return NULL ;
621
622 /* Count the Rows */
623 ntot = 0 ;
624 for (i=0 ; i<CR2RES_NB_DETECTORS ; i++) {
625 if (tables[i] != NULL) {
626 col_names = cpl_table_get_column_names(tables[i]);
627 ncols = cpl_table_get_ncol(tables[i]) ;
628 if (strcmp(recipe, "cr2res_obs_pol")) { // nodding and staring
629 for (j=0 ; j<ncols ; j++) {
630 col_name = cpl_array_get_string(col_names, j);
631 col_kind = cr2res_dfs_SPEC_colname_parse(col_name,
632 &order, &trace_nb) ;
633 if (col_kind != NULL &&
634 !strcmp(col_kind, CR2RES_COL_SPEC_SUFFIX)) {
635 /* Handle this extracted spectrum */
636 ntot += cpl_table_get_nrow(tables[i]) ;
637 }
638 if (col_kind != NULL) cpl_free(col_kind) ;
639 }
640 } else { // POL
641 for (j=0 ; j<ncols ; j++) {
642 col_name = cpl_array_get_string(col_names, j);
643 col_kind = cr2res_dfs_POL_colname_parse(col_name,
644 &order) ;
645 if (col_kind != NULL &&
646 !strcmp(col_kind, CR2RES_COL_POL_INTENS_SUFFIX)) {
647 /* Handle this extracted spectrum */
648 ntot += cpl_table_get_nrow(tables[i]) ;
649 }
650 if (col_kind != NULL) cpl_free(col_kind) ;
651 }
652 }
653 cpl_array_delete(col_names) ;
654 }
655 }
656 cpl_msg_info(__func__, "Found %lld total rows.", ntot);
657
658 /* Create the table */
659 tmp_tab = cpl_table_new(ntot) ;
660 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_WAVE, CPL_TYPE_DOUBLE);
661 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_FLUX, CPL_TYPE_DOUBLE);
662 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_ERR, CPL_TYPE_DOUBLE);
663 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_QUAL, CPL_TYPE_INT);
664 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_ORDER, CPL_TYPE_INT);
665 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_DETEC, CPL_TYPE_INT);
666 if (strcmp(recipe, "cr2res_obs_pol")) { // nodding and staring
667 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_XPOS, CPL_TYPE_INT);
668 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_TRACE, CPL_TYPE_INT);
669 } else {
670 cpl_table_new_column(tmp_tab, CR2RES_IDP_COL_STOKES, CPL_TYPE_DOUBLE);
671 cpl_table_new_column(tmp_tab,
672 CR2RES_IDP_COL_STOKESERR, CPL_TYPE_DOUBLE);
673
674 }
675
676 /* Fill the table */
677 ntot = 0 ;
678 for (i=0 ; i<CR2RES_NB_DETECTORS ; i++) {
679 if (tables[i] != NULL) {
680 col_names = cpl_table_get_column_names(tables[i]);
681 ncols = cpl_table_get_ncol(tables[i]) ;
682 if (strcmp(recipe, "cr2res_obs_pol")) { // nodding and staring
683 for (j=0 ; j<ncols ; j++) {
684 col_name = cpl_array_get_string(col_names, j);
685 col_kind = cr2res_dfs_SPEC_colname_parse(col_name,
686 &order, &trace_nb) ;
687 if (col_kind != NULL &&
688 !strcmp(col_kind, CR2RES_COL_SPEC_SUFFIX)) {
689 /* Handle this extracted spectrum */
690 cr2res_idp_copy_spec(tmp_tab, tables[i], ntot, i+1,
691 order, trace_nb, setting, error_method, nab); ;
692 ntot += cpl_table_get_nrow(tables[i]) ;
693 }
694 if (col_kind != NULL) cpl_free(col_kind) ;
695 }
696 } else {
697 for (j=0 ; j<ncols ; j++) {
698 col_name = cpl_array_get_string(col_names, j);
699 col_kind = cr2res_dfs_POL_colname_parse(col_name, &order);
700 if (col_kind != NULL &&
701 !strcmp(col_kind, CR2RES_COL_POL_INTENS_SUFFIX)) {
702 cr2res_idp_copy_pol(tmp_tab, tables[i], ntot, i + 1,
703 order, setting);
704 ntot += cpl_table_get_nrow(tables[i]) ;
705 }
706 if (col_kind != NULL) cpl_free(col_kind) ;
707 }
708 }
709 cpl_array_delete(col_names) ;
710 }
711 }
712 /*Remove any rows with NaN as the wavelength value*/
713 cpl_table_unselect_all(tmp_tab) ;
714 int ii;
715 for (ii = 0; ii < ntot; ii++) {
716 double wave;
717 wave = cpl_table_get_double(tmp_tab,CR2RES_IDP_COL_WAVE,ii, NULL) ;
718 if (isnan(wave)) {
719 cpl_table_select_row(tmp_tab, ii) ;
720 }
721 }
722 cpl_table_erase_selected(tmp_tab) ;
723
724
725 /* Sort by the wavelengths */
726 sort_list = cpl_propertylist_new() ;
727 cpl_propertylist_append_bool(sort_list, CR2RES_IDP_COL_WAVE, 0) ;
728 //cpl_propertylist_append_bool(sort_list, CR2RES_IDP_COL_XPOS, 1) ;
729 cpl_table_sort(tmp_tab, sort_list) ;
730 cpl_propertylist_delete(sort_list) ;
731
732 cpl_table_unselect_all(tmp_tab) ;
733 /*Find first valid row*/
734 int flag = 0;
735 for (ii = 0; ii < ntot; ii++) {
736 cpl_table_get_double(tmp_tab,CR2RES_IDP_COL_WAVE,ii, &flag) ;
737 if(!flag) break;
738 cpl_table_select_row(tmp_tab, ii);
739 }
740
741 /* Identify close values */
742 for (i = ii+1; i < ntot; i++) {
743 double cur_val, pre_val;
744 flag = 0;
745 pre_val = cpl_table_get_double(tmp_tab,CR2RES_IDP_COL_WAVE,i-1, NULL);
746 cur_val = cpl_table_get_double(tmp_tab,CR2RES_IDP_COL_WAVE,i, &flag) ;
747 if (fabs(pre_val-cur_val) < 1e-3 || flag) {
748 cpl_table_select_row(tmp_tab, i) ;
749 }
750 }
751
752 nb_selected = cpl_table_count_selected(tmp_tab) ;
753 if (nb_selected > 0) {
754 cpl_msg_info(__func__,
755 "IDP Creation - Double defined WLs : %"CPL_SIZE_FORMAT,
756 nb_selected) ;
757 }
758 cpl_table_erase_selected(tmp_tab) ;
759
760 /* Transform table to single row with arrays */
761 col_names = cpl_table_get_column_names(tmp_tab);
762 ncols = cpl_table_get_ncol(tmp_tab);
763 nrows = cpl_table_get_nrow(tmp_tab);
764 idp_tab = cpl_table_new(1);
765 for (j = 0; j < ncols; j++) {
766 cpl_array *tmp_arr;
767 col_name = cpl_array_get_string(col_names, j);
768 cpl_msg_debug(__func__,"colname: %s", col_name);
769 col_type = cpl_table_get_column_type(tmp_tab, col_name);
770 tmp_arr = cpl_array_new(nrows, col_type);
771 if (col_type==CPL_TYPE_DOUBLE){
772 cpl_array_copy_data_double(tmp_arr,
773 cpl_table_get_data_double_const(tmp_tab, col_name));
774 } else if (col_type==CPL_TYPE_INT){
775 cpl_array_copy_data_int(tmp_arr,
776 cpl_table_get_data_int_const(tmp_tab, col_name));
777 } else {continue;}
778 cpl_table_new_column_array(idp_tab, col_name, col_type, nrows);
779 cpl_table_set_array(idp_tab, col_name, 0, tmp_arr);
780 cpl_array_delete(tmp_arr);
781 }
782 cpl_array_delete(col_names) ;
783 cpl_table_delete(tmp_tab);
784
785
786 /* Set the units */
787 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_WAVE, "nm") ;
788 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_DETEC, " ") ;
789 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_ORDER, " ") ;
790 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_QUAL, " ") ;
791 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_FLUX, "adu") ;
792 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_ERR, "adu") ;
793 if (strcmp(recipe, "cr2res_obs_pol")) { // nodding and staring
794 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_TRACE, " ") ;
795 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_XPOS, "pixel") ;
796 } else {
797 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_STOKES, " ") ;
798 cpl_table_set_column_unit(idp_tab, CR2RES_IDP_COL_STOKESERR, " ") ;
799 }
800
801 return idp_tab ;
802
803}
804
805/*----------------------------------------------------------------------------*/
811/*----------------------------------------------------------------------------*/
813 cpl_frameset * fset,
814 double * mjd_start,
815 double * mjd_end)
816{
817 cpl_frame * cur_frame ;
818 const char * cur_fname ;
819 cpl_propertylist * plist ;
820 double mjd_end_cur, mjd_end_max, mjd_obs, dit,
821 mjd_start_cur, mjd_start_min ;
822 int i, nframes, ndit ;
823
824 /* Initialise */
825 mjd_end_max = -1.0 ;
826 mjd_start_min = 1e10 ;
827 nframes = cpl_frameset_get_size(fset) ;
828
829 cpl_errorstate tempes = cpl_errorstate_get();
830 cpl_error_reset();
831
832 /* Loop */
833 for (int ifr = 0; ifr <= 1; ifr++) {
834 for (i = 0; i < nframes; i++) {
835 cur_frame = cpl_frameset_get_position(fset, i);
836 if (ifr == 0 &&
837 cpl_frame_get_group(cur_frame) != CPL_FRAME_GROUP_RAW)
838 continue;
839 cur_fname = cpl_frame_get_filename(cur_frame);
840
841 /* Get header infos */
842 plist = cpl_propertylist_load(cur_fname, 0);
843 dit = cr2res_pfits_get_dit(plist);
844 ndit = cr2res_pfits_get_ndit(plist);
845 mjd_obs = cr2res_pfits_get_mjd_obs(plist);
846 if (cpl_error_get_code() == CPL_ERROR_NONE) {
847 /* Compute current value */
848 mjd_start_cur = mjd_obs;
849 mjd_end_cur = mjd_obs + (dit * ndit / (24 * 60 * 60));
850 }
851 else {
852 mjd_end_cur = -2.0;
853 mjd_start_cur = 1e11;
854 cpl_error_reset();
855 }
856 /* Update max */
857 if (mjd_end_cur > mjd_end_max)
858 mjd_end_max = mjd_end_cur;
859 if (mjd_start_cur < mjd_start_min) {
860 mjd_start_min = mjd_start_cur;
861 }
862 cpl_propertylist_delete(plist);
863 }
864 if (mjd_start_min != 1e10)
865 break;
866 }
867
868 cpl_errorstate_set(tempes);
869
870 if (mjd_start_min < 1e9) {
871 *mjd_start = mjd_start_min ;
872 } else {
873 *mjd_start = -1.0 ;
874 }
875 if (mjd_end_max > 0.0) *mjd_end = mjd_end_max ;
876 else *mjd_end = -1.0 ;
877 return 0 ;
878}
879
882/*----------------------------------------------------------------------------*/
894/*----------------------------------------------------------------------------*/
895static int cr2res_idp_copy_spec(
896 cpl_table * out,
897 const cpl_table * in,
898 cpl_size out_start_idx,
899 int det_nr,
900 int order,
901 int tracenb,
902 const char * setting,
903 int error_method,
904 int nab)
905{
906 char * spec_name ;
907 char * wave_name ;
908 char * err_name ;
909 const double * pspec ;
910 const double * pwave ;
911 const double * perr ;
912 cpl_size in_size, out_size, i, edgepix ;
913
914 /* Check entries */
915 if (out == NULL || in == NULL) return -1 ;
916 in_size = cpl_table_get_nrow(in) ;
917 out_size = cpl_table_get_nrow(out) ;
918
919 /* Get the Spectrum */
920 spec_name = cr2res_dfs_SPEC_colname(order, tracenb) ;
921 if ((pspec = cpl_table_get_data_double_const(in, spec_name)) == NULL) {
922 cpl_msg_error(__func__, "Cannot find the spectrum") ;
923 cpl_free(spec_name) ;
924 return -1 ;
925 }
926 cpl_free(spec_name) ;
927
928 /* Get the Wavelength */
929 wave_name = cr2res_dfs_WAVELENGTH_colname(order, tracenb) ;
930 if ((pwave = cpl_table_get_data_double_const(in, wave_name)) == NULL) {
931 cpl_msg_error(__func__, "Cannot find the wavelength") ;
932 cpl_free(wave_name) ;
933 return -1 ;
934 }
935 cpl_free(wave_name) ;
936
937 /* Get the Spectrum Error */
938 err_name = cr2res_dfs_SPEC_ERR_colname(order, tracenb) ;
939 if ((perr = cpl_table_get_data_double_const(in, err_name)) == NULL) {
940 cpl_msg_error(__func__, "Cannot find the spectrum error") ;
941 cpl_free(err_name) ;
942 return -1 ;
943 }
944 cpl_free(err_name) ;
945
946 /* copy line by line */
947 for (i=0 ; i<in_size ; i++) {
948 if (out_start_idx + i <out_size) {
949 //if (!isnan(pwave[i]))
950 cpl_table_set_double(out, CR2RES_IDP_COL_WAVE,
951 out_start_idx + i, pwave[i]) ;
952 //if (!isnan(pspec[i]))
953 cpl_table_set_double(out, CR2RES_IDP_COL_FLUX,
954 out_start_idx + i, pspec[i]) ;
955 //if (!isnan(perr[i])){
956 /* FIXME: PIPE-11912 - Error propagation is not correct.
957 * Scale up the propagated errors (column name ERR) according to
958 * the following empirically derived equation:
959 * Error_propagated_corrected = ((a*Error_propagated)^2 + b^2)^0.5
960 * where a=2.12 and b=26.1.
961 * For the record, these factors were measured with uncertainties
962 * of 0.02 and 1.2, respectively.
963 * NEED TO ADD HIERARCH ESO SEQ NABCYCLES
964 */
965 if (error_method == CR2RES_EXTRACT_ERROR_POISSON && nab > 0 && perr[i] != 0.0) {
966 double err_corrected = sqrt(pow(2.08*perr[i],2) + nab*pow(25.2,2));
967 cpl_table_set_double(out, CR2RES_IDP_COL_ERR,
968 out_start_idx + i, err_corrected) ;
969 }
970 else{
971 cpl_table_set_double(out, CR2RES_IDP_COL_ERR,
972 out_start_idx + i, perr[i]) ;
973 }
974
975 if (i<5 || (i>=CR2RES_DETECTOR_SIZE-5)) edgepix = 2;
976 else edgepix=0;
977 cpl_table_set_int(out, CR2RES_IDP_COL_QUAL, out_start_idx + i,
978 edgepix + cr2res_wl_is_ghost(setting, pwave[i]));
979 cpl_table_set_int(out, CR2RES_IDP_COL_XPOS, out_start_idx + i,
980 i+1) ;
981 cpl_table_set_int(out, CR2RES_IDP_COL_DETEC, out_start_idx + i,
982 det_nr) ;
983 cpl_table_set_int(out, CR2RES_IDP_COL_ORDER, out_start_idx + i,
984 order) ;
985 cpl_table_set_int(out, CR2RES_IDP_COL_TRACE, out_start_idx + i,
986 tracenb) ;
987 }
988 }
989 return 0 ;
990}
991
992/*----------------------------------------------------------------------------*/
1003/*----------------------------------------------------------------------------*/
1004static int cr2res_idp_copy_pol(
1005 cpl_table * out,
1006 const cpl_table * in,
1007 cpl_size out_start_idx,
1008 int det_nr,
1009 int order,
1010 const char * setting)
1011{
1012 char * spec_name ;
1013 char * wave_name ;
1014 char * err_name ;
1015 char * stokes_name ;
1016 char * stokeserr_name ;
1017 const double * pspec ;
1018 const double * pwave ;
1019 const double * perr ;
1020 const double * pstokes ;
1021 const double * pstokeserr ;
1022 cpl_size in_size, out_size, i, edgepix ;
1023
1024 /* Check entries */
1025 if (out == NULL || in == NULL) return -1 ;
1026 in_size = cpl_table_get_nrow(in) ;
1027 out_size = cpl_table_get_nrow(out) ;
1028
1029 /* Get the Spectrum */
1030 spec_name = cr2res_dfs_POL_INTENS_colname(order) ;
1031 if ((pspec = cpl_table_get_data_double_const(in, spec_name)) == NULL) {
1032 cpl_msg_error(__func__, "Cannot find the intensity spec") ;
1033 cpl_free(spec_name) ;
1034 return -1 ;
1035 }
1036 cpl_free(spec_name) ;
1037
1038 /* Get the Wavelength */
1039 wave_name = cr2res_dfs_POL_WAVELENGTH_colname(order) ;
1040 if ((pwave = cpl_table_get_data_double_const(in, wave_name)) == NULL) {
1041 cpl_msg_error(__func__, "Cannot find the wavelength") ;
1042 cpl_free(wave_name) ;
1043 return -1 ;
1044 }
1045 cpl_free(wave_name) ;
1046
1047 /* Get the Spectrum Error */
1048 err_name = cr2res_dfs_POL_INTENS_ERROR_colname(order) ;
1049 if ((perr = cpl_table_get_data_double_const(in, err_name)) == NULL) {
1050 cpl_msg_error(__func__, "Cannot find the intensity error") ;
1051 cpl_free(err_name) ;
1052 return -1 ;
1053 }
1054 cpl_free(err_name) ;
1055
1056 /* Get the Stokes */
1057 stokes_name = cr2res_dfs_POL_STOKES_colname(order) ;
1058 if ((pstokes = cpl_table_get_data_double_const(in, stokes_name)) == NULL) {
1059 cpl_msg_error(__func__, "Cannot find the Stokes spectrum") ;
1060 cpl_free(stokes_name) ;
1061 return -1 ;
1062 }
1063 cpl_free(stokes_name) ;
1064
1065 /* Get the stokes err */
1066 stokeserr_name = cr2res_dfs_POL_STOKES_ERROR_colname(order) ;
1067 if ((pstokeserr = cpl_table_get_data_double_const(in, stokeserr_name)) == NULL) {
1068 cpl_msg_error(__func__, "Cannot find the Stokes error") ;
1069 cpl_free(stokeserr_name) ;
1070 return -1 ;
1071 }
1072 cpl_free(stokeserr_name) ;
1073
1074 /* copy line by line */
1075 for (i=0 ; i<in_size ; i++) {
1076 if (out_start_idx + i <out_size) {
1077 if (!isnan(pwave[i]))
1078 cpl_table_set_double(out, CR2RES_IDP_COL_WAVE,
1079 out_start_idx + i, pwave[i]) ;
1080 if (!isnan(pspec[i]))
1081 cpl_table_set_double(out, CR2RES_IDP_COL_FLUX,
1082 out_start_idx + i, pspec[i]) ;
1083 if (!isnan(perr[i]))
1084 cpl_table_set_double(out, CR2RES_IDP_COL_ERR,
1085 out_start_idx + i, perr[i]) ;
1086 if (!isnan(pstokes[i]))
1087 cpl_table_set_double(out, CR2RES_IDP_COL_STOKES,
1088 out_start_idx + i, pstokes[i]) ;
1089 if (!isnan(pstokeserr[i]))
1090 cpl_table_set_double(out, CR2RES_IDP_COL_STOKESERR,
1091 out_start_idx + i, pstokeserr[i]) ;
1092
1093 if (i<5 || (i>=CR2RES_DETECTOR_SIZE-5)) edgepix = 2;
1094 else edgepix=0;
1095 cpl_table_set_int(out, CR2RES_IDP_COL_QUAL, out_start_idx + i,
1096 edgepix + cr2res_wl_is_ghost(setting, pwave[i]));
1097 cpl_table_set_int(out, CR2RES_IDP_COL_XPOS, out_start_idx + i,
1098 i+1) ;
1099 cpl_table_set_int(out, CR2RES_IDP_COL_DETEC, out_start_idx + i,
1100 det_nr) ;
1101 cpl_table_set_int(out, CR2RES_IDP_COL_ORDER, out_start_idx + i,
1102 order) ;
1103 }
1104 }
1105 return 0 ;
1106}
1107
1108/*---------------------------------------------------------------------------*/
1115/*---------------------------------------------------------------------------*/
1116int cr2res_wl_is_ghost(const char * setting, double wl){
1117 cpl_vector * start;
1118 cpl_vector * end;
1119 cpl_bivector * ghosts;
1120 cpl_size nghosts;
1121 int i;
1122
1123 ghosts = cr2res_get_ghosts(setting);
1124 if (ghosts == NULL)
1125 return 0;
1126 start = cpl_bivector_get_x(ghosts);
1127 end = cpl_bivector_get_y(ghosts);
1128 nghosts = cpl_vector_get_size(start);
1129
1130 for (i=0; i<nghosts; i++){
1131 if ( wl > cpl_vector_get(start,i) && wl < cpl_vector_get(end,i)) {
1132 cpl_bivector_delete(ghosts);
1133 return 1;
1134 }
1135 }
1136 cpl_bivector_delete(ghosts);
1137 return 0;
1138}
1139/*---------------------------------------------------------------------------*/
1145/*---------------------------------------------------------------------------*/
1146cpl_bivector * cr2res_get_ghosts(const char * setting){
1147 cpl_vector * start;
1148 cpl_vector * end;
1149 int nghost;
1150
1151 if (!strcmp(setting,"Y1029")) {
1152 nghost = 9;
1153 start = cpl_vector_new(nghost);
1154 end = cpl_vector_new(nghost);
1155 cpl_vector_set(start, 0, 955.51); cpl_vector_set(end, 0, 956.59);
1156 cpl_vector_set(start, 1, 972.36); cpl_vector_set(end, 1, 973.46);
1157 cpl_vector_set(start, 2, 990.18); cpl_vector_set(end, 2, 990.81);
1158 cpl_vector_set(start, 3, 1008.18); cpl_vector_set(end, 3, 1008.82);
1159 cpl_vector_set(start, 4, 1026.81); cpl_vector_set(end, 4, 1027.47);
1160 cpl_vector_set(start, 5, 1046.15); cpl_vector_set(end, 5, 1046.90);
1161 cpl_vector_set(start, 6, 1066.29); cpl_vector_set(end, 6, 1067.05);
1162 cpl_vector_set(start, 7, 1087.15); cpl_vector_set(end, 7, 1087.93);
1163 cpl_vector_set(start, 8, 1108.83); cpl_vector_set(end, 8, 1109.63);
1164 } else if (!strcmp(setting,"Y1028")) {
1165 nghost = 9;
1166 start = cpl_vector_new(nghost);
1167 end = cpl_vector_new(nghost);
1168 cpl_vector_set(start, 0, 954.15); cpl_vector_set(end, 0, 955.20);
1169 cpl_vector_set(start, 1, 971.25); cpl_vector_set(end, 1, 971.87);
1170 cpl_vector_set(start, 2, 988.65); cpl_vector_set(end, 2, 989.23);
1171 cpl_vector_set(start, 3, 1006.61); cpl_vector_set(end, 3, 1007.24);
1172 cpl_vector_set(start, 4, 1025.23); cpl_vector_set(end, 4, 1025.90);
1173 cpl_vector_set(start, 5, 1044.60); cpl_vector_set(end, 5, 1045.25);
1174 cpl_vector_set(start, 6, 1064.67); cpl_vector_set(end, 6, 1065.33);
1175 cpl_vector_set(start, 7, 1085.46); cpl_vector_set(end, 7, 1086.18);
1176 cpl_vector_set(start, 8, 1107.18); cpl_vector_set(end, 8, 1107.91);
1177 } else if (!strcmp(setting,"J1226")) {
1178 nghost = 9;
1179 start = cpl_vector_new(nghost);
1180 end = cpl_vector_new(nghost);
1181 cpl_vector_set(start, 0, 1119.44); cpl_vector_set(end, 0, 1020.33);
1182 cpl_vector_set(start, 1, 1142.78); cpl_vector_set(end, 1, 1143.76);
1183 cpl_vector_set(start, 2, 1167.12); cpl_vector_set(end, 2, 1168.08);
1184 cpl_vector_set(start, 3, 1192.52); cpl_vector_set(end, 3, 1193.49);
1185 cpl_vector_set(start, 4, 1219.01); cpl_vector_set(end, 4, 1220.04);
1186 cpl_vector_set(start, 5, 1246.71); cpl_vector_set(end, 5, 1247.76);
1187 cpl_vector_set(start, 6, 1275.70); cpl_vector_set(end, 6, 1276.80);
1188 cpl_vector_set(start, 7, 1306.05); cpl_vector_set(end, 7, 1307.15);
1189 cpl_vector_set(start, 8, 1337.98); cpl_vector_set(end, 8, 1338.94);
1190 } else if (!strcmp(setting,"J1228")) {
1191 nghost = 9;
1192 start = cpl_vector_new(nghost);
1193 end = cpl_vector_new(nghost);
1194 cpl_vector_set(start, 0, 1121.21); cpl_vector_set(end, 0, 1122.12);
1195 cpl_vector_set(start, 1, 1144.57); cpl_vector_set(end, 1, 1145.53);
1196 cpl_vector_set(start, 2, 1168.98); cpl_vector_set(end, 2, 1169.91);
1197 cpl_vector_set(start, 3, 1194.37); cpl_vector_set(end, 3, 1195.38);
1198 cpl_vector_set(start, 4, 1220.92); cpl_vector_set(end, 4, 1221.95);
1199 cpl_vector_set(start, 5, 1248.68); cpl_vector_set(end, 5, 1249.72);
1200 cpl_vector_set(start, 6, 1277.71); cpl_vector_set(end, 6, 1278.83);
1201 cpl_vector_set(start, 7, 1308.12); cpl_vector_set(end, 7, 1309.17);
1202 cpl_vector_set(start, 8, 1339.95); cpl_vector_set(end, 8, 1341.03);
1203 } else if (!strcmp(setting,"J1232")) {
1204 nghost = 9;
1205 start = cpl_vector_new(nghost);
1206 end = cpl_vector_new(nghost);
1207 cpl_vector_set(start, 0, 1124.71); cpl_vector_set(end, 0, 1125.60);
1208 cpl_vector_set(start, 1, 1148.15); cpl_vector_set(end, 1, 1149.46);
1209 cpl_vector_set(start, 2, 1172.62); cpl_vector_set(end, 2, 1173.55);
1210 cpl_vector_set(start, 3, 1198.13); cpl_vector_set(end, 3, 1199.08);
1211 cpl_vector_set(start, 4, 1224.77); cpl_vector_set(end, 4, 1225.74);
1212 cpl_vector_set(start, 5, 1252.56); cpl_vector_set(end, 5, 1253.59);
1213 cpl_vector_set(start, 6, 1281.74); cpl_vector_set(end, 6, 1282.74);
1214 cpl_vector_set(start, 7, 1312.19); cpl_vector_set(end, 7, 1313.26);
1215 cpl_vector_set(start, 8, 1344.15); cpl_vector_set(end, 8, 1345.23);
1216 } else if (!strcmp(setting,"H1559")) {
1217 nghost = 2;
1218 start = cpl_vector_new(nghost);
1219 end = cpl_vector_new(nghost);
1220 cpl_vector_set(start, 0, 1682.63); cpl_vector_set(end, 0, 1682.97);
1221 cpl_vector_set(start, 1, 1735.50); cpl_vector_set(end, 1, 1737.42);
1222 } else if (!strcmp(setting,"H1567")) {
1223 nghost = 1;
1224 start = cpl_vector_new(nghost);
1225 end = cpl_vector_new(nghost);
1226 cpl_vector_set(start, 0, 1744.20); cpl_vector_set(end, 0, 1745.84);
1227 } else if (!strcmp(setting,"H1575")) {
1228 nghost = 1;
1229 start = cpl_vector_new(nghost);
1230 end = cpl_vector_new(nghost);
1231 cpl_vector_set(start, 0, 1753.20); cpl_vector_set(end, 0, 1754.28);
1232 } else {
1233 return NULL;
1234 }
1235
1236 return cpl_bivector_wrap_vectors(start,end);
1237}
char * cr2res_dfs_POL_colname_parse(const char *colname, int *order_idx)
Parse a column name ORDER_TYPE format.
Definition: cr2res_dfs.c:531
char * cr2res_dfs_POL_STOKES_ERROR_colname(int order_idx)
Get the POL_STOKES_ERROR column name for a given order.
Definition: cr2res_dfs.c:241
char * cr2res_dfs_SPEC_ERR_colname(int order_idx, int trace)
Get the ERR column name for a given order/trace.
Definition: cr2res_dfs.c:414
char * cr2res_dfs_POL_INTENS_ERROR_colname(int order_idx)
Get the POL_INTENS_ERROR column name for a given order.
Definition: cr2res_dfs.c:306
char * cr2res_dfs_WAVELENGTH_colname(int order_idx, int trace)
Get the WAVELENGTH column name for a given order/trace.
Definition: cr2res_dfs.c:396
char * cr2res_dfs_POL_STOKES_colname(int order_idx)
Get the POL_STOKES column name for a given order.
Definition: cr2res_dfs.c:225
char * cr2res_dfs_SPEC_colname_parse(const char *colname, int *order_idx, int *trace)
Parse a column name ORDER_TRACE_TYPE format.
Definition: cr2res_dfs.c:505
char * cr2res_dfs_POL_INTENS_colname(int order_idx)
Get the POL_INTENS column name for a given order.
Definition: cr2res_dfs.c:290
char * cr2res_dfs_SPEC_colname(int order_idx, int trace)
Get the SPEC column name for a given order/trace.
Definition: cr2res_dfs.c:378
char * cr2res_dfs_POL_WAVELENGTH_colname(int order_idx)
Get the POL_WAVELENGTH column name for a given order.
Definition: cr2res_dfs.c:209
int cr2res_idp_save(const char *filename, cpl_frameset *allframes, cpl_frameset *rawframes, const cpl_parameterlist *parlist, cpl_table **tables, cpl_propertylist *main_qc_plist, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save an IDP file.
Definition: cr2res_idp.c:98
int cr2res_idp_compute_mjd(cpl_frameset *fset, double *mjd_start, double *mjd_end)
Compute mjd start and end.
Definition: cr2res_idp.c:812
cpl_table * cr2res_idp_create_table(cpl_table **tables, const char *recipe, const char *setting, int error_method, int nab)
Convert EXTRACT_1D tables into IDP table.
Definition: cr2res_idp.c:602
const char * cr2res_pfits_get_progid(const cpl_propertylist *plist)
find out the PROG ID
Definition: cr2res_pfits.c:124
double cr2res_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
Definition: cr2res_pfits.c:199
double cr2res_pfits_get_mjd_obs(const cpl_propertylist *plist)
find out the MJD-OBS value
Definition: cr2res_pfits.c:217
int cr2res_pfits_get_ndit(const cpl_propertylist *plist)
find out the NDIT value
Definition: cr2res_pfits.c:363
const char * cr2res_pfits_get_poltype(const cpl_propertylist *plist)
find out the POL TYPE value
Definition: cr2res_pfits.c:241
int cr2res_pfits_get_obs_id(const cpl_propertylist *plist)
find out the OBS ID value
Definition: cr2res_pfits.c:375