/* Build the object structure. */ void lutzsort(infostruct *info, objliststruct *objlist) { objstruct *obj = objlist->obj+objlist->nobj; memset(obj, 0, (size_t)sizeof(objstruct)); obj->firstpix = info->firstpix; obj->lastpix = info->lastpix; obj->flag = info->flag; objlist->npix += info->pixnb; preanalyse(objlist->nobj, objlist, ANALYSE_FAST); objlist->nobj++; return; }
/* build the object structure. */ void sortit(picstruct *field, picstruct *dfield, picstruct *wfield, picstruct *dwfield, infostruct *info, objliststruct *objlist, PIXTYPE *cdwscan, PIXTYPE *wscan) { picstruct *cfield; objliststruct objlistout, *objlist2; static objstruct obj; objstruct *cobj; pliststruct *pixel; int i,j,n; cfield = dfield? dfield: field; pixel = objlist->plist; objlistout.obj = NULL; objlistout.plist = NULL; objlistout.nobj = objlistout.npix = 0; /*----- Allocate memory to store object data */ objlist->obj = &obj; objlist->nobj = 1; memset(&obj, 0, (size_t)sizeof(objstruct)); objlist->npix = info->pixnb; obj.firstpix = info->firstpix; obj.lastpix = info->lastpix; obj.flag = info->flag; obj.dthresh = objlist->dthresh; obj.thresh = objlist->thresh; preanalyse(0, objlist, ANALYSE_FAST); /*----- Check if the current strip contains the lower isophote... */ if ((int)obj.ymin < cfield->ymin) obj.flag |= OBJ_ISO_PB; if (!(obj.flag & OBJ_OVERFLOW) && (createsubmap(objlist, 0) == RETURN_OK)) { if (parcelout(objlist, &objlistout) == RETURN_OK) objlist2 = &objlistout; else { objlist2 = objlist; for (i=0; i<objlist2->nobj; i++) objlist2->obj[i].flag |= OBJ_DOVERFLOW; sprintf(gstr, "%.0f,%.0f", obj.mx+1, obj.my+1); warning("Deblending overflow for detection at ", gstr); } free(obj.submap); } else objlist2 = objlist; for (i=0; i<objlist2->nobj; i++) { preanalyse(i, objlist2, ANALYSE_FULL|ANALYSE_ROBUST); if (prefs.ext_maxarea && objlist2->obj[i].fdnpix > prefs.ext_maxarea) continue; analyse(field, dfield, i, objlist2); cobj = objlist2->obj + i; if (prefs.blank_flag) { if (createblank(objlist2,i) != RETURN_OK) { /*------ Not enough mem. for the BLANK vignet: flag the object now */ cobj->flag |= OBJ_OVERFLOW; cobj->blank = cobj->dblank = NULL; sprintf(gstr, "%.0f,%.0f", cobj->mx+1, cobj->my+1); warning("Memory overflow during masking for detection at ", gstr); } } if ((n=cleanobjlist->nobj) >= prefs.clean_stacksize) { objstruct *cleanobj; int ymin, ymax, victim=0; ymin = 2000000000; /* No image is expected to be that tall ! */ cleanobj = cleanobjlist->obj; for (j=0; j<n; j++, cleanobj++) if (cleanobj->ycmax < ymin) { victim = j; ymin = cleanobj->ycmax; } /*---- Warn if there is a possibility for any aperture to be truncated */ if (field->ymax < field->height) { cleanobj = &cleanobjlist->obj[victim]; if ((ymax=cleanobj->ycmax) > field->ymax) { sprintf(gstr, "Object at position %.0f,%.0f ", cleanobj->mx+1, cleanobj->my+1); QWARNING(gstr, "may have some apertures truncated:\n" " You might want to increase MEMORY_OBJSTACK"); } else if (ymax>field->yblank && prefs.blank_flag) { sprintf(gstr, "Object at position %.0f,%.0f ", cleanobj->mx+1, cleanobj->my+1); QWARNING(gstr, "may have some unBLANKed neighbours\n" " You might want to increase MEMORY_OBJSTACK"); } } endobject(field, dfield, wfield, dwfield, victim, cleanobjlist); subcleanobj(victim); } /* Only add the object if it is not swallowed by cleaning */ if (!prefs.clean_flag || clean(field, dfield, i, objlist2)) addcleanobj(cobj); } free(objlistout.plist); free(objlistout.obj); return; }
void analyse(int no, objliststruct *objlist, int robust, double gain) { objstruct *obj = &objlist->obj[no]; pliststruct *pixel = objlist->plist, *pixt; PIXTYPE peak, val, cval; double thresh,thresh2, t1t2,darea, mx,my, mx2,my2,mxy, rv, rv2, tv, xm,ym, xm2,ym2,xym, temp,temp2, theta,pmx2,pmy2, errx2, erry2, errxy, cvar, cvarsum; int x, y, xmin, ymin, area2, dnpix; preanalyse(no, objlist); dnpix = 0; mx = my = tv = 0.0; mx2 = my2 = mxy = 0.0; cvarsum = errx2 = erry2 = errxy = 0.0; thresh = obj->thresh; peak = obj->dpeak; rv = obj->fdflux; rv2 = rv * rv; thresh2 = (thresh + peak)/2.0; area2 = 0; xmin = obj->xmin; ymin = obj->ymin; for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix)) { x = PLIST(pixt,x)-xmin; /* avoid roundoff errors on big images */ y = PLIST(pixt,y)-ymin; /* avoid roundoff errors on big images */ cval = PLISTPIX(pixt, cdvalue); tv += (val = PLISTPIX(pixt, value)); if (val>thresh) dnpix++; if (val > thresh2) area2++; mx += cval * x; my += cval * y; mx2 += cval * x*x; my2 += cval * y*y; mxy += cval * x*y; } /* compute object's properties */ xm = mx / rv; /* mean x */ ym = my / rv; /* mean y */ /* In case of blending, use previous barycenters */ if ((robust) && (obj->flag & SEP_OBJ_MERGED)) { double xn, yn; xn = obj->mx-xmin; yn = obj->my-ymin; xm2 = mx2 / rv + xn*xn - 2*xm*xn; ym2 = my2 / rv + yn*yn - 2*ym*yn; xym = mxy / rv + xn*yn - xm*yn - xn*ym; xm = xn; ym = yn; } else { xm2 = mx2 / rv - xm * xm; /* variance of x */ ym2 = my2 / rv - ym * ym; /* variance of y */ xym = mxy / rv - xm * ym; /* covariance */ } /* Calculate the errors on the variances */ for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix)) { x = PLIST(pixt,x)-xmin; /* avoid roundoff errors on big images */ y = PLIST(pixt,y)-ymin; /* avoid roundoff errors on big images */ cvar = PLISTEXIST(var)? PLISTPIX(pixt, var): 0.0; if (gain > 0.0) { /* add poisson noise if given */ cval = PLISTPIX(pixt, cdvalue); if (cval > 0.0) cvar += cval / gain; } /* Note that this works for both blended and non-blended cases * because xm is set to xn above for the blended case. */ cvarsum += cvar; errx2 += cvar * (x - xm) * (x - xm); erry2 += cvar * (y - ym) * (y - ym); errxy += cvar * (x - xm) * (y - ym); } errx2 /= rv2; erry2 /= rv2; errxy /= rv2; /* Handle fully correlated x/y (which cause a singularity...) */ if ((temp2=xm2*ym2-xym*xym)<0.00694) { xm2 += 0.0833333; ym2 += 0.0833333; temp2 = xm2*ym2-xym*xym; obj->flag |= SEP_OBJ_SINGU; /* handle it for the error parameters */ cvarsum *= 0.08333/rv2; if (errx2*erry2 - errxy * errxy < cvarsum * cvarsum) { errx2 += cvarsum; erry2 += cvarsum; } } if ((fabs(temp=xm2-ym2)) > 0.0) theta = atan2(2.0 * xym, temp) / 2.0; else theta = PI/4.0; temp = sqrt(0.25*temp*temp+xym*xym); pmy2 = pmx2 = 0.5*(xm2+ym2); pmx2+=temp; pmy2-=temp; obj->dnpix = (LONG)dnpix; obj->dflux = tv; obj->mx = xm+xmin; /* add back xmin */ obj->my = ym+ymin; /* add back ymin */ obj->mx2 = xm2; obj->errx2 = errx2; obj->my2 = ym2; obj->erry2 = erry2; obj->mxy = xym; obj->errxy = errxy; obj->a = (float)sqrt(pmx2); obj->b = (float)sqrt(pmy2); obj->theta = theta; obj->cxx = (float)(ym2/temp2); obj->cyy = (float)(xm2/temp2); obj->cxy = (float)(-2*xym/temp2); darea = (double)area2 - dnpix; t1t2 = thresh/thresh2; /* debugging */ /*if (t1t2>0.0 && !PLISTEXIST(thresh)) */ /* was: prefs.dweight_flag */ if (t1t2 > 0.0) { obj->abcor = (darea<0.0?darea:-1.0)/(2*PI*log(t1t2<1.0?t1t2:0.99) *obj->a*obj->b); if (obj->abcor>1.0) obj->abcor = 1.0; } else { obj->abcor = 1.0; } return; }