27 #define STORE_SLIT_WIDTH 28 #define STORE_BIN_WIDTH 40 #include "muse_instrument.h" 41 #include "muse_optimize.h" 42 #include "muse_pfits.h" 43 #include "muse_pixtable.h" 44 #include "muse_quality.h" 45 #include "muse_resampling.h" 46 #include "muse_tracing.h" 47 #include "muse_utils.h" 48 #include "muse_wavecalib.h" 76 cpl_size nrows = cpl_table_get_nrow(aPixtable);
81 cpl_errorstate prestate = cpl_errorstate_get();
84 cpl_vector *pos = cpl_vector_new(nrows);
85 cpl_vector *val = cpl_vector_new(nrows);
86 cpl_vector *err = cpl_vector_new(nrows);
87 double *d_pos = cpl_vector_get_data(pos);
88 double *d_val = cpl_vector_get_data(val);
89 double *d_err = cpl_vector_get_data(err);
95 for (i = 0; i < nrows; i++) {
96 if (fabs(d_lambda[i] - aLambda) > 5.5) {
100 d_pos[i] = d_lambda[i];
101 d_val[i] = d_data[i];
102 d_err[i] = sqrt(d_stat[i]);
106 double sigma, area, mse;
108 cpl_fit_mode fit_pars = CPL_FIT_STDEV | CPL_FIT_AREA | CPL_FIT_CENTROID;
109 cpl_vector_fit_gaussian(pos, NULL, val, NULL, fit_pars, &xc, &sigma,
110 &area, &bglevel, &mse, NULL, NULL);
113 for (i = 0; i < nrows; i++) {
114 double e = (d_pos[i] - xc)/sigma;
115 d_val[i] -= area / (CPL_MATH_SQRT2PI * sigma) * exp(-e*e/2) - bglevel;
119 double maxerror = 0.5 * sqrt(area) + 0.15 * area;
121 cpl_table_unselect_all(aPixtable);
122 for (i = 0; i < nrows; i++) {
123 if ((d_val[i] < -maxerror) || (d_val[i] > maxerror)) {
125 cpl_table_select_row(aPixtable, i);
128 cpl_table_erase_selected(aPixtable);
129 nrows = cpl_table_get_nrow(aPixtable);
130 cpl_vector_delete(pos);
131 cpl_vector_delete(val);
132 cpl_vector_delete(err);
134 cpl_table_fill_column_window_float(aPixtable,
"line_lambda",
136 cpl_table_fill_column_window_float(aPixtable,
"line_flux",
138 cpl_table_fill_column_window_float(aPixtable,
"line_background",
142 if (!cpl_errorstate_is_equal(prestate)) {
143 cpl_errorstate_set(prestate);
147 if (area/meansigma < 50) {
152 if ((sigma > 3) || (sigma < 0.7)) {
153 uint32_t origin = (uint32_t)cpl_table_get_int(aPixtable,
158 cpl_msg_debug(__func__,
"Slice %2i.%02i: " 159 "Ignoring line %.1f with implausible width %f (flux=%.0f)",
160 i_ifu, i_slice, aLambda, sigma, area);
191 cpl_table *sel = cpl_table_extract(aPixtable->
table, low + 1, high - low);
192 cpl_table_select_all(sel);
193 cpl_table_and_selected_int(sel,
"dq", CPL_NOT_EQUAL_TO, 0);
194 cpl_table_erase_selected(sel);
196 cpl_table_new_column(sel,
"line_lambda", CPL_TYPE_FLOAT);
197 cpl_table_new_column(sel,
"line_flux", CPL_TYPE_FLOAT);
198 cpl_table_new_column(sel,
"line_background", CPL_TYPE_FLOAT);
203 cpl_table_delete(sel);
234 cpl_table *aTrace, cpl_table *aWave,
235 cpl_table *aArcLines,
int aQuality,
double aWindow)
237 cpl_ensure(aImages, CPL_ERROR_NULL_INPUT, NULL);
238 cpl_ensure(aTrace, CPL_ERROR_NULL_INPUT, NULL);
239 cpl_ensure(aWave, CPL_ERROR_NULL_INPUT, NULL);
240 cpl_ensure(aArcLines, CPL_ERROR_NULL_INPUT, NULL);
245 cpl_table_new_column(pt->
table,
"line_lambda", CPL_TYPE_FLOAT);
246 cpl_table_new_column(pt->
table,
"line_flux", CPL_TYPE_FLOAT);
247 cpl_table_new_column(pt->
table,
"line_background", CPL_TYPE_FLOAT);
251 #pragma omp parallel for default(none) \ 252 shared(i_image, n_images, aImages, aTrace, aWave, aArcLines, \ 253 aQuality, aWindow, pt) 255 for (i_image = 0; i_image < n_images; i_image++) {
258 if (pixtable == NULL) {
263 pt->
header = cpl_propertylist_duplicate(pixtable->
header);
266 if (strlen(l) == 0) {
267 cpl_msg_warning(__func__,
268 "Ignoring frame without arc lamp switched on");
273 char *lamp = cpl_malloc(strlen(l)+3);
274 sprintf(lamp,
"|%s|", l);
277 cpl_size n_entries = 0;
281 for (i_line = 0; i_line < cpl_table_get_nrow(aArcLines); i_line++) {
282 double lambda = cpl_table_get_float(aArcLines,
"lambda", i_line, NULL);
284 cpl_table_get_int(aArcLines,
"quality", i_line, NULL) < aQuality) {
288 char *name = cpl_malloc(strlen(n) + 3);
289 sprintf(name,
"|%s|", n);
290 if (strstr(name, lamp)) {
293 #pragma omp parallel for default(none) \ 294 shared(i_slice, n_slices, n_entries, lambda, slice_pixtable, \ 297 for (i_slice = 0; i_slice < n_slices; i_slice++) {
302 #pragma omp critical(construct_pixtable) 304 cpl_table_insert(pt->
table, sel, cpl_table_get_nrow(pt->
table));
308 n_entries += cpl_table_get_nrow(sel);
309 cpl_table_delete(sel);
317 cpl_msg_info(__func__,
"Using %"CPL_SIZE_FORMAT
" entries with lamp %s",
347 static cpl_polynomial *
350 cpl_errorstate prestate = cpl_errorstate_get();
351 cpl_size nrows = cpl_table_get_nrow(aPixtable);
352 if (nrows <= (aOrderLsf + 1) * (aOrderLambda)) {
355 double *p_dlambda = cpl_table_get_data_double(aPixtable,
"d_lambda");
356 cpl_ensure(p_dlambda != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
357 float *p_line = cpl_table_get_data_float(aPixtable,
"line_lambda");
358 cpl_ensure(p_line != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
360 cpl_ensure(p_data != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
361 float *p_flux = cpl_table_get_data_float(aPixtable,
"line_flux");
362 cpl_ensure(p_flux != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
363 float *p_background = cpl_table_get_data_float(aPixtable,
"line_background");
364 cpl_ensure(p_background != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
366 cpl_matrix *coord = cpl_matrix_new(2, nrows);
367 cpl_vector *data = cpl_vector_new(nrows);
368 double *coord_ptr = cpl_matrix_get_data(coord);
369 double *data_ptr = cpl_vector_get_data(data);
372 for (i_row = 0; i_row < nrows; i_row++) {
373 coord_ptr[i_row] = p_dlambda[i_row];
374 coord_ptr[i_row + nrows] = p_line[i_row];
375 data_ptr[i_row] = (p_data[i_row] - p_background[i_row]) / p_flux[i_row];
378 cpl_polynomial *p = cpl_polynomial_new(2);
379 const cpl_size maxdeg2d[] = { aOrderLsf, aOrderLambda };
380 cpl_polynomial_fit(p, coord, NULL, data, NULL, CPL_TRUE, NULL, maxdeg2d);
381 cpl_matrix_delete(coord);
382 cpl_vector_delete(data);
384 if (!cpl_errorstate_is_equal(prestate)) {
385 cpl_errorstate_set(prestate);
421 muse_wcs *aWCS,
double aLsfRegressionWindow)
423 cpl_ensure_code(aPixtable && aPixtable->
table, CPL_ERROR_NULL_INPUT);
424 cpl_ensure_code(aLsfImage, CPL_ERROR_NULL_INPUT);
425 cpl_ensure_code(aWCS, CPL_ERROR_NULL_INPUT);
426 cpl_ensure_code(aLsfRegressionWindow > 0, CPL_ERROR_ILLEGAL_INPUT);
430 return CPL_ERROR_NONE;
433 cpl_table *pixtable = cpl_table_duplicate(aPixtable->
table);
434 uint32_t origin = (uint32_t)cpl_table_get_int(pixtable,
438 cpl_msg_info(__func__,
"processing slice %2i.%02i" 439 " with %"CPL_SIZE_FORMAT
" entries",
440 i_ifu, i_slice, nrows);
447 cpl_table_subtract_columns(pixtable,
"d_lambda",
"line_lambda");
448 cpl_propertylist *order = cpl_propertylist_new();
449 cpl_propertylist_append_bool(order,
"d_lambda", CPL_FALSE);
450 cpl_table_sort(pixtable, order);
451 cpl_propertylist_delete(order);
456 cpl_size n_lsf = cpl_image_get_size_x(aLsfImage);
457 cpl_size n_lambda = cpl_image_get_size_y(aLsfImage);
458 for (i_lsf = 1; i_lsf <= n_lsf; i_lsf++) {
459 double x = aWCS->crval1 + (i_lsf - aWCS->crpix1) * aWCS->cd11;
460 double x_ref = CPL_MAX(x, cpl_table_get_column_min(pixtable,
"d_lambda")
461 + aLsfRegressionWindow);
462 x_ref = CPL_MIN(x, cpl_table_get_column_max(pixtable,
"d_lambda")
463 - aLsfRegressionWindow);
465 x_ref - aLsfRegressionWindow);
467 x_ref + aLsfRegressionWindow);
468 cpl_table *selected = cpl_table_extract(pixtable, low+1, high-low);
471 cpl_vector *c = cpl_vector_new(2);
472 cpl_vector_set(c, 0, x);
475 for (i_lambda = 1; i_lambda <= n_lambda; i_lambda++) {
477 cpl_vector_set(c, 1, y);
478 double flux = cpl_polynomial_eval(p, c);
479 cpl_image_set(aLsfImage, i_lsf, i_lambda, flux);
481 cpl_vector_delete(c);
483 cpl_msg_warning(__func__,
484 "Failed polynomial fit %2i.%02i %.2f;" 485 " %"CPL_SIZE_FORMAT
" entries",
486 i_ifu, i_slice, x, cpl_table_get_nrow(selected));
488 for (i_lambda = 1; i_lambda <= n_lambda; i_lambda++) {
489 cpl_image_reject(aLsfImage, i_lsf, i_lambda);
492 cpl_polynomial_delete(p);
493 cpl_table_delete(selected);
495 cpl_table_delete(pixtable);
499 for (i_lambda = 1; i_lambda <= n_lambda; i_lambda++) {
500 double line_flux = cpl_image_get_flux_window(aLsfImage, 1, i_lambda,
501 n_lsf, i_lambda) * aWCS->cd11;
502 for (i_lsf = 1; i_lsf <= n_lsf; i_lsf++) {
504 double flux = cpl_image_get(aLsfImage, i_lsf, i_lambda, &invalid);
506 cpl_image_set(aLsfImage, i_lsf, i_lambda, flux / line_flux);
510 return CPL_ERROR_NONE;
523 const cpl_propertylist *aHeader)
526 lsf->
header = cpl_propertylist_new();
529 const char *regex = MUSE_HDR_OVSC_REGEXP
"|"MUSE_WCS_KEYS"|"MUSE_HDR_PT_REGEXP;
530 cpl_propertylist_copy_property_regexp(lsf->
header, aHeader, regex, 1);
532 lsf->
img = cpl_imagelist_new();
534 for (i = 0; i < kMuseSlicesPerCCD; i++) {
535 cpl_imagelist_set(lsf->
img,
536 cpl_image_new(aNLsf, aNLambda, CPL_TYPE_FLOAT), i);
538 double lsf_step = 2*aLsfHalfRange / (aNLsf - 1),
539 lambda_step = (kMuseNominalLambdaMax - kMuseNominalLambdaMin)
542 lsf->
wcs->cd11 = lsf_step;
546 lsf->
wcs->crval1 = -aLsfHalfRange;
547 lsf->
wcs->
crval2 = kMuseNominalLambdaMin;
548 lsf->
wcs->crpix1 = 1.;
563 cpl_propertylist_delete(aLsfCube->
header);
564 cpl_imagelist_delete(aLsfCube->
img);
565 cpl_free(aLsfCube->
wcs);
577 cpl_ensure_code(aLsfCube, CPL_ERROR_NULL_INPUT);
578 cpl_error_code rc = cpl_propertylist_save(aLsfCube->
header, aFileName,
580 if (rc != CPL_ERROR_NONE) {
584 cpl_propertylist *header = cpl_propertylist_new();
585 cpl_propertylist_append_string(header,
"EXTNAME",
"LSF_PROFILE");
586 cpl_propertylist_append_int(header,
"WCSAXES", 2);
587 cpl_propertylist_append_double(header,
"CD1_1", aLsfCube->
wcs->cd11);
588 cpl_propertylist_append_double(header,
"CD1_2", aLsfCube->
wcs->cd12);
589 cpl_propertylist_append_double(header,
"CD2_1", aLsfCube->
wcs->cd21);
590 cpl_propertylist_append_double(header,
"CD2_2", aLsfCube->
wcs->
cd22);
591 cpl_propertylist_append_double(header,
"CRPIX1", aLsfCube->
wcs->crpix1);
592 cpl_propertylist_append_double(header,
"CRPIX2", aLsfCube->
wcs->
crpix2);
593 cpl_propertylist_append_double(header,
"CRVAL1", aLsfCube->
wcs->crval1);
594 cpl_propertylist_append_double(header,
"CRVAL2", aLsfCube->
wcs->
crval2);
595 cpl_propertylist_append_string(header,
"CTYPE1",
"PARAM");
596 cpl_propertylist_append_string(header,
"CTYPE2",
"AWAV");
597 cpl_propertylist_append_string(header,
"CUNIT1",
"Angstrom");
598 cpl_propertylist_append_string(header,
"CUNIT2",
"Angstrom");
600 rc = cpl_imagelist_save(aLsfCube->
img, aFileName,
601 CPL_TYPE_FLOAT, header, CPL_IO_EXTEND);
602 cpl_propertylist_delete(header);
622 cpl_ensure(aProcessing, CPL_ERROR_NULL_INPUT, NULL);
624 unsigned char ifu, nlsfs = 0;
625 for (ifu = 1; ifu <= kMuseNumIFUs; ifu++) {
627 MUSE_TAG_LSF_PROFILE, ifu, CPL_FALSE);
628 cpl_errorstate es = cpl_errorstate_get();
629 cpl_frame *frame = cpl_frameset_get_position(frames, 0);
631 cpl_msg_warning(__func__,
"No %s (cube format) specified for IFU %2hhu!",
632 MUSE_TAG_LSF_PROFILE, ifu);
633 cpl_errorstate_set(es);
634 cpl_frameset_delete(frames);
637 const char *fn = cpl_frame_get_filename(frame);
639 if (lsf[ifu-1] == NULL) {
640 cpl_msg_warning(__func__,
"Could not load LSF (cube format) for IFU %2hhu " 641 "from \"%s\"!", ifu, fn);
642 cpl_frameset_delete(frames);
647 cpl_frameset_delete(frames);
651 cpl_msg_error(__func__,
"Did not load any %ss (cube format)!",
652 MUSE_TAG_LSF_PROFILE);
656 cpl_msg_info(__func__,
"Successfully loaded %s%hhu %ss (cube format).",
657 nlsfs == kMuseNumIFUs ?
"all ":
"", nlsfs, MUSE_TAG_LSF_PROFILE);
666 if (aLsfCube != NULL) {
668 for (ifu = 0; ifu < kMuseNumIFUs; ifu++) {
685 cpl_ensure(aFileName, CPL_ERROR_NULL_INPUT, NULL);
688 int ext = cpl_fits_find_extension(aFileName,
"LSF_PROFILE");
689 char *extname = NULL;
691 extname = cpl_sprintf(
"CHAN%02hhu.LSF_PROFILE", aIFU);
692 ext = cpl_fits_find_extension(aFileName, extname);
695 cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND);
702 lsf->
header = cpl_propertylist_load(aFileName, 0);
703 lsf->
img = cpl_imagelist_load(aFileName, CPL_TYPE_DOUBLE, ext);
705 if (lsf->
img == NULL) {
710 cpl_propertylist *header = cpl_propertylist_load(aFileName, ext);
711 if (header == NULL) {
728 cpl_propertylist_delete(header);
746 cpl_ensure(aLsfCube, CPL_ERROR_NULL_INPUT, NULL);
747 cpl_image *img = NULL;
749 cpl_size w[kMuseNumIFUs][kMuseSlicesPerCCD];
751 for (ifu = 0; ifu < kMuseNumIFUs; ifu++) {
753 for (i_slice = 0; i_slice < kMuseSlicesPerCCD; i_slice++) {
754 w[ifu][i_slice] = (aPixtable == NULL)?1.0:0.0;
758 if (aPixtable != NULL) {
761 uint32_t *origin = (uint32_t*)
763 for (i_row = 0; i_row < n_rows; i_row++) {
766 w[i_ifu-1][i_slice-1]++;
770 for (ifu = 0; ifu < kMuseNumIFUs; ifu++) {
771 if (aLsfCube[ifu] == NULL) {
775 cpl_size n_slices = cpl_imagelist_get_size(aLsfCube[ifu]->img);
776 for (i_slice = 0; i_slice < n_slices; i_slice++) {
777 if (w[ifu][i_slice] > 0) {
778 cpl_image *m = cpl_imagelist_get(aLsfCube[ifu]->img, i_slice);
779 m = cpl_image_duplicate(m);
780 cpl_image_multiply_scalar(m, w[ifu][i_slice]);
781 wsum += w[ifu][i_slice];
785 cpl_errorstate pre = cpl_errorstate_get();
786 cpl_error_code rc = cpl_image_add(img, m);
788 if (rc != CPL_ERROR_NONE) {
789 cpl_msg_warning(__func__,
"Could not add cube of IFU %" 790 CPL_SIZE_FORMAT
": %s",
791 ifu+1, cpl_error_get_message());
792 cpl_errorstate_set(pre);
799 if ((img != NULL) && (wsum > 0)) {
800 cpl_image_divide_scalar(img, wsum);
803 cpl_image_delete(img);
812 for (ifu = 0; ifu < kMuseNumIFUs; ifu++) {
813 if (aLsfCube[ifu] != NULL) {
814 return aLsfCube[ifu]->
wcs;
836 cpl_ensure_code(aLsfImage && aWCS, CPL_ERROR_NULL_INPUT);
837 cpl_ensure_code(aBinWidth > 0., CPL_ERROR_ILLEGAL_INPUT);
839 cpl_size ncol_kernel = aBinWidth / aWCS->cd11;
840 ncol_kernel = ((ncol_kernel + 1) / 2) * 2 + 1;
841 double r = ncol_kernel - aBinWidth / aWCS->cd11;
842 cpl_matrix *kernel = cpl_matrix_new(1, ncol_kernel);
843 cpl_matrix_fill(kernel, 1.0);
844 cpl_matrix_set(kernel, 0, 0, 1 - r/2);
845 cpl_matrix_set(kernel, 0, ncol_kernel-1, 1 - r/2);
846 cpl_image *lsfImage0 = cpl_image_duplicate(aLsfImage);
847 cpl_image_filter(aLsfImage, lsfImage0, kernel, CPL_FILTER_LINEAR,
849 cpl_matrix_delete(kernel);
850 cpl_image_delete(lsfImage0);
852 return CPL_ERROR_NONE;
871 cpl_array *aVal,
double aLambda)
873 cpl_ensure_code(aLsfImage, CPL_ERROR_NULL_INPUT);
874 cpl_ensure_code(aWCS, CPL_ERROR_NULL_INPUT);
875 cpl_ensure_code(aVal, CPL_ERROR_NULL_INPUT);
876 cpl_size n_lsf = cpl_image_get_size_x(aLsfImage);
877 cpl_size n_lambda = cpl_image_get_size_y(aLsfImage);
881 if (lambda_pix < 1) {
884 if (lambda_pix > n_lambda) {
885 lambda_pix = n_lambda;
887 cpl_size i_lambda = floor(lambda_pix);
888 lambda_pix -= i_lambda;
892 cpl_array *lsf_lambda = cpl_array_new(n_lsf + 4, CPL_TYPE_DOUBLE);
893 cpl_array *lsf_values = cpl_array_new(n_lsf + 4, CPL_TYPE_DOUBLE);
895 for (i = 1; i <= n_lsf; i++) {
897 double z = cpl_image_get(aLsfImage, i, i_lambda, &res);
898 if (lambda_pix > 0) {
899 z = z * (1 - lambda_pix)
900 + cpl_image_get(aLsfImage, i, i_lambda+1, &res) * lambda_pix;
902 cpl_array_set(lsf_values, i+1, z);
903 cpl_array_set(lsf_lambda, i+1, aWCS->crval1 + (i - aWCS->crpix1) * aWCS->cd11);
907 cpl_array_set(lsf_lambda, 0, -10000);
908 cpl_array_set(lsf_values, 0, 0);
909 cpl_array_set(lsf_lambda, 1, aWCS->crval1 - aWCS->crpix1 * aWCS->cd11);
910 cpl_array_set(lsf_values, 1, 0);
911 cpl_array_set(lsf_lambda, n_lsf+2, aWCS->crval1 + (n_lsf+1 - aWCS->crpix1) * aWCS->cd11);
912 cpl_array_set(lsf_values, n_lsf+2, 0);
913 cpl_array_set(lsf_lambda, n_lsf+3, 10000);
914 cpl_array_set(lsf_values, n_lsf+3, 0);
917 cpl_array *v = cpl_array_duplicate(lsf_values);
918 cpl_array_multiply(v, lsf_lambda);
919 double offset = cpl_array_get_mean(v)/cpl_array_get_mean(lsf_values);
921 cpl_array_subtract_scalar (lsf_lambda, offset);
924 double norm = cpl_array_get_mean(lsf_values) * (n_lsf + 4) * aWCS->cd11;
925 cpl_array_divide_scalar(lsf_values, norm);
931 memcpy(cpl_array_get_data_double(aVal), cpl_array_get_data_double(values),
932 cpl_array_get_size(aVal) *
sizeof(
double));
934 cpl_array_delete(values);
935 cpl_array_delete(lsf_lambda);
936 cpl_array_delete(lsf_values);
937 return CPL_ERROR_NONE;
Structure definition for a collection of muse_images.
muse_wcs * wcs
Common WCS information for each slice.
void muse_pixtable_extracted_delete(muse_pixtable **aPixtables)
Delete a pixel table array.
double muse_pfits_get_cd(const cpl_propertylist *aHeaders, unsigned int aAxisI, unsigned int aAxisJ)
find out the WCS coordinate at the reference point
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.
double muse_pfits_get_crval(const cpl_propertylist *aHeaders, unsigned int aAxis)
find out the WCS coordinate at the reference point
A structure containing a spatial two-axis WCS.
muse_pixtable ** muse_pixtable_extracted_get_slices(muse_pixtable *aPixtable)
Extract one pixel table per IFU and slice.
cpl_size muse_pixtable_get_nrow(const muse_pixtable *aPixtable)
get the number of rows within the pixel table
cpl_image * muse_lsf_average_cube_all(muse_lsf_cube **aLsfCube, muse_pixtable *aPixtable)
Create an average image from all LSF cubes.
Data cube/stacked image list containing the LSF for one IFU.
muse_lsf_cube * muse_lsf_cube_new(double aLsfHalfRange, cpl_size aNLsf, cpl_size aNLambda, const cpl_propertylist *aHeader)
Create a new LSF datacube.
Structure definition of MUSE three extension FITS file.
cpl_error_code muse_lsf_cube_save(muse_lsf_cube *aLsfCube, const char *aFileName)
Save the LSF cube to disk.
cpl_table * table
The pixel table.
#define MUSE_PIXTABLE_DATA
unsigned int muse_imagelist_get_size(muse_imagelist *aList)
Return the number of stored images.
cpl_table * muse_cpltable_new(const muse_cpltable_def *aDef, cpl_size aLength)
Create an empty table according to the specified definition.
muse_lsf_cube * muse_lsf_cube_load(const char *aFileName, unsigned char aIFU)
Load a LSF cube for one single IFU from disk.
const char * muse_wave_lines_get_lampname(cpl_table *aTable, const int aIdx)
Associate the ion listed in a linelist table row to a lamp name.
double muse_pfits_get_crpix(const cpl_propertylist *aHeaders, unsigned int aAxis)
find out the WCS reference point
Structure definition of MUSE pixel table.
cpl_boolean muse_wave_lines_covered_by_data(double aLambda, muse_ins_mode aMode)
Check, if a given wavelength is covered by a given instrument mode.
#define MUSE_WCS_KEYS
regular expression for WCS properties
muse_image * muse_imagelist_get(muse_imagelist *aList, unsigned int aIdx)
Get the muse_image of given list index.
muse_lsf_cube ** muse_lsf_cube_load_all(muse_processing *aProcessing)
Load all LSF cubes for all IFUs into an array.
cpl_array * muse_cplarray_interpolate_linear(const cpl_array *aTargetAbscissa, const cpl_array *aSourceAbscissa, const cpl_array *aSourceOrdinate)
Linear interpolation of a 1d array.
static cpl_size muse_lsf_check_arc_line(cpl_table *aPixtable, double aLambda)
Check the pixels for one arc line.
void muse_processing_append_used(muse_processing *aProcessing, cpl_frame *aFrame, cpl_frame_group aGroup, int aDuplicate)
Add a frame to the set of used frames.
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.
char * muse_utils_header_get_lamp_names(cpl_propertylist *aHeader, char aSep)
Concatenate names of all active calibration lamps.
#define MUSE_PIXTABLE_ORIGIN
cpl_size muse_cpltable_find_sorted(const cpl_table *aTable, const char *aColumn, double aValue)
Find a row in a table.
unsigned short muse_pixtable_origin_get_ifu(uint32_t aOrigin)
Get the IFU number from the encoded 32bit origin number.
#define MUSE_PIXTABLE_STAT
static cpl_table * select_arc_line(muse_pixtable *aPixtable, double aLambda, double aWindow)
Select the pixels for one arc line.
void muse_lsf_cube_delete_all(muse_lsf_cube **aLsfCube)
Delete all LSF cubes.
const muse_cpltable_def muse_pixtable_def[]
MUSE pixel table definition.
#define MUSE_PIXTABLE_LAMBDA
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_lsf_fold_rectangle(cpl_image *aLsfImage, const muse_wcs *aWCS, double aBinWidth)
Filter an LSF image with a rectangle to model spectrum binning.
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.
static cpl_polynomial * muse_lsf_fit_polynomial(cpl_table *aPixtable, int aOrderLsf, int aOrderLambda)
Do a polynomial fit on an arc pixtable.
cpl_frameset * muse_frameset_find(const cpl_frameset *aFrames, const char *aTag, unsigned char aIFU, cpl_boolean aInvert)
return frameset containing data from an IFU/channel with a certain tag
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
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.