imcore_conf.c

00001 /* $Id: imcore_conf.c,v 1.24 2010/09/10 11:23:09 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2010/09/10 11:23:09 $
00024  * $Revision: 1.24 $
00025  * $Name: v1-1-0 $
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     /* Initialise output */
00160 
00161     *outcat = NULL;
00162 
00163     /* Useful constants */
00164 
00165     fconst = CPL_MATH_LOG2E;
00166     nullval = 0.0;
00167     cattype = cattyp;
00168     nobjects = 0;
00169 
00170     /* Open input image */
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     /* Open the associated confidence map, if it exists */
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     /* Get mflag array for flagging saturated pixels */
00204 
00205     npix = nx*ny;
00206     mflag = cpl_calloc(npix,sizeof(*mflag));
00207 
00208     /* Open the ap structure and define some stuff in it */
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     /* Open the output catalogue FITS table */
00227 
00228     tabinit(&ap);
00229 
00230     /* Set up the data flags */
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     /* Compute a saturation level before background correction. */
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     /* Flag up regions where the value is above the saturation level
00247        determined above. */
00248 
00249     for (i = 0; i < npix ; i++)
00250         if (mflag[i] == MF_CLEANPIX && indata[i] > isatbc)
00251             mflag[i] = MF_SATURATED;
00252 
00253     /* Compute the background variation and remove it from the data*/
00254 
00255     retval = imcore_background(&ap,nbsize,nullval);
00256     if (retval != VIR_OK) 
00257         FATAL_ERR("Error calculating background");
00258 
00259     /* Compute a saturation level after background correction. */
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     /* Compute background statistics */
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     /* Get the propertly list for the input file and add some info*/
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     /* Take mean sky level out of data */
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     /* Work out isophotal detection threshold levels */
00292 
00293     thresh = threshold*skysig;
00294     
00295     /* Minimum intensity for consideration */
00296 
00297     xintmin = 1.5*thresh*((float)ipix);
00298 
00299     /* Minimum size for considering multiple images */
00300 
00301     mulpix = MAX(8,2*ipix);
00302 
00303     /* Actual areal profile levels: T, 2T, 4T, 8T,...but written wrt T
00304        i.e. threshold as a power of 2 */
00305 
00306     offset = logf(thresh)*fconst;
00307 
00308     /* Get a bit of workspace for buffers */
00309 
00310     smoothed = cpl_malloc(nx*sizeof(*smoothed));
00311     smoothedc = cpl_malloc(nx*sizeof(*smoothedc));
00312 
00313     /* Define a few things more things in ap structure */
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     /* Set the weights */
00324 
00325     crweights(filtfwhm);
00326     nw2 = NW/2;
00327 
00328     /* Right, now for the extraction loop.  Begin by defining a group of
00329        three rows of data and confidence */
00330 
00331     for (j = nw2; j < ny-nw2; j++) {
00332         current = indata + j*nx;
00333         currentc = confsqrt + j*nx;
00334         convolve(j);
00335    
00336         /* Do the detection now */
00337 
00338         apline(&ap,current,currentc,smoothed,smoothedc,j,NULL);
00339 
00340         /* Make sure we're not overruning the stacks */
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         /* See if there are any images to terminate */
00349 
00350         if (ap.ipstack > 1)
00351             terminate(&ap);
00352     }
00353 
00354     /* Post process. First truncate the cpl_table to the correct size and then
00355        work out an estimate of the seeing */
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     /* Create a property list with extra parameters. First QC parameters */
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     /* Now DRS parameters */
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     /* Now wrap all this stuff up and send it back */
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     /* Tidy and exit */  
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     /* Get the kernel size */
00447 
00448     nw2 = NW/2;
00449     
00450     /* Set the normalisation constants */
00451 
00452     gsigsq = 1.0/(2.0*pow(MAX(1.0,(double)filtfwhm)/2.35,2.0));
00453     renorm = 0.0;
00454 
00455     /* Now work out the weights */
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     /* Now normalise the weights */
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             /* weightc[n] = 0.01*weights[n]; */
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     /* Zero the summations */
00508 
00509     for (i = 0; i < nx; i++) {
00510         smoothed[i] = 0.0;
00511         smoothedc[i] = 0.0;
00512     }
00513 
00514     /* Now big is the smoothing kernel? */
00515 
00516     nw2 = NW/2;
00517 
00518     /* Now loop for each column */
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 $Log: imcore_conf.c,v $
00550 Revision 1.24  2010/09/10 11:23:09  jim
00551 Fixed declaration of currentc
00552 
00553 Revision 1.23  2010/09/09 12:09:49  jim
00554 Modified to use sqrt weighting with confidence maps. Also added docs
00555 
00556 Revision 1.22  2009/09/09 09:42:25  jim
00557 modified to use CPL defined macros for constants
00558 
00559 Revision 1.21  2009/05/20 12:22:34  jim
00560 Now adds ESO DRS NXOUT and NYOUT to header
00561 
00562 Revision 1.20  2009/01/30 08:26:23  jim
00563 Now adds a global version number to header
00564 
00565 Revision 1.19  2009/01/23 12:24:33  jim
00566 Fixed bugs in pixel flagging
00567 
00568 Revision 1.18  2008/10/13 08:10:56  jim
00569 Fixed pixel masking scheme
00570 
00571 Revision 1.17  2007/05/03 11:15:34  jim
00572 Fixed little problem with table wcs
00573 
00574 Revision 1.16  2007/05/02 09:11:35  jim
00575 Modified to allow for inclusion of table WCS keywords into FITS header
00576 
00577 Revision 1.15  2007/03/01 12:38:26  jim
00578 Small modifications after a bit of code checking
00579 
00580 Revision 1.14  2006/11/27 11:56:59  jim
00581 Changed cpl_propertylist_append to cpl_propertylist_update calls
00582 
00583 Revision 1.13  2006/08/01 11:27:54  jim
00584 Modifications to imcore background estimation and to add ability to
00585 specify the smoothing kernel width
00586 
00587 Revision 1.12  2006/07/11 14:51:02  jim
00588 Fixed small bug in the range of the main loop
00589 
00590 Revision 1.11  2006/07/03 09:33:19  jim
00591 Fixed a few things to keep the compiler happy
00592 
00593 Revision 1.10  2006/06/30 21:31:09  jim
00594 MOdifications to background routines and smoothing kernel
00595 
00596 Revision 1.9  2006/06/13 14:06:10  jim
00597 Gets gain estimate from header
00598 
00599 Revision 1.8  2006/06/06 13:04:22  jim
00600 Fixed apline so that it now takes confidence map info correctly
00601 
00602 Revision 1.7  2006/05/30 12:13:53  jim
00603 Initialised nobjects
00604 
00605 Revision 1.6  2006/05/18 12:35:01  jim
00606 Fixed bug for header writing
00607 
00608 Revision 1.5  2006/03/15 10:43:42  jim
00609 Fixed a few things
00610 
00611 Revision 1.4  2006/03/01 10:31:29  jim
00612 Now uses new vir_fits objects
00613 
00614 Revision 1.3  2005/09/22 08:40:42  jim
00615 Fixed some bugs in imcore and added classification Removed some unnecessary
00616 files
00617 
00618 Revision 1.2  2005/09/20 15:07:47  jim
00619 Fixed a few bugs and added a few things
00620 
00621 Revision 1.1  2005/09/13 13:25:29  jim
00622 Initial entry after modifications to make cpl compliant
00623 
00624 
00625 */

Generated on 7 Feb 2011 for VIRCAM Pipeline by  doxygen 1.6.1