MUSE Pipeline Reference Manual  1.0.2
muse_standard.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 
31 #include <muse.h>
32 #include "muse_standard_z.h"
33 
34 /*---------------------------------------------------------------------------*
35  * Functions code *
36  *---------------------------------------------------------------------------*/
37 
38 /*----------------------------------------------------------------------------*/
51 /*----------------------------------------------------------------------------*/
52 int
53 muse_standard_compute(muse_processing *aProcessing,
54  muse_standard_params_t *aParams)
55 {
56  muse_postproc_properties *prop = muse_postproc_properties_new(MUSE_POSTPROC_STANDARD);
57  /* per-exposure parameters */
58  prop->lambdamin = aParams->lambdamin;
59  prop->lambdamax = aParams->lambdamax;
60  prop->lambdaref = aParams->lambdaref;
61  prop->darcheck = MUSE_POSTPROC_DARCHECK_NONE;
62  if (aParams->darcheck == MUSE_STANDARD_PARAM_DARCHECK_CHECK) {
63  prop->darcheck = MUSE_POSTPROC_DARCHECK_CHECK;
64  } else if (aParams->darcheck == MUSE_STANDARD_PARAM_DARCHECK_CORRECT) {
65  prop->darcheck = MUSE_POSTPROC_DARCHECK_CORRECT;
66  }
67  /* setup and check flux integration profiles */
69  if (aParams->profile == MUSE_STANDARD_PARAM_PROFILE_MOFFAT) {
71  } else if (aParams->profile == MUSE_STANDARD_PARAM_PROFILE_CIRCLE) {
73  } else if (aParams->profile == MUSE_STANDARD_PARAM_PROFILE_SQUARE) {
75  } else if (aParams->profile != MUSE_STANDARD_PARAM_PROFILE_GAUSSIAN) {
76  cpl_msg_error(__func__, "unknown profile \"%s\"", aParams->profile_s);
78  return -1;
79  }
80  /* flux reference */
81  prop->refframe = muse_frameset_find_master(aProcessing->inframes,
82  MUSE_TAG_STD_FLUX_TABLE, 0);
83  if (!prop->refframe) {
84  cpl_msg_error(__func__, "Required input %s not found in input files",
85  MUSE_TAG_STD_FLUX_TABLE);
86  cpl_error_set_message(__func__, CPL_ERROR_NULL_INPUT,
87  MUSE_TAG_STD_FLUX_TABLE" missing");
89  return -1;
90  }
92  if (aParams->select == MUSE_STANDARD_PARAM_SELECT_DISTANCE) {
94  } else if (aParams->select != MUSE_STANDARD_PARAM_SELECT_FLUX) {
95  cpl_msg_error(__func__, "unknown selection \"%s\"", aParams->select_s);
97  return -1;
98  }
100  if (aParams->smooth == MUSE_STANDARD_PARAM_SMOOTH_MEDIAN) {
102  } else if (aParams->smooth == MUSE_STANDARD_PARAM_SMOOTH_NONE) {
104  } else if (aParams->smooth != MUSE_STANDARD_PARAM_SMOOTH_PPOLY) {
105  cpl_msg_error(__func__, "unknown smoothing \"%s\"", aParams->smooth_s);
107  return -1;
108  }
109  prop->extinction = muse_table_load(aProcessing, MUSE_TAG_EXTINCT_TABLE, 0);
110  /* telluric regions */
111  prop->tellregions = muse_table_load(aProcessing, MUSE_TAG_TELLREG, 0);
112  if (!prop->tellregions) {
113  cpl_msg_debug(__func__, "%s could not be found or loaded, using defaults",
114  MUSE_TAG_TELLREG);
115  }
116 
117  /* sort input pixel tables into different exposures */
118  prop->exposures = muse_processing_sort_exposures(aProcessing);
119  if (!prop->exposures) {
120  cpl_msg_error(__func__, "No standard star exposures found in input!");
122  return -1;
123  }
124  int nexposures = cpl_table_get_nrow(prop->exposures);
125 
126  /* now process all the pixel tables, do it separately for each exposure */
127  muse_flux_object **fluxobjs = cpl_calloc(nexposures, sizeof(muse_flux_object *));
128  int i;
129  for (i = 0; i < nexposures; i++) {
130  fluxobjs[i] = muse_postproc_process_exposure(prop, i, NULL);
131  if (!fluxobjs[i]) {
132  int i2;
133  for (i2 = 0; i2 <= i; i2++) {
134  muse_flux_object_delete(fluxobjs[i2]);
135  } /* for i2 */
136  cpl_free(fluxobjs);
138  return -1; /* enough error messages, just return */
139  }
140  } /* for i (exposures) */
142 
143  /* XXX now combine the possibly more than one response tables */
144 
145  cpl_error_code rc = CPL_ERROR_NONE;
146  cpl_array *filters = muse_cplarray_new_from_delimited_string(aParams->filter,
147  ",");
148  for (i = 0; i < nexposures; i++) {
149  int ifilt, ipos = 0, nfilt = cpl_array_get_size(filters);
150  for (ifilt = 0; ifilt < nfilt; ifilt++) {
151  /* try to find and load the filter from a table */
152  cpl_table *filter = muse_table_load_filter(aProcessing,
153  cpl_array_get_string(filters, ifilt));
154  if (!filter) {
155  continue;
156  }
157  muse_image *fov = muse_datacube_collapse(fluxobjs[i]->cube, filter);
158  if (!fluxobjs[i]->cube->recimages) {
159  fluxobjs[i]->cube->recimages = muse_imagelist_new();
160  fluxobjs[i]->cube->recnames = cpl_array_new(0, CPL_TYPE_STRING);
161  }
162  muse_imagelist_set(fluxobjs[i]->cube->recimages, fov, ipos);
163  cpl_array_set_size(fluxobjs[i]->cube->recnames, ipos+1);
164  cpl_array_set_string(fluxobjs[i]->cube->recnames, ipos,
165  cpl_array_get_string(filters, ifilt));
166  cpl_table_delete(filter);
167  ipos++;
168  } /* for ifilt (all filters) */
169  muse_postproc_qc_fwhm(aProcessing, fluxobjs[i]->cube); /* before NANs! */
170  muse_datacube_convert_dq(fluxobjs[i]->cube);
171  muse_processing_save_cube(aProcessing, -1, fluxobjs[i]->cube,
172  MUSE_TAG_CUBE_STD, MUSE_CUBE_TYPE_FITS);
173  /* save the integrated flux image as well */
174  muse_processing_save_image(aProcessing, -1, fluxobjs[i]->intimage,
175  MUSE_TAG_STD_INTIMAGE);
176 
177  /* save the response-curve and the telluric correction */
178  cpl_propertylist *header = cpl_propertylist_duplicate(fluxobjs[i]->cube->header);
179  cpl_propertylist_erase_regexp(header, "^NAXIS|^EXPTIME$|"MUSE_WCS_KEYS, 0);
180  char *objorig = cpl_strdup(cpl_propertylist_get_string(header, "OBJECT"));
181  char *object = cpl_sprintf("Response curve (%s)", objorig);
182  cpl_propertylist_update_string(header, "OBJECT", object);
183  rc = muse_processing_save_table(aProcessing, -1, fluxobjs[i]->response, header,
184  MUSE_TAG_STD_RESPONSE, MUSE_TABLE_TYPE_CPL);
185  cpl_free(object);
186  if (rc != CPL_ERROR_NONE) {
187  cpl_free(objorig);
188  cpl_propertylist_delete(header);
189  for ( ; i < nexposures; i++) {
190  muse_flux_object_delete(fluxobjs[i]);
191  } /* for rest of i */
192  break;
193  } /* if */
194  object = cpl_sprintf("Telluric correction (%s)", objorig);
195  cpl_propertylist_update_string(header, "OBJECT", object);
196  rc = muse_processing_save_table(aProcessing, -1, fluxobjs[i]->telluric, header,
197  MUSE_TAG_STD_TELLURIC, MUSE_TABLE_TYPE_CPL);
198  cpl_free(object);
199  cpl_free(objorig);
200  cpl_propertylist_delete(header);
201  muse_flux_object_delete(fluxobjs[i]);
202  if (rc != CPL_ERROR_NONE) {
203  for ( ; i < nexposures; i++) {
204  muse_flux_object_delete(fluxobjs[i]);
205  } /* for rest of i */
206  break;
207  } /* if */
208  } /* for i (exposures) */
209  cpl_array_delete(filters);
210  cpl_free(fluxobjs);
211 
212  return rc == CPL_ERROR_NONE ? 0 : -1;
213 } /* muse_standard_compute() */
muse_postproc_properties * muse_postproc_properties_new(muse_postproc_type aType)
Create a post-processing properties object.
Definition: muse_postproc.c:67
muse_flux_selection_type select
int profile
Type of flux integration to use. "gaussian" and "moffat" use 2D profile fitting, circle and square ar...
muse_image * muse_datacube_collapse(muse_datacube *aCube, cpl_table *aFilter)
Integrate a FITS NAXIS=3 datacube along the wavelength direction.
cpl_error_code muse_postproc_qc_fwhm(muse_processing *aProcessing, muse_datacube *aCube)
Compute QC1 parameters for datacubes and save them in the FITS header.
int select
How to select the star for flux integration, "flux" uses the brightest star in the field...
void * muse_postproc_process_exposure(muse_postproc_properties *aProp, unsigned int aIndex, muse_postproc_sky_outputs *aSkyOut)
Merge and process pixel tables from one exposure.
int smooth
How to smooth the response curve before writing it to disk. "none" does not do any kind of smoothing ...
const char * profile_s
Type of flux integration to use. "gaussian" and "moffat" use 2D profile fitting, circle and square ar...
Structure definition of MUSE three extension FITS file.
Definition: muse_image.h:40
const char * select_s
How to select the star for flux integration, "flux" uses the brightest star in the field...
cpl_array * recnames
the reconstructed image filter names
Definition: muse_datacube.h:70
muse_flux_profile_type profile
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
cpl_array * muse_cplarray_new_from_delimited_string(const char *aString, const char *aDelim)
Convert a delimited string into an array of strings.
Flux object to store data needed while computing the flux calibration.
Definition: muse_flux.h:65
cpl_error_code muse_datacube_convert_dq(muse_datacube *aCube)
Convert the DQ extension of a datacube to NANs in DATA and STAT.
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
cpl_error_code muse_processing_save_cube(muse_processing *aProcessing, int aIFU, void *aCube, const char *aTag, muse_cube_type aType)
Save a MUSE datacube to disk.
muse_flux_smooth_type smooth
Structure definition of the post-processing properties.
Definition: muse_postproc.h:89
muse_datacube * cube
Definition: muse_flux.h:67
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:94
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
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.
Structure to hold the parameters of the muse_standard recipe.
muse_imagelist * muse_imagelist_new(void)
Create a new (empty) MUSE image list.
cpl_frameset * inframes
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.
int darcheck
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...
cpl_table * muse_processing_sort_exposures(muse_processing *aProcessing)
Sort input frames (containing lists of pixel table filenames) into different exposures.
muse_postproc_darcheck darcheck
Definition: muse_postproc.h:95
cpl_error_code muse_imagelist_set(muse_imagelist *aList, muse_image *aImage, unsigned int aIdx)
Set the muse_image of given list index.
cpl_frame * muse_frameset_find_master(const cpl_frameset *aFrames, const char *aTag, unsigned char aIFU)
find the master frame according to its CCD number and tag
Definition: muse_utils.c:468
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...
void muse_flux_object_delete(muse_flux_object *aFluxObj)
Deallocate memory associated to a muse_flux_object.
Definition: muse_flux.c:89
muse_imagelist * recimages
the reconstructed image data
Definition: muse_datacube.h:63
const char * smooth_s
How to smooth the response curve before writing it to disk. "none" does not do any kind of smoothing ...