VIRCAM Pipeline  1.3.3
imcore_extend.c
1 /* $Id: imcore_extend.c,v 1.4 2010-09-09 12:09:57 jim Exp $
2  *
3  * This file is part of the VIRCAM Pipeline
4  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jim $
23  * $Date: 2010-09-09 12:09:57 $
24  * $Revision: 1.4 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include <cpl.h>
34 
35 #include "imcore.h"
36 #include "floatmath.h"
37 #include "util.h"
38 
39 #define NACC 10
40 #define NCOEF 4
41 
44 /*---------------------------------------------------------------------------*/
87 /*---------------------------------------------------------------------------*/
88 
89 extern int extend(ap_t *ap, float xniso, float xbar, float ybar, float sxx,
90  float sxy, float syy, float areal0, float tmax,
91  float *ttotal) {
92  float srr,ecc,xx,ctheta,stheta,a,b,stretch,rad,sfac,climsq,clim;
93  float pt1,pt2,pt3,c,pa,pb,pc,arg1,xliml,xlimu,y,t,x,xnew,ynew,ellrad;
94  float xmax,xlim1,xlim2,xcord[NACC],xdat[NACC],polycf[NCOEF],rt1,rt2,t1;
95  float xlimit,theta,accum[NACC],*map,skysig,thresh;
96  int jmin,jmax,imax,imin,jj,kk,ii,iupd,j,i,ir,nx,ny;
97  unsigned char *mflag;
98 
99  /* Initialise a few things */
100 
101  map = ap->indata;
102  nx = ap->lsiz;
103  ny = ap->csiz;
104  skysig = ap->sigma;
105  thresh = ap->thresh;
106  mflag = ap->mflag;
107 
108  /* Calculate the eccentricity and position angle of the object */
109 
110  srr = MAX(0.5,sxx+syy);
111  ecc = sqrtf((syy-sxx)*(syy-sxx) + 4.0*sxy*sxy)/srr;
112  ecc = MIN(0.9,ecc);
113  xx = 0.5*(1.0 + ecc)*srr - sxx;
114  if (sxy == 0)
115  theta = 0.0;
116  else
117  if (xx == 0.0)
118  theta = CPL_MATH_PI_2;
119  else
120  theta = atanf(sxy/xx);
121  ctheta = cos(theta);
122  stheta = sin(theta);
123 
124  /* Eccentricity modified by noise effect. NB: 50 == 16*pi */
125 
126  ecc = sqrtf(MAX((syy-sxx)*(syy-sxx)
127  - 16.0*CPL_MATH_PI*skysig*srr*srr*srr/(xniso*xniso)
128  + 4.0*sxy*sxy,0.0))/srr;
129  ecc = MIN(0.9,ecc);
130 
131  /* Set initial aperture to be isophotal area */
132 
133  a = sqrtf(srr*(1.0 + ecc));
134  b = sqrtf(srr*(1.0 - ecc));
135  stretch = sqrt(areal0/(CPL_MATH_PI*a*b));
136 
137  /* Number of isophotal radii to extend */
138 
139  rad = MAX(1.1,(tmax - skysig)/thresh);
140  sfac = MIN(5.0,MAX(2.0,3.0/sqrtf(logf(rad))));
141  a *= sfac*stretch;
142  b *= sfac*stretch;
143 
144  /* Clear accumulator */
145 
146  memset(accum,0,NACC*sizeof(float));
147 
148  /* Generate image boundaries. First for y */
149 
150  climsq = (a*ctheta)*(a*ctheta) + (b*stheta)*(b*stheta);
151  climsq = MAX(1.0,climsq);
152  clim = sqrtf(climsq);
153  pt1 = sinf(2.0*theta)*(b*b-a*a);
154  pt2 = (b*ctheta)*(b*ctheta) + (a*stheta)*(a*stheta);
155  pt3 = (a*b)*(a*b);
156  jmin = MAX(1,(int)(ybar - clim));
157  jmax = MIN(ny,(int)(ybar + clim + 1.0));
158  for (jj = jmin; jj <= jmax; jj++) {
159 
160  /* Now for x */
161 
162  kk = (jj-1)*nx;
163  c = (float)jj - ybar;
164  pa = climsq;
165  pb = pt1*c;
166  pc = pt2*c*c - pt3;
167  arg1 = pb*pb - 4.0*pa*pc;
168  arg1 = sqrtf(MAX(arg1,0.0));
169  xliml = (-pb - arg1)/(2.0*pa);
170  xlimu = (-pb + arg1)/(2.0*pa);
171  imin = MAX(1,(int)(xbar + xliml));
172  imax = MIN(nx,(int)(xbar + xlimu + 1.0));
173  y = c;
174  for(ii = imin; ii <= imax; ii++) {
175  if (mflag[kk+ii-1] == MF_CLEANPIX || mflag[kk+ii-1] == MF_OBJPIX ||
176  mflag[kk+ii-1] == MF_SATURATED) {
177  t = map[kk+ii-1];
178  x = (float)ii - xbar;
179 
180  /* Accumulate elliptical isophotal areas */
181 
182  xnew = x*ctheta - y*stheta;
183  ynew = x*stheta + y*ctheta;
184  ellrad = 2.0*sqrtf((ynew/a)*(ynew/a) + (xnew/b)*(xnew/b));
185  iupd = ((int)((2.0-ellrad)*(float)NACC)) + 1;
186  iupd = MAX(1,iupd);
187  iupd = MIN(NACC,iupd);
188  for(j = 1; j <= iupd; j++)
189  accum[NACC-j] += t;
190  }
191  }
192  }
193 
194  /* Now find limiting intensity */
195 
196  if (xniso < 0.0)
197  for(i = 0; i < NACC; i++)
198  accum[i] = -accum[i];
199  median(accum,NACC,3);
200  xmax = 0.0;
201  xlim1 = -1.0;
202  xlim2 = -1.0;
203  for(i = 0; i < NACC; i++) {
204  xcord[i] = i+1;
205  xmax = MAX(xmax,accum[i]);
206  xdat[i] = accum[i];
207  }
208  polynm(xdat,xcord,NACC,polycf,NCOEF,0);
209  pa = polycf[1];
210  pb = polycf[2]*2.0;
211  pc = polycf[3]*3.0;
212  arg1 = sqrtf(MAX(0.0,pb*pb - 4.0*pa*pc));
213  if (pc != 0.0) {
214  rt1 = (-pb + arg1)/(2.0*pc);
215  rt2 = (-pb - arg1)/(2.0*pc);
216  if(rt1 < (float)NACC && rt1 > 1.0) {
217  ir = (int)rt1;
218  t1 = rt1 - (float)ir;
219  xlim1 = (1.0 - t1)*accum[ir-1] + t1*accum[ir];
220  }
221  if(rt2 < (float)NACC && rt2 > 1.0) {
222  ir = (int)rt2;
223  t1 = rt2 - ir;
224  xlim2 = (1.0 - t1)*accum[ir-1] + t1*accum[ir];
225  }
226  }
227  xlimit = MAX(xlim1,xlim2);
228  if(xlimit < 0.0)
229  xlimit = xmax;
230 
231  /* Update total intensity */
232 
233  if(xniso < 0.0)
234  xlimit = -xlimit;
235  *ttotal = xlimit;
236  return(VIR_OK);
237 }
238 
241 /*
242 
243 $Log: not supported by cvs2svn $
244 Revision 1.3 2009/09/09 09:42:25 jim
245 modified to use CPL defined macros for constants
246 
247 Revision 1.2 2009/01/23 12:24:33 jim
248 Fixed bugs in pixel flagging
249 
250 Revision 1.1 2005/09/13 13:25:29 jim
251 Initial entry after modifications to make cpl compliant
252 
253 
254 */