36 #include "muse_instrument.h"
37 #include "muse_quality.h"
38 #include "muse_tracing.h"
39 #include "muse_utils.h"
48 #define SKY_ROWBYROW_DEBUG 0
77 cpl_ensure_code(aImage, CPL_ERROR_NULL_INPUT);
78 unsigned short nslices = 0;
80 nslices = cpl_table_get_nrow(aTrace);
82 unsigned short slice = 0;
83 cpl_boolean exists = CPL_FALSE;
85 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", ++slice);
86 exists = cpl_propertylist_has(aImage->
header, keyword);
88 cpl_msg_debug(__func__,
"%s %s", keyword, exists ?
"exists" :
"doesn't exist");
94 cpl_msg_debug(__func__,
"Found %hu slices", nslices);
95 cpl_ensure_code(nslices, CPL_ERROR_ILLEGAL_INPUT);
96 const unsigned int kOrdObj = 1;
97 const float kRSigObj = 3.;
100 cpl_image *objmask = cpl_image_collapse_median_create(aImage->
data, 0, 0, 0);
101 #if SKY_ROWBYROW_DEBUG
102 cpl_msg_debug(__func__,
"saving \"sky_removed_objmask.fits\"");
103 cpl_image_save(objmask,
"sky_removed_objmask.fits", CPL_TYPE_UNSPECIFIED,
104 NULL, CPL_IO_CREATE);
107 int nx = cpl_image_get_size_x(aImage->
data),
108 ny = cpl_image_get_size_y(aImage->
data);
109 int *dq = cpl_image_get_data_int(aImage->
dq);
112 unsigned short islice;
113 for (islice = 0; islice < nslices; islice++) {
114 cpl_msg_debug(__func__,
"Processing slice %hu", islice + 1);
118 cpl_polynomial **ptrace = NULL;
119 int i1 = 0, i2 = nx, istart = 0;
124 cpl_msg_warning(__func__,
"slice %2d: tracing polynomials missing!",
129 i1 = floor(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_LEFT], ny/2, NULL));
130 i2 = ceil(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_RIGHT], ny/2, NULL));
131 if (i1 < 1 || i2 > nx || i1 > i2) {
132 cpl_msg_warning(__func__,
"slice %2d: faulty polynomial detected at "
133 "y=%d (borders: %d ... %d)", islice + 1, ny/2, i1, i2);
138 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", islice + 1);
139 istart = cpl_propertylist_get_float(aImage->
header, keyword);
143 while (!(dq[(--ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
147 while (!(dq[(++ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
153 cpl_matrix *p = cpl_matrix_new(1, i2 - i1 + 1);
154 cpl_vector *v = cpl_vector_new(i2 - i1 + 1);
156 for (i = i1; i <= i2; i++) {
157 cpl_matrix_set(p, 0, i - i1, i);
159 double value = cpl_image_get(objmask, i, 1, &err);
161 cpl_vector_set(v, i - i1, NAN);
163 cpl_vector_set(v, i - i1, value);
171 for (i = i1; i <= i2; i++) {
173 ncol = cpl_matrix_get_ncol(p);
174 while (idx < ncol && (
int)cpl_matrix_get(p, 0, idx) < i) {
178 if (idx < ncol && (
int)cpl_matrix_get(p, 0, idx) == i) {
183 for (j = 0; j < ny; j++) {
184 dq[(i-1) + j*nx] |= EURO3D_OBJECT;
187 cpl_vector_delete(v);
188 cpl_matrix_delete(p);
189 cpl_polynomial_delete(p1);
192 cpl_image_delete(objmask);
194 return CPL_ERROR_NONE;
228 cpl_ensure_code(aImage, CPL_ERROR_NULL_INPUT);
229 unsigned short nslices = 0;
231 nslices = cpl_table_get_nrow(aTrace);
232 }
else if (!aTrace) {
233 unsigned short slice = 0;
234 cpl_boolean exists = CPL_FALSE;
236 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", ++slice);
237 exists = cpl_propertylist_has(aImage->
header, keyword);
239 cpl_msg_debug(__func__,
"%s %s", keyword, exists ?
"exists" :
"doesn't exist");
245 cpl_msg_debug(__func__,
"Found %hu slices", nslices);
246 cpl_ensure_code(nslices, CPL_ERROR_ILLEGAL_INPUT);
249 int nx = cpl_image_get_size_x(aImage->
data),
250 ny = cpl_image_get_size_y(aImage->
data);
251 float *data = cpl_image_get_data_float(aImage->
data),
252 *stat = cpl_image_get_data_float(aImage->
stat);
253 int *dq = cpl_image_get_data_int(aImage->
dq);
256 unsigned short islice;
257 for (islice = 0; islice < nslices; islice++) {
258 cpl_msg_debug(__func__,
"Processing slice %hu", islice + 1);
262 cpl_polynomial **ptrace = NULL;
263 int i1 = 0, i2 = nx, istart = 0;
268 cpl_msg_warning(__func__,
"slice %2d: tracing polynomials missing!",
273 i1 = floor(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_LEFT], ny/2, NULL));
274 i2 = ceil(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_RIGHT], ny/2, NULL));
275 if (i1 < 1 || i2 > nx || i1 > i2) {
276 cpl_msg_warning(__func__,
"slice %2d: faulty polynomial detected at "
277 "y=%d (borders: %d ... %d)", islice + 1, ny/2, i1, i2);
282 char *keyword = cpl_sprintf(
"ESO DRS MUSE SLICE%hu CENTER", islice + 1);
283 istart = cpl_propertylist_get_float(aImage->
header, keyword);
287 while (!(dq[(--ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
291 while (!(dq[(++ix-1) + ny/2*nx] & EURO3D_MISSDATA)) {
295 #if SKY_ROWBYROW_DEBUG
296 cpl_msg_debug(__func__,
"1 slice %d row %d edges: %d %d", islice+1, ny/2, i1, i2);
300 for (j = 0; j < ny; j++) {
303 int ileft = istart, icenter = istart, iright = istart;
305 ileft = ceil(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_LEFT], j+1, NULL)),
306 icenter = cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_CENTER], j+1, NULL),
307 iright = floor(cpl_polynomial_eval_1d(ptrace[MUSE_TRACE_RIGHT], j+1, NULL));
311 while (!(dq[(--ix-1) + j*nx] & EURO3D_MISSDATA)) {
315 while (!(dq[(++ix-1) + j*nx] & EURO3D_MISSDATA)) {
318 icenter = (iright + ileft) / 2.;
320 #if SKY_ROWBYROW_DEBUG
321 cpl_msg_debug(__func__,
"2 slice %d row %d edges: %d %d", islice+1, j+1,
326 cpl_matrix *pos = cpl_matrix_new(1, iright - ileft + 1);
327 cpl_vector *values = cpl_vector_new(iright - ileft + 1);
329 unsigned int nval = 0;
331 for (i = ileft; i <= iright; i++) {
332 cpl_matrix_set(pos, 0, i - ileft, i - icenter);
333 if (dq[(i-1) + j*nx] != EURO3D_GOODPIXEL) {
334 cpl_vector_set(values, i - ileft, NAN);
336 cpl_vector_set(values, i - ileft, data[(i-1) + j*nx]);
343 cpl_vector_delete(values);
345 cpl_matrix_delete(pos);
349 unsigned int order = aOrder > nval + 1 ? nval - 1 : aOrder;
355 int npix = cpl_vector_get_size(values);
356 cpl_vector_delete(values);
358 cpl_matrix_delete(pos);
361 for (i = ileft - 1; i < iright; i++) {
363 double sky = cpl_polynomial_eval_1d(poly, i+1 - icenter, NULL);
364 #if SKY_ROWBYROW_DEBUG > 1
365 if (islice+1 == SKY_ROWBYROW_DEBUG_SLICE &&
366 j+1 >= SKY_ROWBYROW_DEBUG_ROW1 && j+1 <= SKY_ROWBYROW_DEBUG_ROW2) {
367 printf(
"subtracting slice %d row %d %d %f ", islice+1, j+1,
368 i+1 - icenter, data[i + j*nx]);
371 data[i + j*nx] -= sky;
374 stat[i + j*nx] += mse / (npix - order-1);
375 #if SKY_ROWBYROW_DEBUG > 1
376 if (islice+1 == SKY_ROWBYROW_DEBUG_SLICE &&
377 j+1 >= SKY_ROWBYROW_DEBUG_ROW1 && j+1 <= SKY_ROWBYROW_DEBUG_ROW2) {
378 printf(
"%f\n", data[i + j*nx]);
383 cpl_polynomial_delete(poly);
389 #if SKY_ROWBYROW_DEBUG
390 cpl_msg_debug(__func__,
"saving \"sky_removed_iterated_edge2.fits\"");
394 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.