-
Notifications
You must be signed in to change notification settings - Fork 21
DM-53312: Robustify the calibrateImage background estimation #1187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| dtype=float, | ||
| default=3.0, | ||
| doc="Maximum pedestal allowable in star_background measurement. If the computed value " | ||
| "exceeds this value, the background pedestal will be set to this value.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the units? Just whatever the post_isr units are?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I didn't want to put units that for some reason may be different than our standard processing...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just quote "in image units" or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now gone.
| origMask = result.exposure.mask.clone() | ||
| bad_mask_planes = ["BAD", "EDGE", "NO_DATA"] | ||
| if "PARTLY_VIGNETTED" in result.exposure.mask.getMaskPlaneDict().keys(): | ||
| bad_mask_planes += ["PARTLY_VIGNETTED"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I love this being here, baked in. This code always ignores the background in the partly vignetted region? What if we want to use this area in coadds in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is just ignoring it in the background estimation. Yusra suggested it and it seemed like a good idea since the S/N (and hence the nature of the detections) seems to go haywire in vignetted regions, so best not to trust them in the background measurement? You are the expert here, so if you think it should go, I will remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, since this is a pedestal this does seem reasonable and doesn't preclude using the partly vignetted region in the coadds. The only problem is ... of course ... the corner detectors which are all partly vignetted. These aren't in DRP tests now, but they are processed regularly in RA/NV/etc at least. What happens then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried running on detectors 0 and 20. The latter took a hot minute, but they both succeeded...which doesn't seem to make a whole lot of sense, but perhaps there are "just enough" pixels not marked as PARTLY_VIGNETTED. Do you have a strong feeling either way? We have never ignored this plane before, so it may be best not to rock that boat. Also, blinking my before & after plots, the outermost region of the focal plane seems entirely unaffected. Ok...I'm leaning towards dropping it for now....thoughts?
| dtype=int, | ||
| default=3, | ||
| doc="Minimum number of footprints in the detection mask for star_background measurement. " | ||
| "This number will get adjusted to 1 percent of the detected peaks if that number " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1% is always the right value and doesn't need to be configurable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I can't guarantee that, I can say that I needed it this high to get to where I needed in many cases, and any higher and it would crap out (either just by imposing an unattainable Goldilocks Zone, or running out of iterations).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does make me a little nervous ... can you make this configurable in case this needs to be tweaked?
| starBackgroundDetectionConfig.thresholdValue = 1.2*currentThresh | ||
| if nFootprintTemp < minFootprints and detected_fraction > 0.9*maxDetFracForFinalBg: | ||
| if nFootprintTemp == 1: | ||
| starBackgroundDetectionConfig.thresholdValue = 1.4*currentThresh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does 1.4 (and 1.2) come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trial and error and a trade-off between "get there faster" and "don't overshoot". The detection plane can be disturbingly sensitive to small tweaks in the threshold, but when there's only a single footprint, a bigger increase is usually needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love that but ... sure at the moment...
| "maximum allowed (%.2f). Setting it to %.2f", | ||
| pedestalBackgroundLevel, self.config.star_background_max_pedestal, | ||
| self.config.star_background_max_pedestal) | ||
| pedestalBackgroundLevel = self.config.star_background_max_pedestal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure you want to set this to the limit and not zero? In amp offsets, the assumption was "do no harm" and it should be uncorrected assuming something has gone terribly wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's debatable...if you think zero is better, I'm ok with going that way (again, this hasn't been hitting, so I'll have to check against the full run, which is sure to hit edge cases to make an informed call).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave this up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failsafes are now gone...
| self.config.star_background_max_pedestal) | ||
| pedestalBackgroundLevel = self.config.star_background_max_pedestal | ||
|
|
||
| self.log.warning("Subtracted pedestalBackgroundLevel = %.4f", pedestalBackgroundLevel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change this to an info level log. If this is normal operations, it's not a warning.
| pedestalBackground = afwMath.BackgroundList() | ||
| pedestalBackground.append(pedestalBackgroundList[1]) | ||
| pedestalBackgroundLevel = pedestalBackground.getImage().array[0, 0] | ||
| if pedestalBackgroundLevel > self.config.star_background_max_pedestal: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized this is wrong ... this needs to be an absolute value, and the sign preserved if you're setting to the max.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's not symmetric (as we discussed in slack).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, then please add an opposite polarity (as we discussed). And these should probably be set to some fraction of the median background rather than a fixed constant.
8ec80b7 to
ae9cedc
Compare
This is to have it available as a mask to avoid when measuring the exposure background in calibrateImage.
ae9cedc to
9547542
Compare
| doc="Minimum pedestal allowable in star_background measurement, represented here " | ||
| "as a fraction (the negative of the absolute) of the initial median background " | ||
| "already subtracted. If the computed value is smaller than this value, the " | ||
| "background pedestal will be se to this value.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
se -> set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are gone (for now, at least...will follow up after the next DRP to see if failsafe's are actually needed).
| star_background_peak_fraction = pexConfig.Field( | ||
| dtype=float, | ||
| default=0.01, | ||
| doc="The minimum number of footprints in the detection mask for star_background measurement. " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This docstring was copied and isn't correct for the config.
| median_background = np.median(backgroundOrig.getImage().array) | ||
| self.log.warning("Original median_background = %.2f", median_background) | ||
| median_background_orig = np.median(backgroundOrig.getImage().array) | ||
| self.log.info("Original median_background = %.2f", median_background_orig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for converting to an info on this one! Also ... have we checked at how long this operation takes? In my experience background.getImage() is surprisingly slow. (Not to solve today; but something to consider for the future).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. On the TODO list...
| origMask = result.exposure.mask.clone() | ||
| bad_mask_planes = ["BAD", "EDGE", "NO_DATA"] | ||
| if "PARTLY_VIGNETTED" in result.exposure.mask.getMaskPlaneDict().keys(): | ||
| bad_mask_planes += ["PARTLY_VIGNETTED"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any thoughts on this?
| self.log.info("nIter = %d, thresh = %.2f: Fraction of pixels marked as DETECTED or " | ||
| "DETECTED_NEGATIVE in star_background_detection = %.3f " | ||
| "(max is %.3f; min is %.3f)", | ||
| "(max is %.3f; min is %.3f) nFooprint = %d (current min is %d)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nFooprint -> nFootprint.
| pedestalBackgroundLevel, minPedestal, minPedestal) | ||
| pedestalBackgroundLevel = minPedestal | ||
|
|
||
| self.log.info("Subtracted pedestalBackgroundLevel = %.4f", pedestalBackgroundLevel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So ... I'm confused how this even works now. Does this change the value inside the background list?
pedestalBackground = afwMath.BackgroundList()
pedestalBackground.append(pedestalBackgroundList[1])
pedestalBackgroundLevel = pedestalBackground.getImage().array[0, 0]
And then ... it's already been subtracted by the task ... so this won't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're so right (and thanks for catching this!). Going with dropping the failsafes for now (will follow-up after the next DRP run).
This includes ensuring a minimum number of footprints in the bespoke background measurement detection task (if there is only a single large contiguous footprint, this indicates that the threshold is too low and will bias the background measurement to unrepresentative values) and adding the SPIKE mask plane to avoid in the background estimation.
9547542 to
e7279b0
Compare
erykoff
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you decided to leave off the PARTLY_VIGNETTED? I think that makes sense for now; further investigation will be required to know exactly what it's doing for the corners.
Also, please change the title of the PR to describe what is actually happening here -- what and not why.
No description provided.