32 #include "muse_twilight_z.h"
49 cpl_ensure_code(aImage && aList, CPL_ERROR_NULL_INPUT);
51 cpl_msg_debug(__func__,
"Adding QC keywords for IFU %hhu", ifu);
53 unsigned stats = CPL_STATS_MEDIAN | CPL_STATS_MEAN | CPL_STATS_STDEV
54 | CPL_STATS_MIN | CPL_STATS_MAX;
59 char *keyword = cpl_sprintf(QC_TWILIGHTm_PREFIXi, ifu, k+1);
61 aImage->
header, keyword, stats);
63 keyword = cpl_sprintf(QC_TWILIGHTm_PREFIXi
" "QC_BASIC_NSATURATED, ifu, k+1);
66 cpl_propertylist_update_int(aImage->
header, keyword, nsaturated);
71 char *kw = cpl_sprintf(QC_TWILIGHTm_MASTER_PREFIX, ifu);
72 stats |= CPL_STATS_FLUX;
75 return CPL_ERROR_NONE;
125 muse_combinepar *aCPars,
128 cpl_ensure(aProcessing && aParams, CPL_ERROR_NULL_INPUT, NULL);
131 cpl_ensure(lmax > lmin, CPL_ERROR_ILLEGAL_INPUT, NULL);
133 cpl_table *geo =
muse_table_load(aProcessing, MUSE_TAG_GEOMETRY_TABLE, 0);
134 cpl_ensure(geo, CPL_ERROR_FILE_NOT_FOUND, NULL);
138 #pragma omp parallel for default(none) \
139 shared(aBPars, aCPars, aProcessing, geo, pts)
140 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
141 cpl_table *trace =
muse_table_load(aProcessing, MUSE_TAG_TRACE_TABLE, nifu),
143 if (!trace || !wavecal) {
144 cpl_msg_warning(__func__,
"Calibrations could not be loaded for IFU "
145 "%2hhu:%s%s", nifu, !trace ?
" "MUSE_TAG_TRACE_TABLE :
"",
146 !wavecal ?
" "MUSE_TAG_WAVECAL_TABLE :
"");
147 cpl_table_delete(trace);
148 cpl_table_delete(wavecal);
152 cpl_msg_debug(__func__,
"load raw files of IFU %2hhu", nifu);
155 cpl_msg_warning(__func__,
"Basic processing failed for IFU %2hhu: %s",
156 nifu, cpl_error_get_message());
157 cpl_table_delete(trace);
158 cpl_table_delete(wavecal);
162 cpl_msg_debug(__func__,
"combine raw files of IFU %2hhu", nifu);
164 muse_twilight_qc_header(masterimage, images);
172 cpl_detector_interpolate_rejected(masterimage->
data);
174 cpl_detector_interpolate_rejected(masterimage->
stat);
176 cpl_msg_debug(__func__,
"interpolated over %d bad pixels in IFU %2hhu",
180 cpl_msg_debug(__func__,
"create pixel table for IFU %2hhu", nifu);
182 cpl_table_delete(trace);
183 cpl_table_delete(wavecal);
186 cpl_propertylist_copy_property_regexp(pts[nifu - 1]->header,
188 QC_TWILIGHT_REGEXP, 0);
192 cpl_table_delete(geo);
197 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
198 "After cutting to %.2f..%.2f Angstrom in wavelength "
199 "no pixels for cube reconstruction are left!", lmin,
201 for (nifu = 1; nifu <= kMuseNumIFUs; nifu++) {
207 double fluxref = cpl_table_get_column_mean(pt->
table, MUSE_PIXTABLE_DATA)
209 cpl_msg_debug(__func__,
"pixel table of IFU 1, fluxref = %e, %"CPL_SIZE_FORMAT
214 cpl_propertylist_append_double(pt->
header, MUSE_HDR_FLAT_FLUX_SKY
"1", fluxref);
215 char *kw = cpl_sprintf(QC_TWILIGHTm_INTFLUX, 1);
216 cpl_propertylist_append_float(pt->
header, kw, fluxref);
218 for (nifu = 2; nifu <= kMuseNumIFUs; nifu++) {
219 if (!pts[nifu - 1]) {
226 double flux = cpl_table_get_column_mean(pts[nifu - 1]->table, MUSE_PIXTABLE_DATA)
228 scale = flux / fluxref;
229 kw = cpl_sprintf(MUSE_HDR_FLAT_FLUX_SKY
"%hhu", nifu);
230 cpl_propertylist_append_double(pt->
header, kw, flux);
232 cpl_msg_debug(__func__,
"merging pixel table of IFU %2hhu, flux = %e, scale = %f",
234 cpl_table_divide_scalar(pts[nifu - 1]->table, MUSE_PIXTABLE_DATA, scale);
235 cpl_table_divide_scalar(pts[nifu - 1]->table, MUSE_PIXTABLE_STAT, scale*scale);
238 cpl_propertylist_copy_property_regexp(pt->
header, pts[nifu - 1]->
header,
239 QC_TWILIGHT_REGEXP, 0);
241 kw = cpl_sprintf(QC_TWILIGHTm_INTFLUX, nifu);
242 cpl_propertylist_append_float(pt->
header, kw, flux);
259 cube->
recnames = cpl_array_new(1, CPL_TYPE_STRING);
261 cpl_array_set_string(cube->
recnames, 0,
"white");
295 muse_twilight_image_normalize_and_fit(
muse_image *aImage,
296 unsigned int aXOrder,
297 unsigned int aYOrder,
298 const cpl_mask *aBPM,
299 const cpl_mask *aVign)
301 cpl_ensure(aImage && aImage->
data, CPL_ERROR_NULL_INPUT, NULL);
305 cpl_image_reject_from_mask(aImage->
data, aBPM);
307 cpl_image_reject_value(aImage->
data, CPL_VALUE_NOTFINITE | CPL_VALUE_ZERO);
311 cpl_image *filtered = cpl_image_duplicate(aImage->
data);
312 cpl_mask *mask = cpl_mask_new(5, 7);
314 cpl_errorstate prestate = cpl_errorstate_get();
315 cpl_image_filter_mask(filtered, aImage->
data, mask, CPL_FILTER_MEDIAN,
317 cpl_mask_delete(mask);
318 if (!cpl_errorstate_is_equal(prestate)) {
319 cpl_msg_warning(__func__,
"filtering cube plane failed: %s",
320 cpl_error_get_message());
324 cpl_image *filtered2 = cpl_image_duplicate(filtered);
326 cpl_image_filter(filtered2, filtered, gauss, CPL_FILTER_LINEAR,
328 cpl_matrix_delete(gauss);
329 if (!cpl_errorstate_is_equal(prestate)) {
330 cpl_msg_warning(__func__,
"filtering 2 failed: %s", cpl_error_get_message());
332 cpl_image_reject_from_mask(filtered2, bpm2);
333 cpl_image_fill_rejected(filtered2, 1.);
335 "TWILIGHT_IMAGE2_SMOOTHED" );
336 cpl_detector_interpolate_rejected(filtered2);
338 "TWILIGHT_IMAGE2_INTERPOLATED" );
340 cpl_image_delete(filtered2);
344 double mean = cpl_image_get_mean(filtered);
345 cpl_msg_debug(__func__,
"mean = %f", mean);
346 cpl_image_multiply_scalar(filtered, 1. / mean);
349 cpl_mask *bpm = cpl_image_get_bpm(filtered);
351 cpl_mask_or(bpm, aVign);
356 mean = cpl_image_get_mean(fit);
357 cpl_msg_debug(__func__,
"mean(fit) = %f", mean);
358 cpl_image_multiply_scalar(fit, 1. / mean);
359 cpl_image_delete(filtered);
377 cubefit->data = cpl_imagelist_new();
378 if (getenv(
"MUSE_TWILIGHT_SKIP")) {
379 char *fn = getenv(
"MUSE_TWILIGHT_SKIP");
381 cpl_msg_warning(__func__,
"Skipping active: loaded previously generated "
382 "cube from \"%s\"", fn);
387 cube->
recnames = cpl_array_new(1, CPL_TYPE_STRING);
390 cpl_array_set_string(cube->
recnames, 0,
"white");
393 strncmp(
"white", cpl_array_get_string(cube->
recnames, 0), 6))) {
397 cpl_array_set_string(cube->
recnames, 0,
"white");
402 aProcessing->
intags, -1, 0);
403 cpl_size iframe, nframes = cpl_frameset_get_size(frames);
404 for (iframe = 0; iframe < nframes; iframe++) {
405 cpl_frame *frame = cpl_frameset_get_position(frames, iframe);
408 cpl_frameset_delete(frames);
409 cpl_msg_warning(__func__,
"Skipping active: faked used frames using only "
411 cpl_frameset_dump(aProcessing->
usedframes, stdout);
413 cubefit->header = cpl_propertylist_duplicate(cube->
header);
416 cpl_error_code rc = CPL_ERROR_NONE;
419 "muse.muse_twilight");
421 "muse.muse_twilight");
427 rp->dlambda = aParams->
dlambda;
431 cube = muse_twilight_reconstruct(aProcessing, aParams, bpars, cpars, rp);
440 cubefit->header = cpl_propertylist_duplicate(cube->
header);
442 MUSE_TAG_CUBE_SKYFLAT,
445 cpl_propertylist_erase_regexp(cubefit->header, QC_TWILIGHT_REGEXP, 0);
454 cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_OUTPUT,
455 "White-light image is missing!");
459 cpl_image *white = cpl_image_duplicate(wmuse->
data);
460 cpl_image_reject_value(white, CPL_VALUE_NOTFINITE | CPL_VALUE_ZERO);
461 cpl_mask *bpm = cpl_image_get_bpm(white),
462 *bpm2 = cpl_mask_duplicate(bpm);
464 cpl_mask *border = cpl_mask_new(1, cpl_mask_get_size_y(bpm2));
465 cpl_mask_not(border);
466 cpl_mask_copy(bpm2, border, 1, 1);
467 cpl_mask_copy(bpm2, border, cpl_mask_get_size_x(bpm2), 1);
468 cpl_mask_delete(border);
471 cpl_mask *kernel = cpl_mask_new(5, 1);
472 cpl_mask_not(kernel);
473 cpl_mask_filter(bpm2, bpm, kernel, CPL_FILTER_DILATION, CPL_BORDER_NOP);
474 cpl_mask_delete(kernel);
475 bpm = cpl_image_set_bpm(white, bpm2);
476 cpl_mask_delete(bpm);
485 cpl_imagelist_get(cube->
data, 0));
486 cpl_mask_delete(maskimage->
mask);
487 maskimage->
mask = mask;
489 #if 0 // only for smoothing in wavelength direction (see below)
491 double crpix3 = cpl_propertylist_get_double(cube->
header,
"CRPIX3"),
492 crval3 = cpl_propertylist_get_double(cube->
header,
"CRVAL3"),
493 cd33 = cpl_propertylist_get_double(cube->
header,
"CD3_3");
494 cpl_propertylist *pbla = cpl_propertylist_new();
495 cpl_propertylist_copy_property_regexp(pbla, cube->
header,
"^C", 0);
496 cpl_propertylist_dump(pbla, stdout);
498 cpl_msg_debug(__func__,
"%f %f %f", crpix3, crval3, cd33);
499 cpl_vector *pos = cpl_vector_new(npl);
503 int ipl, npl = cpl_imagelist_get_size(cube->
data);
504 for (ipl = 0; ipl < npl; ipl++) {
505 image->
data = cpl_imagelist_get(cube->
data, ipl);
506 image->
stat = cpl_imagelist_get(cube->
stat, ipl);
507 cpl_mask *vignmask = maskimage ? maskimage->
mask : NULL;
508 cpl_image *fit = muse_twilight_image_normalize_and_fit(image,
512 cpl_imagelist_set(cubefit->data, fit, ipl);
513 #if 0 // only for smoothing in wavelength direction (see below)
515 cpl_vector_set(pos, ipl, ipl+1);
523 #if 0 // XXX try to smooth with a fit in wavelenth direction?
524 cpl_image *error = cpl_image_new(cpl_image_get_size_x(white),
525 cpl_image_get_size_y(white),
527 cpl_imagelist *cubefit2 = cpl_fit_imagelist_polynomial(pos, cubefit->data,
529 CPL_TYPE_DOUBLE, error);
530 cpl_vector_dump(pos, stdout);
532 cpl_vector_delete(pos);
534 cpl_image_delete(error);
536 cpl_imagelist_save(cubefit2,
"cubefit2.fits", CPL_TYPE_UNSPECIFIED, NULL, CPL_IO_CREATE);
537 cpl_imagelist_delete(cubefit2);
546 cpl_image_delete(whitefit->
dq);
548 cpl_propertylist_update_string(whitefit->
header,
"OBJECT",
549 "white from global fit");
552 cubefit->recnames = cpl_array_new(1, CPL_TYPE_STRING);
553 cpl_array_set_string(cubefit->recnames, 0,
"white_global_fit");
557 double mean = cpl_image_get_mean(white);
558 cpl_image_divide_scalar(white, mean);
559 cpl_image *wdiv = cpl_image_divide_create(white, whitefit->
data);
562 image->
header = cpl_propertylist_new();
563 cpl_propertylist_append_string(image->
header,
"OBJECT",
"normalized "
564 "white-light divided by white global fit");
566 image->
dq = cpl_image_new_from_mask(cpl_image_get_bpm(wdiv));
569 cpl_array_set_size(cubefit->recnames,
570 cpl_array_get_size(cubefit->recnames) + 1);
571 cpl_array_set_string(cubefit->recnames, cpl_array_get_size(cubefit->recnames) - 1,
574 cpl_mask *fovmask = cpl_mask_duplicate(cpl_image_get_bpm(white));
576 bpm = cpl_image_get_bpm(white);
577 cpl_mask_or(bpm, maskimage->
mask);
579 cpl_image_delete(white);
584 cpl_mask *vignmask = cpl_mask_duplicate(fovmask);
585 cpl_mask_not(maskimage->
mask);
586 cpl_mask_or(vignmask, maskimage->
mask);
587 cpl_image *wdiv2 = cpl_image_duplicate(wdiv);
588 cpl_image_reject_from_mask(wdiv2, vignmask);
592 cpl_msg_info(__func__,
"Excluding strong edges (stronger than %.1f%%) "
594 cpl_image *wdivX = cpl_image_duplicate(wdiv2);
595 cpl_mask *wdivXmask = cpl_mask_duplicate(cpl_image_get_bpm(wdivX));
596 cpl_image_fill_rejected(wdivX, 1.);
597 cpl_image_accept_all(wdivX);
598 int i, nx = cpl_image_get_size_x(wdivX),
599 j, ny = cpl_image_get_size_y(wdivX);
601 for (i = 1; i <= nx; i++) {
602 for (j = 2; j <= ny; j++) {
604 double v1 = cpl_image_get(wdivX, i, j - 1, &err),
605 v2 = cpl_image_get(wdivX, i, j, &err);
610 cpl_msg_debug(__func__,
"%03d %03d v1 %f V2 %f --> delta %f",
611 i, j, v1, v2, fabs(v2 - v1));
612 double dv1 = fabs(v1 - 1.),
615 cpl_mask_set(wdivXmask, i, j - 1, CPL_BINARY_1);
617 cpl_mask_set(wdivXmask, i, j, CPL_BINARY_1);
622 for (j = 1; j <= ny; j++) {
623 for (i = 2; i <= nx; i++) {
625 double v1 = cpl_image_get(wdivX, i - 1, j, &err),
626 v2 = cpl_image_get(wdivX, i, j, &err);
631 cpl_msg_debug(__func__,
"%03d %03d v1 %f V2 %f --> delta %f",
632 i, j, v1, v2, fabs(v2 - v1));
633 double dv1 = fabs(v1 - 1.),
636 cpl_mask_set(wdivXmask, i - 1, j, CPL_BINARY_1);
638 cpl_mask_set(wdivXmask, i, j, CPL_BINARY_1);
643 cpl_image_reject_from_mask(wdiv2, wdivXmask);
647 image->
header = cpl_propertylist_new();
648 cpl_propertylist_append_string(image->
header,
"OBJECT",
649 "white-light divided by white global, mask excl edges");
651 image->
dq = cpl_image_new_from_mask(wdivXmask);
652 cpl_mask_delete(wdivXmask);
655 cpl_array_set_size(cubefit->recnames,
656 cpl_array_get_size(cubefit->recnames) + 1);
657 cpl_array_set_string(cubefit->recnames, cpl_array_get_size(cubefit->recnames) - 1,
658 "white_div_global_excl_edges");
662 cpl_image *fit = NULL;
663 if (aParams->
vignsmooth == MUSE_TWILIGHT_PARAM_VIGNSMOOTH_GAUSSIAN) {
666 cpl_msg_info(__func__,
"Running %.1f pix FWHM Gaussian filter...", fwhm);
667 fit = cpl_image_duplicate(wdiv2);
669 int hw = lround(fwhm);
670 hw = hw % 2 ? hw : hw + 1;
671 cpl_msg_debug(__func__,
"using width 2 x %d + 1 for Gaussian matrix", hw);
673 fwhm * CPL_MATH_SIG_FWHM);
674 cpl_errorstate prestate = cpl_errorstate_get();
675 cpl_image_filter(fit, wdiv2, gauss, CPL_FILTER_LINEAR, CPL_BORDER_FILTER);
676 cpl_matrix_delete(gauss);
677 cpl_image_reject_from_mask(fit, cpl_image_get_bpm(wdiv2));
679 cpl_image_threshold(fit, 1., FLT_MAX, 1., FLT_MAX);
680 if (!cpl_errorstate_is_equal(prestate)) {
681 cpl_msg_warning(__func__,
"filtering vignetted area failed: %s",
682 cpl_error_get_message());
687 cpl_msg_info(__func__,
"Running Gaussian filter on extended region...");
689 fit = cpl_image_duplicate(wdiv2);
692 cpl_image *wdiv3 = cpl_image_duplicate(wdiv2);
693 cpl_image_fill_rejected(wdiv3, 1.);
694 cpl_mask *masktest = cpl_mask_load(
"masktest3.fits", 0, 0);
695 cpl_image_reject_from_mask(wdiv3, masktest);
696 cpl_mask_delete(masktest);
701 10. * CPL_MATH_SIG_FWHM);
702 cpl_errorstate prestate = cpl_errorstate_get();
703 cpl_image_filter(fit, wdiv3, gauss, CPL_FILTER_LINEAR, CPL_BORDER_FILTER);
704 cpl_image_delete(wdiv3);
705 cpl_matrix_delete(gauss);
706 cpl_image_reject_from_mask(fit, cpl_image_get_bpm(wdiv2));
708 cpl_image_threshold(fit, 1., FLT_MAX, 1., FLT_MAX);
709 if (!cpl_errorstate_is_equal(prestate)) {
710 cpl_msg_warning(__func__,
"filtering vignetted area failed: %s",
711 cpl_error_get_message());
714 }
else if (aParams->
vignsmooth == MUSE_TWILIGHT_PARAM_VIGNSMOOTH_MEDIAN) {
715 cpl_msg_info(__func__,
"Running %dx%d median filter...",
717 fit = cpl_image_duplicate(wdiv2);
720 cpl_errorstate prestate = cpl_errorstate_get();
721 cpl_image_filter_mask(fit, wdiv2, mask, CPL_FILTER_MEDIAN,
723 cpl_mask_delete(mask);
725 cpl_image_threshold(fit, 1., FLT_MAX, 1., FLT_MAX);
726 if (!cpl_errorstate_is_equal(prestate)) {
727 cpl_msg_warning(__func__,
"filtering vignetted ared failed: %s",
728 cpl_error_get_message());
731 cpl_msg_info(__func__,
"Running polyfit...");
734 cpl_image *wdiv3 = cpl_image_duplicate(wdiv2);
735 cpl_image_threshold(wdiv3, 1., FLT_MAX, 1., FLT_MAX);
740 cpl_image_delete(wdiv3);
742 cpl_image_threshold(fit, 1., FLT_MAX, 1., FLT_MAX);
746 cpl_image_reject_from_mask(fit, vignmask);
749 cpl_image_fill_rejected(fit, 1.);
753 image->
header = cpl_propertylist_new();
754 cpl_propertylist_append_string(image->
header,
"OBJECT",
"vignetting fit");
756 image->
dq = cpl_image_new_from_mask(cpl_image_get_bpm(fit));
759 cpl_array_set_size(cubefit->recnames,
760 cpl_array_get_size(cubefit->recnames) + 1);
761 cpl_array_set_string(cubefit->recnames, cpl_array_get_size(cubefit->recnames) - 1,
766 image->
header = cpl_propertylist_new();
767 cpl_propertylist_append_string(image->
header,
"OBJECT",
768 "white image corrected by vignetting fit");
769 image->
data = cpl_image_divide_create(wdiv2, fit);
770 image->
dq = cpl_image_new_from_mask(cpl_image_get_bpm(image->
data));
773 cpl_array_set_size(cubefit->recnames,
774 cpl_array_get_size(cubefit->recnames) + 1);
775 cpl_array_set_string(cubefit->recnames, cpl_array_get_size(cubefit->recnames) - 1,
777 cpl_image_delete(wdiv2);
780 cpl_msg_info(__func__,
"Combining smooth field of view and vignetted corner"
781 " in %d planes", npl);
782 for (ipl = 0; ipl < npl; ipl++) {
783 cpl_image *cimage = cpl_imagelist_get(cubefit->data, ipl);
784 cpl_image_accept_all(cimage);
785 double mean1 = cpl_image_get_mean(cimage);
786 cpl_image_multiply(cimage, fit);
789 cpl_image_accept_all(cimage);
790 double mean2 = cpl_image_get_mean(cimage);
791 cpl_image_multiply_scalar(cimage, 1. / mean2);
792 double mean3 = cpl_image_get_mean(cimage);
793 if (fabs(mean3 - 1.) > FLT_EPSILON) {
794 cpl_msg_warning(__func__,
"normalization failed in plane %d: mean("
795 "plane) = %f -> %f -> %f", ipl + 1, mean1, mean2, mean3);
798 cpl_mask_delete(vignmask);
800 cpl_mask_delete(fovmask);
804 MUSE_TAG_TWILIGHT_CUBE,
808 return rc == CPL_ERROR_NONE ? 0 : -1;
double crsigma
Sigma rejection factor to use for cosmic ray rejection during final resampling. A zero or negative va...
int muse_processing_save_cimage(muse_processing *aProcessing, int aIFU, cpl_image *aImage, cpl_propertylist *aHeader, const char *aTag)
Save a computed FITS image to disk.
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 of a MUSE datacube.
Structure definition for a collection of muse_images.
void muse_image_delete(muse_image *aImage)
Deallocate memory associated to a muse_image object.
unsigned char muse_utils_get_ifu(const cpl_propertylist *aHeaders)
Find out the IFU/channel from which this header originated.
cpl_image * data
the data extension
cpl_size muse_pixtable_get_nrow(const muse_pixtable *aPixtable)
get the number of rows within the pixel table
muse_datacube * muse_datacube_load(const char *aFilename)
Load header, DATA and optionally STAT and DQ extensions as well as the reconstructed images of a MUSE...
muse_resampling_crstats_type muse_postproc_get_cr_type(const char *aCRTypeString)
Select correct cosmic ray rejection type for crtype string.
cpl_image * stat
the statistics extension
void muse_datacube_delete(muse_datacube *aCube)
Deallocate memory associated to a muse_datacube object.
void muse_imagelist_delete(muse_imagelist *aList)
Free the memory of the MUSE image list.
muse_image * muse_datacube_collapse(muse_datacube *aCube, cpl_table *aFilter)
Integrate a FITS NAXIS=3 datacube along the wavelength direction.
const char * crtype_s
Type of statistics used for detection of cosmic rays during final resampling. "iraf" uses the varianc...
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.
Structure definition of MUSE three extension FITS file.
cpl_array * recnames
the reconstructed image filter names
muse_mask * muse_processing_mask_load(muse_processing *aProcessing, const char *aTag)
Load a mask file and its FITS header.
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
unsigned int muse_imagelist_get_size(muse_imagelist *aList)
Return the number of stored images.
cpl_frameset * usedframes
void muse_combinepar_delete(muse_combinepar *aCPars)
Clear the combination parameters.
muse_resampling_crstats_type crtype
cpl_image * dq
the data quality extension
cpl_error_code muse_pixtable_restrict_wavelength(muse_pixtable *aPixtable, double aLow, double aHigh)
Restrict a pixel table to a certain wavelength range.
Structure definition of MUSE pixel table.
cpl_error_code muse_datacube_convert_dq(muse_datacube *aCube)
Convert the DQ extension of a datacube to NANs in DATA and STAT.
muse_image * muse_imagelist_get(muse_imagelist *aList, unsigned int aIdx)
Get the muse_image of given list index.
int vignxpar
Parameter used by the vignetting smoothing: x order for polyfit (default, recommended 4)...
double vignmaskedges
Pixels on edges stronger than this fraction in the normalized image are excluded from the fit to the ...
int vignypar
Parameter used by the vignetting smoothing: y order for polyfit (default, recommended 4)...
muse_resampling_params * muse_resampling_params_new(muse_resampling_type aMethod)
Create the resampling parameters structure.
Structure to hold the parameters of the muse_twilight recipe.
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.
double dlambda
Sampling for twilight reconstruction, this should result in planes of equal wavelength coverage...
int vignsmooth
Type of smoothing to use for the vignetted region given by the VIGNETTING_MASK; gaussian uses (vignxp...
muse_combinepar * muse_combinepar_new(cpl_parameterlist *aParameters, const char *aPrefix)
Create a new set of combination parameters.
double lambdamin
Minimum wavelength for twilight reconstruction.
cpl_imagelist * data
the cube containing the actual data values
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.
int yorder
Polynomial order to use in y direction to fit the full field of view.
int xorder
Polynomial order to use in x direction to fit the full field of view.
muse_pixtable * muse_pixtable_create(muse_image *aImage, cpl_table *aTrace, cpl_table *aWave, cpl_table *aGeoTable)
Create the pixel table for one CCD.
muse_datacube * muse_resampling_cube(muse_pixtable *aPixtable, muse_resampling_params *aParams, muse_pixgrid **aPixgrid)
Resample a pixel table onto a regular grid structure representing a FITS NAXIS=3 datacube.
cpl_error_code muse_basicproc_stats_append_header(cpl_image *aImage, cpl_propertylist *aHeader, const char *aPrefix, unsigned aStats)
Compute image statistics of an image and add them to a header.
cpl_propertylist * header
the FITS header
muse_resampling_type muse_postproc_get_resampling_type(const char *aResampleString)
Select correct resampling type for resample string.
cpl_image * muse_utils_image_fit_polynomial(const cpl_image *aImage, unsigned short aXOrder, unsigned short aYOrder)
Create a smooth version of a 2D image by fitting it with a 2D polynomial.
Handling of "mask" files.
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
Structure of basic processing parameters.
muse_resampling_type
Resampling types.
void muse_resampling_params_delete(muse_resampling_params *aParams)
Delete a resampling parameters structure.
void muse_mask_delete(muse_mask *aMask)
Deallocate memory associated to a muse_mask object.
muse_image * muse_image_new(void)
Allocate memory for a new muse_image object.
cpl_matrix * muse_matrix_new_gaussian_2d(int aXHalfwidth, int aYHalfwidth, double aSigma)
Create a matrix that contains a normalized 2D Gaussian.
double lambdamax
Maximum wavelength for twilight reconstruction.
cpl_mask * mask
The mask data.
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
cpl_error_code muse_imagelist_set(muse_imagelist *aList, muse_image *aImage, unsigned int aIdx)
Set the muse_image of given list index.
cpl_error_code muse_pixtable_compute_limits(muse_pixtable *aPixtable)
(Re-)Compute the limits of the coordinate columns of a pixel table.
int muse_quality_image_reject_using_dq(cpl_image *aData, cpl_image *aDQ, cpl_image *aStat)
Reject pixels of one or two images on a DQ image.
muse_imagelist * recimages
the reconstructed image data
cpl_mask * muse_cplmask_adapt_to_image(const cpl_mask *aMask, const cpl_image *aImage)
Adapt mask with masked region in one quadrant to size of an image.
cpl_parameterlist * parameters
cpl_imagelist * stat
the cube containing the data variance
cpl_propertylist * header
The FITS header.
cpl_frameset * muse_frameset_find_tags(const cpl_frameset *aFrames, const cpl_array *aTags, unsigned char aIFU, cpl_boolean aInvert)
return frameset containing data from an IFU/channel with the given tag(s)
const char * resample_s
The resampling technique to use for the final output cube. (as string)