imcore_extend.c

00001 /* $Id: imcore_extend.c,v 1.4 2010/09/09 12:09:57 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/09 12:09:57 $
00024  * $Revision: 1.4 $
00025  * $Name: vcam-1_3_2 $
00026  */
00027 
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 
00033 #include <cpl.h>
00034 
00035 #include "imcore.h"
00036 #include "floatmath.h"
00037 #include "util.h"
00038 
00039 #define NACC 10
00040 #define NCOEF 4
00041 
00044 /*---------------------------------------------------------------------------*/
00087 /*---------------------------------------------------------------------------*/
00088 
00089 extern int extend(ap_t *ap, float xniso, float xbar, float ybar, float sxx, 
00090                   float sxy, float syy, float areal0, float tmax, 
00091                   float *ttotal) {
00092     float srr,ecc,xx,ctheta,stheta,a,b,stretch,rad,sfac,climsq,clim;
00093     float pt1,pt2,pt3,c,pa,pb,pc,arg1,xliml,xlimu,y,t,x,xnew,ynew,ellrad;
00094     float xmax,xlim1,xlim2,xcord[NACC],xdat[NACC],polycf[NCOEF],rt1,rt2,t1;
00095     float xlimit,theta,accum[NACC],*map,skysig,thresh;
00096     int jmin,jmax,imax,imin,jj,kk,ii,iupd,j,i,ir,nx,ny;
00097     unsigned char *mflag;
00098 
00099     /* Initialise a few things */
00100 
00101     map = ap->indata;
00102     nx = ap->lsiz;
00103     ny = ap->csiz;
00104     skysig = ap->sigma;
00105     thresh = ap->thresh;
00106     mflag = ap->mflag;
00107 
00108     /* Calculate the eccentricity and position angle of the object */
00109 
00110     srr = MAX(0.5,sxx+syy);
00111     ecc = sqrtf((syy-sxx)*(syy-sxx) + 4.0*sxy*sxy)/srr;
00112     ecc = MIN(0.9,ecc);
00113     xx = 0.5*(1.0 + ecc)*srr - sxx;
00114     if (sxy == 0)
00115         theta = 0.0;
00116     else
00117         if (xx == 0.0) 
00118             theta = CPL_MATH_PI_2;
00119         else 
00120             theta = atanf(sxy/xx);
00121     ctheta = cos(theta);
00122     stheta = sin(theta);
00123 
00124     /* Eccentricity modified by noise effect.  NB: 50 == 16*pi */
00125 
00126     ecc = sqrtf(MAX((syy-sxx)*(syy-sxx) 
00127                     - 16.0*CPL_MATH_PI*skysig*srr*srr*srr/(xniso*xniso)
00128                     + 4.0*sxy*sxy,0.0))/srr;
00129     ecc = MIN(0.9,ecc);
00130     
00131     /* Set initial aperture to be isophotal area */
00132 
00133     a = sqrtf(srr*(1.0 + ecc));
00134     b = sqrtf(srr*(1.0 - ecc));
00135     stretch = sqrt(areal0/(CPL_MATH_PI*a*b));
00136 
00137     /* Number of isophotal radii to extend */
00138 
00139     rad = MAX(1.1,(tmax - skysig)/thresh);
00140     sfac = MIN(5.0,MAX(2.0,3.0/sqrtf(logf(rad))));
00141     a *= sfac*stretch;
00142     b *= sfac*stretch;
00143 
00144     /* Clear accumulator */
00145 
00146     memset(accum,0,NACC*sizeof(float));
00147     
00148     /* Generate image boundaries. First for y */
00149 
00150     climsq = (a*ctheta)*(a*ctheta) + (b*stheta)*(b*stheta);
00151     climsq = MAX(1.0,climsq);
00152     clim = sqrtf(climsq);
00153     pt1 = sinf(2.0*theta)*(b*b-a*a);
00154     pt2 = (b*ctheta)*(b*ctheta) + (a*stheta)*(a*stheta);
00155     pt3 = (a*b)*(a*b);
00156     jmin = MAX(1,(int)(ybar - clim));
00157     jmax = MIN(ny,(int)(ybar + clim + 1.0));
00158     for (jj = jmin; jj <= jmax; jj++) {
00159 
00160         /* Now for x */
00161 
00162         kk = (jj-1)*nx;
00163         c  = (float)jj - ybar;
00164         pa = climsq;
00165         pb = pt1*c;
00166         pc = pt2*c*c - pt3;
00167         arg1 = pb*pb - 4.0*pa*pc;
00168         arg1 = sqrtf(MAX(arg1,0.0));
00169         xliml = (-pb - arg1)/(2.0*pa);
00170         xlimu = (-pb + arg1)/(2.0*pa);
00171         imin = MAX(1,(int)(xbar + xliml));
00172         imax = MIN(nx,(int)(xbar + xlimu + 1.0));
00173         y = c;
00174         for(ii = imin; ii <= imax; ii++) {
00175             if (mflag[kk+ii-1] == MF_CLEANPIX || mflag[kk+ii-1] == MF_OBJPIX ||
00176                 mflag[kk+ii-1] == MF_SATURATED) {
00177                 t = map[kk+ii-1];
00178                 x = (float)ii - xbar;
00179 
00180                 /* Accumulate elliptical isophotal areas */
00181 
00182                 xnew = x*ctheta - y*stheta;
00183                 ynew = x*stheta + y*ctheta;
00184                 ellrad = 2.0*sqrtf((ynew/a)*(ynew/a) + (xnew/b)*(xnew/b));
00185                 iupd = ((int)((2.0-ellrad)*(float)NACC)) + 1;
00186                 iupd = MAX(1,iupd);
00187                 iupd = MIN(NACC,iupd);
00188                 for(j = 1; j <= iupd; j++) 
00189                     accum[NACC-j] += t;
00190             }
00191         }
00192     }
00193 
00194     /* Now find limiting intensity */
00195 
00196     if (xniso < 0.0) 
00197         for(i = 0; i < NACC; i++) 
00198             accum[i] = -accum[i];
00199     median(accum,NACC,3);
00200     xmax = 0.0;
00201     xlim1 = -1.0;
00202     xlim2 = -1.0;
00203     for(i = 0; i < NACC; i++) {
00204         xcord[i] = i+1;
00205         xmax = MAX(xmax,accum[i]);
00206         xdat[i] = accum[i];
00207     }
00208     polynm(xdat,xcord,NACC,polycf,NCOEF,0);
00209     pa = polycf[1];
00210     pb = polycf[2]*2.0;
00211     pc = polycf[3]*3.0;
00212     arg1 = sqrtf(MAX(0.0,pb*pb - 4.0*pa*pc));
00213     if (pc != 0.0) {
00214         rt1 = (-pb + arg1)/(2.0*pc);
00215         rt2 = (-pb - arg1)/(2.0*pc);
00216         if(rt1 < (float)NACC && rt1 > 1.0) {
00217             ir = (int)rt1;
00218             t1 = rt1 - (float)ir;
00219             xlim1 = (1.0 - t1)*accum[ir-1] + t1*accum[ir];
00220         }
00221         if(rt2 < (float)NACC && rt2 > 1.0) {
00222             ir = (int)rt2;
00223             t1 = rt2 - ir;
00224             xlim2 = (1.0 - t1)*accum[ir-1] + t1*accum[ir];
00225         }
00226     }
00227     xlimit = MAX(xlim1,xlim2);
00228     if(xlimit < 0.0) 
00229         xlimit = xmax;
00230 
00231     /* Update total intensity */
00232 
00233     if(xniso < 0.0) 
00234         xlimit = -xlimit;
00235     *ttotal = xlimit;
00236     return(VIR_OK);
00237 }
00238 
00241 /*
00242 
00243 $Log: imcore_extend.c,v $
00244 Revision 1.4  2010/09/09 12:09:57  jim
00245 Added docs
00246 
00247 Revision 1.3  2009/09/09 09:42:25  jim
00248 modified to use CPL defined macros for constants
00249 
00250 Revision 1.2  2009/01/23 12:24:33  jim
00251 Fixed bugs in pixel flagging
00252 
00253 Revision 1.1  2005/09/13 13:25:29  jim
00254 Initial entry after modifications to make cpl compliant
00255 
00256 
00257 */

Generated on 5 Mar 2013 for VIRCAM Pipeline by  doxygen 1.6.1