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);
111 #define HIST_BIN_WIDTH 1.
112 long hlength = lround((max - min) / HIST_BIN_WIDTH + 1);
113 int *hist = cpl_calloc(hlength,
sizeof(
int));
117 for (i = aX1 - 1; i < aX2 && i < nx; i++) {
119 for (j = aY1 - 1; j < aY2 && j < ny; j++) {
124 hist[lround((data[i + j*nx] - min) / HIST_BIN_WIDTH)] += 1;
125 if (data[i + j*nx] > lo && data[i + j*nx] < hi) {
127 dsum += data[i + j*nx];
128 dsq += data[i + j*nx]*data[i + j*nx];
134 sigma = sqrt((dsq - dsum*dsum / ngood) / ngood);
138 cpl_array *histogram = cpl_array_wrap_int(hist, hlength);
140 cpl_array_get_maxpos(histogram, &nmaxpos);
142 printf(
" stats(2): %f+/-%f, histogram: length=%ld, peak=%.0f at %f "
143 "(%"CPL_SIZE_FORMAT
")\n", mean, sigma, hlength,
144 cpl_array_get_max(histogram), (
double)nmaxpos * HIST_BIN_WIDTH + min,
147 printf(
" histogram:\n entry value number\n");
148 for (i = 0; i < hlength; i++) {
149 printf(
" %7d %10.3f %8d\n", i, i * HIST_BIN_WIDTH + min, hist[i]);
157 double gapwidth = sigma * aThres;
159 for (i = nmaxpos ; i < hlength; i++) {
163 while (j < hlength && !hist[j]) {
168 cpl_array_delete(histogram);
171 double gap = (double)(j - i) * HIST_BIN_WIDTH;
172 if (gap > gapwidth) {
179 cpl_array_delete(histogram);
189 hi = i * HIST_BIN_WIDTH + min;
191 printf(
" flagging pixels above %.3f counts (%d of %ld in histogram)\n",
196 for (i = aX1 - 1; i < aX2 && i < nx; i++) {
198 for (j = aY1 - 1; j < aY2 && j < ny; j++) {
199 if (!dq[i + j*nx] && data[i + j*nx] > hi) {
200 dq[i + j*nx] |= EURO3D_COSMICRAY;
266 unsigned int aPasses,
float aThres)
268 cpl_ensure(aImage, CPL_ERROR_NULL_INPUT, -1);
269 cpl_ensure(aThres > 0, CPL_ERROR_ILLEGAL_INPUT, -2);
270 cpl_ensure(aPasses > 0, CPL_ERROR_ILLEGAL_INPUT, -3);
271 int nx = cpl_image_get_size_x(aImage->
data),
272 ny = cpl_image_get_size_y(aImage->
data);
273 cpl_ensure(aXBox <= (
unsigned int)nx, CPL_ERROR_ILLEGAL_INPUT, -4);
274 cpl_ensure(aYBox <= (
unsigned int)ny, CPL_ERROR_ILLEGAL_INPUT, -5);
276 if (aXBox * aYBox < 100) {
277 cpl_msg_warning(__func__,
"Boxes containing more than 100 pixels are "
278 "recommended for DCR!");
280 cpl_msg_debug(__func__,
"Cosmic ray rejection using DCR: subframe %dx%d "
281 "(%d pixels/subframe), %d passes, threshold %.3f sigma)",
282 aXBox, aYBox, aXBox * aYBox, aPasses, aThres);
285 char *dodebug = getenv(
"MUSE_DEBUG_DCR");
286 unsigned short debug = dodebug ? atoi(dodebug) : 0,
289 unsigned npass, ncr = 0;
290 for (npass = 1; npass <= aPasses; npass++) {
292 int imax = 0, jmax = 0;
296 for (i = 1; i <= nx - aXBox + 1; i+=aXBox/2) {
298 for (j = 1; j <= ny - aYBox + 1; j+=aYBox/2) {
299 if (i + aXBox > (
unsigned)imax) {
302 if (j + aYBox > (
unsigned)jmax) {
306 printf(
"subframe [%d:%d,%d:%d] (standard)\n",
307 i, i + aXBox, j, j + aYBox);
310 int npx = muse_cosmics_dcr_subframe(aImage, i, i + aXBox, j, j + aYBox,
314 printf(
"%8d affected pixels\n", npx);
322 printf(
"subframe [%d:%d,%d:%d] (upper)\n",
323 i, i + aXBox, ny - aYBox + 1, ny);
326 int npx = muse_cosmics_dcr_subframe(aImage, i, i + aXBox, ny - aYBox + 1, ny,
330 printf(
"%8d affected pixels\n", npx);
336 printf(
"standard subframe coverage to [%d,%d] (image has %dx%d)\n",
345 for (j = 1; j <= ny - aYBox + 1; j+=aYBox/2) {
347 printf(
"subframe [%d:%d,%d:%d] (right)\n",
348 nx - aXBox + 1, nx, j, j + aYBox);
351 int npx = muse_cosmics_dcr_subframe(aImage, nx - aXBox + 1, nx, j, j + aYBox,
355 printf(
"%8d affected pixels\n", npx);
361 if (imax < nx && jmax < ny) {
364 printf(
"subframe [%d:%d,%d:%d] (corner)\n",
365 nx - aXBox + 1, nx, ny - aXBox + 1, ny);
368 int npx = muse_cosmics_dcr_subframe(aImage, nx - aXBox + 1, nx, ny - aXBox + 1, ny,
372 printf(
"%8d affected pixels\n", npx);
377 cpl_msg_debug(__func__,
"%d pixels found after pass %d", ncr, npass);
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