37 #include "floatmath.h"
41 static void moments_thr(ap_t *,
float [],
int []);
42 static void sort_on_zsm_rev(
int, plstruct *);
43 static void update_ov(
float [],
float,
float,
float,
float);
44 static void check_term(ap_t *,
int *,
float [IMNUM][NPAR+1],
int [IMNUM][2],
51 static float xbar_start;
52 static float ybar_start;
98 extern void overlp(ap_t *ap,
float parm[IMNUM][NPAR],
int *nbit,
float xbar,
99 float ybar,
float total,
int npix,
float tmax) {
101 int npl,ipix,ipixo2,npl2,nbitprev,nobj,toomany,i,isnew,k,kk,j,ibitx[IMNUM];
102 int ibity[IMNUM],ibitl[IMNUM],iwas,iupdate[IMNUM],npl3,iter,lastone,ic,jj;
103 int ii,conv,ipks[IMNUM][2];
104 float fconst,offset,tmul,smul,xintmn,itmaxlim,algthr,radmax,xb,yb,radius2;
105 float results[IMNUM][NPAR+1],distmax,dx,dy,parmnew[IMNUM][NPAR],sumint;
106 float xlevol,radold,slope,xx,xlevel,radius,xdat[NAREAL+1],xcor[NAREAL+1];
107 float dlbydr,wt,dist,xeff,polycf[3],ttt,radthr,delb,deli,ratio;
108 float bitx[IMNUM],bitl[IMNUM],sxx,syy;
118 offset = ap->areal_offset;
126 ipixo2 = MAX(2,(ipix + 1)/2);
127 xintmn = oldthr*ipixo2;
130 algthr = logf(oldthr);
131 radmax = sqrtf(((
float)npix)/CPL_MATH_PI);
140 curthr = smul*oldthr;
141 sort_on_zsm_rev(npl,pl);
144 while (pl[npl2].zsm > curthr && npl2 < npl-1)
166 ap2.areal_offset = offset;
168 ap2.mflag = cpl_calloc((ap2.lsiz)*(ap2.csiz),
sizeof(
unsigned char*));
176 nexthr = MAX(curthr+oldthr,curthr*tmul);
182 check_term(&ap2,&nobj,results,ipks,&toomany);
190 for (i = 0; i < nobj; i++) {
200 sxx = MAX(1.0,results[i][4]);
201 syy = MAX(1.0,results[i][6]);
202 for (k = 0; k < nbitprev; k++) {
203 dx = xb - parm[k][1];
204 dy = yb - parm[k][2];
205 radius2 = dx*dx/sxx + dy*dy/syy;
206 if ((ibitx[k] == ipks[i][0] && ibity[k] == ipks[i][1]) ||
209 for (kk = 0; kk < NPAR; kk++)
210 parmnew[k][kk] = results[i][kk];
211 ibitl[k] = (int)results[i][NPAR];
222 if (isnew && results[i][0] > xintmn) {
223 if (*nbit >= IMNUM) {
228 ibitx[*nbit] = ipks[i][0];
229 ibity[*nbit] = ipks[i][1];
230 for (kk = 0; kk < NPAR; kk++)
231 parm[*nbit][kk] = results[i][kk];
232 ibitl[*nbit] = (int)results[i][NPAR];
243 if (*nbit > nbitprev && nbitprev > 0) {
244 for (i = 0; i < nbitprev; i++)
246 for (j = nbitprev; j < *nbit; j++) {
249 for (i = 0; i < nbitprev; i++) {
250 if (parmnew[i][0] > 0.0) {
251 dx = parmnew[i][1] - parm[i][1];
252 dy = parmnew[i][2] - parm[i][2];
253 radius2 = dx*dx + dy*dy;
254 if (radius2 > distmax) {
262 for (i = 0; i < nbitprev; i++)
263 if (iupdate[i] == 1 && parmnew[i][0] > 0.0)
264 for (j = 0; j < NPAR; j++)
265 parm[i][j] = parmnew[i][j];
270 for (i = 0; i <= *nbit; i++)
271 parmnew[i][0] = -1.0;
279 while (pl[npl3].zsm > nexthr && npl3 < npl2-1)
285 if (npl2 == 0 || toomany || nexthr >= itmaxlim)
306 for (k = 0; k < *nbit; k++) {
311 if (parm[k][0] > xintmn) {
314 for (i = 0; i < NPAR; i++)
315 parm[j][i] = parm[k][i];
319 for (j = 0; j < *nbit; j++) {
330 while (iter < NITER) {
335 for (k = 0; k < *nbit; k++) {
336 if (parm[k][0] < 0.0)
338 xlevol = logf(parm[k][7] + parm[k][3] - bitl[k]);
344 for (i = 1; i <= NAREAL; i++) {
347 xx = (float)ii + offset;
348 if (parm[k][jj] > 0.5) {
350 xlevel = logf(parm[k][3] - bitl[k] + 0.5);
352 xlevel = logf(powf(2.0,xx) - oldthr + parm[k][3] -
354 radius = sqrt(parm[k][jj]/CPL_MATH_PI);
357 dlbydr = (xlevol - xlevel)/MAX(0.01,radius-radold);
358 wt = MIN(1.0,MAX((radius-radold)*5.0,0.1));
359 slope = (1.0 - 0.5*wt)*slope + 0.5*wt*MIN(5.0,dlbydr);
369 for (i = 0; i < *nbit; i++) {
370 if (parm[i][0] >= 0.0 && i != k) {
371 dx = parm[k][1] - parm[i][1];
372 dy = parm[k][2] - parm[i][2];
373 dist = sqrtf(dx*dx + dy*dy);
374 xeff = xlevel - MAX(0.0,MIN(50.0,slope*(dist-radius)));
375 bitx[i] += expf(xeff);
384 polynm(xdat,xcor,ic,polycf,3,0);
385 ttt = polycf[1] + 2.0*polycf[2]*radius;
388 slope = MAX(0.1,MAX(-ttt,slope));
389 radthr = radius + (xlevel - algthr)/slope;
390 if (radthr > radmax) {
397 delb = parm[k][8]*(parm[k][3] - bitl[k]);
398 parm[k][8] = CPL_MATH_PI*radthr*radthr;
402 parm[k][7] += (parm[k][3] - bitl[k]);
406 deli = 2.0*CPL_MATH_PI*((parm[k][3] - bitl[k])*(1.0 + slope*radius) -
407 oldthr*(1.0 + slope*radthr))/(slope*slope);
408 parm[k][0] += delb + MAX(0.0,deli);
409 for (i = 0; i < 7; i++)
411 if (parm[k][0] > xintmn)
412 sumint += parm[k][0];
422 for (i = 0; i < *nbit; i++) {
423 if (parm[i][0] >= 0.0) {
424 if (abs(bitx[i] - bitl[i]) > 3.0)
428 bitl[i] = MIN(bitl[i],NINT(parm[i][3]-oldthr));
431 lastone = (conv || (iter == NITER-1));
443 ratio = total/sumint;
444 for (i = 0; i < *nbit; i++)
445 parm[i][0] = ratio*parm[i][0];
470 static void sort_on_zsm_rev(
int npts, plstruct *pts) {
477 jj = MIN(npts,(3*jj)/4-1);
481 for (ii = 0; ii < ifin; ii++) {
484 if (pts[i].zsm > pts[j].zsm)
493 }
while (pts[i].zsm <= tmp.zsm);
523 static void moments_thr(ap_t *ap,
float results[NPAR+1],
int ipk[2]) {
525 float x,y,xoff,yoff,xsum,ysum,xsumsq,ysumsq,tsum,xysum,t,tmax,twelfth;
526 float xbar,ybar,sxx,syy,sxy,fconst,offset,xsum_w,ysum_w,wsum,w;
532 offset = ap->areal_offset;
533 plarray = ap->plarray;
549 tmax = plarray[0].z - curthr;
550 ipk[0] = plarray[0].x;
551 ipk[1] = plarray[0].y;
553 for (i = 8; i < NPAR; i++)
559 for (i = 0; i < np; i++) {
560 x = (float)plarray[i].x - xoff;
561 y = (float)plarray[i].y - yoff;
562 t = plarray[i].z - curthr;
563 w = plarray[i].zsm - curthr;
572 xsumsq += (x*x + twelfth)*t;
573 ysumsq += (y*y + twelfth)*t;
575 update_ov(results+8,t,oldthr,fconst,offset);
577 ipk[0] = plarray[i].x;
578 ipk[1] = plarray[i].y;
594 sxx = MAX(0.0,(xsumsq/tsum-xbar*xbar));
595 syy = MAX(0.0,(ysumsq/tsum-ybar*ybar));
596 sxy = xysum/tsum - xbar*ybar;
597 wsum = MAX(1.0,wsum);
602 xbar = MAX(1.0,MIN(xbar,ap->lsiz));
603 ybar = MAX(1.0,MIN(ybar,ap->csiz));
614 results[NPAR] = ((nnext > ap->ipnop && nexthr < lasthr) ? 0 : 1);
644 static void update_ov(
float iap[NAREAL],
float t,
float thresh,
float fconst,
655 nup = MAX(1,MIN(NAREAL,(
int)(logf(t+thresh)*fconst-offset)+1));
656 for (i = 0; i < nup; i++)
688 static void check_term(ap_t *ap,
int *nobj,
float parm[IMNUM][NPAR+1],
689 int peaks[IMNUM][2],
int *toomany) {
691 float momresults[NPAR+1];
697 for (ip = 1; ip <= ap->maxip; ip++) {
698 if (ap->parent[ip].pnop != -1) {
703 if ((ap->parent[ip].pnop >= ap->ipnop &&
704 ap->parent[ip].touch == 0)) {
706 moments_thr(ap,momresults,ipks);
707 if (momresults[0] > 0.0) {
708 if (*nobj == IMNUM-1) {
712 for (i = 0; i <= NPAR; i++)
713 parm[*nobj][i] = momresults[i];
714 for (i = 0; i < 2; i++)
715 peaks[*nobj][i] = ipks[i];
void overlp(ap_t *ap, float parm[IMNUM][NPAR], int *nbit, float xbar, float ybar, float total, int npix, float tmax)
Deblend overlapping images.
void apreinit(ap_t *ap)
Re-initialise the ap structure.
void apclose(ap_t *ap)
Close ap structure.
void apclust(ap_t *ap, int np, plstruct *plstr)
Detect multiple objects from a given Plessey array.
void restack(ap_t *ap, int ip)
Free information for an object from the ap structure.
void extract_data(ap_t *ap, int ip)
Put data into the Plessey array for an object.
void apinit(ap_t *ap)
Initialise the ap structure.