MUSE Pipeline Reference Manual  2.1.1
recipes/muse_lsf.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) 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
20  * 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 /*---------------------------------------------------------------------------*
28  * Includes *
29  *---------------------------------------------------------------------------*/
30 #include <string.h>
31 #include <math.h>
32 
33 #include <muse.h>
34 #include <muse_data_format_z.h>
35 #include <muse_instrument.h>
36 #include <muse_lsf.h>
37 #include "muse_lsf_z.h"
38 
39 #ifndef USE_LSF_PARAMS
40 #ifdef MUSE_LSF_PARAM_METHOD_HERMIT
41 #error Please remove the "method" parameter from muse_lsf_params.xml
42 #endif
43 #endif
44 
45 /*---------------------------------------------------------------------------*
46  * Functions code *
47  *---------------------------------------------------------------------------*/
48 
57 static muse_lsf_cube *
58 muse_lsf_compute_slices(muse_pixtable *aPixtable, muse_lsf_params_t *aParams)
59 {
60  cpl_ensure(aPixtable, CPL_ERROR_NULL_INPUT, NULL);
61  muse_lsf_cube *lsfCube = muse_lsf_cube_new(aParams->lsf_range,
62  aParams->lsf_size,
63  aParams->lambda_size,
64  aPixtable->header);
65  muse_pixtable **slice_pixtable = muse_pixtable_extracted_get_slices(aPixtable);
66 
67  int i_slice, n_slices = muse_pixtable_extracted_get_size(slice_pixtable);
68 #pragma omp parallel for default(none) /* as req. by Ralf */ \
69  shared(lsfCube, n_slices, slice_pixtable, aParams)
70  for (i_slice = 0; i_slice < n_slices; i_slice++) {
71  cpl_image *img = cpl_imagelist_get(lsfCube->img, i_slice);
72  muse_lsf_fit_slice(slice_pixtable[i_slice], img,
73  lsfCube->wcs, aParams->lsf_regression_window);
74  }
75  muse_pixtable_extracted_delete(slice_pixtable);
76  return lsfCube;
77 }
78 
88 static cpl_error_code
89 muse_lsf_subtract_arcs(muse_lsf_cube *aLsfCube, cpl_table *aPixtable) {
90  cpl_size n_rows = cpl_table_get_nrow(aPixtable);
91  cpl_size i_row;
92  for (i_row = 0; i_row < n_rows; i_row++) {
93  uint32_t origin = (uint32_t)cpl_table_get_int(aPixtable, MUSE_PIXTABLE_ORIGIN,
94  i_row, NULL);
95  int i_slice = muse_pixtable_origin_get_slice(origin);
96  double lambda = cpl_table_get(aPixtable, "line_lambda", i_row, NULL);
97  double flux = cpl_table_get(aPixtable, "line_flux", i_row, NULL);
98  double v = cpl_table_get(aPixtable, MUSE_PIXTABLE_LAMBDA, i_row, NULL)
99  - lambda;
100  cpl_array *val = cpl_array_wrap_double(&v, 1);
101  muse_lsf_apply(cpl_imagelist_get(aLsfCube->img, i_slice - 1),
102  aLsfCube->wcs, val, lambda);
103  cpl_array_unwrap(val);
104  cpl_table_set(aPixtable, MUSE_PIXTABLE_DATA, i_row,
105  cpl_table_get(aPixtable, MUSE_PIXTABLE_DATA, i_row, NULL)
106  - v * flux);
107  }
108  return CPL_ERROR_NONE;
109 }
110 
126 static cpl_error_code
127 muse_lsf_qc(muse_lsf_cube *aLsfCube)
128 {
129  cpl_ensure_code(aLsfCube, CPL_ERROR_NULL_INPUT);
130 
131  cpl_size i_slice, n_slices = cpl_imagelist_get_size(aLsfCube->img);
132  for (i_slice = 0; i_slice < n_slices; i_slice++) {
133  cpl_image *img = cpl_imagelist_get(aLsfCube->img, i_slice);
134  cpl_size n_lsf = cpl_image_get_size_x(img);
135  cpl_size n_lambda = cpl_image_get_size_y(img);
136  cpl_array *fwhm = cpl_array_new(n_lambda, CPL_TYPE_DOUBLE);
137  cpl_size i_lambda;
138  for (i_lambda = 0; i_lambda < n_lambda; i_lambda++) {
139  int res;
140  double ref = cpl_image_get(img, n_lsf/2, i_lambda+1, &res);
141  cpl_size i_min;
142  for (i_min = n_lsf/2; i_min > 0; i_min--) {
143  if (cpl_image_get(img, i_min, i_lambda+1, &res) < ref/2) {
144  break;
145  }
146  }
147  double f_min = (ref/2 - cpl_image_get(img, i_min, i_lambda+1, &res))
148  / (cpl_image_get(img, i_min+1, i_lambda+1, &res)
149  - cpl_image_get(img, i_min, i_lambda+1, &res));
150 
151  cpl_size i_max;
152  for (i_max = n_lsf/2; i_max <= n_lsf; i_max++) {
153  if (cpl_image_get(img, i_max, i_lambda+1, &res) < ref/2) {
154  break;
155  }
156  }
157  double f_max = (ref/2 - cpl_image_get(img, i_max, i_lambda+1, &res))
158  / (cpl_image_get(img, i_max-1, i_lambda+1, &res)
159  - cpl_image_get(img, i_max, i_lambda+1, &res));
160 
161  double f = (i_max - f_max - i_min - f_min) * aLsfCube->wcs->cd11;
162  cpl_array_set(fwhm, i_lambda, f);
163  }
164  char keyword[KEYWORD_LENGTH];
165  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM MEAN",
166  (int)i_slice+1);
167  cpl_propertylist_append_float(aLsfCube->header, keyword, cpl_array_get_mean(fwhm));
168  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM STDEV",
169  (int)i_slice+1);
170  cpl_propertylist_append_float(aLsfCube->header, keyword, cpl_array_get_stdev(fwhm));
171  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM MIN",
172  (int)i_slice+1);
173  cpl_propertylist_append_float(aLsfCube->header, keyword, cpl_array_get_min(fwhm));
174  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM MAX",
175  (int)i_slice+1);
176  cpl_propertylist_append_float(aLsfCube->header, keyword, cpl_array_get_max(fwhm));
177  cpl_array_delete(fwhm);
178  }
179 
180  return CPL_ERROR_NONE;
181 }
182 
183 #ifdef USE_LSF_PARAMS
185 muse_lsf_params_compute(cpl_table *aLines,
186  muse_pixtable *aPixtable,
187  int max_iterations)
188 {
189  muse_pixtable **slice_pixtable = muse_pixtable_extracted_get_slices(aPixtable);
190  int n_slices = muse_pixtable_extracted_get_size(slice_pixtable);
191  int i_slice;
192 
193  muse_lsf_params **lsfParams
194  = cpl_calloc(n_slices+1, sizeof(muse_lsf_params *));
195  #pragma omp parallel for default(none) num_threads(2) /* as req. by Ralf */ \
196  shared(aLines, n_slices, i_slice, lsfParams, slice_pixtable, \
197  max_iterations)
198  for (i_slice = 0; i_slice < n_slices; i_slice++) {
199  uint32_t origin
200  = (uint32_t)cpl_table_get_int(slice_pixtable[i_slice]->table,
201  MUSE_PIXTABLE_ORIGIN, 0, NULL);
202  unsigned short ifu = muse_pixtable_origin_get_ifu(origin);
203  unsigned short slice = muse_pixtable_origin_get_slice(origin);
204 
205  cpl_errorstate prestate = cpl_errorstate_get();
206  lsfParams[i_slice]
207  = muse_lsf_params_fit(slice_pixtable[i_slice], aLines, max_iterations);
208  if (!cpl_errorstate_is_equal(prestate)) {
209  cpl_msg_error(__func__, "While processing slice %hu.%hu:", ifu, slice);
210  cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
211  cpl_errorstate_set(prestate);
212  }
213  }
214  muse_pixtable_extracted_delete(slice_pixtable);
215  return lsfParams;
216 } /* muse_lsf_params_compute() */
217 
218 /*----------------------------------------------------------------------------*/
224 /*----------------------------------------------------------------------------*/
225 static cpl_error_code
226 muse_lsf_params_qc(cpl_propertylist *aHeader, const muse_lsf_params **aSlicePars)
227 {
228  cpl_ensure_code(aHeader != NULL, CPL_ERROR_NULL_INPUT);
229  cpl_ensure_code(aSlicePars != NULL, CPL_ERROR_NULL_INPUT);
230 
231  const muse_lsf_params **det;
232  for (det = aSlicePars; *det != NULL; det++) {
233  cpl_size n_lambda = 30;
234  double lambda_step = (kMuseNominalLambdaMax - kMuseNominalLambdaMin)
235  / (n_lambda - 1);
236  cpl_array *fwhm = cpl_array_new(n_lambda, CPL_TYPE_DOUBLE);
237  cpl_size i_lambda;
238  for (i_lambda = 0; i_lambda < n_lambda; i_lambda++) {
239  double lambda = kMuseNominalLambdaMin + i_lambda * lambda_step;
240  double f = muse_lsf_fwhm_lambda(*det, lambda, 0.04, 150);
241  cpl_array_set(fwhm, i_lambda, f);
242  }
243  char keyword[KEYWORD_LENGTH];
244  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM MEAN",
245  (int)(*det)->slice);
246  cpl_propertylist_append_float(aHeader, keyword, cpl_array_get_mean(fwhm));
247  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM STDEV",
248  (int)(*det)->slice);
249  cpl_propertylist_append_float(aHeader, keyword, cpl_array_get_stdev(fwhm));
250  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM MIN",
251  (int)(*det)->slice);
252  cpl_propertylist_append_float(aHeader, keyword, cpl_array_get_min(fwhm));
253  snprintf(keyword, KEYWORD_LENGTH, "ESO QC LSF SLICE%i FWHM MAX",
254  (int)(*det)->slice);
255  cpl_propertylist_append_float(aHeader, keyword, cpl_array_get_max(fwhm));
256  cpl_array_delete(fwhm);
257  }
258 
259  return CPL_ERROR_NONE;
260 } /* muse_lsf_params_qc() */
261 
262 static cpl_error_code
263 muse_lsf_params_save_table(cpl_propertylist *aHeader,
264  const muse_lsf_params **aSlicePars,
265  muse_processing *aProcessing, int aIFU)
266 {
267  cpl_error_code r = CPL_ERROR_NONE;
268  if (aSlicePars != NULL) {
269  cpl_frame *frame
270  = muse_processing_new_frame(aProcessing, aIFU, aHeader,
271  "LSF_PROFILE", CPL_FRAME_TYPE_TABLE);
272  if (frame != NULL) {
273  const char *filename = cpl_frame_get_filename(frame);
274  cpl_msg_info(__func__, "Saving LSF table as %s", filename);
275  char *channel = cpl_sprintf("CHAN%02d", aIFU);
276  cpl_propertylist_update_string(aHeader, "EXTNAME", channel);
277  cpl_free(channel);
278  r = cpl_propertylist_save(aHeader, filename, CPL_IO_CREATE);
279  r = muse_lsf_params_save(aSlicePars, filename);
280  if (r == CPL_ERROR_NONE) {
281 #pragma omp critical(muse_processing_output_frames)
282  cpl_frameset_insert(aProcessing->outframes, frame);
283  } else {
284  cpl_frame_delete(frame);
285  }
286  }
287  }
288  return r;
289 } /* muse_lsf_params_save_table() */
290 #endif // defined(USE_LSF_PARAMS)
291 
292 /*----------------------------------------------------------------------------*/
299 /*----------------------------------------------------------------------------*/
300 int
301 muse_lsf_compute(muse_processing *aProcessing, muse_lsf_params_t *aParams)
302 {
304  "muse.muse_lsf");
306  aParams->nifu,
307  bpars, NULL);
309  cpl_ensure(images, cpl_error_get_code(), -1);
310 
311  cpl_table *arclines = muse_processing_load_ctable(aProcessing, MUSE_TAG_LINE_CATALOG, 0);
312  cpl_table *tracetable = muse_processing_load_ctable(aProcessing, MUSE_TAG_TRACE_TABLE,
313  aParams->nifu);
314  cpl_table *wavecaltable = muse_processing_load_ctable(aProcessing, MUSE_TAG_WAVECAL_TABLE,
315  aParams->nifu);
316  if (!arclines || !tracetable || !wavecaltable) {
317  cpl_msg_error(__func__, "Calibration could not be loaded:%s%s%s",
318  !arclines ? " " : "",
319  !tracetable ? " "MUSE_TAG_TRACE_TABLE : "",
320  !wavecaltable ? " "MUSE_TAG_WAVECAL_TABLE : "");
321  muse_imagelist_delete(images);
322  cpl_table_delete(arclines);
323  cpl_table_delete(tracetable);
324  cpl_table_delete(wavecaltable);
325  return -1;
326  }
327 
328  /* keep the error state at this point, before doing the spectral processing */
329  cpl_errorstate prestate = cpl_errorstate_get();
330 
331  if (aParams->method == MUSE_LSF_PARAM_METHOD_INTERPOLATE) {
332 
334  images, tracetable, wavecaltable, arclines,
335  aParams->line_quality,
336  aParams->lsf_range + aParams->lsf_regression_window);
337 
338  cpl_table_delete(arclines);
339  cpl_table_delete(tracetable);
340  cpl_table_delete(wavecaltable);
341  muse_imagelist_delete(images);
342  if (arcpixtable == NULL) {
343  cpl_msg_error(__func__, "Could not create pixel table of arc lines for "
344  "IFU %d", aParams->nifu);
345  return -1;
346  }
347 
348  muse_lsf_cube *lsfcube = muse_lsf_compute_slices(arcpixtable, aParams);
349  if (lsfcube == NULL) {
350  cpl_msg_error(__func__, "Could not create LSF cube for IFU %d",
351  aParams->nifu);
352  if (aParams->save_subtracted) {
353  muse_processing_save_table(aProcessing, aParams->nifu, arcpixtable, NULL,
354  MUSE_TAG_PT_SUB, MUSE_TABLE_TYPE_PIXTABLE);
355  }
356  muse_pixtable_delete(arcpixtable);
357  return -1;
358  }
359 
360  /* add QC parameters to the primary header of the LSF cube and save it */
361  muse_lsf_qc(lsfcube);
362  muse_processing_save_cube(aProcessing, aParams->nifu, lsfcube,
363  MUSE_TAG_LSF_PROFILE, MUSE_CUBE_TYPE_LSF);
364  if (aParams->save_subtracted) {
365  cpl_table_duplicate_column(arcpixtable->table, "orig", arcpixtable->table,
367  muse_lsf_subtract_arcs(lsfcube, arcpixtable->table);
368  muse_processing_save_table(aProcessing, aParams->nifu, arcpixtable, NULL,
369  MUSE_TAG_PT_SUB, MUSE_TABLE_TYPE_PIXTABLE);
370  }
371  muse_pixtable_delete(arcpixtable);
372  muse_lsf_cube_delete(lsfcube);
373 
374  }
375 #ifdef USE_LSF_PARAMS
376  else if (aParams->method == MUSE_LSF_PARAM_METHOD_HERMIT) {
377  muse_combinepar *cpars = muse_combinepar_new(aProcessing->parameters,
378  "muse.muse_lsf");
379  muse_image *masterimage = muse_combine_images(cpars, images);
380  muse_combinepar_delete(cpars);
381  muse_imagelist_delete(images);
382 
383  muse_pixtable *arcpixtable = muse_pixtable_create(masterimage, tracetable,
384  wavecaltable, NULL);
385  cpl_table_delete(tracetable);
386  cpl_table_delete(wavecaltable);
387  if (!arcpixtable) {
388  cpl_msg_error(__func__, "ARC pixel table creation failed");
389  cpl_table_delete(arclines);
390  muse_image_delete(masterimage);
391  return -1;
392  }
393 
394  /* erase unused (flux == 0.) and non-isolated (quality < 3) lines */
395  cpl_table_unselect_all(arclines);
396  cpl_table_or_selected_int(arclines, MUSE_LINE_CATALOG_QUALITY,
397  CPL_LESS_THAN, aParams->line_quality);
398  cpl_table_or_selected_float(arclines, "flux", CPL_NOT_GREATER_THAN, 0.);
399  cpl_table_erase_selected(arclines);
400  /* sort list by decreasing flux and cut it to the 40 brightest lines */
401  cpl_propertylist *flux_sort = cpl_propertylist_new();
402  cpl_propertylist_append_bool(flux_sort, "flux", CPL_TRUE);
403  cpl_table_sort(arclines, flux_sort);
404  cpl_propertylist_delete(flux_sort);
405  cpl_size nrows = 40;
406  if (nrows < cpl_table_get_nrow(arclines)) {
407  cpl_table_erase_window(arclines, nrows, cpl_table_get_nrow(arclines));
408  }
409 
410  if (aParams->save_subtracted) {
411  cpl_table_duplicate_column(arcpixtable->table, "orig", arcpixtable->table,
413  }
414  muse_lsf_params **lsf = muse_lsf_params_compute(arclines, arcpixtable, 40);
415 
416  cpl_propertylist *qc_header = cpl_propertylist_new();
417  muse_lsf_params_qc(qc_header, (const muse_lsf_params **)lsf);
418  muse_lsf_params_save_table(qc_header, (const muse_lsf_params **)lsf,
419  aProcessing, aParams->nifu);
421  cpl_propertylist_delete(qc_header);
422 
423  if (aParams->save_subtracted) {
424  muse_processing_save_table(aProcessing, aParams->nifu, arcpixtable, NULL,
425  MUSE_TAG_PT_SUB, MUSE_TABLE_TYPE_PIXTABLE);
426  }
427 
428  muse_pixtable_delete(arcpixtable);
429  cpl_table_delete(arclines);
430  muse_image_delete(masterimage);
431  }
432 #endif // defined(USE_LSF_PARAMS)
433  else {
434  cpl_msg_error(__func__, "Unknown LSF method %s", aParams->method_s);
435  }
436  return (cpl_errorstate_is_equal(prestate))?0:-1;
437 }
int method
LSF generation method. Depending on this value, either an interpolated LSF cube is created...
Definition: muse_lsf_z.h:91
int lambda_size
Image size in line wavelength direction.
Definition: muse_lsf_z.h:77
Structure definition for a collection of muse_images.
muse_wcs * wcs
Common WCS information for each slice.
Definition: muse_lsf.h:55
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.
cpl_size muse_pixtable_extracted_get_size(muse_pixtable **aPixtables)
Get the size of an array of extracted pixel tables.
cpl_propertylist * header
Primary header used to save the LSF cube to disk.
Definition: muse_lsf.h:51
muse_imagelist * muse_basicproc_combine_images_lampwise(muse_processing *aProcessing, unsigned char aIFU, muse_basicproc_params *aBPars, cpl_frameset ***aLabeledFrames)
Combine several images into a lampwise image list.
double muse_lsf_fwhm_lambda(const muse_lsf_params *aDP, double aLambda, double aSampling, unsigned int aLength)
Measure the FWHM of an LSF at a given wavelength.
muse_pixtable ** muse_pixtable_extracted_get_slices(muse_pixtable *aPixtable)
Extract one pixel table per IFU and slice.
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_lsf_z.h:50
void muse_imagelist_delete(muse_imagelist *aList)
Free the memory of the MUSE image list.
Data cube/stacked image list containing the LSF for one IFU.
Definition: muse_lsf.h:49
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
muse_lsf_cube * muse_lsf_cube_new(double aLsfHalfRange, cpl_size aNLsf, cpl_size aNLambda, const cpl_propertylist *aHeader)
Create a new LSF datacube.
cpl_table * table
The pixel table.
void muse_basicproc_params_delete(muse_basicproc_params *aBPars)
Free a structure of basic processing parameters.
void muse_lsf_params_delete_all(muse_lsf_params **aParams)
Delete an allocated array of muse_lsf_params structure.
int save_subtracted
Save the pixel table after the LSF subtraction.
Definition: muse_lsf_z.h:65
#define MUSE_PIXTABLE_DATA
Definition: muse_pixtable.h:48
void muse_combinepar_delete(muse_combinepar *aCPars)
Clear the combination parameters.
Definition: muse_combine.c:715
Structure definition of MUSE pixel table.
int lsf_size
Image size in LSF direction.
Definition: muse_lsf_z.h:74
cpl_frame * muse_processing_new_frame(muse_processing *aProcessing, int aIFU, cpl_propertylist *aHeader, const char *aTag, cpl_frame_type aType)
Create a new frame for a result file.
Structure to hold the parameters of the muse_lsf recipe.
Definition: muse_lsf_z.h:48
cpl_frameset * outframes
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.
int line_quality
Minimal quality flag in line catalog for selection.
Definition: muse_lsf_z.h:68
muse_combinepar * muse_combinepar_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new set of combination parameters.
Definition: muse_combine.c:672
muse_lsf_params * muse_lsf_params_fit(muse_pixtable *aPixtable, cpl_table *aLines, int aMaxIter)
Fit all entries of one slice.
cpl_error_code muse_lsf_apply(const cpl_image *aLsfImage, const muse_wcs *aWCS, cpl_array *aVal, double aLambda)
Apply the LSF to a number of data points of one slice.
muse_pixtable * muse_pixtable_create(muse_image *aImage, cpl_table *aTrace, cpl_table *aWave, cpl_table *aGeoTable)
Create the pixel table for one CCD.
#define MUSE_PIXTABLE_ORIGIN
Definition: muse_pixtable.h:54
unsigned short muse_pixtable_origin_get_ifu(uint32_t aOrigin)
Get the IFU number from the encoded 32bit origin number.
cpl_table * muse_processing_load_ctable(muse_processing *aProcessing, const char *aTag, unsigned char aIFU)
Load a CPL table according to its tag and IFU/channel number.
cpl_error_code muse_lsf_params_save(const muse_lsf_params **aLsfParams, const char *aFile)
Save slice LSF parameters to the extension "slice" on disk.
#define MUSE_PIXTABLE_LAMBDA
Definition: muse_pixtable.h:53
muse_pixtable * muse_lsf_create_arcpixtable(muse_imagelist *aImages, cpl_table *aTrace, cpl_table *aWave, cpl_table *aArcLines, int aQuality, double aWindow)
Read images and combine the arc lines into one pixtable.
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 * method_s
LSF generation method. Depending on this value, either an interpolated LSF cube is created...
Definition: muse_lsf_z.h:93
void muse_lsf_cube_delete(muse_lsf_cube *aLsfCube)
Deallocate the memory for the LSF cube.
cpl_imagelist * img
Stacked image list for LSF; one per slice.
Definition: muse_lsf.h:53
Structure definition of detector (slice) parameters.
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
double lsf_range
Wavelength window (half size) around each line to estimate LSF.
Definition: muse_lsf_z.h:71
cpl_parameterlist * parameters
cpl_error_code muse_lsf_fit_slice(const muse_pixtable *aPixtable, cpl_image *aLsfImage, muse_wcs *aWCS, double aLsfRegressionWindow)
Compute the LSF for all wavelengths of one slice.
cpl_propertylist * header
The FITS header.
double lsf_regression_window
Size of the regression window in LSF direction.
Definition: muse_lsf_z.h:80