MUSE Pipeline Reference Manual  0.18.5
muse_scipost.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 <muse.h>
30 #include "muse_scipost_z.h"
31 
32 /*---------------------------------------------------------------------------*
33  * Functions code *
34  *---------------------------------------------------------------------------*/
35 
36 /*----------------------------------------------------------------------------*/
52 /*----------------------------------------------------------------------------*/
53 int
54 muse_scipost_compute(muse_processing *aProcessing,
55  muse_scipost_params_t *aParams)
56 {
57  muse_postproc_properties *prop = muse_postproc_properties_new(MUSE_POSTPROC_SCIPOST);
58  /* per-exposure parameters */
59  prop->lambdamin = aParams->lambdamin;
60  prop->lambdamax = aParams->lambdamax;
61  prop->lambdaref = aParams->lambdaref;
62  prop->darcheck = MUSE_POSTPROC_DARCHECK_NONE;
63  if (aParams->darcheck == MUSE_SCIPOST_PARAM_DARCHECK_CHECK) {
64  prop->darcheck = MUSE_POSTPROC_DARCHECK_CHECK;
65  } else if (aParams->darcheck == MUSE_SCIPOST_PARAM_DARCHECK_CORRECT) {
66  prop->darcheck = MUSE_POSTPROC_DARCHECK_CORRECT;
67  }
68  /* flux calibration */
69  prop->response = muse_table_load(aProcessing, MUSE_TAG_STD_RESPONSE, 0);
70  prop->extinction = muse_table_load(aProcessing, MUSE_TAG_EXTINCT_TABLE, 0);
71  prop->telluric = muse_table_load(aProcessing, MUSE_TAG_STD_TELLURIC, 0);
72  /* astrometric correction */
73  if (aParams->astrometry) {
74  prop->wcs = muse_propertylist_load(aProcessing, MUSE_TAG_ASTROMETRY_WCS);
75  if (!prop->wcs) {
76  /* if it was not in the input, create a default WFM astrometry */
77  cpl_msg_warning(__func__, "Using default MUSE WFM astrometry, output "
78  "world coordinates will be inaccurate!");
79  prop->wcs = muse_wcs_create_default();
80  }
81  }
82 
83  const struct {
84  int par;
85  muse_postproc_skymethod postproc;
86  } skymethod[] = {
87  { MUSE_SCIPOST_PARAM_SKYMETHOD_NONE, MUSE_POSTPROC_SKYMETHOD_NONE },
88  { MUSE_SCIPOST_PARAM_SKYMETHOD_SUBTRACT_MODEL, MUSE_POSTPROC_SKYMETHOD_NONE },
89  { MUSE_SCIPOST_PARAM_SKYMETHOD_MODEL, MUSE_POSTPROC_SKYMETHOD_MODEL },
90  { MUSE_SCIPOST_PARAM_SKYMETHOD_ROW_BY_ROW, MUSE_POSTPROC_SKYMETHOD_ROWBYROW },
91  { MUSE_SCIPOST_PARAM_SKYMETHOD_INVALID_VALUE, MUSE_POSTPROC_SKYMETHOD_MODEL },
92  };
93  prop->skymethod = MUSE_POSTPROC_SKYMETHOD_MODEL;
94  int i_method;
95  for (i_method = 0;
96  skymethod[i_method].par != MUSE_SCIPOST_PARAM_SKYMETHOD_INVALID_VALUE;
97  i_method++) {
98  if (skymethod[i_method].par == aParams->skymethod) {
99  prop->skymethod = skymethod[i_method].postproc;
100  break;
101  }
102  }
103 
104  prop->skymodel_params.fraction = aParams->skymodel_fraction;
105  prop->skymodel_params.sampling = aParams->skymodel_sampling;
106  prop->skymodel_params.csampling = aParams->skymodel_csampling;
107 
108  prop->sky = muse_sky_master_new();
109  if (aParams->skymethod == MUSE_SCIPOST_PARAM_SKYMETHOD_SUBTRACT_MODEL) {
110  prop->sky->lsf = muse_processing_lsf_params_load(aProcessing, 0);
111  if (prop->sky->lsf != NULL) {
112  prop->sky->lines = muse_sky_lines_load(aProcessing);
113  if (prop->sky->lines == NULL) {
114  cpl_msg_warning(__func__, "Sky lines missing for subtraction");
115  }
116  }
117  prop->sky->continuum = muse_sky_continuum_load(aProcessing);
118  } else if (aParams->skymethod == MUSE_SCIPOST_PARAM_SKYMETHOD_MODEL) {
119  prop->sky->lsf = muse_processing_lsf_params_load(aProcessing, 0);
120  if (prop->sky->lsf == NULL) {
121  cpl_msg_error(__func__, "Missing required LSF parameter frames for sky model");
122  }
123  prop->sky->lines = muse_sky_lines_load(aProcessing);
124  if (prop->sky->lines == NULL) {
125  cpl_msg_error(__func__, "Missing required sky lines frame for sky model");
126  }
127  if ((prop->sky->lsf == NULL) || (prop->sky->lines == NULL)) {
129  return -1;
130  }
131  prop->sky->continuum = muse_sky_continuum_load(aProcessing);
132  prop->sky_mask = muse_processing_mask_load(aProcessing, MUSE_TAG_SKY_MASK);
133  }
134 
135  /* sort input pixel tables into different exposures */
136  prop->exposures = muse_processing_sort_exposures(aProcessing);
137  if (!prop->exposures) {
138  cpl_msg_error(__func__, "no science exposures found in input");
140  return -1;
141  }
142  int nexposures = cpl_table_get_nrow(prop->exposures);
143 
144  /* now process all the pixel tables, do it separately for each exposure */
145  /* allocate one additional element for NULL termination */
146  muse_pixtable **pixtables = cpl_calloc(nexposures + 1, sizeof(muse_pixtable *));
147  int i;
148  for (i = 0; i < nexposures; i++) {
149  pixtables[i] = muse_postproc_process_exposure(prop, i);
150  if (!pixtables[i]) {
151  int i2;
152  for (i2 = 0; i2 <= i; i2++) {
153  muse_pixtable_delete(pixtables[i2]);
154  } /* for i2 */
155  cpl_free(pixtables);
157  return -1; /* enough error messages, just return */
158  }
159  if (aParams->save_individual) {
160  muse_processing_save_table(aProcessing, -1, pixtables[i], NULL,
161  MUSE_TAG_PIXTABLE_REDUCED,
163  }
164  if (aParams->save_positioned) {
165  /* duplicate table to not mess with the coordinates in the individual *
166  * pixel tables, which are still needed when combining the exposures */
167  muse_pixtable *pt = muse_pixtable_duplicate(pixtables[i]);
168  double ra = muse_pfits_get_ra(pt->header),
169  dec = muse_pfits_get_dec(pt->header);
170  muse_wcs_position_celestial(pt, ra, dec);
171  muse_processing_save_table(aProcessing, -1, pt, NULL,
172  MUSE_TAG_PIXTABLE_POSITIONED,
175  }
176  } /* for i (exposures) */
178 
179  /* now combine the possibly more than one exposures */
180  muse_pixtable *bigpixtable = NULL;
181  if (nexposures > 1) {
183  cpl_error_code rc = muse_xcombine_weights(pixtables, weight);
184  if (rc != CPL_ERROR_NONE) {
185  cpl_msg_error(__func__, "weighting the pixel tables didn't work: %s",
186  cpl_error_get_message());
187  for (i = 0; i < nexposures; i++) {
188  muse_pixtable_delete(pixtables[i]);
189  } /* for i (exposures) */
190  cpl_free(pixtables);
191  return -1;
192  }
193  /* combine individual pixel tables and delete them */
194  bigpixtable = muse_xcombine_tables(pixtables);
195  if (!bigpixtable) {
196  cpl_msg_error(__func__, "combining the pixel tables didn't work: %s",
197  cpl_error_get_message());
198  for (i = 0; i < nexposures; i++) {
199  muse_pixtable_delete(pixtables[i]);
200  } /* for i (exposures) */
201  cpl_free(pixtables);
202  return -1;
203  }
204  } else {
205  bigpixtable = pixtables[0];
206  muse_wcs_position_celestial(bigpixtable,
207  muse_pfits_get_ra(bigpixtable->header),
208  muse_pfits_get_dec(bigpixtable->header));
209  }
210  cpl_free(pixtables);
211 
212  muse_resampling_type resample
215  rp->dx = aParams->dx;
216  rp->dy = aParams->dy;
217  rp->dlambda = aParams->dlambda;
218  rp->crtype = muse_postproc_get_cr_type(aParams->crtype_s);
219  rp->crsigma = aParams->crsigma;
220  rp->ld = aParams->ld;
221  rp->rc = aParams->rc;
222  rp->pfx = aParams->pixfrac;
223  rp->pfy = aParams->pixfrac;
224  rp->pfl = aParams->pixfrac;
225  cpl_propertylist *outwcs = muse_postproc_cube_load_output_wcs(aProcessing);
226  muse_resampling_params_set_wcs(rp, outwcs);
227  cpl_propertylist_delete(outwcs);
229  cpl_error_code rc = muse_postproc_cube_resample_and_collapse(aProcessing,
230  bigpixtable,
231  format, rp,
232  aParams->filter);
234  if (aParams->save_combined) {
235  muse_processing_save_table(aProcessing, -1, bigpixtable, NULL,
236  MUSE_TAG_PIXTABLE_COMBINED,
238  }
239  if (aParams->stacked) {
240  cpl_msg_debug(__func__, "additional output as column-stacked image");
241  muse_image *img = muse_resampling_image(bigpixtable,
243  aParams->dx, aParams->dlambda);
244  muse_processing_save_image(aProcessing, -1, img, MUSE_TAG_OBJECT_RESAMPLED);
245  muse_image_delete(img);
246  }
247 
248  muse_pixtable_delete(bigpixtable);
249 
250  return rc == CPL_ERROR_NONE ? 0 : -1;
251 } /* muse_scipost_compute() */
muse_image * muse_resampling_image(muse_pixtable *aPixtable, muse_resampling_type aMethod, double aDX, double aDLambda)
Resample a pixel table onto a two-dimensional regular grid.
cpl_propertylist * muse_postproc_cube_load_output_wcs(muse_processing *aProcessing)
Find a file with a usable output WCS in the input frameset.
muse_postproc_properties * muse_postproc_properties_new(muse_postproc_type aType)
Create a post-processing properties object.
Definition: muse_postproc.c:66
muse_postproc_skymethod
Method of sky subtraction to apply.
Definition: muse_postproc.h:65
void muse_image_delete(muse_image *aImage)
Deallocate memory associated to a muse_image object.
Definition: muse_image.c:84
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
muse_pixtable * muse_pixtable_duplicate(muse_pixtable *aPixtable)
Make a copy of the pixtanle.
int save_combined
If true, save the fully reduced and combined pixel table for the full set of exposures. The difference to save_positioned is that here all pixel tables are combined into one, with an added "weight" column. This is useful, if only the final resampling step is to be done separately.
double muse_pfits_get_ra(const cpl_propertylist *aHeaders)
find out the right ascension
Definition: muse_pfits.c:206
cpl_error_code muse_resampling_params_set_wcs(muse_resampling_params *aParams, const cpl_propertylist *aWCS)
Set an output WCS (and wavelength scale) in the resampling parameters.
muse_xcombine_types muse_postproc_get_weight_type(const char *aWeightString)
Select correct weighting type for weight string.
cpl_table * muse_sky_lines_load(muse_processing *)
Load the sky data files.
muse_resampling_crstats_type muse_postproc_get_cr_type(const char *aCRTypeString)
Select correct cosmic ray rejection type for crtype string.
int ld
Number of adjacent pixels to take into account during resampling in all three directions (loop distan...
Structure definition of MUSE three extension FITS file.
Definition: muse_image.h:41
cpl_error_code muse_postproc_cube_resample_and_collapse(muse_processing *aProcessing, muse_pixtable *aPixtable, muse_cube_type aFormat, muse_resampling_params *aParams, const char *aFilter)
High level function to resample to a datacube and collapse that to an image of the field of view and ...
muse_mask * muse_processing_mask_load(muse_processing *aProcessing, const char *aTag)
Load a mask file and its FITS header.
cpl_error_code muse_xcombine_weights(muse_pixtable **aPixtables, muse_xcombine_types aWeighting)
compute the weights for combination of two or more exposures
Definition: muse_xcombine.c:82
muse_postproc_skymethod skymethod
Definition: muse_postproc.h:98
const char * filter
The filter name(s) to be used for the output field-of-view image. Each name has to correspond to an E...
muse_resampling_crstats_type crtype
const char * weight_s
Type of weighting scheme to use when combining multiple exposures. (as string)
cpl_table * muse_sky_continuum_load(muse_processing *)
Load the SKY_CONTINUUM spectrum.
Structure definition of MUSE pixel table.
muse_cube_type muse_postproc_get_cube_format(const char *aFormatString)
Select correct cube format for format string.
double dy
Vertical step size for resampling (in arcsec or pixel). The following defaults are taken when this va...
cpl_table * lines
Table of Atmospheric emission lines and their intensities.
Definition: muse_sky.h:63
muse_resampling_params * muse_resampling_params_new(muse_resampling_type aMethod)
Create the resampling parameters structure.
double pixfrac
Pixel down-scaling factor for the "drizzle" resampling method.
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
double rc
Critical radius for the "renka" resampling method.
muse_cube_type
cpl_propertylist * wcs
Definition: muse_postproc.h:97
Structure definition of the post-processing properties.
Definition: muse_postproc.h:87
double skymodel_fraction
Fraction of the image to be considered as sky. If an input sky mask is provided, the fraction is appl...
void muse_postproc_properties_delete(muse_postproc_properties *aProp)
Free memory taken by a post-processing properties object and all its components.
Definition: muse_postproc.c:92
const char * crtype_s
Type of statistics used for detection of cosmic rays during final resampling. "iraf" uses the varianc...
int darcheck
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
double skymodel_sampling
Spectral sampling of the sky spectrum [Angstrom].
double muse_pfits_get_dec(const cpl_propertylist *aHeaders)
find out the declination
Definition: muse_pfits.c:224
int astrometry
If false, skip any astrometric calibration, even if one was passed in the input set of files...
double skymodel_csampling
Spectral sampling of the continuum spectrum [Angstrom].
const char * format_s
Type of output file format, "Cube" is a standard FITS cube with NAXIS=3 and multiple extensions (for ...
double lambdamax
Cut off the data above this wavelength after loading the pixel table(s).
int muse_processing_save_image(muse_processing *aProcessing, int aIFU, muse_image *aImage, const char *aTag)
Save a computed MUSE image to disk.
muse_resampling_type muse_postproc_get_resampling_type(const char *aResampleString)
Select correct resampling type for resample string.
double dx
Horizontal step size for resampling (in arcsec or pixel). The following defaults are taken when this ...
muse_pixtable * muse_xcombine_tables(muse_pixtable **aPixtables)
combine the pixel tables of several exposures into one
muse_sky_master * sky
Definition: muse_postproc.h:99
int skymethod
The method used to subtract the sky background. "model" should work in all cases, it uses a global sk...
Structure to hold the parameters of the muse_scipost recipe.
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
double crsigma
Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative va...
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.
muse_resampling_type
Resampling types.
Resampling parameters.
void muse_resampling_params_delete(muse_resampling_params *aParams)
Delete a resampling parameters structure.
muse_lsf_params ** muse_processing_lsf_params_load(muse_processing *aProcessing, int aIFU)
Load slice LSF parameters.
Definition: muse_lsf.c:392
cpl_propertylist * muse_propertylist_load(muse_processing *aProcessing, const char *aTag)
load a propertylist according to its tag
Definition: muse_utils.c:520
void * muse_postproc_process_exposure(muse_postproc_properties *aProp, unsigned int aIndex)
Merge and process pixel tables from one exposure.
cpl_table * continuum
Continuum flux table
Definition: muse_sky.h:65
cpl_error_code muse_wcs_position_celestial(muse_pixtable *aPixtable, double aRA, double aDEC)
Convert native to celestial spherical coordinates in a pixel table.
Definition: muse_wcs.c:1132
muse_sky_params skymodel_params
cpl_table * muse_processing_sort_exposures(muse_processing *aProcessing)
Sort input frames (containing lists of pixel table filenames) into different exposures.
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
int save_individual
If true, save fully reduced pixel table for each individual exposure as output product.
int save_positioned
If true, save fully reduced and positioned pixel table for each individual exposure as output product...
muse_postproc_darcheck darcheck
Definition: muse_postproc.h:93
muse_xcombine_types
Xposure combination types.
Definition: muse_xcombine.h:45
double dlambda
Wavelength step size (in Angstrom). Natural instrument sampling is used, if this is 0...
muse_lsf_params ** lsf
LSF parameter for the resampled spectrum.
Definition: muse_sky.h:67
int stacked
If true, write an additional output file in form of a 2D stacked image (x direction is pseudo-spatial...
const char * resample_s
The resampling technique to use for the final output cube. (as string)
cpl_propertylist * header
The FITS header.
muse_sky_master * muse_sky_master_new(void)
Create a muse_sky_master structure.
cpl_propertylist * muse_wcs_create_default(void)
Create FITS headers containing a default (relative) WCS.
Definition: muse_wcs.c:838