An OBJC is the entire object in its polychromatic glory, while
an OBJECT1 is the measured object in just one of the bands.
Reading the following description will be easier if you have a nodding acquaintance with the frames pipeline, but it should be useful to all.
This is due to the object being to close to the edge to extract a profile at the local center and OBJECT1_EDGE is also set.
OBJECT1_EDGE objects will have OBJECT1_NODEBLEND set, and the object will not be deblended.
If OBJECT1_EDGE is set in any band, it will be set for the OBJC. Children inherit this flag.
If OBJECT1_EDGE is set in any band, it will be set for all bands, and for the OBJC itself.
If, while running the deblender, it so happens that only one child remains, this flag is turned off.
This flag is inherited by children.
This flag is inherited by the OBJC.
This flag is inherited by the OBJC.
This flag is propagated to the OBJC.
(OBJECT1_BINNED1 | OBJECT1_BINNED2 | OBJECT1_BINNED4) [28,29,30]
OBJC,
while object1 refers to an OBJECT1.
You are expected to imagine a loop over all filters, setting flags
as appropriate.
The following pseudo-code roughly corresponds to the organisation of the frames pipeline, and bears some resemblence to C. The following idioms are used:
The numbers in the right hand margin refer to the previous section, where the individual flags are described.
find_objects
{
if(pixels over threshold touch edge of frame) {
object1->flags |= OBJECT1_EDGE; [2]
}
if(object includes unsearched pixels (e.g. unsmoothed edges of frames)) {
object1->flags |= OBJECT1_NOTCHECKED; [19]
reject all peaks in NOTCHECKED parts of frame;
}
/*
* information about which mode object was detected in
*/
if(bright objects) {
object1->flags |= OBJECT1_BRIGHT; [1]
}
if(not binned) {
object1->flags |= OBJECT1_BINNED1; [28]
} else if(binned 2x2) {
object1->flags |= OBJECT1_BINNED2; [29]
} else if(binned 4x4) {
object1->flags |= OBJECT1_BINNED4; [30]
}
/*
* information about pixels contained in object
*/
if(object contains interpolated pixels) {
object1->flags |= OBJECT1_INTERP; [17]
if(object contains cosmic ray contaminated pixels) {
object1->flags |= OBJECT1_CR; [12]
}
if(object contains saturated pixels after centering on peak) {
object1->flags |= OBJECT1_SATUR; [18]
}
}
}
find_centre
{
if(saturated and saturated star centroider fails) {
object1->flags |= OBJECT1_PEAKCENTER; [5]
}
if(too close to edge while searching for peak) {
object1->flags |= OBJECT1_EDGE | OBJECT1_PEAKCENTER; [2,5]
}
if(object has vanishing second derviative) {
object1->flags |= OBJECT1_PEAKCENTER; [5]
}
if(object1->flags & OBJECT1_PEAKCENTER) { [5]
take centre of brightest pixel as peak position;
}
}
merge_colors
{
if(more than one peaks is detected within an object in one band) {
objc->flags |= OBJECT1_BLENDED; [3]
}
if(distinct peaks found in different bands of same object) {
objc->flags |= OBJECT1_BLENDED; [3]
}
if(multiple distinct peaks in merged objects) {
objc->flags |= OBJECT1_BLENDED; [3]
}
}
subtract_bright_stars
{
if(object contains pixels from which star wings were subtracted) {
object1->flags |= OBJECT1_SUBTRACTED; [20]
}
if(object is in part of frame where bright star wings exceeded 10 sky sigma,
or star wings increased variance by more than 50%) {
object1->flags |= OBJECT1_NOTCHECKED; [19]
}
}
measure_objects
{
/*
* book keeping
*/
if(detected as a bright object) {
if(being remeasured after faint object detection) {
make new object which is sibling of bright object;
unset OBJECT1_BRIGHT in objc and object1; [1]
}
}
create_object1s {
objc->flags |= object1->flags & OBJECT1_BLENDED; [3]
}
/*
* extract profile
*/
if(failed to extract radial profile) {
object1->flags |= OBJECT1_EDGE | OBJECT1_NOPETRO | OBJECT1_NOPROFILE;
give up measuring object in this band; [2,7,8]
}
if(pixel overflow while extracting radial profile) {
object1->flags |= OBJECT1_SATUR; [18]
}
if(object is still detected at edge of extracted profile (about 260arcsec)){
object1->flags |= OBJECT1_TOO_LARGE; [24]
}
if(measured profile includes points with a S/N <= 0) {
object1->flags |= OBJECT1_BAD_RADIAL; [15]
}
if(central value of object more than 100 sigma below sky level) {
object1->flags |= OBJECT1_BADSKY | OBJECT1_NOPETRO; [8,22]
give up measuring object in this band; something is horribly wrong.
}
if(radial profile has fewer than two points) {
object1->flags |= OBJECT1_NOPROFILE; [7]
object1->flags |=
OBJECT1_NOPETRO | OBJECT1_ELLIPFAINT | OBJECT1_NOSTOKES;
give up measuring Petrosian quantities, Stokes parameters, and
isophotal quantities; [8,21,27]
}
/*
* measure a few misc quantities
*/
if(central surface brightness is below threshold for isophotal shape ||
failed to fit ellipse at threshold +- delta) {
object1->flags |= OBJECT1_ELLIPFAINT; [27]
give up fitting ellipse;
}
if(failed to measure U or Q due to numerical difficulties) {
object1->flags |= OBJECT1_NOSTOKES; [21]
}
/*
* measure Petrosian quantities
*/
while(surface brightness at innermost candidate for Petrosian radius
is too low) {
reject candidate;
object1->flags |= OBJECT1_PETROFAINT; [23]
}
if(there are no Petrosian radii) {
object1->flags |= OBJECT1_NOPETRO; [8]
if(we didn't reject any candidates for the Petrosian radius) {
object1->flags |= OBJECT1_NOPETRO_BIG; [10]
use outermost point in radial profile as "Petrosian" radius;
} else {
use fallback value for "Petrosian" radius;
}
} else {
if(there is more than one Petrosian radius) {
object1->flags |= OBJECT1_MANYPETRO; [9]
}
}
if(more than one value of Petrosian 50% light radius) {
object1->flags |= OBJECT1_MANYR50; /* how can this happen? */ [13]
}
if(more than one value of Petrosian 90% light radius) {
object1->flags |= OBJECT1_MANYR90; /* how can this happen? */ [14]
}
if(object is less than one (r') Petrosian radius from edge of frame) {
object1->flags |= OBJECT1_INCOMPLETE_PROFILE; [16]
}
/*
* Measure quantities about the centre determined in this band
*/
if(local band is too close to the edge of the frame) {
object1->flags |= OBJECT1_CANONICAL_CENTER | OBJECT1_EDGE; [0][2]
use (transformed) canonical center;
}
/*
* mark measured as a bright object
*/
if(measuring bright objects) {
objc->flags |= OBJECT1_BRIGHT; [1]
}
/*
* propagate flags to and from OBJC
*/
if(objc->flags & OBJECT1_BLENDED) { [3]
object1->flags |= OBJECT1_BLENDED; [3]
}
objc->flags |= object1->flags & (OBJECT1_EDGE | [2]
OBJECT1_BLENDED | [3]
OBJECT1_CHILD | [4]
OBJECT1_NOPETRO | [8]
OBJECT1_MANYPETRO | [9]
OBJECT1_INTERP | [17]
OBJECT1_CR | [12]
OBJECT1_SATUR | [18]
OBJECT1_NOTCHECKED | [19]
OBJECT1_BINNED1 | [28]
OBJECT1_BINNED2 | [29]
OBJECT1_BINNED4); [30]
}
deblender
{
if(there are too many peaks in object) {
objc->flags |= OBJECT1_NODEBLEND | OBJECT1_DEBLEND_TOO_MANY_PEAKS; [6,11]
give up deblending;
}
make_new_child_from_objc {
child->flags = objc->flags & (OBJECT1_EDGE | [2]
OBJECT1_PEAKCENTER | [5]
OBJECT1_INTERP | [17]
OBJECT1_NOTCHECKED | [19]
OBJECT1_SUBTRACTED); [20]
child->flags |= OBJECT1_CHILD; [4]
child_object1->flags = object1->flags & (OBJECT1_EDGE | [2]
OBJECT1_PEAKCENTER | [5]
OBJECT1_NOTCHECKED | [19]
OBJECT1_SUBTRACTED); [20]
child_object1->flags |= (OBJECT1_CHILD & ~OBJECT1_DETECTED); [4,32]
child_object1->flags |= OBJECT1_BINNED1; [28]
}
phObjcDeblend {
if(objc->flags & (OBJECT1_EDGE)) { [2,18]
objc->flags |= OBJECT1_NODEBLEND; [6]
give up, as saturation invalidates assumptions made by deblender;
}
if(child is consistent with PSF) {
child_object1->flags |= OBJECT1_DEBLENDED_AS_PSF; [25]
}
deblend_template_find {
if(template for this child is too large (more than half a frame)) {
objc->parent->flags |= OBJECT1_TOO_LARGE | OBJECT1_NODEBLEND;[6,24]
give up on deblending parent;
}
if(template hangs over edge of frame in any band) {
objc->parent->flags |= OBJECT1_EDGE | OBJECT1_NODEBLEND; [2,6]
give up on deblending parent;
}
if(failed to find template in this band) {
object1->flags &= ~OBJECT1_DETECTED; [32]
object1->flags |= OBJECT1_DEBLENDED_AS_PSF; [25]
}
objc->flags |= object1->flags & OBJECT1_DETECTED; [32]
}
if(only one child remains) {
objc->flags &= ~OBJECT1_BLENDED; [3]
no need to deblend;
}
if(at least one possible child is rejected due to singular matrix) {
objc->flags |= OBJECT1_DEBLEND_PRUNED; [26]
object1->flags |= OBJECT1_DEBLEND_PRUNED; [26]
}
if(child includes saturated pixels) {
object1->flags |= OBJECT1_SATUR | OBJECT1_INTERP; [17,18]
}
}
}