MUSE Pipeline Reference Manual  1.0.2
muse_create_sky.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) 2005-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 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 /*---------------------------------------------------------------------------*
27  * Includes *
28  *---------------------------------------------------------------------------*/
29 #include <string.h>
30 #include <math.h>
31 
32 #include <muse.h>
33 #include "muse_create_sky_z.h"
34 
35 /*---------------------------------------------------------------------------*
36  * Functions code *
37  *---------------------------------------------------------------------------*/
38 static muse_pixtable *
39 muse_create_sky_load_pixtable(muse_processing *aProcessing,
40  muse_create_sky_params_t *aParams)
41 {
42  muse_pixtable *pixtable = NULL;
43 
44  /* sort input pixel tables into different exposures */
45  cpl_table *exposures = muse_processing_sort_exposures(aProcessing);
46  if (!exposures) {
47  cpl_msg_error(__func__, "no science exposures found in input");
48  return NULL;
49  }
50  int nexposures = cpl_table_get_nrow(exposures);
51  if (nexposures != 1) {
52  cpl_msg_error(__func__, "More than one exposure (%i) in sky creation",
53  nexposures);
54  }
55 
56  /* now process all the pixel tables, do it separately for each exposure */
57  int i;
58  for (i = 0; i < nexposures; i++) {
59  cpl_table *thisexp = cpl_table_extract(exposures, i, 1);
61  aParams->lambdamin,
62  aParams->lambdamax);
63  cpl_table_delete(thisexp);
64  /* erase pre-existing QC parameters */
65  cpl_propertylist_erase_regexp(p->header, "ESO QC ", 0);
66  if (pixtable == NULL) {
67  pixtable = p;
68  } else {
69  cpl_table_insert(pixtable->table, p->table,
70  cpl_table_get_nrow(pixtable->table));
72  }
73  }
74  cpl_table_delete(exposures);
75 
76  if ((pixtable != NULL) && (muse_pixtable_is_skysub(pixtable) == CPL_TRUE)) {
77  cpl_msg_error(__func__, "Pixel table already sky subtracted");
78  muse_pixtable_delete(pixtable);
79  pixtable = NULL;
80  }
81 
82  cpl_table *response = muse_table_load(aProcessing, MUSE_TAG_STD_RESPONSE, 0);
83  cpl_table *extinction = muse_table_load(aProcessing, MUSE_TAG_EXTINCT_TABLE, 0);
84  cpl_table *telluric = muse_table_load(aProcessing, MUSE_TAG_STD_TELLURIC, 0);
85 
86  if ((pixtable != NULL) && (response != NULL)) {
87  if (muse_pixtable_is_fluxcal(pixtable) == CPL_TRUE) {
88  cpl_msg_error(__func__,
89  "Pixel table already flux calibrated. Dont specify %s, %s, %s",
90  MUSE_TAG_STD_RESPONSE, MUSE_TAG_EXTINCT_TABLE,
91  MUSE_TAG_STD_TELLURIC);
92  muse_pixtable_delete(pixtable);
93  pixtable = NULL;
94  } else {
95  cpl_error_code rc = muse_flux_calibrate(pixtable, response, extinction, telluric);
96  if (rc != CPL_ERROR_NONE) {
97  cpl_msg_error(__func__, "while muse_flux_calibrate");
98  muse_pixtable_delete(pixtable);
99  pixtable = NULL;
100  }
101  }
102  }
103 
104  cpl_table_delete(response);
105  cpl_table_delete(extinction);
106  cpl_table_delete(telluric);
107 
108  if ((pixtable != NULL) && (muse_pixtable_is_fluxcal(pixtable) != CPL_TRUE)) {
109  cpl_msg_error(__func__, "Pixel table not flux calibrated, cannot create "
110  "sky!");
111  muse_pixtable_delete(pixtable);
112  pixtable = NULL;
113  }
114 
115  if (pixtable != NULL) {
116  cpl_table_and_selected_int(pixtable->table, MUSE_PIXTABLE_DQ,
117  CPL_NOT_EQUAL_TO, EURO3D_GOODPIXEL);
118  cpl_table_erase_selected(pixtable->table);
119  }
120 
121  /* do DAR correction for WFM data */
122  if (muse_pfits_get_mode(pixtable->header) <= MUSE_MODE_WFM_AO_N) {
123  cpl_msg_debug(__func__, "WFM detected: starting DAR correction");
124  cpl_error_code rc = muse_dar_correct(pixtable, aParams->lambdaref);
125  cpl_msg_debug(__func__, "DAR correction returned rc=%d: %s", rc,
126  rc != CPL_ERROR_NONE ? cpl_error_get_message() : "");
127  } /* if WFM */
128 
129  return pixtable;
130 }
131 
132 static muse_sky_master *
133 muse_create_sky_compute_master(cpl_table *spectrum, muse_processing *aProcessing)
134 {
135  cpl_array *lambda = muse_cpltable_extract_column(spectrum, "lambda");
136  double lambda_low = cpl_array_get_min(lambda);
137  double lambda_high = cpl_array_get_max(lambda);
138  cpl_table *sky_lines = muse_sky_lines_load(aProcessing);
139  if (sky_lines != NULL) {
140  muse_sky_lines_set_range(sky_lines, lambda_low-5, lambda_high+5);
141  }
142 
143  cpl_array *data = muse_cpltable_extract_column(spectrum, "data");
144  cpl_array *stat = muse_cpltable_extract_column(spectrum, "stat");
145  // do the fit, ignoring possible errors
146  cpl_errorstate prestate = cpl_errorstate_get();
147  muse_sky_master *res = muse_sky_master_fit(lambda, data, stat, sky_lines);
148  if (!cpl_errorstate_is_equal(prestate)) {
149  cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
150  cpl_errorstate_set(prestate);
151  }
152 
153  cpl_table_delete(sky_lines);
154  cpl_array_unwrap(lambda);
155  cpl_array_unwrap(data);
156  cpl_array_unwrap(stat);
157  cpl_table_delete(spectrum);
158 
159  return res;
160 }
161 
162 static void
163 muse_create_sky_save_master(cpl_propertylist *aHeader,
164  const muse_sky_master *aMaster,
165  muse_processing *aProcessing)
166 {
167  cpl_frame *frame
168  = muse_processing_new_frame(aProcessing, -1, aHeader,
169  "SKY_LINES", CPL_FRAME_TYPE_TABLE);
170  if (frame != NULL) {
171  const char *filename = cpl_frame_get_filename(frame);
172  int r;
173  r = cpl_propertylist_save(aHeader, filename, CPL_IO_CREATE);
174  r = muse_cpltable_append_file(aMaster->lines, filename,
175  "LINES", muse_sky_lines_lines_def);
176  if (r == CPL_ERROR_NONE) {
177  cpl_frameset_insert(aProcessing->outframes, frame);
178  } else {
179  cpl_frame_delete(frame);
180  }
181  }
182  frame = muse_processing_new_frame(aProcessing, -1, aHeader,
183  "SKY_CONTINUUM", CPL_FRAME_TYPE_TABLE);
184  if (frame != NULL) {
185  const char *filename = cpl_frame_get_filename(frame);
186  int r;
187  r = cpl_propertylist_save(aHeader, filename, CPL_IO_CREATE);
188  r = muse_cpltable_append_file(aMaster->continuum, filename,
189  "CONTINUUM", muse_fluxspectrum_def);
190  if (r == CPL_ERROR_NONE) {
191  cpl_frameset_insert(aProcessing->outframes, frame);
192  } else {
193  cpl_frame_delete(frame);
194  }
195  }
196 }
197 
198 /*----------------------------------------------------------------------------*/
204 /*----------------------------------------------------------------------------*/
205 static cpl_error_code
206 muse_create_sky_qc_sky(cpl_propertylist *aHeader,
207  const muse_sky_master *aMaster)
208 {
209  cpl_ensure_code(aHeader && aMaster, CPL_ERROR_NULL_INPUT);
210 
211  cpl_ensure_code(aMaster->lines && cpl_table_get_nrow(aMaster->lines) > 0,
212  CPL_ERROR_DATA_NOT_FOUND);
213  char keyword[KEYWORD_LENGTH];
214  int i, ngroups = cpl_table_get_column_max(aMaster->lines, "group") + 1;
215  for (i = 0; i < ngroups; i++) {
216  cpl_table_unselect_all(aMaster->lines);
217  cpl_table_or_selected_int(aMaster->lines, "group", CPL_EQUAL_TO, i);
218  cpl_table *gtable = cpl_table_extract_selected(aMaster->lines);
219  cpl_size row;
220  cpl_table_get_column_maxpos(gtable, "flux", &row);
221  const char *name = cpl_table_get_string(gtable, "name", row);
222  double wavelength = cpl_table_get_double(gtable, "lambda", row, NULL),
223  flux = cpl_table_get_double(gtable, "flux", row, NULL);
224  snprintf(keyword, KEYWORD_LENGTH, "ESO QC SKY LINE%i NAME", i+1);
225  cpl_propertylist_append_string(aHeader, keyword, name);
226  snprintf(keyword, KEYWORD_LENGTH, "ESO QC SKY LINE%i AWAV", i+1);
227  cpl_propertylist_append_double(aHeader, keyword, wavelength);
228  snprintf(keyword, KEYWORD_LENGTH, "ESO QC SKY LINE%i FLUX", i+1);
229  if (!isfinite(flux)) {
230  /* add obviously wrong value to the header, *
231  * since CFITSIO chokes on NANs and the like */
232  cpl_propertylist_append_double(aHeader, keyword, -9999.999);
233  cpl_msg_error(__func__, "Sky-line fit failed for group %d, computed "
234  "flux is infinite!", i+1);
235  } else {
236  cpl_propertylist_append_double(aHeader, keyword, flux);
237  }
238  cpl_table_delete(gtable);
239  double offset = aMaster->lsf[0]->offset
240  + (aMaster->lsf[0]->refraction - 1) * wavelength;
241  snprintf(keyword, KEYWORD_LENGTH, "ESO QC SKY LINE%i OFFSET", i+1);
242  cpl_propertylist_append_double(aHeader, keyword, offset);
243  } /* for ngroups */
244  cpl_table_unselect_all(aMaster->lines);
245 
246  cpl_ensure_code(aMaster->continuum && cpl_table_get_nrow(aMaster->continuum) > 0,
247  CPL_ERROR_DATA_NOT_FOUND);
248  cpl_size row, nrows = cpl_table_get_nrow(aMaster->continuum);
249  double flux = 0.0;
250  for (row = 0; row < nrows; row++) {
251  flux += cpl_table_get_double(aMaster->continuum, "flux", row, NULL);
252  }
253  snprintf(keyword, KEYWORD_LENGTH, "ESO QC SKY CONT FLUX");
254  if (!isfinite(flux)) {
255  /* again, workaround for weird CFITSIO error */
256  cpl_propertylist_append_double(aHeader, keyword, -9999.999);
257  cpl_msg_error(__func__, "Sky-continuum contains infinite values, fit may "
258  "have failed!");
259  } else {
260  cpl_propertylist_append_double(aHeader, keyword, flux);
261  }
262  double maxdev = 0.0,
263  prev = cpl_table_get_double(aMaster->continuum, "flux", 0, NULL),
264  l_prev = cpl_table_get_double(aMaster->continuum, "lambda", 0, NULL);
265  for (row = 1; row < nrows; row++) {
266  double cur = cpl_table_get_double(aMaster->continuum, "flux", row, NULL),
267  l_cur = cpl_table_get_double(aMaster->continuum, "lambda", row, NULL),
268  dev = fabs((cur - prev)/ (l_cur - l_prev));
269  if (maxdev < dev) {
270  maxdev = dev;
271  }
272  prev = cur;
273  l_prev = l_cur;
274  } /* for row (continuum table rows) */
275  snprintf(keyword, KEYWORD_LENGTH, "ESO QC SKY CONT MAXDEV");
276  cpl_propertylist_append_double(aHeader, keyword, maxdev);
277 
278  return CPL_ERROR_NONE;
279 } /* muse_create_sky_qc_sky() */
280 
281 /*----------------------------------------------------------------------------*/
289 /*----------------------------------------------------------------------------*/
290 static muse_image *
291 muse_create_sky_whitelight_image(muse_pixtable *aPixtable, int aCr)
292 {
293  cpl_boolean usegrid = getenv("MUSE_COLLAPSE_PIXTABLE")
294  && atoi(getenv("MUSE_COLLAPSE_PIXTABLE")) > 0;
298  if (aCr) {
300  params->crsigma = 15.;
301  }
302  muse_pixgrid *grid = NULL;
303  muse_datacube *cube = muse_resampling_cube(aPixtable, params,
304  usegrid ? &grid : NULL);
305  if (cube == NULL) {
306  cpl_msg_error(__func__, "Could not create cube for whitelight image");
308  muse_pixgrid_delete(grid);
309  return NULL;
310  }
311  muse_image *image = NULL;
312  cpl_table *fwhite = muse_table_load_filter(NULL, "white");
313  if (usegrid) {
315  image = muse_resampling_collapse_pixgrid(aPixtable, grid,
316  cube, fwhite, params);
317  } else {
318  image = muse_datacube_collapse(cube, fwhite);
319  }
321  muse_pixgrid_delete(grid);
322  muse_datacube_delete(cube);
323  cpl_table_delete(fwhite);
324  return image;
325 } /* muse_create_sky_whitelight_image() */
326 
327 /*----------------------------------------------------------------------------*/
339 /*----------------------------------------------------------------------------*/
340 static void
341 muse_create_sky_create_continuum(muse_pixtable *aPixtable,
342  muse_sky_master *aMaster,
343  muse_lsf_params **aLsf,
344  double binwidth) {
345  cpl_table_delete(aMaster->continuum);
346  aMaster->continuum = NULL;
347  muse_sky_subtract_pixtable(aPixtable, aMaster, aLsf);
348  aMaster->continuum = muse_resampling_spectrum(aPixtable, binwidth);
349  cpl_table_erase_column(aMaster->continuum, "stat");
350  cpl_table_erase_column(aMaster->continuum, "dq");
351  cpl_table_name_column(aMaster->continuum, "data", "flux");
352 }
353 
354 /*----------------------------------------------------------------------------*/
361 /*----------------------------------------------------------------------------*/
362 int
363 muse_create_sky_compute(muse_processing *aProcessing,
364  muse_create_sky_params_t *aParams)
365 {
366  muse_pixtable *pixtable = muse_create_sky_load_pixtable(aProcessing, aParams);
367  if (pixtable == NULL) {
368  cpl_msg_error(__func__, "Could not load pixel table");
369  return -1;
370  }
371 
372  /*
373  First step: find the regions containing sky:
374  - create a whitelight image
375  - create the mask from it
376  - select pixtable rows containing sky
377  - create spectrum from selected rows
378  */
379  muse_mask *smask = muse_processing_mask_load(aProcessing, MUSE_TAG_SKY_MASK);
380  if (smask) { /* apply existing mask on input pixel table */
381  cpl_table_select_all(pixtable->table);
382  muse_pixtable_and_selected_mask(pixtable, smask);
383  muse_mask_delete(smask);
384  }
385 
386  int cube_cr = (!strncmp(aParams->cr_s, "cube", 5));
387  muse_image *whitelight = muse_create_sky_whitelight_image(pixtable, cube_cr);
388  if (whitelight == NULL) {
389  cpl_msg_error(__func__, "Could not create whitelight image");
390  return -1;
391  }
392  muse_processing_save_image(aProcessing, -1, whitelight, MUSE_TAG_IMAGE_FOV);
393 
394  muse_mask *sky_mask = muse_sky_create_skymask(whitelight, aParams->fraction,
395  "ESO QC SKY");
396  muse_processing_save_mask(aProcessing, -1, sky_mask, MUSE_TAG_SKY_MASK);
397 
398  cpl_table_select_all(pixtable->table);
399  muse_pixtable_and_selected_mask(pixtable, sky_mask);
400  muse_image_delete(whitelight);
401  muse_mask_delete(sky_mask);
402 
403  cpl_table *spectrum = muse_resampling_spectrum(pixtable, aParams->sampling);
404 
405  if (!strncmp(aParams->cr_s, "spectrum", 9)) {
406  muse_sky_mark_cosmic(spectrum, pixtable);
407  cpl_table_delete(spectrum);
408  spectrum = muse_resampling_spectrum(pixtable, aParams->sampling);
409  }
410 
411  if (spectrum == NULL) {
412  muse_pixtable_delete(pixtable);
413  return -1;
414  }
415  muse_processing_save_table(aProcessing, -1, spectrum, pixtable->header,
416  MUSE_TAG_SKY_SPECTRUM, MUSE_TABLE_TYPE_CPL);
417 
418  /*
419  Second step: create master sky, containing line list and
420  continuum. If a continuum was given as calibration frame, we
421  ignore the computed one and replace it by the external one.
422  */
423  cpl_msg_info(__func__, "Creating master sky spectrum using fits to lines "
424  "(fluxes) and residual continuum");
425  muse_sky_master *master
426  = muse_create_sky_compute_master(spectrum, aProcessing);
427  if (master == NULL) {
428  muse_pixtable_delete(pixtable);
429  return -1;
430  }
431 
432  cpl_errorstate prestate = cpl_errorstate_get();
433 
434  cpl_table *continuum = muse_sky_continuum_load(aProcessing);
435  muse_lsf_params **lsfParam =
436  muse_processing_lsf_params_load(aProcessing, 0);
437  if (continuum != NULL) {
438  cpl_table_delete(master->continuum);
439  master->continuum = continuum;
440  } else if (lsfParam != NULL) {
441  muse_create_sky_create_continuum(pixtable, master,
442  lsfParam, aParams->csampling);
443  }
444  muse_lsf_params_delete(lsfParam);
445 
446  cpl_propertylist *qc_header = cpl_propertylist_new();
447  muse_create_sky_qc_sky(qc_header, master);
448 
449  muse_create_sky_save_master(qc_header, master, aProcessing);
450 
451  /* Clean up the local objects. */
452  muse_sky_master_delete(master);
453  cpl_propertylist_delete(qc_header);
454  muse_pixtable_delete(pixtable);
455  return cpl_errorstate_is_equal(prestate) ? 0 : -1;
456 }
Structure definition of a MUSE datacube.
Definition: muse_datacube.h:47
void muse_image_delete(muse_image *aImage)
Deallocate memory associated to a muse_image object.
Definition: muse_image.c:85
int muse_processing_save_mask(muse_processing *aProcessing, int aIFU, muse_mask *aMask, const char *aTag)
Save a computed MUSE mask to disk.
cpl_error_code muse_dar_correct(muse_pixtable *aPixtable, double aLambdaRef)
Correct the pixel coordinates of all pixels of a given pixel table for differential atmospheric refra...
Definition: muse_dar.c:306
cpl_error_code muse_pixtable_and_selected_mask(muse_pixtable *aPixtable, muse_mask *aMask)
Select all pixels where the (x,y) positions are enabled in the given mask.
cpl_table * muse_sky_lines_load(muse_processing *)
Load the sky data files.
Structure to hold the MASTER SKY result.
Definition: muse_sky.h:57
double csampling
Spectral sampling of the continuum spectrum [Angstrom].
void muse_datacube_delete(muse_datacube *aCube)
Deallocate memory associated to a muse_datacube object.
const muse_cpltable_def muse_sky_lines_lines_def[]
muse_image * muse_datacube_collapse(muse_datacube *aCube, cpl_table *aFilter)
Integrate a FITS NAXIS=3 datacube along the wavelength direction.
muse_mask * muse_sky_create_skymask(muse_image *, double, const char *)
Select spaxels to be considered as sky.
The pixel grid.
Definition: muse_pixgrid.h:56
Structure definition of MUSE three extension FITS file.
Definition: muse_image.h:40
muse_mask * muse_processing_mask_load(muse_processing *aProcessing, const char *aTag)
Load a mask file and its FITS header.
cpl_table * table
The pixel table.
cpl_table * muse_table_load_filter(muse_processing *aProcessing, const char *aFilterName)
Load a table for a given filter name.
Definition: muse_utils.c:853
void muse_sky_mark_cosmic(cpl_table *aSpectrum, muse_pixtable *aPixtable)
Mark all pixel above a certain limit as COSMIC.
muse_resampling_crstats_type crtype
cpl_boolean muse_pixtable_is_skysub(muse_pixtable *aPixtable)
Determine whether the pixel table is sky subtracted.
cpl_table * muse_sky_continuum_load(muse_processing *)
Load the SKY_CONTINUUM spectrum.
Structure definition of MUSE pixel table.
cpl_frame * muse_processing_new_frame(muse_processing *aProcessing, int aIFU, cpl_propertylist *aHeader, const char *aTag, cpl_frame_type aType)
Create a new frame for a result file.
cpl_array * muse_cpltable_extract_column(cpl_table *aTable, const char *aColumn)
Create an array from a section of a column.
cpl_table * lines
Table of Atmospheric emission lines and their intensities.
Definition: muse_sky.h:61
cpl_frameset * outframes
muse_resampling_params * muse_resampling_params_new(muse_resampling_type aMethod)
Create the resampling parameters structure.
cpl_boolean muse_pixtable_is_fluxcal(muse_pixtable *aPixtable)
Determine whether the pixel table is flux calibrated.
cpl_error_code muse_flux_calibrate(muse_pixtable *aPixtable, const cpl_table *aResponse, const cpl_table *aExtinction, const cpl_table *aTelluric)
Convert the input pixel table from counts to fluxes.
Definition: muse_flux.c:2568
const muse_cpltable_def muse_fluxspectrum_def[]
Definition of the flux spectrum table structure.
cpl_error_code muse_sky_lines_set_range(cpl_table *, double, double)
Limit the lines in the table to a wavelength range.
void muse_sky_master_delete(muse_sky_master *)
Delete a MASTER SKY structure.
muse_datacube * muse_resampling_cube(muse_pixtable *aPixtable, muse_resampling_params *aParams, muse_pixgrid **aPixgrid)
Resample a pixel table onto a regular grid structure representing a FITS NAXIS=3 datacube.
muse_sky_master * muse_sky_master_fit(const cpl_array *, const cpl_array *, const cpl_array *, const cpl_table *)
Fit all entries of the pixel table to the master sky.
muse_image * muse_resampling_collapse_pixgrid(muse_pixtable *aPixtable, muse_pixgrid *aPixgrid, muse_datacube *aCube, cpl_table *aFilter, muse_resampling_params *aParams)
Integrate a pixel table / pixel grid along the wavelength direction.
void muse_pixgrid_delete(muse_pixgrid *aPixels)
Delete a pixgrid and remove its memory.
Definition: muse_pixgrid.c:398
int muse_processing_save_image(muse_processing *aProcessing, int aIFU, muse_image *aImage, const char *aTag)
Save a computed MUSE image to disk.
muse_pixtable * muse_pixtable_load_merge_channels(cpl_table *aExposureList, double aLambdaMin, double aLambdaMax)
Load and merge the pixel tables of the 24 MUSE sub-fields.
Handling of "mask" files.
Definition: muse_mask.h:42
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
double sampling
Spectral sampling of the sky spectrum [Angstrom].
cpl_table * muse_table_load(muse_processing *aProcessing, const char *aTag, unsigned char aIFU)
load a table according to its tag and IFU/channel number
Definition: muse_utils.c:721
cpl_error_code muse_processing_save_table(muse_processing *aProcessing, int aIFU, void *aTable, cpl_propertylist *aHeader, const char *aTag, muse_table_type aType)
Save a computed table to disk.
double fraction
Fraction of the image to be considered as sky. If an input sky mask is provided, the fraction is appl...
muse_resampling_type
Resampling types.
double lambdamax
Cut off the data above this wavelength after loading the pixel table(s).
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
Resampling parameters.
void muse_resampling_params_delete(muse_resampling_params *aParams)
Delete a resampling parameters structure.
muse_resampling_type method
muse_lsf_params ** muse_processing_lsf_params_load(muse_processing *aProcessing, int aIFU)
Load slice LSF parameters.
void muse_mask_delete(muse_mask *aMask)
Deallocate memory associated to a muse_mask object.
Definition: muse_mask.c:68
const char * cr_s
Type of cosmic ray cleaning to use. "Cube" is the standard CR cleaning which works on a datacube...
cpl_table * continuum
Continuum flux table
Definition: muse_sky.h:63
cpl_table * muse_resampling_spectrum(muse_pixtable *aPixtable, double aBinwidth)
Resample the selected pixels of a pixel table into a spectrum.
cpl_table * muse_processing_sort_exposures(muse_processing *aProcessing)
Sort input frames (containing lists of pixel table filenames) into different exposures.
Structure definition of detector (slice) parameters.
Definition: muse_lsf.h:50
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
Structure to hold the parameters of the muse_create_sky recipe.
cpl_error_code muse_sky_subtract_pixtable(muse_pixtable *a, muse_sky_master *, muse_lsf_params **)
Subtract the sky spectrum from the "data" column of a pixel table.
muse_lsf_params ** lsf
LSF parameter for the resampled spectrum.
Definition: muse_sky.h:65
muse_ins_mode muse_pfits_get_mode(const cpl_propertylist *aHeaders)
find out the observation mode
Definition: muse_pfits.c:1097
void muse_lsf_params_delete(muse_lsf_params **aParams)
Delete an allocated array of muse_lsf_params structure.
cpl_error_code muse_cpltable_append_file(const cpl_table *aTable, const char *aFile, const char *aExtension, const muse_cpltable_def aDefinition[])
Save a table to disk (into a FITS extension)
cpl_propertylist * header
The FITS header.