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
00285
00286 for (i = 0; i < nx*ny; i++) {
00287 indata[i] -= skymed;
00288
00289
00290
00291 }
00292
00293
00294
00295 thresh = threshold*skysig;
00296
00297
00298
00299 xintmin = 1.5*thresh*((float)ipix);
00300
00301
00302
00303 mulpix = MAX(8,2*ipix);
00304
00305
00306
00307
00308 offset = logf(thresh)*fconst;
00309
00310
00311
00312 smoothed = cpl_malloc(nx*sizeof(*smoothed));
00313 smoothedc = cpl_malloc(nx*sizeof(*smoothedc));
00314
00315
00316
00317 ap.mulpix = mulpix;
00318 ap.areal_offset = offset;
00319 ap.thresh = thresh;
00320 ap.xintmin = xintmin;
00321 ap.sigma = skysig;
00322 ap.background = skymed;
00323 ap.saturation = (float)isat;
00324
00325
00326
00327 crweights(filtfwhm);
00328 nw2 = NW/2;
00329
00330
00331
00332
00333 for (j = nw2; j < ny-nw2; j++) {
00334 current = indata + j*nx;
00335 currentc = confsqrt + j*nx;
00336 convolve(j);
00337
00338
00339
00340 apline(&ap,current,currentc,smoothed,smoothedc,j,NULL);
00341
00342
00343
00344 if (ap.ibstack > (ap.maxbl - ap.lsiz))
00345 apfu(&ap);
00346 if (ap.ipstack > (ap.maxpa*3/4))
00347 for (i = 0; i < ap.maxpa*3/8; i++)
00348 apfu(&ap);
00349
00350
00351
00352 if (ap.ipstack > 1)
00353 terminate(&ap);
00354 }
00355
00356
00357
00358
00359 cpl_table_set_size(tab,nobjects);
00360 retval = do_seeing(&ap);
00361 if (retval != VIR_OK)
00362 FATAL_ERR("Error working out seeing");
00363 tabclose(&ap);
00364
00365
00366
00367 extra = cpl_propertylist_duplicate(vircam_fits_get_ehu(infile));
00368 cpl_propertylist_update_float(extra,"ESO QC SATURATION",ap.saturation);
00369 cpl_propertylist_set_comment(extra,"ESO QC SATURATION",
00370 "[adu] Saturation level");
00371 cpl_propertylist_update_float(extra,"ESO QC MEAN_SKY",ap.background);
00372 cpl_propertylist_set_comment(extra,"ESO QC MEAN_SKY",
00373 "[adu] Median sky brightness");
00374 cpl_propertylist_update_float(extra,"ESO QC SKY_NOISE",ap.sigma);
00375 cpl_propertylist_set_comment(extra,"ESO QC SKY_NOISE",
00376 "[adu] Pixel noise at sky level");
00377
00378
00379
00380 cpl_propertylist_update_float(extra,"ESO DRS THRESHOL",ap.thresh);
00381 cpl_propertylist_set_comment(extra,"ESO DRS THRESHOL",
00382 "[adu] Isophotal analysis threshold");
00383 cpl_propertylist_update_int(extra,"ESO DRS MINPIX",ap.ipnop);
00384 cpl_propertylist_set_comment(extra,"ESO DRS MINPIX",
00385 "[pixels] Minimum size for images");
00386 cpl_propertylist_update_int(extra,"ESO DRS CROWDED",ap.icrowd);
00387 cpl_propertylist_set_comment(extra,"ESO DRS CROWDED",
00388 "Crowded field analysis flag");
00389 cpl_propertylist_update_float(extra,"ESO DRS RCORE",ap.rcore);
00390 cpl_propertylist_set_comment(extra,"ESO DRS RCORE",
00391 "[pixels] Core radius for default profile fit");
00392 cpl_propertylist_update_float(extra,"ESO DRS SEEING",ap.fwhm);
00393 cpl_propertylist_set_comment(extra,"ESO DRS SEEING",
00394 "[pixels] Average FWHM");
00395 cpl_propertylist_update_float(extra,"ESO DRS FILTFWHM",ap.filtfwhm);
00396 cpl_propertylist_set_comment(extra,"ESO DRS FILTFWHM",
00397 "[pixels] FWHM of smoothing kernel");
00398 cpl_propertylist_update_int(extra,"ESO DRS XCOL",imcore_xcol);
00399 cpl_propertylist_set_comment(extra,"ESO DRS XCOL","Column for X position");
00400 cpl_propertylist_update_int(extra,"ESO DRS YCOL",imcore_ycol);
00401 cpl_propertylist_set_comment(extra,"ESO DRS YCOL","Column for Y position");
00402 cpl_propertylist_update_int(extra,"ESO DRS NXOUT",nx);
00403 cpl_propertylist_set_comment(extra,"ESO DRS NXOUT",
00404 "X Dimension of input image");
00405 cpl_propertylist_update_int(extra,"ESO DRS NYOUT",ny);
00406 cpl_propertylist_set_comment(extra,"ESO DRS NYOUT",
00407 "Y Dimension of input image");
00408 snprintf(card,64,"IMCORE version: %s",imcore_version);
00409 cpl_propertylist_append_string(extra,"HISTORY",card);
00410
00411
00412
00413 plist = cpl_propertylist_duplicate(vircam_fits_get_phu(infile));
00414 status = VIR_OK;
00415 (void)vircam_tabwcs(extra,imcore_xcol,imcore_ycol,&status);
00416 *outcat = vircam_tfits_wrap(tab,NULL,plist,extra);
00417
00418
00419
00420 tidy();
00421 return(VIR_OK);
00422 }
00423
00424
00441
00442
00443 static void crweights(float filtfwhm) {
00444 int i,j,nw2,n;
00445 double gsigsq,di,dj;
00446 float renorm;
00447
00448
00449
00450 nw2 = NW/2;
00451
00452
00453
00454 gsigsq = 1.0/(2.0*pow(MAX(1.0,(double)filtfwhm)/2.35,2.0));
00455 renorm = 0.0;
00456
00457
00458
00459 n = -1;
00460 for (i = -nw2; i <= nw2; i++) {
00461 di = (double)i;
00462 di *= gsigsq*di;
00463 for (j = -nw2; j <= nw2; j++) {
00464 dj = (double)j;
00465 dj *= gsigsq*dj;
00466 n++;
00467 weights[n] = (float)exp(-(di + dj));
00468 renorm += weights[n];
00469 }
00470 }
00471
00472
00473
00474 n = -1;
00475 for (i = -nw2; i <= nw2; i++) {
00476 for (j = -nw2; j <= nw2; j++) {
00477 n++;
00478 weights[n] /= renorm;
00479
00480 weightc[n] = weights[n];
00481 }
00482 }
00483 }
00484
00485
00503
00504
00505 static void convolve(int ir) {
00506 int i,nw2,ix,jx,jy,n;
00507 float *idata,*cdata;
00508
00509
00510
00511 for (i = 0; i < nx; i++) {
00512 smoothed[i] = 0.0;
00513 smoothedc[i] = 0.0;
00514 }
00515
00516
00517
00518 nw2 = NW/2;
00519
00520
00521
00522 for (ix = nw2; ix < nx-nw2; ix++) {
00523 n = -1;
00524 for (jy = ir-nw2; jy <= ir+nw2; jy++) {
00525 idata = indata + jy*nx;
00526 cdata = confsqrt + jy*nx;
00527 for (jx = ix-nw2; jx <= ix+nw2; jx++) {
00528 n++;
00529 smoothed[ix] += weights[n]*idata[jx];
00530 smoothedc[ix] += weightc[n]*idata[jx]*cdata[jx];
00531 }
00532 }
00533 }
00534 }
00535
00536 static void tidy(void) {
00537
00538 if (freeconf)
00539 freespace(confdata);
00540 freespace(confsqrt);
00541 freespace(smoothed);
00542 freespace(smoothedc);
00543 freespace(mflag);
00544 apclose(&ap);
00545 }
00546
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
00626
00627
00628
00629
00630