ERIS Pipeline Reference Manual
1.8.15
eris
skycorr
sc_readspec.c
Go to the documentation of this file.
1
/*
2
* This file is part of the SKYCORR software package.
3
* Copyright (C) 2009-2013 European Southern Observatory
4
*
5
* This programme 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 programme 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 programme. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
37
/*****************************************************************************
38
* INCLUDES *
39
****************************************************************************/
40
41
#include <
sc_readspec.h
>
42
43
44
/*****************************************************************************
45
* CODE *
46
****************************************************************************/
47
48
//cpl_error_code sc_readspec(cpl_table *spec, cpl_parameterlist *parlist)
49
//{
50
// /*!
51
// * \callgraph
52
// *
53
// * Reads a science or sky spectrum (type taken from the general parameter
54
// * list) in ASCII, FITS table, or FITS image format and puts the read data
55
// * in a CPL table consisting of the columns "lambda", "flux", and
56
// * "weight". Only 1D data are supported. The required observing parameters
57
// * are read from the FITS header (only sky spectrum) or the parameter
58
// * list.
59
// *
60
// * \b INPUT:
61
// * \param spec empty CPL table
62
// * \param parlist general CPL parameter list
63
// *
64
// * \b OUTPUT:
65
// * \param spec CPL table with wavelengths, fluxes, and weights
66
// * \param parlist general CPL parameter list with FITS header values
67
// *
68
// * \b ERRORS:
69
// * - Invalid object value(s)
70
// * - Error in subroutine
71
// * - No data
72
// * - see subroutines
73
// */
74
75
// cpl_error_code status = CPL_ERROR_NONE;
76
// cpl_parameter *p;
77
// sctarr tabdat;
78
// char spectype[4], basedir[SC_MAXLEN], outdir[SC_MAXLEN];
79
// char outname[SC_MAXLEN], outfilename[3*SC_MAXLEN];
80
// char errtxt[SC_MAXLEN];
81
// double meanlam = 0.;
82
83
// /* Create output table columns */
84
// cpl_table_set_size(spec, 0);
85
// cpl_table_new_column(spec, "lambda", CPL_TYPE_DOUBLE);
86
// cpl_table_new_column(spec, "flux", CPL_TYPE_DOUBLE);
87
// cpl_table_new_column(spec, "dflux", CPL_TYPE_DOUBLE);
88
// cpl_table_new_column(spec, "mask", CPL_TYPE_INT);
89
// cpl_table_new_column(spec, "weight", CPL_TYPE_DOUBLE);
90
91
// /* Get type of spectrum (science or sky) */
92
// p = cpl_parameterlist_find(parlist, "spectype");
93
// strncpy(spectype, cpl_parameter_get_string(p), 4);
94
95
// /* Get name components of converted file */
96
// p = cpl_parameterlist_find(parlist, "inst_dir");
97
// strncpy(basedir, cpl_parameter_get_string(p), SC_MAXLEN);
98
// p = cpl_parameterlist_find(parlist, "output_dir");
99
// sc_basic_abspath(outdir, cpl_parameter_get_string(p), basedir);
100
// p = cpl_parameterlist_find(parlist, "output_name");
101
// strncpy(outname, cpl_parameter_get_string(p), SC_MAXLEN);
102
103
// /* Compose name of converted file ('sci' or 'sky' label) */
104
// if (strncmp(spectype, "SCI", 3) == 0) {
105
// sprintf(outfilename, "%s%s_sci.fits", outdir, outname);
106
// } else if (strncmp(spectype, "SKY", 3) == 0) {
107
// sprintf(outfilename, "%s%s_sky.fits", outdir, outname);
108
// } else {
109
// sprintf(errtxt, "%s: cpl_parameterlist *parlist (spectype neither "
110
// "'SCI' nor 'SKY')", SC_ERROR_IOV_TXT);
111
// return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s", errtxt);
112
// }
113
114
// /* Read file and convert it to CPL table and CPL property list */
115
// if ((status = sc_conv_readfile(&tabdat, parlist)) != CPL_ERROR_NONE) {
116
// if (strncmp(spectype, "SCI", 3) == 0) {
117
// sprintf(errtxt, "%s: error while processing input science "
118
// "spectrum", SC_ERROR_EIS_TXT);
119
// cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_EIS, "%s", errtxt);
120
// } else if (strncmp(spectype, "SKY", 3) == 0) {
121
// sprintf(errtxt, "%s: error while processing input sky spectrum",
122
// SC_ERROR_EIS_TXT);
123
// cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_EIS, "%s", errtxt);
124
// }
125
// return status;
126
// }
127
128
// /* Write CPL table and CPL property list to FITS table */
129
// sc_conv_writetable(&tabdat, parlist);
130
131
// /* Free allocated memory */
132
// sc_conv_tarr_delete(&tabdat);
133
134
// /* Get spectroscopic data */
135
// if (cpl_error_get_code() == CPL_ERROR_NONE) {
136
// sc_readspec_fits(spec, parlist, outfilename);
137
// }
138
139
// /* Get observing parameters (for reference sky spectrum only) */
140
// if (cpl_error_get_code() == CPL_ERROR_NONE &&
141
// strncmp(spectype, "SKY", 3) == 0) {
142
// sc_readspec_header(parlist, outfilename);
143
// }
144
145
// /* Exit in case of errors */
146
// if ((status = cpl_error_get_code()) != CPL_ERROR_NONE) {
147
// if (strncmp(spectype, "SCI", 3) == 0) {
148
// sprintf(errtxt, "%s: error while processing input science "
149
// "spectrum", SC_ERROR_EIS_TXT);
150
// cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_EIS, "%s", errtxt);
151
// } else if (strncmp(spectype, "SKY", 3) == 0) {
152
// sprintf(errtxt, "%s: error while processing input sky spectrum",
153
// SC_ERROR_EIS_TXT);
154
// cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_EIS, "%s", errtxt);
155
// }
156
// return status;
157
// }
158
159
// /* Set weights for spectra without error column */
161
162
// if (cpl_table_get_nrow(spec) == 0) {
163
// sprintf(errtxt, "%s: cpl_table *spec", SC_ERROR_NDA_TXT);
164
// return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_NDA, "%s", errtxt);
165
// }
166
167
// /* All weights = 0? */
168
// if (cpl_table_get_column_max(spec, "weight") == 0) {
169
// sprintf(errtxt, "%s: cpl_table *spec (all weights = 0)",
170
// SC_ERROR_IOV_TXT);
171
// return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s", errtxt);
172
// }
173
174
// /* Set mean wavelength */
175
// meanlam = 0.5 * (cpl_table_get(spec, "lambda", 0, NULL) +
176
// cpl_table_get(spec, "lambda", cpl_table_get_nrow(spec)-1,
177
// NULL));
178
// p = cpl_parameterlist_find(parlist, "meanlam");
179
// cpl_parameter_set_double(p, meanlam);
180
181
182
// return CPL_ERROR_NONE;
183
//}
184
185
186
//cpl_error_code sc_readspec_fits(cpl_table *spec,
187
// const cpl_parameterlist *parlist,
188
// const char *filename)
189
//{
190
// /*!
191
// * Reads a FITS file with tabulated spectroscopic data (wavelength, flux,
192
// * flux error, mask) in the 1st extension (no other extensions are
193
// * allowed) and puts the read data in a CPL table consisting of the
194
// * columns "lambda", "flux", and "weight". The names of the required FITS
195
// * table columns are provided by the general CPL parameter list. The
196
// * presence of flux error is optional. For skipping such a column, the
197
// * name has to be 'NONE'. The original input file could also lack a mask
198
// * column (also indicated by 'NONE'). However, ::sc_conv_readfile makes
199
// * sure that a suitable mask column indicated by the given column name or
200
// * ::SC_DEFMASKCOL (in the case of 'NONE') + '_I' is present. A weight of
201
// * zero is taken if a wavelength is excluded by the mask. If there is no
202
// * error column, the parameter list default error times mean flux is
203
// * assumed for all data points.
204
// *
205
// * \b INPUT:
206
// * \param spec empty CPL table
207
// * \param parlist general CPL parameter list
208
// * \param filename path and name of FITS file
209
// *
210
// * \b OUTPUT:
211
// * \param spec CPL table with wavelengths, fluxes, and weights
212
// *
213
// * \b ERRORS:
214
// * - File opening failed
215
// * - Unexpected file structure
216
// */
217
218
// const cpl_parameter *p;
219
// cpl_table *intab;
220
// cpl_array *colnames;
221
// cpl_boolean exerr = CPL_TRUE, exmask = CPL_TRUE;
222
// char errtxt[SC_MAXLEN], col_lam[SC_LENLINE+1];
223
// char col_flux[SC_LENLINE+1], col_dflux[SC_LENLINE+1];
224
// char col_mask[SC_LENLINE+1], col_imask[SC_LENLINE+3];
225
// char colname[SC_LENLINE+1];
226
// int coln[4] = {0, 0, 0, 0};
227
// int next = 0, ncolmin = 5, ncol = 0, check = 0, j = 0, nrow = 0, i = 0;
228
// int mask = 0;
229
// double wlgtomicron = 0., lam = 0., flux = 0., dflux = 0.;
230
231
// /* Write info message */
232
// cpl_msg_debug(cpl_func, "Read %s", filename);
233
234
// /* Check file existence and number of FITS extensions */
235
// next = cpl_fits_count_extensions(filename);
236
// if (next < 0) {
237
// sprintf(errtxt, "%s: %s", SC_ERROR_FOF_TXT, filename);
238
// return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_FOF, "%s", errtxt);
239
// } else if (next != 1) {
240
// sprintf(errtxt, "%s: %s (# of FITS extensions != 1)",
241
// SC_ERROR_UFS_TXT, filename);
242
// return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_UFS, "%s", errtxt);
243
// }
244
245
// /* Get column labels from parameter list */
246
// p = cpl_parameterlist_find_const(parlist, "col_lam");
247
// strncpy(col_lam, cpl_parameter_get_string(p), SC_LENLINE+1);
248
// if (strcmp(col_lam, "NONE") == 0) {
249
// sprintf(col_lam, "%s", SC_DEFLAMCOL);
250
// }
251
// p = cpl_parameterlist_find_const(parlist, "col_flux");
252
// strncpy(col_flux, cpl_parameter_get_string(p), SC_LENLINE+1);
253
// if (strcmp(col_flux, "NONE") == 0) {
254
// sprintf(col_flux, "%s", SC_DEFFLUXCOL);
255
// }
256
// p = cpl_parameterlist_find_const(parlist, "col_dflux");
257
// strncpy(col_dflux, cpl_parameter_get_string(p), SC_LENLINE+1);
258
// if (strcmp(col_dflux, "NONE") == 0) {
259
// cpl_table_erase_column(spec, "dflux");
260
// exerr = CPL_FALSE;
261
// ncolmin--;
262
// }
263
// p = cpl_parameterlist_find_const(parlist, "col_mask");
264
// strncpy(col_mask, cpl_parameter_get_string(p), SC_LENLINE+1);
265
// if (strcmp(col_mask, "NONE") == 0) {
266
// cpl_table_erase_column(spec, "mask");
267
// exmask = CPL_FALSE;
268
// sprintf(col_imask, "%s_I", SC_DEFMASKCOL);
269
// ncolmin--;
270
// } else {
271
// sprintf(col_imask, "%s_I", col_mask);
272
// }
273
274
// /* Get wavelength unit conversion factor */
275
// p = cpl_parameterlist_find_const(parlist, "wlgtomicron");
276
// wlgtomicron = cpl_parameter_get_double(p);
277
278
// /* Read FITS table */
279
// intab = cpl_table_load(filename, 1, 0);
280
281
// /* Get column labels */
282
// colnames = cpl_table_get_column_names(intab);
283
// ncol = cpl_array_get_size(colnames);
284
285
// /* Check existence of columns */
286
287
// for (check = 0, j = 0; j < ncol; j++) {
288
// strncpy(colname, cpl_array_get_string(colnames, j),
289
// SC_LENLINE+1);
290
// if (strcmp(colname, col_lam) == 0) {
291
// coln[0] = j;
292
// check++;
293
// } else if (strcmp(colname, col_flux) == 0) {
294
// coln[1] = j;
295
// check++;
296
// } else if (strcmp(colname, col_dflux) == 0) {
297
// coln[2] = j;
298
// check++;
299
// } else if (strcmp(colname, col_mask) == 0) {
300
// check++;
301
// } else if (strcmp(colname, col_imask) == 0) {
302
// coln[3] = j;
303
// check++;
304
// }
305
// }
306
307
// if (check < ncolmin) {
308
// cpl_table_set_size(spec, 0);
309
// cpl_array_delete(colnames);
310
// cpl_table_delete(intab);
311
// sprintf(errtxt, "%s: %s (missing FITS table column(s))",
312
// SC_ERROR_UFS_TXT, filename);
313
// return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_UFS, "%s",
314
// errtxt);
315
// }
316
317
// /* Resize output table */
318
// nrow = cpl_table_get_nrow(intab);
319
// cpl_table_set_size(spec, nrow);
320
321
// /* Transfer wavelength and flux/transmission and compute weights */
322
323
// for (i = 0; i < nrow; i++) {
324
325
// lam = cpl_table_get(intab,
326
// cpl_array_get_string(colnames, coln[0]), i, NULL)
327
// * wlgtomicron;
328
// cpl_table_set(spec, "lambda", i, lam);
329
330
// flux = cpl_table_get(intab,
331
// cpl_array_get_string(colnames, coln[1]), i,
332
// NULL);
333
// cpl_table_set(spec, "flux", i, flux);
334
335
// if (exerr == CPL_TRUE) {
336
// dflux = cpl_table_get(intab,
337
// cpl_array_get_string(colnames, coln[2]), i,
338
// NULL);
339
// cpl_table_set(spec, "dflux", i, dflux);
340
// } else {
341
// dflux = 1.;
342
// }
343
344
// mask = cpl_table_get(intab, cpl_array_get_string(colnames, coln[3]),
345
// i, NULL);
346
// if (exmask == CPL_TRUE) {
347
// cpl_table_set(spec, "mask", i, mask);
348
// }
349
350
// if (dflux <= 0. || mask == 0) {
351
// cpl_table_set(spec, "weight", i, 0.);
352
// } else {
353
// cpl_table_set(spec, "weight", i, 1. / dflux);
354
// }
355
356
// }
357
358
// /* Delete temporary CPL objects */
359
// cpl_array_delete(colnames);
360
// cpl_table_delete(intab);
361
362
// return CPL_ERROR_NONE;
363
//}
364
365
366
//cpl_error_code sc_readspec_header(cpl_parameterlist *parlist,
367
// const char *filename)
368
//{
369
// /*!
370
// * Reads keywords from a FITS file header and puts the read values in the
371
// * general CPL parameter list. The presence of keywords for date (MJD or
372
// * date in years), time (UTC in s), and telescope altitude angle (in deg)
373
// * is required. The keyword names are included in the general parameter
374
// * list. The default names are MJD_OBS, TM-START, and ESO TEL ALT. If an
375
// * expected keyword cannot be found in the FITS header, an error message
376
// * will be written to the CPL error structure. The values of the required
377
// * parameters are also part of the general parameter list. If a value is
378
// * set manually, this value is taken instead of the corresponding FITS
379
// * keyword content.
380
// *
381
// * \b INPUT:
382
// * \param parlist general CPL parameter list
383
// * \param filename path and name of FITS file
384
// *
385
// * \b OUTPUT:
386
// * \param parlist general CPL parameter list with FITS header values
387
// *
388
// * \b ERRORS:
389
// * - File opening failed
390
// * - Unexpected file structure
391
// */
392
393
// cpl_parameter *p;
394
// cpl_propertylist *header = NULL;
395
// cpl_property *prop;
396
// cpl_type type;
397
// char key[SC_NKEY][SC_LENLINE+1] = {"", "", ""}, errtxt[SC_MAXLEN];
398
// int next = 0, ext = 0, i = 0, nerr = 0;
399
// double val = 0.;
400
401
// /* Parameter names related to FITS keywords */
402
// char keypar[SC_NKEY][SC_LENLINE+1] =
403
// {"date_key", "time_key", "telalt_key"};
404
// char valpar[SC_NKEY][SC_LENLINE+1] =
405
// {"date_val", "time_val", "telalt_val"};
406
407
// /* Find FITS extension with required keywords and write the header of this
408
// extension into CPL property list */
409
// next = cpl_fits_count_extensions(filename);
410
// for (ext = 0; ext <= next; ext++) {
411
// header = cpl_propertylist_load(filename, ext);
412
// if (header == NULL) {
413
// sprintf(errtxt, "%s: %s", SC_ERROR_FOF_TXT, filename);
414
// return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_FOF, "%s",
415
// errtxt);
416
// }
417
// /* Check first keyword */
418
// p = cpl_parameterlist_find(parlist, keypar[0]);
419
// strncpy(key[0], cpl_parameter_get_string(p), SC_LENLINE+1);
420
// prop = cpl_propertylist_get_property(header, key[0]);
421
// if (prop != NULL) {
422
// break;
423
// } else {
424
// if (ext < next) {
425
// cpl_propertylist_delete(header);
426
// }
427
// }
428
// }
429
430
// /* Write info message */
431
// cpl_msg_debug(cpl_func, "Take keywords from FITS extension %d", ext);
432
433
// /* Update general parameter list with keywords from CPL property list */
434
435
// for (i = 0; i < SC_NKEY; i++) {
436
437
// /* Get value from parameter list */
438
// p = cpl_parameterlist_find(parlist, valpar[i]);
439
// val = cpl_parameter_get_double(p);
440
441
// /* Get name of required FITS keyword */
442
// p = cpl_parameterlist_find(parlist, keypar[i]);
443
// strncpy(key[i], cpl_parameter_get_string(p), SC_LENLINE+1);
444
445
// /* Write info message */
446
// cpl_msg_debug(cpl_func, "Read keyword %s", key[i]);
447
448
// /* Get FITS keyword */
449
// prop = cpl_propertylist_get_property(header, key[i]);
450
451
// if (prop == NULL && val == -1.) {
452
453
// /* Set error message in the case of missing keyword */
454
// nerr++;
455
// sprintf(errtxt, "%s: %s (keyword %s not found)",
456
// SC_ERROR_UFS_TXT, filename, key[i]);
457
// cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_UFS, "%s", errtxt);
458
459
// } else {
460
461
// /* Take FITS keyword only if parameter value was not given
462
// manually */
463
// if (val == -1.) {
464
// /* Check for type */
465
// type = cpl_property_get_type(prop);
466
// if (type == CPL_TYPE_DOUBLE) {
467
// val = cpl_property_get_double(prop);
468
// } else if (type == CPL_TYPE_FLOAT) {
469
// val = (double) cpl_property_get_float(prop);
470
// } else if (type == CPL_TYPE_INT) {
471
// val = (double) cpl_property_get_int(prop);
472
// } else {
473
// nerr++;
474
// sprintf(errtxt, "%s: %s (non-numerical keyword %s)",
475
// SC_ERROR_UFS_TXT, filename, key[i]);
476
// cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_UFS, "%s",
477
// errtxt);
478
// continue;
479
// }
480
// }
481
482
// /* MJD -> date in years (if required; save MJD before) */
483
// if (i == 0 && val > 3000.) {
484
// p = cpl_parameterlist_find(parlist, "mjd");
485
// cpl_parameter_set_double(p, val);
486
// val = sc_basic_mjd2fracyear(val);
487
// }
488
489
// /* Write new value into parameter list */
490
// p = cpl_parameterlist_find(parlist, valpar[i]);
491
// cpl_parameter_set_double(p, val);
492
493
// }
494
495
// }
496
497
// /* Free allocated memory */
498
// cpl_propertylist_delete(header);
499
500
// /* Return SC_ERROR_UFS in the case of keyword mismatch */
501
// if (nerr > 0) {
502
// return (cpl_error_code)SC_ERROR_UFS;
503
// }
504
505
// return CPL_ERROR_NONE;
506
//}
507
508
509
//cpl_error_code sc_readspec_setweight(cpl_table *spec,
510
// const cpl_parameterlist *parlist)
511
//{
512
// /*!
513
// * Sets the weights for spectra that do not contain an error column.
514
// * The default relative error provided by the general CPL parameter list
515
// * is multiplied by the mean flux of all wavelengths that are used by the
516
// * fit. The resulting absolute error is taken for all wavelengths with
517
// * non-zero weight.
518
// *
519
// * \b INPUT:
520
// * \param spec CPL table with observed spectrum
521
// * \param parlist general CPL parameter list
522
// *
523
// * \b OUTPUT:
524
// * \param spec spectrum with optimised weights
525
// *
526
// * \b ERRORS:
527
// * - Invalid object value(s)
528
// */
529
530
// cpl_error_code err = CPL_ERROR_NONE;
531
// const cpl_parameter *p;
532
// char col_dflux[SC_LENLINE+1], errtxt[SC_MAXLEN];
533
// int nrow = 0, i = 0, nw = 0;
534
// double deferr = 0., weight = 0., fsum = 0., weight0 = 0.;
535
536
// /* Return if error data exist */
537
// p = cpl_parameterlist_find_const(parlist, "col_dflux");
538
// strncpy(col_dflux, cpl_parameter_get_string(p), SC_LENLINE+1);
539
// if (strcmp(col_dflux, "NONE") != 0) {
540
// return CPL_ERROR_NONE;
541
// }
542
543
// /* Get default relative error */
544
// p = cpl_parameterlist_find_const(parlist, "default_error");
545
// deferr = cpl_parameter_get_double(p);
546
547
// /* Count data points with non-zero weight and sum up their fluxes */
548
// nrow = cpl_table_get_nrow(spec);
549
// for (i = 0; i < nrow; i++) {
550
// weight = cpl_table_get(spec, "weight", i, NULL);
551
// if (weight > 0) {
552
// nw++;
553
// fsum += cpl_table_get(spec, "flux", i, NULL);
554
// }
555
// }
556
557
// /* Set errors to default error * mean if error column is missing */
558
// if (fsum > 0) {
559
// weight0 = (double) nw / (fsum * deferr);
560
// for (i = 0; i < nrow; i++) {
561
// weight = cpl_table_get(spec, "weight", i, NULL);
562
// if (weight > 0) {
563
// cpl_table_set(spec, "weight", i, weight0);
564
// }
565
// }
566
// }
567
568
// /* Check for errors */
569
570
// if (fsum == 0) {
571
// sprintf(errtxt, "%s: cpl_table *spec (all fluxes = 0)",
572
// SC_ERROR_IOV_TXT);
573
// err = cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s", errtxt);
574
// }
575
576
// if (nw == 0) {
577
// sprintf(errtxt, "%s: cpl_table *spec (all weights = 0)",
578
// SC_ERROR_IOV_TXT);
579
// err = cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s", errtxt);
580
// }
581
582
// return err;
583
//}
584
sc_readspec.h
Generated on Thu Nov 27 2025 10:22:36 for ERIS Pipeline Reference Manual by
1.9.6