MUSE Pipeline Reference Manual  0.18.5
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  *
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_dark_z.h"
37 
38 /*---------------------------------------------------------------------------*
39  * Functions code *
40  *---------------------------------------------------------------------------*/
41 
42 /*---------------------------------------------------------------------------*/
49 /*---------------------------------------------------------------------------*/
50 #define DARK_HALFSIZE 9
51 #define DARK_NSAMPLES 300
52 static void
53 muse_dark_qc_header(muse_image *aImage, int aBad, double aNorm,
54  muse_imagelist *aList)
55 {
56  cpl_msg_debug(__func__, "Adding QC keywords");
57 
58  /* copy saturation numbers from the input images */
59  unsigned int i;
60  for (i = 0; i < muse_imagelist_get_size(aList); i++) {
61  char *keyword = cpl_sprintf(QC_DARK_PREFIXi" "QC_BASIC_NSATURATED, i+1);
62  int nsaturated = cpl_propertylist_get_int(muse_imagelist_get(aList, i)->header,
63  MUSE_HDR_TMP_NSAT);
64  cpl_propertylist_update_int(aImage->header, keyword, nsaturated);
65  cpl_free(keyword);
66  } /* for i (all images in list) */
67 
68  /* properties of the resulting master frame */
69  cpl_propertylist_append_int(aImage->header, QC_DARK_MASTER_NBADPIX, aBad);
70 
71  unsigned stats = CPL_STATS_MEDIAN | CPL_STATS_MEAN | CPL_STATS_STDEV
72  | CPL_STATS_MIN | CPL_STATS_MAX;
74  QC_DARK_MASTER_PREFIX, stats);
75 
76  /* use the bias-level computation function to get an accurate dark current */
77  double dval = 0., derr = 0.;
78  cpl_flux_get_bias_window(aImage->data, NULL, DARK_HALFSIZE, DARK_NSAMPLES,
79  &dval, &derr);
80  /* values per hour for output */
81  double exptime = muse_pfits_get_exptime(aImage->header);
82  dval *= 3600. / exptime;
83  derr *= 3600. / exptime;
84  cpl_propertylist_append_float(aImage->header, QC_DARK_MASTER_DARKVALUE, dval);
85  cpl_propertylist_append_float(aImage->header, QC_DARK_MASTER_DARKERROR, derr);
86 
87  /* warn about unlikely values */
88  if (dval < 0. || dval > 10.) {
89  cpl_msg_warning(__func__, "Could not determine reliable dark current "
90  "(found %.3f+/-%.3f count/pix/h)", dval, derr);
91  if (aNorm < 1000.) {
92  cpl_msg_warning(__func__, "May be due to low dark time (%.2f s)",
93  aNorm);
94  }
95  return;
96  }
97 
98  /* output info if good values found */
99  cpl_msg_info(__func__, "Dark current is %.3f+/-%.3f count/pix/h",
100  dval, derr);
101 } /* muse_dark_qc_header() */
102 
103 /*---------------------------------------------------------------------------*/
110 /*---------------------------------------------------------------------------*/
111 int
112 muse_dark_compute(muse_processing *aProcessing, muse_dark_params_t *aParams)
113 {
115  "muse.muse_dark");
116  muse_imagelist *images = muse_basicproc_load(aProcessing, aParams->nifu, bpars);
118  cpl_ensure(images, cpl_error_get_code(), -1);
119 
120  /* exposure time of the first input image to be used later for normalization */
121  double exptime0 =
122  muse_pfits_get_exptime(muse_imagelist_get(images, 0)->header);
123 
124  muse_combinepar *cpars = muse_combinepar_new(aProcessing->parameters,
125  "muse.muse_dark");
126  muse_image *masterimage = muse_combine_images(cpars, images);
127  muse_combinepar_delete(cpars);
128  if (!masterimage) {
129  cpl_msg_error(__func__, "Combining input frames failed!");
130  muse_imagelist_delete(images);
131  return -1;
132  }
133  cpl_propertylist_erase_regexp(masterimage->header, MUSE_WCS_KEYS, 0);
134  int nbad = muse_quality_dark_badpix(masterimage, 0, aParams->hotsigma);
135 
136  if (aParams->normalize > 0) {
137  /* all frames were scaled to exposure time of the first frame *
138  * so use that to normalize the master dark to 1s exposure time */
139  cpl_msg_info(__func__, "Normalize master dark image to %.3fs",
140  aParams->normalize);
141  double f = exptime0 / aParams->normalize;
142  muse_image_scale(masterimage, 1. / f);
143  cpl_propertylist_update_double(masterimage->header, "EXPTIME",
144  aParams->normalize);
145  char *comment = cpl_sprintf("[s] Master dark normalized to %.3fs exposure "
146  "time", aParams->normalize);
147  cpl_propertylist_set_comment(masterimage->header, "EXPTIME", comment);
148  cpl_free(comment);
149  }
150 
151  muse_dark_qc_header(masterimage, nbad, exptime0, images);
152  muse_imagelist_delete(images);
153  muse_basicproc_qc_saturated(masterimage, QC_DARK_MASTER_PREFIX);
154  int rc = muse_processing_save_image(aProcessing, aParams->nifu, masterimage,
155  MUSE_TAG_MASTER_DARK);
156  muse_image_delete(masterimage);
157 
158  return rc == CPL_ERROR_NONE ? 0 : -1;
159 } /* 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:84
int muse_image_scale(muse_image *aImage, double aScale)
Scale a muse_image with correct treatment of variance.
Definition: muse_image.c:687
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
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:673
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:278
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.