32 #include "muse_artifacts.h" 34 #include "muse_quality.h" 69 int aX1,
int aX2,
int aY1,
int aY2,
70 float aThres,
unsigned short aDebug)
72 float *data = cpl_image_get_data_float(aImage->
data);
73 int *dq = cpl_image_get_data_int(aImage->
dq);
76 double dsum = 0., dsq = 0.,
77 min = FLT_MAX, max = -FLT_MAX;
79 nx = cpl_image_get_size_x(aImage->
data),
80 ny = cpl_image_get_size_y(aImage->
data);
81 for (i = aX1 - 1; i < aX2 && i < nx; i++) {
83 for (j = aY1 - 1; j < aY2 && j < ny; j++) {
87 dsum += data[i + j*nx];
88 dsq += data[i + j*nx]*data[i + j*nx];
90 if (data[i + j*nx] < min) {
93 if (data[i + j*nx] > max) {
99 double mean = dsum / ngood,
100 sigma = sqrt((dsq - dsum*dsum / ngood) / ngood),
101 lo = mean - sigma * aThres,
102 hi = mean + sigma * aThres;
104 printf(
" stats(1): %f+/-%f -> limits=%f...%f, extremes=%f...%f\n",
105 mean, sigma, lo, hi, min, max);
108 if (!isfinite(mean) || !isfinite(sigma) || !isfinite(lo) || !isfinite(hi) ||
109 min == FLT_MAX || max == -FLT_MAX) {
111 printf(
"No good pixels found or statistics are infinite!\n" 112 " stats: %f+/-%f -> limits=%f...%f, extremes=%f...%f\n",
113 mean, sigma, lo, hi, min, max);
121 #define HIST_BIN_WIDTH 1. 122 long hlength = lround((max - min) / HIST_BIN_WIDTH + 1);
123 int *hist = cpl_calloc(hlength,
sizeof(
int));
127 for (i = aX1 - 1; i < aX2 && i < nx; i++) {
129 for (j = aY1 - 1; j < aY2 && j < ny; j++) {
134 hist[lround((data[i + j*nx] - min) / HIST_BIN_WIDTH)] += 1;
135 if (data[i + j*nx] > lo && data[i + j*nx] < hi) {
137 dsum += data[i + j*nx];
138 dsq += data[i + j*nx]*data[i + j*nx];
144 sigma = sqrt((dsq - dsum*dsum / ngood) / ngood);
148 cpl_array *histogram = cpl_array_wrap_int(hist, hlength);
150 cpl_array_get_maxpos(histogram, &nmaxpos);
152 printf(
" stats(2): %f+/-%f, histogram: length=%ld, peak=%.0f at %f " 153 "(%"CPL_SIZE_FORMAT
")\n", mean, sigma, hlength,
154 cpl_array_get_max(histogram), (
double)nmaxpos * HIST_BIN_WIDTH + min,
157 printf(
" histogram:\n entry value number\n");
158 for (i = 0; i < hlength; i++) {
159 printf(
" %7d %10.3f %8d\n", i, i * HIST_BIN_WIDTH + min, hist[i]);
167 double gapwidth = sigma * aThres;
169 for (i = nmaxpos ; i < hlength; i++) {
173 while (j < hlength && !hist[j]) {
178 cpl_array_delete(histogram);
181 double gap = (double)(j - i) * HIST_BIN_WIDTH;
182 if (gap > gapwidth) {
189 cpl_array_delete(histogram);
199 hi = i * HIST_BIN_WIDTH + min;
201 printf(
" flagging pixels above %.3f counts (%d of %ld in histogram)\n",
206 for (i = aX1 - 1; i < aX2 && i < nx; i++) {
208 for (j = aY1 - 1; j < aY2 && j < ny; j++) {
209 if (!dq[i + j*nx] && data[i + j*nx] > hi) {
210 dq[i + j*nx] |= EURO3D_COSMICRAY;
276 unsigned int aPasses,
float aThres)
278 cpl_ensure(aImage, CPL_ERROR_NULL_INPUT, -1);
279 cpl_ensure(aThres > 0, CPL_ERROR_ILLEGAL_INPUT, -2);
280 cpl_ensure(aPasses > 0, CPL_ERROR_ILLEGAL_INPUT, -3);
281 int nx = cpl_image_get_size_x(aImage->
data),
282 ny = cpl_image_get_size_y(aImage->
data);
283 cpl_ensure(aXBox <= (
unsigned int)nx, CPL_ERROR_ILLEGAL_INPUT, -4);
284 cpl_ensure(aYBox <= (
unsigned int)ny, CPL_ERROR_ILLEGAL_INPUT, -5);
286 if (aXBox * aYBox < 100) {
287 cpl_msg_warning(__func__,
"Boxes containing more than 100 pixels are " 288 "recommended for DCR!");
291 char *dodebug = getenv(
"MUSE_DEBUG_DCR");
292 unsigned short debug = dodebug ? atoi(dodebug) : 0,
295 cpl_msg_debug(__func__,
"Cosmic ray rejection using DCR: subframe %dx%d " 296 "(%d pixels/subframe), %d passes, threshold %.3f sigma)",
297 aXBox, aYBox, aXBox * aYBox, aPasses, aThres);
300 unsigned npass, ncr = 0;
301 for (npass = 1; npass <= aPasses; npass++) {
303 int imax = 0, jmax = 0;
305 unsigned ncrpass = 0;
309 for (i = 1; i <= nx - aXBox + 1; i+=aXBox/2) {
311 for (j = 1; j <= ny - aYBox + 1; j+=aYBox/2) {
312 if (i + aXBox > (
unsigned)imax) {
315 if (j + aYBox > (
unsigned)jmax) {
319 printf(
"subframe [%d:%d,%d:%d] (standard)\n",
320 i, i + aXBox, j, j + aYBox);
323 int npx = muse_cosmics_dcr_subframe(aImage, i, i + aXBox, j, j + aYBox,
326 if (debug > 1 && npx) {
327 printf(
"%8d affected pixels\n", npx);
335 printf(
"subframe [%d:%d,%d:%d] (upper)\n",
336 i, i + aXBox, ny - aYBox + 1, ny);
339 int npx = muse_cosmics_dcr_subframe(aImage, i, i + aXBox, ny - aYBox + 1, ny,
342 if (debug > 1 && npx) {
343 printf(
"%8d affected pixels\n", npx);
349 printf(
"standard subframe coverage to [%d,%d] (image has %dx%d)\n",
358 for (j = 1; j <= ny - aYBox + 1; j+=aYBox/2) {
360 printf(
"subframe [%d:%d,%d:%d] (right)\n",
361 nx - aXBox + 1, nx, j, j + aYBox);
364 int npx = muse_cosmics_dcr_subframe(aImage, nx - aXBox + 1, nx, j, j + aYBox,
367 if (debug > 1 && npx) {
368 printf(
"%8d affected pixels\n", npx);
374 if (imax < nx && jmax < ny) {
377 printf(
"subframe [%d:%d,%d:%d] (corner)\n",
378 nx - aXBox + 1, nx, ny - aXBox + 1, ny);
381 int npx = muse_cosmics_dcr_subframe(aImage, nx - aXBox + 1, nx, ny - aXBox + 1, ny,
384 if (debug > 1 && npx) {
385 printf(
"%8d affected pixels\n", npx);
392 cpl_msg_debug(__func__,
"%d (%d new) pixels found after pass %d", ncr,
cpl_image * data
the data extension
int muse_cosmics_dcr(muse_image *aImage, unsigned int aXBox, unsigned int aYBox, unsigned int aPasses, float aThres)
Quickly mark cosmic rays in an image using the DCR algorithm.
Structure definition of MUSE three extension FITS file.
cpl_image * dq
the data quality extension