MUSE Pipeline Reference Manual  1.0.2
muse_ampl.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 <stdio.h>
30 #include <float.h>
31 #include <math.h>
32 #include <string.h>
33 #include <cpl.h>
34 #include <muse.h>
35 #include "muse_ampl_z.h"
36 
37 /*---------------------------------------------------------------------------*
38  * Functions code *
39  *---------------------------------------------------------------------------*/
40 
41 /*---------------------------------------------------------------------------*/
47 /*---------------------------------------------------------------------------*/
48 static void
49 muse_ampl_qc_header(muse_image *aImage, muse_imagelist *aList)
50 {
51  /* write the image statistics for input ampl exposures */
52  unsigned int k;
53  for (k = 0; k < muse_imagelist_get_size(aList); k++) {
54  char *keyword = cpl_sprintf("ESO QC AMPL INPUT%d "QC_BASIC_NSATURATED, k+1);
55  int nsaturated = cpl_propertylist_get_int(muse_imagelist_get(aList, k)->header,
56  MUSE_HDR_TMP_NSAT);
57  cpl_propertylist_update_int(aImage->header, keyword, nsaturated);
58  cpl_free(keyword);
59  } /* for k (all images in list) */
60 } /* muse_ampl_qc_header() */
61 
62 /*----------------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------------*/
70 static cpl_table *
71 muse_ampl_table_new(const double aAmpl[][2])
72 {
73  cpl_ensure(aAmpl, CPL_ERROR_NULL_INPUT, NULL);
74  int i = -1, n = 0;
75  while (aAmpl[++i][0] > 0.) n++;
76  cpl_msg_debug(__func__, "creating table with %d entries", n);
77  cpl_table *tampl = cpl_table_new(n);
78  cpl_table_new_column(tampl, "lambda", CPL_TYPE_DOUBLE);
79  cpl_table_new_column(tampl, "throughput", CPL_TYPE_DOUBLE);
80  for (i = 0; i < n; i++) {
81  cpl_table_set_double(tampl, "lambda", i, aAmpl[i][0]);
82  cpl_table_set_double(tampl, "throughput", i, aAmpl[i][1]);
83  } /* for i */
84 #if 0
85  cpl_table_dump(tampl, 0, 100000, stdout);
86  fflush(stdout);
87 #endif
88  return tampl;
89 } /* muse_ampl_table_new() */
90 
91 /*----------------------------------------------------------------------------*/
98 /*----------------------------------------------------------------------------*/
99 int
100 muse_ampl_compute(muse_processing *aProcessing, muse_ampl_params_t *aParams)
101 {
102  /* search and load the files that we really need */
103  cpl_table *trace = muse_table_load(aProcessing, MUSE_TAG_TRACE_TABLE,
104  aParams->nifu);
105  cpl_table *wave = muse_table_load(aProcessing, MUSE_TAG_WAVECAL_TABLE,
106  aParams->nifu);
107  if (!trace || !wave) {
108  cpl_msg_error(__func__, "Calibration could not be loaded:%s%s",
109  !trace ? " "MUSE_TAG_TRACE_TABLE : "",
110  !wave ? " "MUSE_TAG_WAVECAL_TABLE : "");
111  /* try to clean up in case some files were successfully loaded */
112  cpl_table_delete(trace);
113  cpl_table_delete(wave);
114  return -1;
115  }
116 
117  /* now that we know that we have everything, start the real processing */
119  "muse.muse_ampl");
120  muse_imagelist *images = muse_basicproc_load(aProcessing, aParams->nifu, bpars);
122  if (!images) {
123  cpl_error_set_message(__func__, cpl_error_get_code(),
124  "Loading and processing raw data failed!");
125  cpl_table_delete(trace);
126  cpl_table_delete(wave);
127  return -1;
128  }
129  muse_combinepar *cpars = muse_combinepar_new(aProcessing->parameters,
130  "muse.muse_ampl");
131  cpars->scale = CPL_TRUE; /* always scale to relative exposure time */
132  muse_image *image = muse_combine_images(cpars, images);
133  muse_combinepar_delete(cpars);
134  if (!image) {
135  cpl_msg_error(__func__, "Combining input frames failed!");
136  muse_imagelist_delete(images);
137  cpl_table_delete(trace);
138  cpl_table_delete(wave);
139  return -1;
140  }
141 
142  cpl_propertylist_erase_regexp(image->header, MUSE_WCS_KEYS, 0);
143  muse_ampl_qc_header(image, images);
144  muse_basicproc_qc_saturated(image, "ESO QC AMPL MASTER");
145  muse_imagelist_delete(images);
146  if (aParams->savemaster) {
147  muse_processing_save_image(aProcessing, aParams->nifu, image, "MASTER_AMPL");
148  }
149 
150  /* get the filter name from the header and try to load its response */
151  const char *fname = muse_pfits_get_pam2_filter(image->header);
152  cpl_table *filter = muse_table_load_filter(aProcessing, fname);
153  if (!filter) {
154  cpl_msg_error(__func__, "Filter \"%s\" could not be loaded from FILTER_LIST"
155  " file!", fname);
156  return -1;
157  }
158 
159  /* create the pixel table to work on */
160  muse_pixtable *pt = muse_pixtable_create(image, trace, wave, NULL);
161  cpl_table_delete(trace);
162  cpl_table_delete(wave);
163  if (!pt) {
164  cpl_msg_error(__func__, "pixel table was not created: %s",
165  cpl_error_get_message());
166  muse_image_delete(image);
167  cpl_table_delete(filter);
168  return -1;
169  }
170  cpl_table *geotable = muse_table_load(aProcessing, MUSE_TAG_GEOMETRY_TABLE, 0);
171  /* start with the approximate (constant) area per IFU [cm**2] */
172  double fpsize = 60. / muse_pfits_get_focu_scale(pt->header),
173  ifuarea = pow(fpsize / 10., 2) / kMuseNumIFUs;
174  const char *modestring = muse_pfits_get_mode(pt->header) < MUSE_MODE_NFM_AO_N
175  ? "WFM" : "NFM";
176  if (!geotable) {
177  if (muse_pfits_get_mode(pt->header) >= MUSE_MODE_NFM_AO_N) {
178  /* in narrow-field mode MUSE has a much smaller size in the focal plane */
179  ifuarea /= pow(kMuseSpaxelSizeX_WFM / kMuseSpaxelSizeX_NFM, 2);
180  } /* if NFM */
181  cpl_msg_warning(__func__, "assuming constant per-IFU area of %f cm**2 "
182  "(mode %s)", ifuarea, modestring);
183  } else {
184  /* sum up the area from the geometry table */
185  ifuarea = muse_geo_table_ifu_area(geotable, aParams->nifu, fpsize / 10.);
186  cpl_msg_info(__func__, "computed area of IFU %d in focal plane: %.3f cm**2 "
187  "(mode %s)", aParams->nifu, ifuarea, modestring);
188  cpl_table_delete(geotable);
189  } /* else */
190 
191  /*
192  * the actual processing of interest happens next:
193  * - input data is in electrons, ignoring the CCD response it is in photons
194  * - convolve the flux of each CCD pixel with the filter response
195  * - convert data to W and W/cm**2
196  * - convert photo diode current from A to W/cm**2
197  * - compute throughput relative to both photo diodes from the total detected
198  * power per area
199  * - compute the throughput relative to the 2nd photo diode from the power
200  * per area detected in each slice
201  */
202  /* data in photon units: */
203  cpl_table_set_column_unit(pt->table, MUSE_PIXTABLE_DATA, "ph");
204  /* collect energy [J] in stat column: */
205  cpl_table_set_column_unit(pt->table, MUSE_PIXTABLE_STAT, "J");
206  /* cut off and sum data values and energies */
207  const float *lbda = cpl_table_get_data_float_const(pt->table, MUSE_PIXTABLE_LAMBDA);
208  float *data = cpl_table_get_data_float(pt->table, MUSE_PIXTABLE_DATA),
209  *stat = cpl_table_get_data_float(pt->table, MUSE_PIXTABLE_STAT);
210  cpl_table_unselect_all(pt->table);
211  cpl_msg_debug(__func__, "Using black body correction with T = %.1f K",
212  aParams->temp);
213  /* summed values: data and the respective photon energy, as well as *
214  * the weighted mean wavelength (and the weight sum used for that) */
215  double dsum = 0., esum = 0., lwmean = 0., wsum = 0.;
216  cpl_size irow, nrow = cpl_table_get_nrow(pt->table);
217  for (irow = 0; irow < nrow; irow++) {
218  double resp = muse_flux_response_interpolate(filter, lbda[irow], NULL,
220  if (resp <= 0.) {
221  cpl_table_select_row(pt->table, irow);
222  continue;
223  }
224  /* fold the remaining datapoints with the filter response */
225  data[irow] *= resp;
226  /* misuse the stat column to save photon energy: *
227  * Eph = h nu = h * c / lambda * nph *
228  * units: [Js] * [m/s] / [m] * [1] = [J] */
229  stat[irow] = CPL_PHYS_H * CPL_PHYS_C / lbda[irow] * 1e10 * data[irow];
230  dsum += data[irow]; /* sum the number of photons */
231  esum += stat[irow]; /* some the photon energy */
232  /* compute the normalized (unitless) Planck curve Bn(T,lambda) *
233  * for the assumed flat-field (halogen) lamp temperature */
234  double lbda_m = lbda[irow] / 1e10, /* wavelength [m] */
235  fb = (CPL_PHYS_H * CPL_PHYS_C) / (CPL_PHYS_K * aParams->temp * lbda_m),
236  Bn = 15. / lbda_m * pow(fb / CPL_MATH_PI, 4) / (exp(fb) - 1.);
237  wsum += data[irow] / Bn;
238  lwmean += lbda[irow] * data[irow] / Bn;
239  } /* for irow (pixel table rows) */
240  lwmean /= wsum;
241  cpl_msg_info(__func__, "%"CPL_SIZE_FORMAT" of %"CPL_SIZE_FORMAT" pixel table "
242  "rows (%.2f%%) unused", cpl_table_count_selected(pt->table), nrow,
243  100. * cpl_table_count_selected(pt->table) / nrow);
244  cpl_table_erase_selected(pt->table);
246  double exptime = muse_pfits_get_exptime(pt->header),
247  power = esum / exptime; /* power [W] */
248  /* ... to compute the corresponding power density */
249  double pdensity = power / ifuarea; /* power density [W/cm**2] */
250  cpl_msg_info(__func__, "Summed flux: %e ph, energy: %e J, power: %e W, power "
251  "density: %e W/cm**2", dsum, esum, power, pdensity);
252 
253  /* create tables from kMuseAmpl1[][] and kMuseAmpl2[][] and use *
254  * them to compute mean photo diode sensitivities in [A/W*cm**2]; *
255  * take into account the size of the photo diodes */
256  cpl_table *tampl1 = muse_ampl_table_new(kMuseAmpl1),
257  *tampl2 = muse_ampl_table_new(kMuseAmpl2);
258  double sens1 = muse_flux_response_interpolate(tampl1, lwmean, NULL,
260  * kMuseAmplPhysicalSize,
261  sens2 = muse_flux_response_interpolate(tampl2, lwmean, NULL,
263  * kMuseAmplPhysicalSize;
264  cpl_table_delete(tampl1);
265  cpl_table_delete(tampl2);
266  cpl_msg_info(__func__, "mean photo diode sensitivities at weighted mean "
267  "wavelength %.2f Angstrom: %f A/W*cm**2, %f A/W*cm**2", lwmean,
268  sens1, sens2);
269  /* take into account beam widening for photo diode 2 */
270  cpl_msg_debug(__func__, "using beam widening factor %.3f for photo diode 2",
271  aParams->fbeam);
272  sens2 /= aParams->fbeam;
273 
274  /* now convert the AMPL measurements from the FITS *
275  * header to the same power density units */
276  cpl_errorstate state = cpl_errorstate_get();
277  double pam1 = muse_pfits_get_pam_intensity(image->header, 1), /* [A] */
278  pam2 = muse_pfits_get_pam_intensity(image->header, 2); /* [A] */
279  if (!cpl_errorstate_is_equal(state)) {
280  cpl_msg_error(__func__, "Pico-amplifier measurement(s) not found in header: %s",
281  cpl_error_get_message());
282  muse_image_delete(image);
283  cpl_table_delete(filter);
285  return -1;
286  }
287  double pam1stdev = muse_pfits_get_pam_stdev(image->header, 1),
288  pam2stdev = muse_pfits_get_pam_stdev(image->header, 2),
289  p1density = pam1 / sens1, /* now [W/cm**2] */
290  p2density = pam2 / sens2; /* now [W/cm**2] */
291  cpl_msg_info(__func__, "amplifiers: AMPL1 %.3e +/- %.3e A, %.2e W/cm**2, "
292  "AMPL2 %.3e +/- %.3e A, %.2e W/cm**2", pam1, pam1stdev,
293  p1density, pam2, pam2stdev, p2density);
294  /* now compute the instrument throughput: compare the power density *
295  * detected on the CCD to the same value measured at each photo diode, *
296  * (unitless throughput values); the throughput errors are estimated as in *
297  * VLT-TRE-MUS-14670-0682 v0.90, as 3% error due to equal IFU area and the *
298  * filter error either 1 or 2%; additionally the value computed for the *
299  * fbeam parameter is around 1.03 +/- 0.04, so 4% error there. */
300  double thru1 = pdensity / p1density * 100.,
301  thru2 = pdensity / p2density * 100.,
302  areaerr = 0.03,
303  filterr = lwmean > 5000 && lwmean < 8000 ? 0.01 : 0.02,
304  beamerr = 0.04, /* approximate error on fbeam */
305  thru2err = sqrt(areaerr*areaerr + beamerr*beamerr + filterr*filterr);
306  cpl_msg_info(__func__, "throughput values: to AMPL1 %.3f %%, to "
307  "AMPL2 %.3f +/- %.3f %%", thru1, thru2, thru2err * thru2);
308 
309  /* write some of this as QC parameters */
310  cpl_propertylist_erase_regexp(pt->header, "ESO QC", 0);
311  cpl_propertylist_append_float(pt->header, "ESO QC AMPL PHOTONS", dsum);
312  cpl_propertylist_append_float(pt->header, "ESO QC AMPL POWER", power);
313  cpl_propertylist_append_float(pt->header, "ESO QC AMPL THRU1", thru1);
314  cpl_propertylist_append_float(pt->header, "ESO QC AMPL THRU2", thru2);
315  cpl_propertylist_append_float(pt->header, "ESO QC AMPL THRU2ERR", thru2 * thru2err);
316 
317  /* sum the power per slice and record as QC parameter */
319  double slicearea = ifuarea / kMuseSlicesPerCCD;
320  cpl_msg_warning(__func__, "assuming constant per-slice area of %f cm**2",
321  slicearea);
322  int ipt;
323  for (ipt = 0; ipt < muse_pixtable_extracted_get_size(pts); ipt++) {
324  uint32_t origin = cpl_table_get_int(pts[ipt]->table, MUSE_PIXTABLE_ORIGIN,
325  0, NULL);
326  unsigned short slice = muse_pixtable_origin_get_slice(origin);
327  /* the stat column contains the photon energy now, see *
328  * above; use its sum to compute the per-slice power */
329  double spower = cpl_table_get_column_mean(pts[ipt]->table, MUSE_PIXTABLE_STAT)
330  * cpl_table_get_nrow(pts[ipt]->table) / exptime, /* [W] */
331  spdensity = spower / slicearea, /* [W/cm**2] */
332  sthru2 = spdensity / p2density * 100.;
333  char *keyword = cpl_sprintf("ESO QC AMPL SLICE%d THRU2", slice);
334  cpl_propertylist_append_float(pt->header, keyword, sthru2);
335  cpl_free(keyword);
336  cpl_msg_info(__func__, "slice %2d: power %.3e W, throughput %.3f %%",
337  slice, spower, sthru2);
338  } /* for ipt (all slice pixel tables) */
340  if (aParams->savetable) {
341  /* Since this is not a real pixel table any more, since we messed with the *
342  * columns heavily, a user should not interpret it as a pixel table. So *
343  * this needs to be saved as a normal FITS table, if requested at all. */
344  muse_processing_save_table(aProcessing, aParams->nifu, pt->table,
345  pt->header, "TABLE_AMPL", MUSE_TABLE_TYPE_CPL);
346  }
347 
348  /* To see if the filter convolution has worked: project it back to an *
349  * image. As this is then the primary output product, copy the computed *
350  * QC parameters from both other outputs to its header before saving it. */
352  muse_image *outimage = muse_imagelist_get(list, 0);
353  cpl_propertylist_copy_property_regexp(outimage->header, image->header,
354  "^ESO QC", 0);
355  cpl_propertylist_copy_property_regexp(outimage->header, pt->header,
356  "^ESO QC", 0);
357  /* we don't need the SLICEi.CENTER keywords here, remove them */
358  cpl_propertylist_erase_regexp(outimage->header, "^ESO DRS MUSE SLICE.* CENTER", 0);
359  /* Here we have to use a hack to save this image, since it's not *
360  * a normal muse_image but has different contents because we messed *
361  * with the pixel table before creating it. */
362  muse_processing_save_header(aProcessing, aParams->nifu, outimage->header,
363  "AMPL_CONVOLVED");
364  /* Get the newly created frame and its filename *
365  * to extend that file with the image data. */
366  cpl_frame *outframe = muse_frameset_find_master(aProcessing->outframes,
367  "AMPL_CONVOLVED", aParams->nifu);
368  const char *fn = cpl_frame_get_filename(outframe);
369  cpl_propertylist *hext = cpl_propertylist_new();
370  cpl_propertylist_append_string(hext, "EXTNAME", "PHOTONS");
371  cpl_propertylist_set_comment(hext, "EXTNAME", "This extension contains photon counts");
372  cpl_propertylist_append_string(hext, "BUNIT", cpl_table_get_column_unit(pt->table,
373  MUSE_PIXTABLE_DATA));
374  cpl_image_save(outimage->data, fn, CPL_TYPE_UNSPECIFIED, hext, CPL_IO_EXTEND);
375  cpl_propertylist_update_string(hext, "EXTNAME", "ENERGY");
376  cpl_propertylist_set_comment(hext, "EXTNAME", "This extension contains per-pixel energy");
377  cpl_propertylist_update_string(hext, "BUNIT", cpl_table_get_column_unit(pt->table,
378  MUSE_PIXTABLE_STAT));
379  cpl_image_save(outimage->stat, fn, CPL_TYPE_UNSPECIFIED, hext, CPL_IO_EXTEND);
380 #if 0 /* ignore the dq components, it's not necessary here */
381  cpl_propertylist_update_string(hext, "EXTNAME", EXTNAME_DQ);
382  cpl_propertylist_set_comment(hext, "EXTNAME", EXTNAME_DQ_COMMENT);
383  cpl_propertylist_erase(hext, "BUNIT"); /* no unit for data quality */
384  cpl_image_save(outimage->dq, fn, CPL_TYPE_UNSPECIFIED, hext, CPL_IO_EXTEND);
385 #endif
386  cpl_frame_delete(outframe);
387  cpl_propertylist_delete(hext);
388 
389  /* clean up */
390  muse_imagelist_delete(list);
392  muse_image_delete(image);
393  cpl_table_delete(filter);
394 
395  return 0;
396 } /* muse_ampl_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:85
void muse_pixtable_extracted_delete(muse_pixtable **aPixtables)
Delete a pixel table array.
unsigned short muse_pixtable_origin_get_slice(uint32_t aOrigin)
Get the slice number from the encoded 32bit origin number.
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_ampl_z.h:50
cpl_size muse_pixtable_extracted_get_size(muse_pixtable **aPixtables)
Get the size of an array of extracted pixel tables.
muse_pixtable ** muse_pixtable_extracted_get_slices(muse_pixtable *aPixtable)
Extract one pixel table per IFU and slice.
cpl_image * data
the data extension
Definition: muse_image.h:46
Structure to hold the parameters of the muse_ampl recipe.
Definition: muse_ampl_z.h:48
cpl_image * stat
the statistics extension
Definition: muse_image.h:64
double muse_geo_table_ifu_area(const cpl_table *aTable, const unsigned char aIFU, double aScale)
Compute the area of an IFU in the VLT focal plane.
Definition: muse_geo.c:297
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:741
Structure definition of MUSE three extension FITS file.
Definition: muse_image.h:40
double muse_pfits_get_focu_scale(const cpl_propertylist *aHeaders)
find out the scale in the VLT focal plane
Definition: muse_pfits.c:804
cpl_table * table
The pixel table.
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:72
double temp
Lamp temperature [K] used to create the black body function.
Definition: muse_ampl_z.h:88
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
unsigned int muse_imagelist_get_size(muse_imagelist *aList)
Return the number of stored images.
muse_imagelist * muse_pixtable_to_imagelist(muse_pixtable *aPixtable)
Project a pixel table with data from one IFU back onto its image.
void muse_combinepar_delete(muse_combinepar *aCPars)
Clear the combination parameters.
Definition: muse_combine.c:715
cpl_image * dq
the data quality extension
Definition: muse_image.h:56
const char * muse_pfits_get_pam2_filter(const cpl_propertylist *aHeaders)
query the filter set up in front of photo diode (pico amplifier) 2
Definition: muse_pfits.c:1201
double muse_flux_response_interpolate(const cpl_table *aResponse, double aLambda, double *aError, muse_flux_interpolation_type aType)
Compute linearly interpolated response of some kind at given wavelength.
Definition: muse_flux.c:336
cpl_error_code muse_processing_save_header(muse_processing *aProcessing, int aIFU, cpl_propertylist *aHeader, const char *aTag)
Save a FITS header to disk.
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.
double muse_pfits_get_pam_intensity(const cpl_propertylist *aHeaders, int aDiode)
query the intensity measured by one photo diode (pico amplifier)
Definition: muse_pfits.c:1151
cpl_frameset * outframes
int savetable
Save the table with all the processed pixel values.
Definition: muse_ampl_z.h:94
double muse_pfits_get_pam_stdev(const cpl_propertylist *aHeaders, int aDiode)
query the intensity std. dev. of one photo diode (pico amplifier)
Definition: muse_pfits.c:1181
muse_combinepar * muse_combinepar_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new set of combination parameters.
Definition: muse_combine.c:672
muse_pixtable * muse_pixtable_create(muse_image *aImage, cpl_table *aTrace, cpl_table *aWave, cpl_table *aGeoTable)
Create the pixel table for one CCD.
double fbeam
Factor to describe the widening of the beam from the focal plane to photo diode 2.
Definition: muse_ampl_z.h:85
int muse_processing_save_image(muse_processing *aProcessing, int aIFU, muse_image *aImage, const char *aTag)
Save a computed MUSE image to disk.
double muse_pfits_get_exptime(const cpl_propertylist *aHeaders)
find out the exposure time
Definition: muse_pfits.c:347
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
int savemaster
Save the processed and combined master image before any concolution is done.
Definition: muse_ampl_z.h:91
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.
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
cpl_error_code muse_pixtable_compute_limits(muse_pixtable *aPixtable)
(Re-)Compute the limits of the coordinate columns of a pixel table.
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
muse_ins_mode muse_pfits_get_mode(const cpl_propertylist *aHeaders)
find out the observation mode
Definition: muse_pfits.c:1097
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.