00001
00002
00003
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
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
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
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
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
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
00076
00077 memset(accum,0,NACC*sizeof(float));
00078
00079
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
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
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
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
00162
00163 if(xniso < 0.0)
00164 xlimit = -xlimit;
00165 *ttotal = xlimit;
00166 return(VIR_OK);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176