MUSE Pipeline Reference Manual  0.18.5
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->inputFrames,
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  }
91  prop->extinction = muse_table_load(aProcessing, MUSE_TAG_EXTINCT_TABLE, 0);
92  /* telluric regions */
93  prop->tellregions = muse_table_load(aProcessing, MUSE_TAG_TELLREG, 0);
94  if (!prop->tellregions) {
95  cpl_msg_debug(__func__, "%s could not be found or loaded, using defaults",
96  MUSE_TAG_TELLREG);
97  }
98 
99  /* sort input pixel tables into different exposures */
100  prop->exposures = muse_processing_sort_exposures(aProcessing);
101  if (!prop->exposures) {
102  cpl_msg_error(__func__, "No standard star exposures found in input!");
104  return -1;
105  }
106  int nexposures = cpl_table_get_nrow(prop->exposures);
107 
108  /* now process all the pixel tables, do it separately for each exposure */
109  muse_flux_object **fluxobjs = cpl_calloc(nexposures, sizeof(muse_flux_object *));
110  int i;
111  for (i = 0; i < nexposures; i++) {
112  fluxobjs[i] = muse_postproc_process_exposure(prop, i);
113  if (!fluxobjs[i]) {
114  int i2;
115  for (i2 = 0; i2 <= i; i2++) {
116  muse_flux_object_delete(fluxobjs[i2]);
117  } /* for i2 */
118  cpl_free(fluxobjs);
120  return -1; /* enough error messages, just return */
121  }
122  } /* for i (exposures) */
124 
125  /* XXX now combine the possibly more than one response tables */
126 
127  cpl_error_code rc = CPL_ERROR_NONE;
128  cpl_array *filters = muse_cplarray_new_from_delimited_string(aParams->filter,
129  ",");
130  for (i = 0; i < nexposures; i++) {
131  int ifilt, ipos = 0, nfilt = cpl_array_get_size(filters);
132  for (ifilt = 0; ifilt < nfilt; ifilt++) {
133  /* try to find and load the filter from a table */
134  cpl_table *filter = muse_table_load_filter(aProcessing,
135  cpl_array_get_string(filters, ifilt));
136  if (!filter) {
137  continue;
138  }
139  muse_image *fov = muse_datacube_collapse(fluxobjs[i]->cube, filter);
140  if (!fluxobjs[i]->cube->recimages) {
141  fluxobjs[i]->cube->recimages = muse_imagelist_new();
142  fluxobjs[i]->cube->recnames = cpl_array_new(0, CPL_TYPE_STRING);
143  }
144  muse_imagelist_set(fluxobjs[i]->cube->recimages, fov, ipos);
145  cpl_array_set_size(fluxobjs[i]->cube->recnames, ipos+1);
146  cpl_array_set_string(fluxobjs[i]->cube->recnames, ipos,
147  cpl_array_get_string(filters, ifilt));
148  cpl_table_delete(filter);
149  ipos++;
150  } /* for ifilt (all filters) */
151  muse_postproc_qc_fwhm(aProcessing, fluxobjs[i]->cube); /* before NANs! */
152  muse_datacube_convert_dq(fluxobjs[i]->cube);
153  muse_processing_save_cube(aProcessing, -1, fluxobjs[i]->cube,
154  MUSE_TAG_CUBE_STD, MUSE_CUBE_TYPE_FITS);
155 
156  /* save the response-curve and the telluric correction */
157  cpl_propertylist *header = cpl_propertylist_duplicate(fluxobjs[i]->cube->header);
158  cpl_propertylist_erase_regexp(header, "^NAXIS|^EXPTIME$|"MUSE_WCS_KEYS, 0);
159  char *objorig = cpl_strdup(cpl_propertylist_get_string(header, "OBJECT"));
160  char *object = cpl_sprintf("Response curve (%s)", objorig);
161  cpl_propertylist_update_string(header, "OBJECT", object);
162  rc = muse_processing_save_table(aProcessing, -1, fluxobjs[i]->response, header,
163  MUSE_TAG_STD_RESPONSE, MUSE_TABLE_TYPE_CPL);
164  cpl_free(object);
165  if (rc != CPL_ERROR_NONE) {
166  cpl_free(objorig);
167  cpl_propertylist_delete(header);
168  for ( ; i < nexposures; i++) {
169  muse_flux_object_delete(fluxobjs[i]);
170  } /* for rest of i */
171  break;
172  } /* if */
173  object = cpl_sprintf("Telluric correction (%s)", objorig);
174  cpl_propertylist_update_string(header, "OBJECT", object);
175  rc = muse_processing_save_table(aProcessing, -1, fluxobjs[i]->telluric, header,
176  MUSE_TAG_STD_TELLURIC, MUSE_TABLE_TYPE_CPL);
177  cpl_free(object);
178  cpl_free(objorig);
179  cpl_propertylist_delete(header);
180  muse_flux_object_delete(fluxobjs[i]);
181  if (rc != CPL_ERROR_NONE) {
182  for ( ; i < nexposures; i++) {
183  muse_flux_object_delete(fluxobjs[i]);
184  } /* for rest of i */
185  break;
186  } /* if */
187  } /* for i (exposures) */
188  cpl_array_delete(filters);
189  cpl_free(fluxobjs);
190 
191  return rc == CPL_ERROR_NONE ? 0 : -1;
192 } /* muse_standard_compute() */
muse_postproc_properties * muse_postproc_properties_new(muse_postproc_type aType)
Create a post-processing properties object.
Definition: muse_postproc.c:66
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.
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:41
cpl_array * recnames
the reconstructed image filter names
Definition: muse_datacube.h:71
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:585
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:57
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.
Structure definition of the post-processing properties.
Definition: muse_postproc.h:87
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
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).
Structure to hold the parameters of the muse_standard recipe.
muse_imagelist * muse_imagelist_new(void)
Create a new (empty) MUSE image list.
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
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.
void * muse_postproc_process_exposure(muse_postproc_properties *aProp, unsigned int aIndex)
Merge and process pixel tables from one exposure.
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.
cpl_frameset * inputFrames
muse_postproc_darcheck darcheck
Definition: muse_postproc.h:93
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:425
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:84
muse_imagelist * recimages
the reconstructed image data
Definition: muse_datacube.h:64