Skip to content
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

DM-40507: Cleanup DipoleFitTask #305

Merged
merged 8 commits into from Mar 28, 2024
Merged

DM-40507: Cleanup DipoleFitTask #305

merged 8 commits into from Mar 28, 2024

Conversation

parejkoj
Copy link
Contributor

No description provided.

The loops made it hard to find where these keys were created, and there
are helpers to create flux and centroid keys with their associated
uncertainties automatically.
Using NO_UNCERTAINTY for centroids, to make it explicit that we don't
have uncertainties for these values right now.
* Naive* are purely examples and shouldn't be used in production
* Peak* are unnecessary with Psf and Dipole models and mostly for
testing purposes
* PsfDipoleFlux is slower than PsfDipoleFit (this task).
* PsfDipoleFit provides a dipole classification.
PsfDipoleFlux is the older, slower algorithm, but it makes a useful
check on the new PsfDipoleFit.
Copy link
Contributor

@isullivan isullivan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall. I am a little concerned that our fake source completeness gets a little worse when I run ap_verify with this ticket, but that is something for us to investigate further on another ticket.

self.doReplaceWithNoise = False


class DipoleFitTask(measBase.SingleFrameMeasurementTask):
"""A task that fits a dipole to a difference image, with an optional separate detection image.
"""A task that fits a dipole to a difference image, with an optional
separate detection image.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you are just reformatting this description, but I don't see where we support an optional separate detection image.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The posExp/negExp kwargs are what give this support.

@@ -1113,6 +1113,7 @@ def measureDipoles(self, measRecord, exposure, posExp=None, negExp=None):
):
measRecord.set(self.classificationFlagKey, False)
measRecord.set(self.classificationAttemptedFlagKey, False)
# TODO: Do we want to fail here, or just leave it marked as not fit?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@isullivan : this question still needs answering: I would lean towards not "failing" them, and just leaving them marked as not being attempted to be fit nor as dipoles.

Copy link
Contributor

@isullivan isullivan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. A few more comments and cleanups requested.

python/lsst/ip/diffim/dipoleFitTask.py Show resolved Hide resolved
plt.subplot(1, 3, 1)
display2dArray(z, 'Data', extent=extent)
plt.subplot(1, 3, 2)
display2dArray(fit, 'Model', extent=extent)
plt.subplot(1, 3, 3)
display2dArray(z - fit, 'Residual', extent=extent)
return fig
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove fig from the return? Note that it is still documented as the return value. Also the function display2dArray does still return fig, but that isn't used.

Copy link
Contributor Author

@parejkoj parejkoj Mar 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it was causing the show down below to not get used, and it wasn't used by anything. I've removed it from the docstring.

# Peaks are the same sign (not a dipole)
or (len(pks) > 1 and (np.sign(pks[0].getPeakValue())
or (nPeaks > 1 and (np.sign(pks[0].getPeakValue())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the peaks guaranteed to be ordered from largest positive peak to largest negative peak? I am concerned about checking pks[0] and pks[-1] explicitly, instead of sorting the peaks. If the peaks are sorted, please add a code comment stating that assumption.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, our convention is that peaks are always ordered from highest to lowest. This is a pretty deep convention and a lot of code depends on it.

python/lsst/ip/diffim/dipoleFitTask.py Show resolved Hide resolved
measRecord[self.posFluxErrKey] = result.signalToNoise # to be changed to actual sigma!
measRecord[self.posCentroidKeyX] = result.posCentroidX
measRecord[self.posCentroidKeyY] = result.posCentroidY
measRecord[self.posFluxKey.getInstFlux()] = result.posFlux
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realize this was how we needed to set by key!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one way. I think when this was written, the string-based method (measRecord["blah_instFlux"]) was much slower, which has since been mostly fixed. But having the keys in the plugin makes it easier, since you can just get the field key directly.

tests/test_detectAndMeasure.py Outdated Show resolved Hide resolved
@parejkoj parejkoj force-pushed the tickets/DM-40507 branch 2 times, most recently from 9e52b8b to 229a75a Compare March 28, 2024 01:01
* Enforce plugin order, so that DipoleFit can fall back on SdssCentroid
for non-dipoles.
* DipoleFitPlugin can run at "centroid" order, because it simultaneously fits
centroids and fluxes.
* Switch centroid slot after SdssCentroid, so that the "best" centroid
comes from DipoleFit (even if it's just copied over).
* Switch dipole centroid field names to better match centroid slot
convention (foo_x/foo_y, for plugin foo).
* Rename DipoleFitTask default name to match Task name convention.

Cleanup tests to pass with the better centroids:
* Loosen flux tolerance.
* Remove test of "unphysical" sources that relied on bad centroiding
pushing the sky sources off the image.
* Remove tests that relied on old centroider behavior when measuring
on unmerged footprints.

Refactor non-dipole "error" handling:
* No need to flag sources that were not fit as failures, they're already
marked as not dipoles.
* Handle "too large" footprints as failures separately from other non-
dipole sources.
* Remove redundant flag setting: some flags either default to False, or were
set just above.
We want the debug logs to appear if the loglevel is DEBUG.
Plot display was broken because `show()` never got called!
@parejkoj parejkoj merged commit eb961e4 into main Mar 28, 2024
2 checks passed
@parejkoj parejkoj deleted the tickets/DM-40507 branch March 28, 2024 05:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants