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 #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
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
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
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
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
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
00145
00146 memset(accum,0,NACC*sizeof(float));
00147
00148
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
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
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
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
00232
00233 if(xniso < 0.0)
00234 xlimit = -xlimit;
00235 *ttotal = xlimit;
00236 return(VIR_OK);
00237 }
00238
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257