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
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <math.h>
00033
00034 #include <cpl.h>
00035 #include "../vircam_fits.h"
00036 #include "../vircam_pfits.h"
00037 #include "../vircam_wcsutils.h"
00038
00039 #include "ap.h"
00040 #include "util.h"
00041 #include "imcore.h"
00042 #include "floatmath.h"
00043 #include "imcore_version.h"
00044
00045 #define FATAL_ERR(_a) {freetable(tab); cpl_msg_error(fctid,_a); tidy(); return(VIR_FATAL);}
00046
00047 #define NW 5
00048
00049 static float *smoothed = NULL;
00050 static float *smoothedc = NULL;
00051 static unsigned char *mflag = NULL;
00052 static float *indata = NULL;
00053 static int *confdata = NULL;
00054 static float *confsqrt = NULL;
00055 static ap_t ap;
00056 static int freeconf = 0;
00057
00058 static float weights[NW*NW];
00059 static float weightc[NW*NW];
00060 static long nx;
00061 static long ny;
00062
00063 static void crweights(float);
00064 static void convolve(int);
00065 static void tidy(void);
00066
00069
00144
00145
00146 extern int imcore_conf(vir_fits *infile, vir_fits *conf, int ipix,
00147 float threshold, int icrowd, float rcore, int nbsize,
00148 int cattyp, float filtfwhm, vir_tfits **outcat) {
00149
00150 int i,retval,mulpix,j,nw2,status;
00151 float fconst,nullval,skymed,skysig,thresh,xintmin,offset;
00152 float *current,isatbc,isat,junk,*currentc;
00153 long npix,nxc,nyc,npts;
00154 cpl_image *map,*cmap;
00155 cpl_propertylist *plist,*extra;
00156 char card[64];
00157 const char *fctid = "imcore_conf";
00158
00159
00160
00161 *outcat = NULL;
00162
00163
00164
00165 fconst = CPL_MATH_LOG2E;
00166 nullval = 0.0;
00167 cattype = cattyp;
00168 nobjects = 0;
00169
00170
00171
00172 map = vircam_fits_get_image(infile);
00173 if ((indata = cpl_image_get_data_float(map)) == NULL)
00174 FATAL_ERR("Error getting image data");
00175 nx = (long)cpl_image_get_size_x(map);
00176 ny = (long)cpl_image_get_size_y(map);
00177 npts = nx*ny;
00178 if (vircam_pfits_get_gain(vircam_fits_get_ehu(infile),&gain) != VIR_OK)
00179 gain = 5.0;
00180
00181
00182
00183 if (conf != NULL) {
00184 cmap = vircam_fits_get_image(conf);
00185 if ((confdata = cpl_image_get_data(cmap)) == NULL)
00186 FATAL_ERR("Error getting confidence map data");
00187 nxc = (long)cpl_image_get_size_x(cmap);
00188 nyc = (long)cpl_image_get_size_y(cmap);
00189 if ((nx != nxc) || (ny != nyc))
00190 FATAL_ERR("Input image and confidence dimensions don't match");
00191 freeconf = 0;
00192 } else {
00193 confdata = cpl_malloc(npts*sizeof(*confdata));
00194 for (i = 0; i < npts; i++)
00195 confdata[i] = 100;
00196 freeconf = 1;
00197 cmap = NULL;
00198 }
00199 confsqrt = cpl_malloc(npts*sizeof(*confsqrt));
00200 for (i = 0; i < npts; i++)
00201 confsqrt[i] = sqrt(0.01*(float)confdata[i]);
00202
00203
00204
00205 npix = nx*ny;
00206 mflag = cpl_calloc(npix,sizeof(*mflag));
00207
00208
00209
00210 ap.lsiz = nx;
00211 ap.csiz = ny;
00212 ap.inframe = map;
00213 ap.conframe = cmap;
00214 ap.xtnum = vircam_fits_get_nexten(infile);
00215 apinit(&ap);
00216 ap.indata = indata;
00217 ap.confdata = confdata;
00218 ap.multiply = 1;
00219 ap.ipnop = ipix;
00220 ap.mflag = mflag;
00221 ap.rcore = rcore;
00222 ap.filtfwhm = filtfwhm;
00223 ap.icrowd = icrowd;
00224 ap.fconst = fconst;
00225
00226
00227
00228 tabinit(&ap);
00229
00230
00231
00232 for (i = 0; i < npix; i++)
00233 if (confdata[i] == 0)
00234 mflag[i] = MF_ZEROCONF;
00235 else if (indata[i] < STUPID_VALUE)
00236 mflag[i] = MF_STUPID_VALUE;
00237 else
00238 mflag[i] = MF_CLEANPIX;
00239
00240
00241
00242 retval = imcore_backstats(&ap,nullval,1,&skymed,&skysig,&isatbc);
00243 if (retval != VIR_OK)
00244 FATAL_ERR("Error calculating saturation level");
00245
00246
00247
00248
00249 for (i = 0; i < npix ; i++)
00250 if (mflag[i] == MF_CLEANPIX && indata[i] > isatbc)
00251 mflag[i] = MF_SATURATED;
00252
00253
00254
00255 retval = imcore_background(&ap,nbsize,nullval);
00256 if (retval != VIR_OK)
00257 FATAL_ERR("Error calculating background");
00258
00259
00260
00261 retval = imcore_backstats(&ap,nullval,1,&skymed,&skysig,&isat);
00262 if (retval != VIR_OK)
00263 FATAL_ERR("Error calculating saturation");
00264
00265
00266
00267
00268 retval = imcore_backstats(&ap,nullval,0,&skymed,&skysig,&junk);
00269 if (retval != VIR_OK)
00270 FATAL_ERR("Error calculating background stats");
00271
00272
00273
00274 plist = vircam_fits_get_ehu(infile);
00275 cpl_propertylist_update_float(plist,"ESO DRS SKYLEVEL",skymed);
00276 cpl_propertylist_set_comment(plist,"ESO DRS SKYLEVEL",
00277 "[adu] Median sky brightness");
00278 cpl_propertylist_update_float(plist,"ESO DRS SKYNOISE",skysig);
00279 cpl_propertylist_set_comment(plist,"ESO DRS SKYNOISE",
00280 "[adu] Pixel noise at sky level");
00281
00282
00283
00284 for (i = 0; i < nx*ny; i++) {
00285 indata[i] -= skymed;
00286 if (indata[i]*confsqrt[i] > 3.0*skysig &&
00287 mflag[i] != MF_SATURATED && mflag[i] != MF_STUPID_VALUE)
00288 mflag[i] = MF_3SIG;
00289 }
00290
00291
00292
00293 thresh = threshold*skysig;
00294
00295
00296
00297 xintmin = 1.5*thresh*((float)ipix);
00298
00299
00300
00301 mulpix = MAX(8,2*ipix);
00302
00303
00304
00305
00306 offset = logf(thresh)*fconst;
00307
00308
00309
00310 smoothed = cpl_malloc(nx*sizeof(*smoothed));
00311 smoothedc = cpl_malloc(nx*sizeof(*smoothedc));
00312
00313
00314
00315 ap.mulpix = mulpix;
00316 ap.areal_offset = offset;
00317 ap.thresh = thresh;
00318 ap.xintmin = xintmin;
00319 ap.sigma = skysig;
00320 ap.background = skymed;
00321 ap.saturation = (float)isat;
00322
00323
00324
00325 crweights(filtfwhm);
00326 nw2 = NW/2;
00327
00328
00329
00330
00331 for (j = nw2; j < ny-nw2; j++) {
00332 current = indata + j*nx;
00333 currentc = confsqrt + j*nx;
00334 convolve(j);
00335
00336
00337
00338 apline(&ap,current,currentc,smoothed,smoothedc,j,NULL);
00339
00340
00341
00342 if (ap.ibstack > (ap.maxbl - ap.lsiz))
00343 apfu(&ap);
00344 if (ap.ipstack > (ap.maxpa*3/4))
00345 for (i = 0; i < ap.maxpa*3/8; i++)
00346 apfu(&ap);
00347
00348
00349
00350 if (ap.ipstack > 1)
00351 terminate(&ap);
00352 }
00353
00354
00355
00356
00357 cpl_table_set_size(tab,nobjects);
00358 retval = do_seeing(&ap);
00359 if (retval != VIR_OK)
00360 FATAL_ERR("Error working out seeing");
00361 tabclose(&ap);
00362
00363
00364
00365 extra = cpl_propertylist_duplicate(vircam_fits_get_ehu(infile));
00366 cpl_propertylist_update_float(extra,"ESO QC SATURATION",ap.saturation);
00367 cpl_propertylist_set_comment(extra,"ESO QC SATURATION",
00368 "[adu] Saturation level");
00369 cpl_propertylist_update_float(extra,"ESO QC MEAN_SKY",ap.background);
00370 cpl_propertylist_set_comment(extra,"ESO QC MEAN_SKY",
00371 "[adu] Median sky brightness");
00372 cpl_propertylist_update_float(extra,"ESO QC SKY_NOISE",ap.sigma);
00373 cpl_propertylist_set_comment(extra,"ESO QC SKY_NOISE",
00374 "[adu] Pixel noise at sky level");
00375
00376
00377
00378 cpl_propertylist_update_float(extra,"ESO DRS THRESHOL",ap.thresh);
00379 cpl_propertylist_set_comment(extra,"ESO DRS THRESHOL",
00380 "[adu] Isophotal analysis threshold");
00381 cpl_propertylist_update_int(extra,"ESO DRS MINPIX",ap.ipnop);
00382 cpl_propertylist_set_comment(extra,"ESO DRS MINPIX",
00383 "[pixels] Minimum size for images");
00384 cpl_propertylist_update_int(extra,"ESO DRS CROWDED",ap.icrowd);
00385 cpl_propertylist_set_comment(extra,"ESO DRS CROWDED",
00386 "Crowded field analysis flag");
00387 cpl_propertylist_update_float(extra,"ESO DRS RCORE",ap.rcore);
00388 cpl_propertylist_set_comment(extra,"ESO DRS RCORE",
00389 "[pixels] Core radius for default profile fit");
00390 cpl_propertylist_update_float(extra,"ESO DRS SEEING",ap.fwhm);
00391 cpl_propertylist_set_comment(extra,"ESO DRS SEEING",
00392 "[pixels] Average FWHM");
00393 cpl_propertylist_update_float(extra,"ESO DRS FILTFWHM",ap.filtfwhm);
00394 cpl_propertylist_set_comment(extra,"ESO DRS FILTFWHM",
00395 "[pixels] FWHM of smoothing kernel");
00396 cpl_propertylist_update_int(extra,"ESO DRS XCOL",imcore_xcol);
00397 cpl_propertylist_set_comment(extra,"ESO DRS XCOL","Column for X position");
00398 cpl_propertylist_update_int(extra,"ESO DRS YCOL",imcore_ycol);
00399 cpl_propertylist_set_comment(extra,"ESO DRS YCOL","Column for Y position");
00400 cpl_propertylist_update_int(extra,"ESO DRS NXOUT",nx);
00401 cpl_propertylist_set_comment(extra,"ESO DRS NXOUT",
00402 "X Dimension of input image");
00403 cpl_propertylist_update_int(extra,"ESO DRS NYOUT",ny);
00404 cpl_propertylist_set_comment(extra,"ESO DRS NYOUT",
00405 "Y Dimension of input image");
00406 snprintf(card,64,"IMCORE version: %s",imcore_version);
00407 cpl_propertylist_append_string(extra,"HISTORY",card);
00408
00409
00410
00411 plist = cpl_propertylist_duplicate(vircam_fits_get_phu(infile));
00412 status = VIR_OK;
00413 (void)vircam_tabwcs(extra,imcore_xcol,imcore_ycol,&status);
00414 *outcat = vircam_tfits_wrap(tab,NULL,plist,extra);
00415
00416
00417
00418 tidy();
00419 return(VIR_OK);
00420 }
00421
00422
00439
00440
00441 static void crweights(float filtfwhm) {
00442 int i,j,nw2,n;
00443 double gsigsq,di,dj;
00444 float renorm;
00445
00446
00447
00448 nw2 = NW/2;
00449
00450
00451
00452 gsigsq = 1.0/(2.0*pow(MAX(1.0,(double)filtfwhm)/2.35,2.0));
00453 renorm = 0.0;
00454
00455
00456
00457 n = -1;
00458 for (i = -nw2; i <= nw2; i++) {
00459 di = (double)i;
00460 di *= gsigsq*di;
00461 for (j = -nw2; j <= nw2; j++) {
00462 dj = (double)j;
00463 dj *= gsigsq*dj;
00464 n++;
00465 weights[n] = (float)exp(-(di + dj));
00466 renorm += weights[n];
00467 }
00468 }
00469
00470
00471
00472 n = -1;
00473 for (i = -nw2; i <= nw2; i++) {
00474 for (j = -nw2; j <= nw2; j++) {
00475 n++;
00476 weights[n] /= renorm;
00477
00478 weightc[n] = weights[n];
00479 }
00480 }
00481 }
00482
00483
00501
00502
00503 static void convolve(int ir) {
00504 int i,nw2,ix,jx,jy,n;
00505 float *idata,*cdata;
00506
00507
00508
00509 for (i = 0; i < nx; i++) {
00510 smoothed[i] = 0.0;
00511 smoothedc[i] = 0.0;
00512 }
00513
00514
00515
00516 nw2 = NW/2;
00517
00518
00519
00520 for (ix = nw2; ix < nx-nw2; ix++) {
00521 n = -1;
00522 for (jy = ir-nw2; jy <= ir+nw2; jy++) {
00523 idata = indata + jy*nx;
00524 cdata = confsqrt + jy*nx;
00525 for (jx = ix-nw2; jx <= ix+nw2; jx++) {
00526 n++;
00527 smoothed[ix] += weights[n]*idata[jx];
00528 smoothedc[ix] += weightc[n]*idata[jx]*cdata[jx];
00529 }
00530 }
00531 }
00532 }
00533
00534 static void tidy(void) {
00535
00536 if (freeconf)
00537 freespace(confdata);
00538 freespace(confsqrt);
00539 freespace(smoothed);
00540 freespace(smoothedc);
00541 freespace(mflag);
00542 apclose(&ap);
00543 }
00544
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625