MUSE Pipeline Reference Manual  2.1.1
muse_dark.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-2013 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 <stdio.h>
30 #include <float.h>
31 #include <math.h>
32 #include <string.h>
33 #include <cpl.h>
34 #include <muse.h>
35 #include "muse_dark_z.h"
36 
37 /*---------------------------------------------------------------------------*
38  * Functions code *
39  *---------------------------------------------------------------------------*/
40 
41 /*---------------------------------------------------------------------------*/
48 /*---------------------------------------------------------------------------*/
49 #define DARK_HALFSIZE 9
50 #define DARK_NSAMPLES 300
51 static void
52 muse_dark_qc_header(muse_image *aImage, int aBad, double aNorm,
53  muse_imagelist *aList)
54 {
55  cpl_msg_debug(__func__, "Adding QC keywords");
56 
57  /* copy saturation numbers from the input images */
58  unsigned int k;
59  for (k = 0; k < muse_imagelist_get_size(aList); k++) {
60  char *keyword = cpl_sprintf(QC_DARK_PREFIXi" "QC_BASIC_NSATURATED, k+1);
61  int nsaturated = cpl_propertylist_get_int(muse_imagelist_get(aList, k)->header,
62  MUSE_HDR_TMP_NSAT);
63  cpl_propertylist_update_int(aImage->header, keyword, nsaturated);
64  cpl_free(keyword);
65  } /* for k (all images in list) */
66 
67  /* properties of the resulting master frame */
68  cpl_propertylist_append_int(aImage->header, QC_DARK_MASTER_NBADPIX, aBad);
69 
70  unsigned stats = CPL_STATS_MEDIAN | CPL_STATS_MEAN | CPL_STATS_STDEV
71  | CPL_STATS_MIN | CPL_STATS_MAX;
73  QC_DARK_MASTER_PREFIX, stats);
74 
75  /* use the bias-level computation function to get an accurate dark current */
76  double dval = 0., derr = 0.;
77  cpl_flux_get_bias_window(aImage->data, NULL, DARK_HALFSIZE, DARK_NSAMPLES,
78  &dval, &derr);
79  /* values per hour for output */
80  double exptime = muse_pfits_get_exptime(aImage->header);
81  dval *= 3600. / exptime;
82  derr *= 3600. / exptime;
83  cpl_propertylist_append_float(aImage->header, QC_DARK_MASTER_DARKVALUE, dval);
84  cpl_propertylist_append_float(aImage->header, QC_DARK_MASTER_DARKERROR, derr);
85 
86  /* warn about unlikely values */
87  if (dval < 0. || dval > 10.) {
88  cpl_msg_warning(__func__, "Could not determine reliable dark current "
89  "(found %.3f+/-%.3f count/pix/h)", dval, derr);
90  if (aNorm < 1000.) {
91  cpl_msg_warning(__func__, "May be due to low dark time (%.2f s)",
92  aNorm);
93  }
94  return;
95  }
96 
97  /* output info if good values found */
98  cpl_msg_info(__func__, "Dark current is %.3f+/-%.3f count/pix/h",
99  dval, derr);
100 } /* muse_dark_qc_header() */
101 
102 /*---------------------------------------------------------------------------*/
109 /*---------------------------------------------------------------------------*/
110 int
111 muse_dark_compute(muse_processing *aProcessing, muse_dark_params_t *aParams)
112 {
114  "muse.muse_dark");
115  muse_imagelist *images = muse_basicproc_load(aProcessing, aParams->nifu, bpars);
117  cpl_ensure(images, cpl_error_get_code(), -1);
118 
119  /* exposure time of the first input image to be used later for normalization */
120  double exptime0 =
121  muse_pfits_get_exptime(muse_imagelist_get(images, 0)->header);
122 
123  muse_combinepar *cpars = muse_combinepar_new(aProcessing->parameters,
124  "muse.muse_dark");
125  muse_image *masterimage = muse_combine_images(cpars, images);
126  muse_combinepar_delete(cpars);
127  if (!masterimage) {
128  cpl_msg_error(__func__, "Combining input frames failed!");
129  muse_imagelist_delete(images);
130  return -1;
131  }
132  cpl_propertylist_erase_regexp(masterimage->header, MUSE_WCS_KEYS, 0);
133  int nbad = muse_quality_dark_badpix(masterimage, 0, aParams->hotsigma);
134 
135  if (aParams->normalize > 0) {
136  /* all frames were scaled to exposure time of the first frame *
137  * so use that to normalize the master dark to 1s exposure time */
138  cpl_msg_info(__func__, "Normalize master dark image to %.3fs",
139  aParams->normalize);
140  double f = exptime0 / aParams->normalize;
141  muse_image_scale(masterimage, 1. / f);
142  cpl_propertylist_update_double(masterimage->header, "EXPTIME",
143  aParams->normalize);
144  char *comment = cpl_sprintf("[s] Master dark normalized to %.3fs exposure "
145  "time", aParams->normalize);
146  cpl_propertylist_set_comment(masterimage->header, "EXPTIME", comment);
147  cpl_free(comment);
148  }
149 
150  muse_dark_qc_header(masterimage, nbad, exptime0, images);
151  muse_imagelist_delete(images);
152  muse_basicproc_qc_saturated(masterimage, QC_DARK_MASTER_PREFIX);
153  int rc = muse_processing_save_image(aProcessing, aParams->nifu, masterimage,
154  MUSE_TAG_MASTER_DARK);
155  muse_image_delete(masterimage);
156 
157  return rc == CPL_ERROR_NONE ? 0 : -1;
158 } /* muse_dark_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 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:85
int muse_image_scale(muse_image *aImage, double aScale)
Scale a muse_image with correct treatment of variance.
Definition: muse_image.c:703
cpl_image * data
the data extension
Definition: muse_image.h:46
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:741
Structure definition of MUSE three extension FITS file.
Definition: muse_image.h:40
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:72
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:715
#define MUSE_WCS_KEYS
regular expression for WCS properties
Definition: muse_wcs.h:48
muse_image * muse_imagelist_get(muse_imagelist *aList, unsigned int aIdx)
Get the muse_image of given list index.
double hotsigma
Sigma level, in terms of median deviation above the median dark level, above which a pixel is detecte...
Definition: muse_dark_z.h:91
Structure to hold the parameters of the muse_dark recipe.
Definition: muse_dark_z.h:48
muse_combinepar * muse_combinepar_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new set of combination parameters.
Definition: muse_combine.c:672
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.
int muse_quality_dark_badpix(muse_image *aDark, double aSigmaLo, double aSigmaHi)
Find bad (especially hot) pixels (in a master dark).
Definition: muse_quality.c:80
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
Definition: muse_dark_z.h:50
double muse_pfits_get_exptime(const cpl_propertylist *aHeaders)
find out the exposure time
Definition: muse_pfits.c:382
double normalize
Normalize the master dark to this exposure time (in seconds). To disable normalization, set this to a negative value.
Definition: muse_dark_z.h:88
Structure of basic processing parameters.
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.