20#include "hdrl_cat_overlp.h"
22#include "hdrl_cat_apio.h"
23#include "hdrl_cat_apclust.h"
24#include "hdrl_cat_polynm.h"
25#include "hdrl_cat_terminate.h"
26#include "hdrl_cat_utils_sort.h"
41static double xbar_start;
42static double ybar_start;
47static void moments_thr(ap_t *ap,
double results[NPAR+1], cpl_size ipk[2]);
48static void update_ov(
double iap[NAREAL],
double t,
double thresh,
double fconst,
double offset);
49static void check_term( ap_t *ap, cpl_size *nobj,
double parm[IMNUM][NPAR+1],
50 cpl_size peaks[IMNUM][2], cpl_size *toomany);
52static int cmp_plstruct(
const void *a,
const void *b);
89 ap_t *ap,
double parm[IMNUM][NPAR], cpl_size *nbit,
90 double xbar,
double ybar,
double total, cpl_size npix,
double tmax)
93 plstruct *pl = ap->plarray;
94 cpl_size npl = ap->npl_pix;
95 cpl_size ipix = ap->ipnop;
96 double fconst = ap->fconst;
97 double offset = ap->areal_offset;
104 double tmul = 1.2589678;
106 cpl_size ipixo2 = CPL_MAX(2, (ipix + 1) / 2);
107 double xintmn = oldthr * ipixo2;
108 double itmaxlim = 0.9 * tmax;
111 curthr = smul * oldthr;
126 while (npl2 < npl - 1 && pl[npl2].zsm > curthr) {
130 if (npl2 > IDBLIM) curthr += oldthr;
138 return CPL_ERROR_NONE;
147 ap2.areal_offset = offset;
149 ap2.mflag = cpl_calloc((ap2.lsiz) * (ap2.csiz),
sizeof(*ap2.mflag));
157 cpl_size ibitx[IMNUM];
158 cpl_size ibity[IMNUM];
160 cpl_size iupdate[IMNUM];
161 double parmnew[IMNUM][NPAR];
163 cpl_size nbitprev = 0;
166 nexthr = CPL_MAX(curthr + oldthr, curthr * tmul);
173 double results[IMNUM][NPAR+1];
174 cpl_size ipks[ IMNUM][2];
176 check_term(&ap2, &nobj, results, ipks, &toomany);
186 for (cpl_size i = 0; i < nobj; i++) {
195 double xb = results[i][1];
196 double yb = results[i][2];
197 double sxx = CPL_MAX(1., results[i][4]);
198 double syy = CPL_MAX(1., results[i][6]);
200 for (cpl_size k = 0; k < nbitprev; k++) {
202 double dx = xb - parm[k][1];
203 double dy = yb - parm[k][2];
205 double radius2 = dx * dx / sxx + dy * dy / syy;
207 if ( (ibitx[k] == ipks[i][0] && ibity[k] == ipks[i][1]) || radius2 < 1.) {
211 for (cpl_size kk = 0; kk < NPAR; kk++) {
212 parmnew[k][kk] = results[i][kk];
225 if (isnew && results[i][0] > xintmn) {
227 if (*nbit >= IMNUM) {
235 ibitx[*nbit] = ipks[i][0];
236 ibity[*nbit] = ipks[i][1];
238 for (cpl_size kk = 0; kk < NPAR; kk++) {
239 parm[*nbit][kk] = results[i][kk];
254 if (*nbit > nbitprev && nbitprev > 0) {
256 for (cpl_size i = 0; i < nbitprev; i++) iupdate[i] = 0;
258 for (cpl_size j = nbitprev; j < *nbit; j++) {
263 for (cpl_size i = 0; i < nbitprev; i++) {
265 if (parmnew[i][0] > 0.) {
267 double radius2 = pow(parmnew[i][1] - parm[i][1], 2.) + pow(parmnew[i][2] - parm[i][2], 2.);
269 if (radius2 > distmax) {
278 for (cpl_size i = 0; i < nbitprev; i++) {
279 if (iupdate[i] == 1 && parmnew[i][0] > 0.) {
280 for (cpl_size j = 0; j < NPAR; j++) parm[i][j] = parmnew[i][j];
286 for (cpl_size i = 0; i <= *nbit; i++) {
294 while (npl3 < npl2-1 && pl[npl3].zsm > nexthr) {
300 if (npl2 == 0 || toomany || nexthr >= itmaxlim) {
317 npix, curthr, nexthr, lasthr);
319 return CPL_ERROR_NONE;
347 ap_t *ap,
double parm[IMNUM][NPAR], cpl_size *nbit,
348 double xbar,
double ybar,
double total, cpl_size npix,
349 double curthr_prev,
double nexthr_prev,
double lasthr_prev)
352 cpl_size ipix = ap->ipnop;
353 double offset = ap->areal_offset;
356 curthr = curthr_prev;
357 nexthr = nexthr_prev;
358 lasthr = lasthr_prev;
363 cpl_size ipixo2 = CPL_MAX(2, (ipix + 1) / 2);
364 double xintmn = oldthr * ipixo2;
365 double algthr = log(oldthr);
366 double radmax = sqrt((
double)npix / CPL_MATH_PI);
370 for (cpl_size k = 0; k < *nbit; k++) {
374 if (parm[k][0] > xintmn) {
378 for (cpl_size i = 0; i < NPAR; i++) parm[j][i] = parm[k][i];
386 for (cpl_size jj = 0; jj < *nbit; jj++) {
392 double xdat[NAREAL + 1];
393 double xcor[NAREAL + 1];
394 cpl_size lastone = 0;
397 while (iter < NITER) {
402 for (cpl_size k = 0; k < *nbit; k++) {
404 if (parm[k][0] >= 0.) {
407 double xlevol = log(parm[k][7] + parm[k][3] - bitl[k]);
408 double xlevel = xlevol;
411 double radius = radold;
415 for (cpl_size i = 1; i <= NAREAL; i++) {
417 cpl_size jj = NPAR - i;
418 cpl_size ii = NAREAL - i;
420 double xx = (double)ii + offset;
422 if (parm[k][jj] > 0.5) {
425 xlevel = log(parm[k][3] - bitl[k] + 0.5);
427 xlevel = log(pow(2., xx) - oldthr + parm[k][3] - bitl[k] - 0.5);
430 radius = sqrt(parm[k][jj] / CPL_MATH_PI);
434 double dlbydr = (xlevol - xlevel) / CPL_MAX(0.01, radius - radold);
436 double wt = CPL_MIN(1., CPL_MAX((radius - radold) * 5., 0.1));
438 slope = (1. - 0.5 * wt) * slope + 0.5 * wt * CPL_MIN(5., dlbydr);
448 for (cpl_size i = 0; i < *nbit; i++) {
450 if (parm[i][0] >= 0.0 && i != k) {
452 double dist = sqrt(pow(parm[k][1] - parm[i][1], 2.) + pow(parm[k][2] - parm[i][2], 2.));
454 double xeff = xlevel - CPL_MAX(0., CPL_MIN(50., slope * (dist - radius)));
456 bitx[i] += exp(xeff);
467 ttt = polycf[1] + 2. * polycf[2] * radius;
472 slope = CPL_MAX(0.1, CPL_MAX(-ttt, slope));
474 double radthr = radius + (xlevel - algthr) / slope;
475 if (radthr > radmax) {
481 double delb = parm[k][8] * (parm[k][3] - bitl[k]);
482 parm[k][8] = CPL_MATH_PI * radthr * radthr;
485 parm[k][7] += (parm[k][3] - bitl[k]);
488 double deli = 2. * CPL_MATH_PI * ( (parm[k][3] - bitl[k]) * (1. + slope * radius)
489 - oldthr * (1. + slope*radthr)
492 parm[k][0] += delb + CPL_MAX(0., deli);
494 for (cpl_size i = 0; i < 7; i++) {
498 if (parm[k][0] > xintmn) {
499 sumint += parm[k][0];
512 for (cpl_size i = 0; i < *nbit; i++) {
514 if (parm[i][0] >= 0.) {
516 if (fabs(bitx[i] - bitl[i]) > 3.) conv = 0;
522 double a = parm[i][3] - oldthr;
523 bitl[i] = CPL_MIN(bitl[i], (cpl_size)(a + (a < 0 ? -0.5 : 0.5)));
529 lastone = (conv || (iter == NITER - 1));
537 if (sumint == 0.) *nbit = 1;
539 double ratio = total / sumint;
540 for (cpl_size i = 0; i < *nbit; i++) {
541 parm[i][0] = ratio * parm[i][0];
545 return CPL_ERROR_NONE;
563static void moments_thr(ap_t *ap,
double results[NPAR + 1], cpl_size ipk[2])
566 double fconst = ap->fconst;
567 double offset = ap->areal_offset;
568 plstruct *plarray = ap->plarray;
569 cpl_size np = ap->npl_pix;
572 double xoff = xbar_start;
573 double yoff = ybar_start;
583 double tmax = plarray[0].z - curthr;
585 ipk[0] = plarray[0].x;
586 ipk[1] = plarray[0].y;
588 for (cpl_size i = 8; i < NPAR; i++) {
594 for (cpl_size i = 0; i < np; i++) {
596 double x = (double)(plarray[i].x) - xoff;
597 double y = (double)(plarray[i].y) - yoff;
599 double t = plarray[i].z - curthr;
600 double w = plarray[i].zsm - curthr;
615 xsumsq += (x * x) * t;
616 ysumsq += (y * y) * t;
620 update_ov(results + 8, t, oldthr, fconst, offset);
624 ipk[0] = plarray[i].x;
625 ipk[1] = plarray[i].y;
640 double xbar = xsum / tsum;
641 double ybar = ysum / tsum;
643 double sxx = CPL_MAX(0., (xsumsq / tsum - xbar * xbar));
644 double syy = CPL_MAX(0., (ysumsq / tsum - ybar * ybar));
645 double sxy = xysum / tsum - xbar * ybar;
647 wsum = CPL_MAX(1., wsum);
649 xbar = xsum_w / wsum;
650 ybar = ysum_w / wsum;
655 xbar = CPL_MAX(1., CPL_MIN(xbar, ap->lsiz));
656 ybar = CPL_MAX(1., CPL_MIN(ybar, ap->csiz));
666 results[NPAR] = ((nnext > ap->ipnop && nexthr < lasthr) ? 0 : 1);
683static void update_ov(
double iap[NAREAL],
double t,
double thresh,
double fconst,
double offset)
689 cpl_size nup = CPL_MAX(1, CPL_MIN(NAREAL, (cpl_size)(log(t + thresh) * fconst - offset) + 1));
691 for (cpl_size i = 0; i < nup; i++) {
711static void check_term( ap_t *ap, cpl_size *nobj,
double parm[IMNUM][NPAR+1],
712 cpl_size peaks[IMNUM][2], cpl_size *toomany)
718 double momresults[NPAR + 1];
721 for (cpl_size ip = 1; ip <= ap->maxip; ip++) {
723 if (ap->parent[ip].pnop != -1) {
725 if ( ap->parent[ip].pnop >= ap->ipnop
726 && ap->parent[ip].touch == 0)
730 moments_thr(ap, momresults, ipks);
731 if (momresults[0] > 0.) {
733 if (*nobj == IMNUM - 1) {
738 for (cpl_size i = 0; i <= NPAR; i++) {
739 parm[*nobj][i] = momresults[i];
742 for (cpl_size i = 0; i < 2; i++) {
743 peaks[*nobj][i] = ipks[i];
755static int cmp_plstruct(
const void *a,
const void *b) {
757 const plstruct *a_d = (
const plstruct*)a;
758 const plstruct *b_d = (
const plstruct*)b;
761 return -(a_d->zsm < b_d->zsm ? -1 : (a_d->zsm > b_d->zsm ? 1 : 0));
void hdrl_apclust(ap_t *ap, cpl_size np, plstruct *plstr)
Detect multiple objects from a given Plessey array.
void hdrl_apinit(ap_t *ap)
Initialize the ap structure.
void hdrl_apreinit(ap_t *ap)
Re-initialize the ap structure.
void hdrl_apclose(ap_t *ap)
Close ap structure.
cpl_error_code hdrl_overlp(ap_t *ap, double parm[IMNUM][NPAR], cpl_size *nbit, double xbar, double ybar, double total, cpl_size npix, double tmax)
Deblend overlapping images.
cpl_error_code hdrl_overlp_2orMore(ap_t *ap, double parm[IMNUM][NPAR], cpl_size *nbit, double xbar, double ybar, double total, cpl_size npix, double curthr_prev, double nexthr_prev, double lasthr_prev)
Deblend overlapping images 2 or more. If you know that exist more than 1 (come to the previous versio...
cpl_error_code hdrl_polynm(double xdat[], double xcor[], cpl_size n, double polycf[], cpl_size m, cpl_size ilim)
Work out the median seeing.
void hdrl_restack(ap_t *ap, cpl_size ip)
Free information for an object from the ap structure.
void hdrl_extract_data(ap_t *ap, cpl_size ip)
Put data into the Plessey array for an object.
cpl_error_code sort_array_f(void *a, cpl_size nE, cpl_size sE, f_compare f)
sort_array_f Core sort algorith that it's called with the other sort function. If you need to changed...