MUSE Pipeline Reference Manual  2.1.1
muse_sky_qc.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set sw=2 sts=2 et cin: */
3 /*
4  * This file is part of the MUSE Instrument Pipeline
5  * Copyright (C) 2014 European Southern Observatory
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 /*----------------------------------------------------------------------------*
23  * Includes *
24  *----------------------------------------------------------------------------*/
25 #include "muse_sky.h"
26 
27 #include "muse_pfits.h"
28 
32 /*----------------------------------------------------------------------------*/
44 /*----------------------------------------------------------------------------*/
45 void
46 muse_sky_qc_lines(cpl_propertylist *aHeader, cpl_table *aLines,
47  const char *aPrefix)
48 {
49  if (!aHeader || !aLines || !aPrefix) {
50  cpl_error_set(__func__, CPL_ERROR_NULL_INPUT);
51  return;
52  }
53  if (cpl_table_get_nrow(aLines) < 1) {
54  cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND);
55  return;
56  }
57 
58  char keyword[KEYWORD_LENGTH];
59  int i, ngroups = cpl_table_get_column_max(aLines, "group") + 1;
60  for (i = 0; i < ngroups; i++) {
61  cpl_table_unselect_all(aLines);
62  cpl_table_or_selected_int(aLines, "group", CPL_EQUAL_TO, i);
63  cpl_table *gtable = cpl_table_extract_selected(aLines);
64  cpl_size irow;
65  cpl_table_get_column_maxpos(gtable, "flux", &irow);
66  const char *name = cpl_table_get_string(gtable, "name", irow);
67  double wavelength = cpl_table_get_double(gtable, "lambda", irow, NULL),
68  flux = cpl_table_get_double(gtable, "flux", irow, NULL);
69  snprintf(keyword, KEYWORD_LENGTH, "%s LINE%i NAME", aPrefix, i+1);
70  cpl_propertylist_append_string(aHeader, keyword, name);
71  snprintf(keyword, KEYWORD_LENGTH, "%s LINE%i AWAV", aPrefix, i+1);
72  cpl_propertylist_append_double(aHeader, keyword, wavelength);
73  snprintf(keyword, KEYWORD_LENGTH, "%s LINE%i FLUX", aPrefix, i+1);
74  if (!isfinite(flux)) {
75  /* add obviously wrong value to the header, *
76  * since CFITSIO chokes on NANs and the like */
77  cpl_propertylist_append_double(aHeader, keyword, -9999.999);
78  cpl_msg_error(__func__, "Sky-line fit failed for group %d, computed "
79  "flux is infinite!", i+1);
80  } else {
81  cpl_propertylist_append_double(aHeader, keyword, flux);
82  }
83  cpl_table_delete(gtable);
84  } /* for ngroups */
85  cpl_table_unselect_all(aLines);
86 } /* muse_sky_qc_lines() */
87 
88 /*----------------------------------------------------------------------------*/
100 /*----------------------------------------------------------------------------*/
101 void
102 muse_sky_qc_continuum(cpl_propertylist *aHeader, cpl_table *aContinuum,
103  const char *aPrefix)
104 {
105  if (!aHeader || !aContinuum || !aPrefix) {
106  cpl_error_set(__func__, CPL_ERROR_NULL_INPUT);
107  return;
108  }
109  cpl_size irow, nrow = cpl_table_get_nrow(aContinuum);
110  if (nrow < 1) {
111  cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND);
112  return;
113  }
114 
115  double flux = 0.0;
116  for (irow = 0; irow < nrow; irow++) {
117  flux += cpl_table_get_double(aContinuum, "flux", irow, NULL);
118  }
119  char keyword[KEYWORD_LENGTH];
120  snprintf(keyword, KEYWORD_LENGTH, "%s CONT FLUX", aPrefix);
121  if (!isfinite(flux)) {
122  /* again, workaround for weird CFITSIO error */
123  cpl_propertylist_append_double(aHeader, keyword, -9999.999);
124  cpl_msg_error(__func__, "Sky-continuum contains infinite values, fit may "
125  "have failed!");
126  } else {
127  cpl_propertylist_append_double(aHeader, keyword, flux);
128  }
129  double maxdev = 0.0,
130  prev = cpl_table_get_double(aContinuum, "flux", 0, NULL),
131  l_prev = cpl_table_get_double(aContinuum, "lambda", 0, NULL);
132  for (irow = 1; irow < nrow; irow++) {
133  double cur = cpl_table_get_double(aContinuum, "flux", irow, NULL),
134  l_cur = cpl_table_get_double(aContinuum, "lambda", irow, NULL),
135  dev = fabs((cur - prev)/ (l_cur - l_prev));
136  if (maxdev < dev) {
137  maxdev = dev;
138  }
139  prev = cur;
140  l_prev = l_cur;
141  } /* for irow (continuum table rows) */
142  snprintf(keyword, KEYWORD_LENGTH, "%s CONT MAXDEV", aPrefix);
143  cpl_propertylist_append_double(aHeader, keyword, maxdev);
144 } /* muse_sky_qc_continuum() */
145 
void muse_sky_qc_lines(cpl_propertylist *aHeader, cpl_table *aLines, const char *aPrefix)
Fill a header with the QC parameters for the sky lines.
Definition: muse_sky_qc.c:46
void muse_sky_qc_continuum(cpl_propertylist *aHeader, cpl_table *aContinuum, const char *aPrefix)
Fill a header with the QC parameters for the sky continuum.
Definition: muse_sky_qc.c:102