MUSE Pipeline Reference Manual  0.18.1
muse_skyflat.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  *
5  * This file is part of the MUSE Instrument Pipeline
6  * Copyright (C) 2005-2011 European Southern Observatory
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 /*----------------------------------------------------------------------------*
28  * Includes *
29  *----------------------------------------------------------------------------*/
30 #include <stdio.h>
31 #include <float.h>
32 #include <math.h>
33 #include <string.h>
34 #include <cpl.h>
35 #include <muse.h>
36 #include "muse_skyflat_z.h"
37 
38 /*---------------------------------------------------------------------------*
39  * Functions code *
40  *---------------------------------------------------------------------------*/
41 
42 /*---------------------------------------------------------------------------*/
48 /*---------------------------------------------------------------------------*/
49 static void
50 muse_skyflat_qc_header(muse_image *aImage, muse_imagelist *aList)
51 {
52  cpl_msg_debug(__func__, "Adding QC keywords");
53 
54  unsigned stats = CPL_STATS_MEDIAN | CPL_STATS_MEAN | CPL_STATS_STDEV
55  | CPL_STATS_MIN | CPL_STATS_MAX;
56 
57  /* write the image statistics for input skyflat field exposures */
58  unsigned int i;
59  for (i = 0; i < muse_imagelist_get_size(aList); i++) {
60  char *keyword = cpl_sprintf(QC_SKYFLAT_PREFIXi, i+1);
62  aImage->header, keyword, stats);
63  cpl_free(keyword);
64  keyword = cpl_sprintf(QC_SKYFLAT_PREFIXi" "QC_BASIC_NSATURATED, i+1);
65  int nsaturated = cpl_propertylist_get_int(muse_imagelist_get(aList, i)->header,
66  MUSE_HDR_TMP_NSAT);
67  cpl_propertylist_update_int(aImage->header, keyword, nsaturated);
68  cpl_free(keyword);
69  } /* for i (all images in list) */
70 
71  /* properties of the resulting master frame */
72  stats |= CPL_STATS_FLUX;
74  QC_SKYFLAT_MASTER_PREFIX, stats);
75 } /* muse_skyflat_qc_header() */
76 
77 /*---------------------------------------------------------------------------*/
92 /*---------------------------------------------------------------------------*/
93 static double
94 muse_skyflat_qc_integrate_flux(muse_image *aImage, cpl_table *aTrace,
95  cpl_table *aWave, muse_skyflat_params_t *aParams)
96 {
97  cpl_msg_debug(__func__, "Adding flux statistics for QC, from %.1f to %.1f "
98  "Angstrom", aParams->lambdamin, aParams->lambdamax);
99 
100  /* interpolate all bad pixels */
102  cpl_detector_interpolate_rejected(aImage->data);
103 
104  /* create pixel table from master sky flat */
105  muse_pixtable *pt = muse_pixtable_create(aImage, aTrace, aWave, NULL);
106  if (!pt) {
107  cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT);
108  return -1;
109  }
110 
111  /* cut the pixel table to the requested wavelength range */
112  muse_pixtable_restrict_wavelength(pt, aParams->lambdamin, aParams->lambdamax);
113  /* then split up into slices */
115  /* integrate the flux over each slice, then sum up over all slices */
116  int i, nint = 0,
117  nslice = muse_pixtable_extracted_get_size(slicepts);
118  double intflux = 0.;
119  for (i = 0; i < nslice; i++) {
120  double flux = cpl_table_get_column_mean(slicepts[i]->table,
121  MUSE_PIXTABLE_DATA);
122  int npix = muse_pixtable_get_nrow(slicepts[i]);
123  flux *= npix; /* we need the sum */
124  intflux += flux;
125  nint += npix;
126 
127  char *keyword = cpl_sprintf(QC_SKYFLAT_MASTER_SLICEj_INTFLUX, i+1);
128  cpl_propertylist_update_float(aImage->header, keyword, flux);
129  cpl_free(keyword);
130  } /* for i (all slices) */
131  cpl_propertylist_update_float(aImage->header, QC_SKYFLAT_MASTER_INTFLUX, intflux);
134 
135  return intflux / nint;
136 } /* muse_skyflat_qc_integrate_flux() */
137 
138 /*---------------------------------------------------------------------------*/
145 /*---------------------------------------------------------------------------*/
146 int
147 muse_skyflat_compute(muse_processing *aProcessing,
148  muse_skyflat_params_t *aParams)
149 {
151  "muse.muse_skyflat");
152  muse_imagelist *images = muse_basicproc_load(aProcessing, aParams->nifu, bpars);
154  cpl_ensure(images, cpl_error_get_code(), -1);
155 
156  muse_combinepar *cpars = muse_combinepar_new(aProcessing->parameters,
157  "muse.muse_skyflat");
158  muse_image *masterimage = muse_combine_images(cpars, images);
159  muse_combinepar_delete(cpars);
160  if (!masterimage) {
161  cpl_msg_error(__func__, "Combining input frames failed!");
162  muse_imagelist_delete(images);
163  return -1;
164  }
165  cpl_propertylist_erase_regexp(masterimage->header, MUSE_WCS_KEYS, 0);
166 
167  muse_skyflat_qc_header(masterimage, images);
168  muse_imagelist_delete(images);
169 
170  cpl_table *tracetable = muse_table_load(aProcessing, MUSE_TAG_TRACE_TABLE,
171  aParams->nifu);
172  cpl_table *wavecaltable = muse_table_load(aProcessing, MUSE_TAG_WAVECAL_TABLE,
173  aParams->nifu);
174  if (!tracetable || !wavecaltable) {
175  cpl_msg_error(__func__, "Calibration could not be loaded:%s%s",
176  !tracetable ? " "MUSE_TAG_TRACE_TABLE : "",
177  !wavecaltable ? " "MUSE_TAG_WAVECAL_TABLE : "");
178  /* try to clean up in case some files were successfully loaded */
179  muse_image_delete(masterimage);
180  cpl_table_delete(tracetable);
181  cpl_table_delete(wavecaltable);
182  return -1;
183  }
184  double mean = muse_skyflat_qc_integrate_flux(masterimage, tracetable,
185  wavecaltable, aParams);
186  cpl_table_delete(tracetable);
187  cpl_table_delete(wavecaltable);
188  if (mean < 0) {
189  cpl_msg_error(__func__, "Flux integration failed: %s",
190  cpl_error_get_message());
191  muse_image_delete(masterimage);
192  return -1;
193  }
194 
195  /* if requested, normalize the output skyflat-field to 1 *
196  * using the mean value computed from the integrated flux */
197  if (aParams->normalize) {
198  muse_image_scale(masterimage, 1. / mean);
199  /* EXPTIME keyword does not make sense any more for normalized skyflat */
200  cpl_propertylist_erase(masterimage->header, "EXPTIME");
201  }
202 
203  /* add saturation and slice image statistics as QC */
204  muse_basicproc_qc_saturated(masterimage, QC_SKYFLAT_MASTER_PREFIX);
205  int rc = muse_processing_save_image(aProcessing, aParams->nifu, masterimage,
206  MUSE_TAG_MASTER_SKYFLAT);
207  muse_image_delete(masterimage);
208  return rc == CPL_ERROR_NONE ? 0 : -1;
209 } /* muse_skyflat_compute() */
muse_imagelist * muse_basicproc_load(muse_processing *aProcessing, unsigned char aIFU, muse_basicproc_params *aBPars)
Load the raw input files from disk and do basic processing.
Structure to hold the parameters of the muse_skyflat recipe.
Structure definition for a collection of muse_images.
void muse_image_delete(muse_image *aImage)
Deallocate memory associated to a muse_image object.
Definition: muse_image.c:84
void muse_pixtable_extracted_delete(muse_pixtable **aPixtables)
Delete a pixel table array.
int muse_image_scale(muse_image *aImage, double aScale)
Scale a muse_image with correct treatment of variance.
Definition: muse_image.c:687
cpl_size muse_pixtable_extracted_get_size(muse_pixtable **aPixtables)
Get the size of an array of extracted pixel tables.
cpl_size muse_pixtable_get_nrow(muse_pixtable *aPixtable)
get the number of rows within the pixel table
muse_pixtable ** muse_pixtable_extracted_get_slices(muse_pixtable *aPixtable)
Extract one pixel table per IFU and slice.
cpl_image * data
the data extension
Definition: muse_image.h:47
void muse_imagelist_delete(muse_imagelist *aList)
Free the memory of the MUSE image list.
muse_basicproc_params * muse_basicproc_params_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new structure of basic processing parameters.
muse_image * muse_combine_images(muse_combinepar *aCPars, muse_imagelist *aImages)
Combine several images into one.
Definition: muse_combine.c:742
Structure definition of MUSE three extension FITS file.
Definition: muse_image.h:41
void muse_basicproc_params_delete(muse_basicproc_params *aBPars)
Free a structure of basic processing parameters.
cpl_propertylist * header
the FITS header
Definition: muse_image.h:73
unsigned int muse_imagelist_get_size(muse_imagelist *aList)
Return the number of stored images.
void muse_combinepar_delete(muse_combinepar *aCPars)
Clear the combination parameters.
Definition: muse_combine.c:716
cpl_error_code muse_pixtable_restrict_wavelength(muse_pixtable *aPixtable, double aLow, double aHigh)
Restrict a pixel table to a certain wavelength range.
Structure definition of MUSE pixel table.
muse_image * muse_imagelist_get(muse_imagelist *aList, unsigned int aIdx)
Get the muse_image of given list index.
muse_combinepar * muse_combinepar_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new set of combination parameters.
Definition: muse_combine.c:673
muse_pixtable * muse_pixtable_create(muse_image *aImage, cpl_table *aTrace, cpl_table *aWave, cpl_table *aGeoTable)
Create the pixel table for one CCD.
cpl_error_code muse_basicproc_stats_append_header(cpl_image *aImage, cpl_propertylist *aHeader, const char *aPrefix, unsigned aStats)
Compute image statistics of an image and add them to a header.
int muse_processing_save_image(muse_processing *aProcessing, int aIFU, muse_image *aImage, const char *aTag)
Save a computed MUSE image to disk.
cpl_error_code muse_image_reject_from_dq(muse_image *aImage)
Reject pixels of a muse_image depending on its DQ data.
Definition: muse_image.c:848
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:452
Structure of basic processing parameters.
int normalize
Normalize the master skyflat to the flux integrated over the given wavelength range.
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
double lambdamax
Maximum wavelength to use for flux integration.
double lambdamin
Minimum wavelength to use for flux integration.
cpl_parameterlist * parameters
cpl_error_code muse_basicproc_qc_saturated(muse_image *aImage, const char *aPrefix)
Add QC parameter about saturated pixels to a muse_image.