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;
99 float xbar,
float ybar,
float total,
int npix,
102 int npl,ipix,ipixo2,npl2,nbitprev,nobj,toomany,i,isnew,k,kk,j,ibitx[IMNUM];
103 int ibity[IMNUM],iwas,iupdate[IMNUM],npl3,iter,lastone,ic,jj;
104 int ii,conv,ipks[IMNUM][2];
105 float fconst,offset,tmul,smul,xintmn,itmaxlim,algthr,radmax,xb,yb,radius2;
106 float results[IMNUM][NPAR+1],distmax,dx,dy,parmnew[IMNUM][NPAR],sumint;
107 float xlevol,radold,slope,xx,xlevel,radius,xdat[NAREAL+1],xcor[NAREAL+1];
108 float dlbydr,wt,dist,xeff,polycf[3],ttt,radthr,delb,deli,ratio;
109 float bitx[IMNUM],bitl[IMNUM],sxx,syy;
119 offset = ap->areal_offset;
127 ipixo2 = MAX(2,(ipix + 1)/2);
128 xintmn = oldthr*ipixo2;
131 algthr = logf(oldthr);
132 radmax = sqrtf(((
float)npix)/CPL_MATH_PI);
141 curthr = smul*oldthr;
142 sort_on_zsm_rev(npl,pl);
145 while (pl[npl2].zsm > curthr && npl2 < npl-1)
167 ap2.areal_offset = offset;
169 ap2.mflag = cpl_calloc((ap2.lsiz)*(ap2.csiz),
sizeof(
unsigned char*));
177 nexthr = MAX(curthr+oldthr,curthr*tmul);
183 check_term(&ap2,&nobj,results,ipks,&toomany);
191 for (i = 0; i < nobj; i++) {
201 sxx = MAX(1.0,results[i][4]);
202 syy = MAX(1.0,results[i][6]);
203 for (k = 0; k < nbitprev; k++) {
204 dx = xb - parm[k][1];
205 dy = yb - parm[k][2];
206 radius2 = dx*dx/sxx + dy*dy/syy;
207 if ((ibitx[k] == ipks[i][0] && ibity[k] == ipks[i][1]) ||
210 for (kk = 0; kk < NPAR; kk++)
211 parmnew[k][kk] = results[i][kk];
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];
242 if (*nbit > nbitprev && nbitprev > 0) {
243 for (i = 0; i < nbitprev; i++)
245 for (j = nbitprev; j < *nbit; j++) {
248 for (i = 0; i < nbitprev; i++) {
249 if (parmnew[i][0] > 0.0) {
250 dx = parmnew[i][1] - parm[i][1];
251 dy = parmnew[i][2] - parm[i][2];
252 radius2 = dx*dx + dy*dy;
253 if (radius2 > distmax) {
261 for (i = 0; i < nbitprev; i++)
262 if (iupdate[i] == 1 && parmnew[i][0] > 0.0)
263 for (j = 0; j < NPAR; j++)
264 parm[i][j] = parmnew[i][j];
269 for (i = 0; i <= *nbit; i++)
270 parmnew[i][0] = -1.0;
278 while (pl[npl3].zsm > nexthr && npl3 < npl2-1)
284 if (npl2 == 0 || toomany || nexthr >= itmaxlim)
305 for (k = 0; k < *nbit; k++) {
310 if (parm[k][0] > xintmn) {
313 for (i = 0; i < NPAR; i++)
314 parm[j][i] = parm[k][i];
318 for (j = 0; j < *nbit; j++) {
329 while (iter < NITER) {
334 for (k = 0; k < *nbit; k++) {
335 if (parm[k][0] < 0.0)
337 xlevol = logf(parm[k][7] + parm[k][3] - bitl[k]);
343 for (i = 1; i <= NAREAL; i++) {
346 xx = (float)ii + offset;
347 if (parm[k][jj] > 0.5) {
349 xlevel = logf(parm[k][3] - bitl[k] + 0.5);
351 xlevel = logf(powf(2.0,xx) - oldthr + parm[k][3] -
353 radius = sqrt(parm[k][jj]/CPL_MATH_PI);
356 dlbydr = (xlevol - xlevel)/MAX(0.01,radius-radold);
357 wt = MIN(1.0,MAX((radius-radold)*5.0,0.1));
358 slope = (1.0 - 0.5*wt)*slope + 0.5*wt*MIN(5.0,dlbydr);
368 for (i = 0; i < *nbit; i++) {
369 if (parm[i][0] >= 0.0 && i != k) {
370 dx = parm[k][1] - parm[i][1];
371 dy = parm[k][2] - parm[i][2];
372 dist = sqrtf(dx*dx + dy*dy);
373 xeff = xlevel - MAX(0.0,MIN(50.0,slope*(dist-radius)));
374 bitx[i] += expf(xeff);
383 imcore_polynm(xdat,xcor,ic,polycf,3,0);
384 ttt = polycf[1] + 2.0*polycf[2]*radius;
387 slope = MAX(0.1,MAX(-ttt,slope));
388 radthr = radius + (xlevel - algthr)/slope;
389 if (radthr > radmax) {
396 delb = parm[k][8]*(parm[k][3] - bitl[k]);
397 parm[k][8] = CPL_MATH_PI*radthr*radthr;
401 parm[k][7] += (parm[k][3] - bitl[k]);
405 deli = 2.0*CPL_MATH_PI*((parm[k][3] - bitl[k])*(1.0 + slope*radius) -
406 oldthr*(1.0 + slope*radthr))/(slope*slope);
407 parm[k][0] += delb + MAX(0.0,deli);
408 for (i = 0; i < 7; i++)
410 if (parm[k][0] > xintmn)
411 sumint += parm[k][0];
421 for (i = 0; i < *nbit; i++) {
422 if (parm[i][0] >= 0.0) {
423 if (fabs(bitx[i] - bitl[i]) > 3.0)
427 bitl[i] = MIN(bitl[i],NINT(parm[i][3]-oldthr));
430 lastone = (conv || (iter == NITER-1));
442 ratio = total/sumint;
443 for (i = 0; i < *nbit; i++)
444 parm[i][0] = ratio*parm[i][0];
469 static void sort_on_zsm_rev(
int npts, plstruct *pts) {
476 jj = MIN(npts,(3*jj)/4-1);
480 for (ii = 0; ii < ifin; ii++) {
483 if (pts[i].zsm > pts[j].zsm)
492 }
while (pts[i].zsm <= tmp.zsm);
522 static void moments_thr(ap_t *ap,
float results[NPAR+1],
int ipk[2]) {
524 float x,y,xoff,yoff,xsum,ysum,xsumsq,ysumsq,tsum,xysum,t,tmax,twelfth;
525 float xbar,ybar,sxx,syy,sxy,fconst,offset,xsum_w,ysum_w,wsum,w;
531 offset = ap->areal_offset;
532 plarray = ap->plarray;
548 tmax = plarray[0].z - curthr;
549 ipk[0] = plarray[0].x;
550 ipk[1] = plarray[0].y;
552 for (i = 8; i < NPAR; i++)
558 for (i = 0; i < np; i++) {
559 x = (float)plarray[i].x - xoff;
560 y = (float)plarray[i].y - yoff;
561 t = plarray[i].z - curthr;
562 w = plarray[i].zsm - curthr;
571 xsumsq += (x*x + twelfth)*t;
572 ysumsq += (y*y + twelfth)*t;
574 update_ov(results+8,t,oldthr,fconst,offset);
576 ipk[0] = plarray[i].x;
577 ipk[1] = plarray[i].y;
593 sxx = MAX(0.0,(xsumsq/tsum-xbar*xbar));
594 syy = MAX(0.0,(ysumsq/tsum-ybar*ybar));
595 sxy = xysum/tsum - xbar*ybar;
596 wsum = MAX(1.0,wsum);
601 xbar = MAX(1.0,MIN(xbar,ap->lsiz));
602 ybar = MAX(1.0,MIN(ybar,ap->csiz));
613 results[NPAR] = ((nnext > ap->ipnop && nexthr < lasthr) ? 0 : 1);
643 static void update_ov(
float iap[NAREAL],
float t,
float thresh,
float fconst,
654 nup = MAX(1,MIN(NAREAL,(
int)(logf(t+thresh)*fconst-offset)+1));
655 for (i = 0; i < nup; i++)
687 static void check_term(ap_t *ap,
int *nobj,
float parm[IMNUM][NPAR+1],
688 int peaks[IMNUM][2],
int *toomany) {
690 float momresults[NPAR+1];
696 for (ip = 1; ip <= ap->maxip; ip++) {
697 if (ap->parent[ip].pnop != -1) {
702 if ((ap->parent[ip].pnop >= ap->ipnop &&
703 ap->parent[ip].touch == 0)) {
705 moments_thr(ap,momresults,ipks);
706 if (momresults[0] > 0.0) {
707 if (*nobj == IMNUM-1) {
711 for (i = 0; i <= NPAR; i++)
712 parm[*nobj][i] = momresults[i];
713 for (i = 0; i < 2; i++)
714 peaks[*nobj][i] = ipks[i];
void imcore_apclust(ap_t *ap, int np, plstruct *plstr)
Detect multiple objects from a given Plessey array.
void imcore_extract_data(ap_t *ap, int ip)
Put data into the Plessey array for an object.
void imcore_apclose(ap_t *ap)
Close ap structure.
void imcore_restack(ap_t *ap, int ip)
Free information for an object from the ap structure.
void imcore_apreinit(ap_t *ap)
Re-initialise the ap structure.
void imcore_overlp(ap_t *ap, float parm[IMNUM][NPAR], int *nbit, float xbar, float ybar, float total, int npix, float tmax)
Deblend overlapping images.
void imcore_apinit(ap_t *ap)
Initialise the ap structure.