MUSE Pipeline Reference Manual  0.18.1
muse_scibasic.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_scibasic_z.h"
37 
38 /*---------------------------------------------------------------------------*
39  * Functions code *
40  *---------------------------------------------------------------------------*/
41 
42 static int
43 muse_scibasic_per_exposure(muse_processing *aProcessing,
44  muse_scibasic_params_t *aParams,
45  cpl_table *aTrace, cpl_table *aWave, cpl_table *aGeo,
46  muse_image *aImage, cpl_array *aSkyLines)
47 {
48  cpl_ensure(aImage && aTrace && aWave, CPL_ERROR_NULL_INPUT, -1);
49 
50  /* add saturated number of pixels as QC early to save it in all outputs */
51  muse_basicproc_qc_saturated(aImage, QC_SCIBASIC_PREFIX);
52 
53  if (aParams->saveimage) {
54  char *tag = cpl_sprintf("%s_RED", aProcessing->inputTag);
55  muse_processing_save_image(aProcessing, aParams->nifu, aImage, tag);
56  cpl_free(tag);
57  }
58 
59  /* create and save the output pixel table in any case */
60  muse_pixtable *pixtable = muse_pixtable_create(aImage, aTrace, aWave, aGeo);
61  if (!pixtable) {
62  cpl_msg_error(__func__, "pixel table was not created: %s",
63  cpl_error_get_message());
64  return -1;
65  }
66  if (aSkyLines) {
67  muse_basicproc_shift_pixtable(pixtable, aSkyLines, aParams->skyhalfwidth,
68  aParams->skybinsize);
69  }
70 
71  if (aParams->resample) {
72  /* to visualize the current state better than the pixtable *
73  * can do, resample the data onto an image */
74  muse_image *image = muse_resampling_image(pixtable,
76  1., aParams->dlambda);
77  char *tag = cpl_sprintf("%s_RESAMPLED", aProcessing->inputTag);
78  /* don't want to save QC headers with the samples table: */
79  cpl_propertylist_erase_regexp(image->header, QC_SCIBASIC_PREFIX, 0);
80  muse_processing_save_image(aProcessing, aParams->nifu, image, tag);
81  cpl_free(tag);
82  muse_image_delete(image);
83  }
84 
85  /* Trim the pixel table to a useful wavelength range before saving it. *
86  * Use slightly larger ranges to not cut too much, and so leave the *
87  * first plane of the output datacube hopefully mostly intact. */
88  const double llimN = 4750. - FLT_EPSILON, hlimN = 9350. + FLT_EPSILON,
89  llimE = 4600. - FLT_EPSILON, hlimE = 9350. + FLT_EPSILON;
90  if (aParams->crop) {
91  if (muse_pfits_get_mode(pixtable->header) > MUSE_MODE_WFM_NONAO_X) {
92  cpl_msg_info(__func__, "Nominal mode: cropping the pixel table to "
93  "%.1f...%.1f Angstrom", llimN, hlimN);
94  muse_pixtable_restrict_wavelength(pixtable, llimN, hlimN);
95  } else { /* extended mode */
96  cpl_msg_info(__func__, "Extended mode: cropping the pixel table to "
97  "%.1f...%.1f Angstrom", llimE, hlimE);
98  muse_pixtable_restrict_wavelength(pixtable, llimE, hlimE);
99  }
100  } /* if crop */
101 
102  /* construct output tag and finally save */
103  char *outtag = cpl_sprintf("PIXTABLE_%s", aProcessing->inputTag);
104  muse_processing_save_table(aProcessing, aParams->nifu, pixtable, NULL, outtag,
106  cpl_free(outtag);
107  muse_pixtable_delete(pixtable);
108 
109  return 0;
110 } /* muse_scibasic_per_exposure() */
111 
112 /*----------------------------------------------------------------------------*/
119 /*----------------------------------------------------------------------------*/
120 int
121 muse_scibasic_compute(muse_processing *aProcessing,
122  muse_scibasic_params_t *aParams)
123 {
124  muse_imagelist *images = NULL;
125  if (strcmp(aProcessing->inputTag, "REDUCED") != 0) {
126  muse_basicproc_params *bpars
127  = muse_basicproc_params_new(aProcessing->parameters, "muse.muse_scibasic");
128  images = muse_basicproc_load(aProcessing, aParams->nifu, bpars);
130  } else {
131  images = muse_basicproc_load_reduced(aProcessing, aParams->nifu);
132  }
133  cpl_ensure(images, cpl_error_get_code(), -1);
134 
135  cpl_table *tracetable = muse_table_load(aProcessing, MUSE_TAG_TRACE_TABLE,
136  aParams->nifu);
137  cpl_table *wavecaltable = muse_table_load(aProcessing, MUSE_TAG_WAVECAL_TABLE,
138  aParams->nifu);
139  cpl_table *geotable = muse_table_load(aProcessing, MUSE_TAG_GEOMETRY_TABLE, 0);
140  if (!tracetable || !wavecaltable || !geotable) {
141  cpl_msg_error(__func__, "Calibration could not be loaded:%s%s%s",
142  !tracetable ? " "MUSE_TAG_TRACE_TABLE : "",
143  !wavecaltable ? " "MUSE_TAG_WAVECAL_TABLE : "",
144  !geotable ? " "MUSE_TAG_GEOMETRY_TABLE : "");
145  /* try to clean up in case some files were successfully loaded */
146  muse_imagelist_delete(images);
147  cpl_table_delete(tracetable);
148  cpl_table_delete(wavecaltable);
149  cpl_table_delete(geotable);
150  return -1;
151  }
152  cpl_array *lines = muse_cplarray_new_from_delimited_string(aParams->skylines, ","),
153  *skylines = muse_cplarray_string_to_double(lines);
154  cpl_array_delete(lines);
155  int rc = 0;
156  muse_combinepar *cpars = muse_combinepar_new(aProcessing->parameters,
157  "muse.muse_scibasic");
158  if (cpars->combine == MUSE_COMBINE_NONE) { /* no combination, the default */
159  int i, nimages = muse_imagelist_get_size(images);
160  for (i = 0; i < nimages && !rc; i++) {
161  muse_image *image = muse_imagelist_get(images, i);
162  rc = muse_scibasic_per_exposure(aProcessing, aParams, tracetable,
163  wavecaltable, geotable, image, skylines);
164  }
165  } else { /* some combination is supposed to happen */
166  muse_image *image = muse_combine_images(cpars, images);
167  rc = muse_scibasic_per_exposure(aProcessing, aParams, tracetable,
168  wavecaltable, geotable, image, skylines);
169  muse_image_delete(image);
170  } /* else: combined processing */
171  cpl_array_delete(skylines);
172  muse_combinepar_delete(cpars);
173 
174  /* clean up */
175  muse_imagelist_delete(images);
176  cpl_table_delete(tracetable);
177  cpl_table_delete(wavecaltable);
178  cpl_table_delete(geotable);
179 
180  return rc; /* can only be 0 or -1 */
181 } /* muse_scibasic_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.
const char * inputTag
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.
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
cpl_array * muse_cplarray_string_to_double(const cpl_array *aArray)
Convert a string array into an array of type double.
void muse_imagelist_delete(muse_imagelist *aList)
Free the memory of the MUSE image list.
muse_imagelist * muse_basicproc_load_reduced(muse_processing *aProcessing, unsigned char aIFU)
Load reduced input files from disk.
muse_basicproc_params * muse_basicproc_params_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new structure of basic processing parameters.
double dlambda
Wavelength step (in Angstrom per pixel) to use for resampling.
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
cpl_error_code muse_pixtable_restrict_wavelength(muse_pixtable *aPixtable, double aLow, double aHigh)
Restrict a pixel table to a certain wavelength range.
int saveimage
Save the pre-processed CCD-based image of each input exposure before it is transformed into a pixel t...
cpl_array * muse_cplarray_new_from_delimited_string(const char *aString, const char *aDelim)
Convert a delimited string into an array of strings.
Structure definition of MUSE pixel table.
muse_image * muse_imagelist_get(muse_imagelist *aList, unsigned int aIdx)
Get the muse_image of given list index.
int resample
Resample the input science data into 2D spectral images using tracing and wavelength calibration solu...
muse_combinepar * muse_combinepar_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new set of combination parameters.
Definition: muse_combine.c:673
int nifu
IFU to handle. If set to 0, all IFUs are processed serially. If set to -1, all IFUs are processed in ...
double skyhalfwidth
Half-width of the extraction box (in Angstrom) around each sky emission line.
int crop
Automatically crop the output pixel tables in wavelength depending on the expected useful wavelength ...
muse_pixtable * muse_pixtable_create(muse_image *aImage, cpl_table *aTrace, cpl_table *aWave, cpl_table *aGeoTable)
Create the pixel table for one CCD.
cpl_error_code muse_basicproc_shift_pixtable(muse_pixtable *aPt, cpl_array *aLines, double aHalfWidth, double aBinWidth)
Compute wavelength corrections for science data based on reference sky lines.
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_scibasic recipe.
double skybinsize
Size of the bins (in Angstrom per pixel) for the intermediate spectrum to do the Gaussian fit to each...
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.
Structure of basic processing parameters.
const char * skylines
List of wavelengths of sky emission lines (in Angstrom) to use as reference for wavelength offset cor...
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
muse_ins_mode muse_pfits_get_mode(const cpl_propertylist *aHeaders)
find out the observation mode
Definition: muse_pfits.c:1003
cpl_parameterlist * parameters
cpl_propertylist * header
The FITS header.
cpl_error_code muse_basicproc_qc_saturated(muse_image *aImage, const char *aPrefix)
Add QC parameter about saturated pixels to a muse_image.