35 #include "muse_instrument.h"
36 #include "muse_quality.h"
37 #include "muse_tracing.h"
38 #include "muse_utils.h"
47 #define SKY_ROWBYROW_DEBUG 0
76 cpl_ensure_code(aImage, CPL_ERROR_NULL_INPUT);
77 unsigned short nslices = 0;
79 nslices = cpl_table_get_nrow(aTrace);
81 unsigned short slice = 0;
82 cpl_boolean exists = CPL_FALSE;
84 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", ++slice);
85 exists = cpl_propertylist_has(aImage->
header, keyword);
87 cpl_msg_debug(__func__,
"%s %s", keyword, exists ?
"exists" :
"doesn't exist");
93 cpl_msg_debug(__func__,
"Found %hu slices", nslices);
94 cpl_ensure_code(nslices, CPL_ERROR_ILLEGAL_INPUT);
95 const unsigned int kOrdObj = 1;
96 const float kRSigObj = 3.;
99 cpl_image *objmask = cpl_image_collapse_median_create(aImage->
data, 0, 0, 0);
100 #if SKY_ROWBYROW_DEBUG
101 cpl_msg_debug(__func__,
"saving \"sky_removed_objmask.fits\"");
102 cpl_image_save(objmask,
"sky_removed_objmask.fits", CPL_TYPE_UNSPECIFIED,
103 NULL, CPL_IO_CREATE);
106 int nx = cpl_image_get_size_x(aImage->
data),
107 ny = cpl_image_get_size_y(aImage->
data);
108 int *dq = cpl_image_get_data_int(aImage->
dq);
111 unsigned short islice;
112 for (islice = 0; islice < nslices; islice++) {
113 cpl_msg_debug(__func__,
"Processing slice %hu", islice + 1);
117 cpl_polynomial **ptrace = NULL;
118 int i1 = 0, i2 = nx, istart = 0;
123 cpl_msg_warning(__func__,
"slice %2d: tracing polynomials missing!",
128 i1 = floor(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_LEFT], ny/2, NULL));
129 i2 = ceil(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_RIGHT], ny/2, NULL));
130 if (i1 < 1 || i2 > nx || i1 > i2) {
131 cpl_msg_warning(__func__,
"slice %2d: faulty polynomial detected at "
132 "y=%d (borders: %d ... %d)", islice + 1, ny/2, i1, i2);
137 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", islice + 1);
138 istart = cpl_propertylist_get_float(aImage->
header, keyword);
142 while (!(dq[(--ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
146 while (!(dq[(++ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
152 cpl_matrix *p = cpl_matrix_new(1, i2 - i1 + 1);
153 cpl_vector *v = cpl_vector_new(i2 - i1 + 1);
155 for (i = i1; i <= i2; i++) {
156 cpl_matrix_set(p, 0, i - i1, i);
158 double value = cpl_image_get(objmask, i, 1, &err);
160 cpl_vector_set(v, i - i1, NAN);
162 cpl_vector_set(v, i - i1, value);
170 for (i = i1; i <= i2; i++) {
172 ncol = cpl_matrix_get_ncol(p);
173 while (idx < ncol && (
int)cpl_matrix_get(p, 0, idx) < i) {
177 if (idx < ncol && (
int)cpl_matrix_get(p, 0, idx) == i) {
182 for (j = 0; j < ny; j++) {
183 dq[(i-1) + j*nx] |= EURO3D_OBJECT;
186 cpl_vector_delete(v);
187 cpl_matrix_delete(p);
188 cpl_polynomial_delete(p1);
191 cpl_image_delete(objmask);
193 return CPL_ERROR_NONE;
227 cpl_ensure_code(aImage, CPL_ERROR_NULL_INPUT);
228 unsigned short nslices = 0;
230 nslices = cpl_table_get_nrow(aTrace);
231 }
else if (!aTrace) {
232 unsigned short slice = 0;
233 cpl_boolean exists = CPL_FALSE;
235 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", ++slice);
236 exists = cpl_propertylist_has(aImage->
header, keyword);
238 cpl_msg_debug(__func__,
"%s %s", keyword, exists ?
"exists" :
"doesn't exist");
244 cpl_msg_debug(__func__,
"Found %hu slices", nslices);
245 cpl_ensure_code(nslices, CPL_ERROR_ILLEGAL_INPUT);
248 int nx = cpl_image_get_size_x(aImage->
data),
249 ny = cpl_image_get_size_y(aImage->
data);
250 float *data = cpl_image_get_data_float(aImage->
data),
251 *stat = cpl_image_get_data_float(aImage->
stat);
252 int *dq = cpl_image_get_data_int(aImage->
dq);
255 unsigned short islice;
256 for (islice = 0; islice < nslices; islice++) {
257 cpl_msg_debug(__func__,
"Processing slice %hu", islice + 1);
261 cpl_polynomial **ptrace = NULL;
262 int i1 = 0, i2 = nx, istart = 0;
267 cpl_msg_warning(__func__,
"slice %2d: tracing polynomials missing!",
272 i1 = floor(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_LEFT], ny/2, NULL));
273 i2 = ceil(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_RIGHT], ny/2, NULL));
274 if (i1 < 1 || i2 > nx || i1 > i2) {
275 cpl_msg_warning(__func__,
"slice %2d: faulty polynomial detected at "
276 "y=%d (borders: %d ... %d)", islice + 1, ny/2, i1, i2);
281 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", islice + 1);
282 istart = cpl_propertylist_get_float(aImage->
header, keyword);
286 while (!(dq[(--ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
290 while (!(dq[(++ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
294 #if SKY_ROWBYROW_DEBUG
295 cpl_msg_debug(__func__,
"1 slice %d row %d edges: %d %d", islice+1, ny/2, i1, i2);
299 for (j = 0; j < ny; j++) {
302 int ileft = istart, icenter = istart, iright = istart;
304 ileft = ceil(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_LEFT], j+1, NULL)),
305 icenter = cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_CENTER], j+1, NULL),
306 iright = floor(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_RIGHT], j+1, NULL));
310 while (!(dq[(--ix-1) + j*nx] & EURO3D_MISSDATA)) {
314 while (!(dq[(++ix-1) + j*nx] & EURO3D_MISSDATA)) {
317 icenter = (iright + ileft) / 2.;
319 #if SKY_ROWBYROW_DEBUG
320 cpl_msg_debug(__func__,
"2 slice %d row %d edges: %d %d", islice+1, j+1,
325 cpl_matrix *pos = cpl_matrix_new(1, iright - ileft + 1);
326 cpl_vector *values = cpl_vector_new(iright - ileft + 1);
328 unsigned int nval = 0;
330 for (i = ileft; i <= iright; i++) {
331 cpl_matrix_set(pos, 0, i - ileft, i - icenter);
332 if (dq[(i-1) + j*nx] != EURO3D_GOODPIXEL) {
333 cpl_vector_set(values, i - ileft, NAN);
335 cpl_vector_set(values, i - ileft, data[(i-1) + j*nx]);
342 cpl_vector_delete(values);
344 cpl_matrix_delete(pos);
348 unsigned int order = aOrder > nval + 1 ? nval - 1 : aOrder;
354 int npix = cpl_vector_get_size(values);
355 cpl_vector_delete(values);
357 cpl_matrix_delete(pos);
360 for (i = ileft - 1; i < iright; i++) {
362 double sky = cpl_polynomial_eval_1d(poly, i+1 - icenter, NULL);
363 #if SKY_ROWBYROW_DEBUG > 1
364 if (islice+1 == SKY_ROWBYROW_DEBUG_SLICE &&
365 j+1 >= SKY_ROWBYROW_DEBUG_ROW1 && j+1 <= SKY_ROWBYROW_DEBUG_ROW2) {
366 printf(
"subtracting slice %d row %d %d %f ", islice+1, j+1,
367 i+1 - icenter, data[i + j*nx]);
370 data[i + j*nx] -= sky;
373 stat[i + j*nx] += mse / (npix - order-1);
374 #if SKY_ROWBYROW_DEBUG > 1
375 if (islice+1 == SKY_ROWBYROW_DEBUG_SLICE &&
376 j+1 >= SKY_ROWBYROW_DEBUG_ROW1 && j+1 <= SKY_ROWBYROW_DEBUG_ROW2) {
377 printf(
"%f\n", data[i + j*nx]);
382 cpl_polynomial_delete(poly);
388 #if SKY_ROWBYROW_DEBUG
389 cpl_msg_debug(__func__,
"saving \"sky_removed_iterated_edge2.fits\"");
393 return CPL_ERROR_NONE;
cpl_polynomial ** muse_trace_table_get_polys_for_slice(const cpl_table *aTable, const unsigned short aSlice)
construct polynomial from the trace table entry for the given slice
cpl_image * data
the data extension
cpl_error_code muse_sky_subtract_rowbyrow(muse_image *aImage, cpl_table *aTrace, float aRSigma, unsigned int aOrder)
Subtract the sky row-by-row from a CCD-based image.
cpl_image * stat
the statistics extension
Structure definition of MUSE three extension FITS file.
cpl_propertylist * header
the FITS header
void muse_trace_polys_delete(cpl_polynomial *aPolys[])
Delete the multi-polynomial array created in relation to tracing.
cpl_image * dq
the data quality extension
cpl_polynomial * muse_utils_iterate_fit_polynomial(cpl_matrix *aPos, cpl_vector *aVal, cpl_vector *aErr, cpl_table *aExtra, const unsigned int aOrder, const double aRSigma, double *aMSE, double *aChiSq)
Iterate a polynomial fit.
cpl_error_code muse_image_save(muse_image *aImage, const char *aFilename)
Save the three image extensions and the FITS headers of a MUSE image to a file.
cpl_error_code muse_sky_subtract_rowbyrow_mask(muse_image *aImage, cpl_table *aTrace)
Prepare an (object) mask for the sky row-by-row fitting.