29 #include "muse_quality.h"
30 #include "muse_cplwrappers.h"
31 #include "muse_mask.h"
32 #include "muse_data_format_z.h"
48 {
"lambda", CPL_TYPE_DOUBLE,
"Angstrom",
"%7.2f",
"wavelength", CPL_TRUE},
49 {
"flux", CPL_TYPE_DOUBLE,
"erg/(s cm^2 arcsec^2)",
"%e",
"Flux", CPL_TRUE},
50 { NULL, 0, NULL, NULL, NULL, CPL_FALSE }
63 unsigned count = cpl_imagelist_get_size(aCube->
data);
65 double crval3 = cpl_propertylist_get_float(aCube->
header,
"CRVAL3");
66 double crpix3 = cpl_propertylist_get_float(aCube->
header,
"CRPIX3");
67 double cdelt3 = cpl_propertylist_get_float(aCube->
header,
"CD3_3");
69 cpl_mask *nmask = cpl_mask_duplicate(aMask);
71 for (i = 0; i < count; i++) {
72 cpl_table_set(spectrum,
"lambda", i, crval3 + (i + 1 - crpix3) * cdelt3);
74 cpl_image *img = cpl_imagelist_get(aCube->
data, i);
75 cpl_mask *bpm = cpl_image_get_bpm(img);
76 cpl_mask_or(bpm, nmask);
77 if (aCube->
dq != NULL) {
78 cpl_image *dq = cpl_imagelist_get(aCube->
dq, i);
79 cpl_mask *dq_mask = cpl_mask_threshold_image_create(dq, -0.5, 0.5);
80 cpl_mask_not(dq_mask);
81 cpl_mask_or(bpm, dq_mask);
82 cpl_mask_delete(dq_mask);
84 double dev = cpl_image_get_stdev(img);
85 double mean = cpl_image_get_mean(img);
86 cpl_table_set(spectrum,
"data", i, mean);
87 cpl_table_set(spectrum,
"stat", i, dev / sqrt(cpl_mask_count(bpm)));
88 cpl_table_set(spectrum,
"dq", i, (cpl_mask_count(bpm) < 3));
90 cpl_mask_delete(nmask);
110 double t0 = cpl_image_get_min(aImage->
data);
112 cpl_msg_info(__func__,
"minimum = %g, threshold = %g", t0, t1);
115 selectedRegions->
mask = cpl_mask_threshold_image_create(aImage->
data, t0, t1);
116 cpl_mask_not(selectedRegions->
mask);
117 cpl_mask_or(selectedRegions->
mask, cpl_image_get_bpm(aImage->
data));
118 cpl_mask_not(selectedRegions->
mask);
120 selectedRegions->
header = cpl_propertylist_duplicate(aImage->
header);
122 const char *keyword =
"ESO QC SKY THRESHOLD";
123 cpl_propertylist_append_double(selectedRegions->
header, keyword, t1);
125 return selectedRegions;
151 cpl_ensure(aLambda, CPL_ERROR_NULL_INPUT, NULL);
152 cpl_ensure(aLsf, CPL_ERROR_NULL_INPUT, NULL);
160 cpl_array_unwrap(linesLambda);
161 cpl_array_unwrap(linesFlux);
163 cpl_array *sensitivity = cpl_array_duplicate(aLambda);
164 cpl_array_subtract_scalar(sensitivity, aLsf->
lambda_ref);
167 cpl_array_multiply(spectrum, sensitivity);
169 cpl_array_delete(sensitivity);
189 float *lbda = cpl_table_get_data_float(aPixtable->
table, MUSE_PIXTABLE_LAMBDA);
190 float *data = cpl_table_get_data_float(aPixtable->
table, MUSE_PIXTABLE_DATA);
191 int *dq = cpl_table_get_data_int(aPixtable->
table, MUSE_PIXTABLE_DQ);
193 cpl_size spec_nrows = cpl_table_get_nrow(aSpectrum);
194 double *spec_data = cpl_table_get_data_double(aSpectrum,
"data");
195 double *spec_stat = cpl_table_get_data_double(aSpectrum,
"stat");
196 double *spec_std = cpl_malloc(spec_nrows *
sizeof(
double));
198 for (i_spec = 0; i_spec < spec_nrows; i_spec++) {
199 spec_std[i_spec] = sqrt(spec_stat[i_spec]);
203 cpl_array *asel = cpl_table_where_selected(aPixtable->
table);
204 const cpl_size *sel = cpl_array_get_data_cplsize_const(asel);
205 cpl_size isel, nsel = cpl_array_get_size(asel);
206 cpl_size n_cosmic = 0;
207 for (isel = 0; isel < nsel; isel++) {
208 cpl_size i_row = sel[isel];
209 if ((dq[i_row] != EURO3D_GOODPIXEL)) {
212 double l = lbda[i_row];
214 if ((i_spec < spec_nrows - 1) && (spec_data[i_spec] < spec_data[i_spec+1])) {
217 if (spec_data[i_spec] + 5 * spec_std[i_spec] < data[i_row]) {
218 dq[i_row] = EURO3D_COSMICRAY;
222 cpl_msg_info(__func__,
"Marked %"CPL_SIZE_FORMAT
" pixels of %"CPL_SIZE_FORMAT
" as cosmic (one of %i)",
223 n_cosmic, nsel, (
int)(nsel/n_cosmic));
225 cpl_array_delete(asel);
Structure definition of a MUSE datacube.
cpl_image * data
the data extension
cpl_table * muse_sky_spectrum_from_cube(muse_datacube *aCube, const cpl_mask *aMask)
Create a spectrum out of a cube by applying a mask.
muse_mask * muse_mask_new(void)
Allocate memory for a new muse object.
muse_mask * muse_sky_create_skymask(muse_image *aImage, double aFraction)
Select spaxels to be considered as sky.
cpl_error_code muse_cplarray_poly1d(cpl_array *aArray, const cpl_array *aCoeff)
Apply a polynomial to an array.
Structure definition of MUSE three extension FITS file.
cpl_table * table
The pixel table.
cpl_propertylist * header
the FITS header
cpl_array * muse_lsf_spectrum_get_lines(const cpl_array *aLambda, const cpl_array *aLinesLambda, const cpl_array *aLinesFlux, const muse_lsf_params *aLsf)
Set the lines spectrum from the lines table and the detector LSF.
void muse_sky_mark_cosmic(cpl_table *aSpectrum, muse_pixtable *aPixtable)
Mark all pixel above a certain limit as COSMIC.
cpl_table * muse_cpltable_new(const muse_cpltable_def *aDef, cpl_size aLength)
Create an empty table according to the specified definition.
cpl_array * sensitivity
Relative detector sensitivity parametrization.
Structure definition of MUSE pixel table.
cpl_array * muse_cpltable_extract_column(cpl_table *aTable, const char *aColumn)
Create an array from a section of a column.
double muse_cplimage_get_percentile(const cpl_image *aImage, double aFraction)
Get the percentile of an image.
cpl_imagelist * data
the cube containing the actual data values
const muse_cpltable_def muse_fluxspectrum_def[]
Definition of the flux spectrum table structure.
cpl_imagelist * dq
the optional cube containing the bad pixel status
cpl_size muse_cpltable_find_sorted(const cpl_table *aTable, const char *aColumn, double aValue)
Find a row in a table.
cpl_propertylist * header
the FITS header
double lambda_ref
Reference wavelength for polynomial parametrizations.
Handling of "mask" files.
cpl_error_code muse_image_reject_from_dq(muse_image *aImage)
Reject pixels of a muse_image depending on its DQ data.
cpl_propertylist * header
the FITS header
Definition of a cpl table structure.
cpl_array * muse_sky_apply_lsf(const cpl_array *aLambda, const cpl_table *aLines, const muse_lsf_params *aLsf)
Apply the LSF parameters to a spectrum.
cpl_mask * mask
The mask data.
Structure definition of detector (slice) parameters.