00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <math.h>
00031 #include <string.h>
00032
00033 #include "ap.h"
00034 #include "util.h"
00035 #include "imcore.h"
00036 #include "floatmath.h"
00037
00038 #include "../vircam_pfits.h"
00039 #include "../vircam_fits.h"
00040
00041 #define FATAL_ERR(_a) {freetable(tab); cpl_msg_error(fctid,_a); tidy(); return(VIR_FATAL);}
00042
00043 #define NW 5
00044
00045 static float *indata = NULL;
00046 static int *confdata = NULL;
00047 static float *confsqrt = NULL;
00048 static float *smoothed = NULL;
00049 static float *smoothedc = NULL;
00050 static unsigned char *mflag = NULL;
00051 static ap_t ap;
00052 static int freeconf = 0;
00053 static float *incopy = NULL;
00054 static int *ccopy = NULL;
00055
00056 static float weights[NW*NW];
00057 static float weightc[NW*NW];
00058 static long nx;
00059 static long ny;
00060
00061 static void crweights(float);
00062 static void convolve(int);
00063 static void tidy(void);
00064
00067
00110
00111
00112 extern int imcore_opm(vir_fits *infile, vir_fits *conf, int ipix,
00113 float threshold, int nbsize, float filtfwhm,
00114 int niter) {
00115
00116 int i,retval,j,nw2,iter,nclip,nxc,nyc;
00117 float fconst,nullval,skymed,skysig,thresh,xintmin,offset;
00118 float isat,isatbc,*current,junk,*currentc;
00119 long npix;
00120 cpl_image *map,*cmap;
00121 cpl_propertylist *plist;
00122 cpl_binary *opm;
00123 const char *fctid = "imcore_opm";
00124
00125
00126
00127 fconst = CPL_MATH_LOG2E;
00128 nullval = 0.0;
00129 cattype = 4;
00130
00131
00132
00133 map = vircam_fits_get_image(infile);
00134 if ((indata = cpl_image_get_data_float(map)) == NULL)
00135 FATAL_ERR("Error getting image data");
00136 nx = (long)cpl_image_get_size_x(map);
00137 ny = (long)cpl_image_get_size_y(map);
00138 npix = nx*ny;
00139 if (vircam_pfits_get_gain(vircam_fits_get_ehu(infile),&gain) != VIR_OK)
00140 gain = 5.0;
00141
00142
00143
00144 if (conf != NULL) {
00145 cmap = vircam_fits_get_image(conf);
00146 if ((confdata = cpl_image_get_data(cmap)) == NULL)
00147 FATAL_ERR("Error getting confidence map data");
00148 nxc = (long)cpl_image_get_size_x(cmap);
00149 nyc = (long)cpl_image_get_size_y(cmap);
00150 if ((nx != nxc) || (ny != nyc))
00151 FATAL_ERR("Input image and confidence dimensions don't match");
00152 freeconf = 0;
00153 } else {
00154 confdata = cpl_malloc(npix*sizeof(*confdata));
00155 for (i = 0; i < npix; i++)
00156 confdata[i] = 100;
00157 freeconf = 1;
00158 cmap = NULL;
00159 }
00160 confsqrt = cpl_malloc(npix*sizeof(*confsqrt));
00161 for (i = 0; i < npix; i++)
00162 confsqrt[i] = sqrt(0.01*(float)confdata[i]);
00163
00164
00165
00166 incopy = cpl_malloc(npix*sizeof(*incopy));
00167 ccopy = cpl_malloc(npix*sizeof(*ccopy));
00168 memmove(incopy,indata,npix*sizeof(*incopy));
00169 memmove(ccopy,confdata,npix*sizeof(*ccopy));
00170
00171
00172
00173 mflag = cpl_calloc(npix,sizeof(*mflag));
00174
00175
00176
00177 ap.lsiz = nx;
00178 ap.csiz = ny;
00179 ap.inframe = map;
00180 ap.conframe = cmap;
00181 ap.xtnum = vircam_fits_get_nexten(infile);
00182 apinit(&ap);
00183 ap.indata = indata;
00184 ap.confdata = confdata;
00185 ap.multiply = 1;
00186 ap.ipnop = ipix;
00187 ap.mflag = mflag;
00188 ap.fconst = fconst;
00189 ap.filtfwhm = filtfwhm;
00190
00191
00192
00193 tabinit(&ap);
00194
00195
00196
00197 for (i = 0; i < npix ; i++)
00198 if (confdata[i] == 0)
00199 mflag[i] = MF_ZEROCONF;
00200 else if (indata[i] < STUPID_VALUE)
00201 mflag[i] = MF_STUPID_VALUE;
00202 else
00203 mflag[i] = MF_CLEANPIX;
00204
00205
00206
00207 retval = imcore_backstats(&ap,nullval,1,&skymed,&skysig,&isatbc);
00208 if (retval != VIR_OK)
00209 FATAL_ERR("Error calculating saturation level");
00210
00211
00212
00213 for (i = 0; i < npix ; i++)
00214 if (mflag[i] == MF_CLEANPIX && indata[i] > isatbc)
00215 mflag[i] = MF_SATURATED;
00216
00217
00218
00219 smoothed = cpl_malloc(nx*sizeof(*smoothed));
00220 smoothedc = cpl_malloc(nx*sizeof(*smoothedc));
00221
00222
00223
00224 crweights(filtfwhm);
00225 nw2 = NW/2;
00226
00227
00228
00229 for (iter = 0; iter < niter; iter++) {
00230
00231
00232
00233 retval = imcore_background(&ap,nbsize,nullval);
00234 if (retval != VIR_OK)
00235 FATAL_ERR("Error calculating background");
00236
00237
00238
00239 retval = imcore_backstats(&ap,nullval,1,&skymed,&skysig,&isat);
00240 if (retval != VIR_OK)
00241 FATAL_ERR("Error calculating saturation");
00242
00243
00244
00245 retval = imcore_backstats(&ap,nullval,0,&skymed,&skysig,&junk);
00246 if (retval != VIR_OK)
00247 FATAL_ERR("Error calculating background stats");
00248
00249
00250
00251 plist = vircam_fits_get_ehu(infile);
00252 cpl_propertylist_update_float(plist,"ESO DRS SKYLEVEL",skymed);
00253 cpl_propertylist_set_comment(plist,"ESO DRS SKYLEVEL",
00254 "[adu] Median sky brightness");
00255 cpl_propertylist_update_float(plist,"ESO DRS SKYNOISE",skysig);
00256 cpl_propertylist_set_comment(plist,"ESO DRS SKYNOISE",
00257 "[adu] Pixel noise at sky level");
00258
00259
00260
00261 for (i = 0; i < nx*ny; i++)
00262 indata[i] -= skymed;
00263
00264
00265
00266 thresh = threshold*skysig;
00267
00268
00269
00270 xintmin = 1.5*thresh*((float)ipix);
00271
00272
00273
00274
00275 offset = logf(thresh)*fconst;
00276
00277
00278
00279 ap.areal_offset = offset;
00280 ap.thresh = thresh;
00281 ap.xintmin = xintmin;
00282 ap.sigma = skysig;
00283 ap.background = skymed;
00284 ap.saturation = isat;
00285
00286
00287
00288
00289 for (j = nw2; j < ny-nw2; j++) {
00290 current = indata + j*nx;
00291 currentc = confsqrt + j*nx;
00292 convolve(j);
00293
00294
00295
00296 apline(&ap,current,currentc,smoothed,smoothedc,j,NULL);
00297
00298
00299
00300 if (ap.ibstack > (ap.maxbl - ap.lsiz))
00301 apfu(&ap);
00302 if (ap.ipstack > (ap.maxpa*3/4))
00303 for (i = 0; i < ap.maxpa*3/8; i++)
00304 apfu(&ap);
00305
00306
00307
00308 if (ap.ipstack > 1)
00309 terminate(&ap);
00310 }
00311
00312
00313
00314 memmove(indata,incopy,npix*sizeof(*indata));
00315 nclip = 0;
00316 opm = cpl_mask_get_data(ap.opmask);
00317 for (i = 0; i < npix; i++) {
00318 if (opm[i]) {
00319 confdata[i] = 0;
00320 opm[i] = 0;
00321 nclip++;
00322 }
00323 }
00324 if (nclip == 0)
00325 break;
00326 }
00327 opm = cpl_mask_get_data(ap.opmask);
00328 for (i = 0; i < npix; i++)
00329 opm[i] = (confdata[i] == 0);
00330 memmove(confdata,ccopy,npix*sizeof(*confdata));
00331 retval = tabclose(&ap);
00332
00333
00334
00335 tidy();
00336 return(VIR_OK);
00337 }
00338
00339
00356
00357
00358 static void crweights(float filtfwhm) {
00359 int i,j,nw2,n;
00360 double gsigsq,di,dj;
00361 float renorm;
00362
00363
00364
00365 nw2 = NW/2;
00366
00367
00368
00369 gsigsq = 1.0/(2.0*pow(MAX(1.0,(double)filtfwhm)/2.35,2.0));
00370 renorm = 0.0;
00371
00372
00373
00374 n = -1;
00375 for (i = -nw2; i <= nw2; i++) {
00376 di = (double)i;
00377 di *= gsigsq*di;
00378 for (j = -nw2; j <= nw2; j++) {
00379 dj = (double)j;
00380 dj *= gsigsq*dj;
00381 n++;
00382 weights[n] = (float)exp(-(di + dj));
00383 renorm += weights[n];
00384 }
00385 }
00386
00387
00388
00389 n = -1;
00390 for (i = -nw2; i <= nw2; i++) {
00391 for (j = -nw2; j <= nw2; j++) {
00392 n++;
00393 weights[n] /= renorm;
00394
00395 weightc[n] = weights[n];
00396 }
00397 }
00398 }
00399
00400
00418
00419
00420 static void convolve(int ir) {
00421 int i,nw2,ix,jx,jy,n;
00422 float *idata,*cdata;
00423
00424
00425
00426 for (i = 0; i < nx; i++) {
00427 smoothed[i] = 0.0;
00428 smoothedc[i] = 0.0;
00429 }
00430
00431
00432
00433 nw2 = NW/2;
00434
00435
00436
00437 for (ix = nw2; ix < nx-nw2; ix++) {
00438 n = -1;
00439 for (jy = ir-nw2; jy <= ir+nw2; jy++) {
00440 idata = indata + jy*nx;
00441 cdata = confsqrt + jy*nx;
00442 for (jx = ix-nw2; jx <= ix+nw2; jx++) {
00443 n++;
00444 smoothed[ix] += weights[n]*idata[jx];
00445 smoothedc[ix] += weightc[n]*idata[jx]*cdata[jx];
00446 }
00447 }
00448 }
00449 }
00450
00451 static void tidy(void) {
00452
00453 if (freeconf)
00454 freespace(confdata);
00455 freespace(confsqrt);
00456 freespace(smoothed);
00457 freespace(smoothedc);
00458 freespace(mflag);
00459 freespace(incopy);
00460 freespace(ccopy);
00461 apclose(&ap);
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483