imcore_extend.c

00001 /*
00002 
00003 $Id: imcore_extend.c,v 1.1 2005/09/13 13:25:29 jim Exp $
00004 
00005 */
00006 
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 
00011 #include <cpl.h>
00012 
00013 #include "imcore.h"
00014 #include "floatmath.h"
00015 #include "util.h"
00016 
00017 #define NACC 10
00018 #define NCOEF 4
00019 
00020 extern int extend(ap_t *ap, float xniso, float xbar, float ybar, float sxx, 
00021                   float sxy, float syy, float areal0, float tmax, 
00022                   float *ttotal) {
00023     float srr,ecc,xx,ctheta,stheta,a,b,stretch,rad,sfac,climsq,clim;
00024     float pt1,pt2,pt3,c,pa,pb,pc,arg1,xliml,xlimu,y,t,x,xnew,ynew,ellrad;
00025     float xmax,xlim1,xlim2,xcord[NACC],xdat[NACC],polycf[NCOEF],rt1,rt2,t1;
00026     float xlimit,theta,accum[NACC],*map,skysig,thresh;
00027     int jmin,jmax,imax,imin,jj,kk,ii,iupd,j,i,ir,nx,ny;
00028     unsigned char *mflag;
00029 
00030     /* Initialise a few things */
00031 
00032     map = ap->indata;
00033     nx = ap->lsiz;
00034     ny = ap->csiz;
00035     skysig = ap->sigma;
00036     thresh = ap->thresh;
00037     mflag = ap->mflag;
00038 
00039     /* Calculate the eccentricity and position angle of the object */
00040 
00041     srr = MAX(0.5,sxx+syy);
00042     ecc = sqrtf((syy-sxx)*(syy-sxx) + 4.0*sxy*sxy)/srr;
00043     ecc = MIN(0.9,ecc);
00044     xx = 0.5*(1.0 + ecc)*srr - sxx;
00045     if (sxy == 0)
00046         theta = 0.0;
00047     else
00048         if (xx == 0.0) 
00049             theta = M_PI_2;
00050         else 
00051             theta = atanf(sxy/xx);
00052     ctheta = cos(theta);
00053     stheta = sin(theta);
00054 
00055     /* Eccentricity modified by noise effect.  NB: 50 == 16*pi */
00056 
00057     ecc = sqrtf(MAX((syy-sxx)*(syy-sxx) 
00058                     - 16.0*M_PI*skysig*srr*srr*srr/(xniso*xniso)
00059                     + 4.0*sxy*sxy,0.0))/srr;
00060     ecc = MIN(0.9,ecc);
00061     
00062     /* Set initial aperture to be isophotal area */
00063 
00064     a = sqrtf(srr*(1.0 + ecc));
00065     b = sqrtf(srr*(1.0 - ecc));
00066     stretch = sqrt(areal0/(M_PI*a*b));
00067 
00068     /* Number of isophotal radii to extend */
00069 
00070     rad = MAX(1.1,(tmax - skysig)/thresh);
00071     sfac = MIN(5.0,MAX(2.0,3.0/sqrtf(logf(rad))));
00072     a *= sfac*stretch;
00073     b *= sfac*stretch;
00074 
00075     /* Clear accumulator */
00076 
00077     memset(accum,0,NACC*sizeof(float));
00078     
00079     /* Generate image boundaries. First for y */
00080 
00081     climsq = (a*ctheta)*(a*ctheta) + (b*stheta)*(b*stheta);
00082     climsq = MAX(1.0,climsq);
00083     clim = sqrtf(climsq);
00084     pt1 = sinf(2.0*theta)*(b*b-a*a);
00085     pt2 = (b*ctheta)*(b*ctheta) + (a*stheta)*(a*stheta);
00086     pt3 = (a*b)*(a*b);
00087     jmin = MAX(1,(int)(ybar - clim));
00088     jmax = MIN(ny,(int)(ybar + clim + 1.0));
00089     for (jj = jmin; jj <= jmax; jj++) {
00090 
00091         /* Now for x */
00092 
00093         kk = (jj-1)*nx;
00094         c  = (float)jj - ybar;
00095         pa = climsq;
00096         pb = pt1*c;
00097         pc = pt2*c*c - pt3;
00098         arg1 = pb*pb - 4.0*pa*pc;
00099         arg1 = sqrtf(MAX(arg1,0.0));
00100         xliml = (-pb - arg1)/(2.0*pa);
00101         xlimu = (-pb + arg1)/(2.0*pa);
00102         imin = MAX(1,(int)(xbar + xliml));
00103         imax = MIN(nx,(int)(xbar + xlimu + 1.0));
00104         y = c;
00105         for(ii = imin; ii <= imax; ii++) {
00106             if (mflag[kk+ii-1] == MF_CLEANPIX || mflag[kk+ii-1] == MF_OBJPIX) {
00107                 t = map[kk+ii-1];
00108                 x = (float)ii - xbar;
00109 
00110                 /* Accumulate elliptical isophotal areas */
00111 
00112                 xnew = x*ctheta - y*stheta;
00113                 ynew = x*stheta + y*ctheta;
00114                 ellrad = 2.0*sqrtf((ynew/a)*(ynew/a) + (xnew/b)*(xnew/b));
00115                 iupd = ((int)((2.0-ellrad)*(float)NACC)) + 1;
00116                 iupd = MAX(1,iupd);
00117                 iupd = MIN(NACC,iupd);
00118                 for(j = 1; j <= iupd; j++) 
00119                     accum[NACC-j] += t;
00120             }
00121         }
00122     }
00123 
00124     /* Now find limiting intensity */
00125 
00126     if (xniso < 0.0) 
00127         for(i = 0; i < NACC; i++) 
00128             accum[i] = -accum[i];
00129     median(accum,NACC,3);
00130     xmax = 0.0;
00131     xlim1 = -1.0;
00132     xlim2 = -1.0;
00133     for(i = 0; i < NACC; i++) {
00134         xcord[i] = i+1;
00135         xmax = MAX(xmax,accum[i]);
00136         xdat[i] = accum[i];
00137     }
00138     polynm(xdat,xcord,NACC,polycf,NCOEF,0);
00139     pa = polycf[1];
00140     pb = polycf[2]*2.0;
00141     pc = polycf[3]*3.0;
00142     arg1 = sqrtf(MAX(0.0,pb*pb - 4.0*pa*pc));
00143     if (pc != 0.0) {
00144         rt1 = (-pb + arg1)/(2.0*pc);
00145         rt2 = (-pb - arg1)/(2.0*pc);
00146         if(rt1 < (float)NACC && rt1 > 1.0) {
00147             ir = (int)rt1;
00148             t1 = rt1 - (float)ir;
00149             xlim1 = (1.0 - t1)*accum[ir-1] + t1*accum[ir];
00150         }
00151         if(rt2 < (float)NACC && rt2 > 1.0) {
00152             ir = (int)rt2;
00153             t1 = rt2 - ir;
00154             xlim2 = (1.0 - t1)*accum[ir-1] + t1*accum[ir];
00155         }
00156     }
00157     xlimit = MAX(xlim1,xlim2);
00158     if(xlimit < 0.0) 
00159         xlimit = xmax;
00160 
00161     /* Update total intensity */
00162 
00163     if(xniso < 0.0) 
00164         xlimit = -xlimit;
00165     *ttotal = xlimit;
00166     return(VIR_OK);
00167 }
00168 
00169 /*
00170 
00171 $Log: imcore_extend.c,v $
00172 Revision 1.1  2005/09/13 13:25:29  jim
00173 Initial entry after modifications to make cpl compliant
00174 
00175 
00176 */

Generated on Wed Apr 10 04:01:54 2013 for VIRCAM Pipeline by  doxygen 1.5.1