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-14738: Support DCR-matched templates for image differencing #93

Merged
merged 3 commits into from Aug 7, 2018

Conversation

isullivan
Copy link
Contributor

No description provided.

@@ -0,0 +1,350 @@
# This file is part of pipe_tasks.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment is false.

@@ -0,0 +1,619 @@
# This file is part of pipe_tasks.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment is false

Defaults to 1.0, which gives equal weight to both solutions.
"""
# Calculate weighted averages of the image and variance planes.
# Note that ``newModel *= gain`` would multiply the variance by ``gain**2``
Copy link
Contributor

Choose a reason for hiding this comment

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

If it works, it works, but its is still not obvious WHY multiplying gain**2 and dividing by (1+ gain)**2 would be bad when you're averaging two images:

>>> var1 = 25
>>> var2 = 0.4
>>> s1 = np.random.normal(2, np.sqrt(var1), 10000)
>>> s2 = np.random.normal(3, np.sqrt(var2), 10000)
>>> (var1 + var2)/4.
6.35
>>> np.var(0.5*(s1+s2))
6.4071829805944898

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using gain**2 would work fine as long as gain=1., but otherwise it biases the variance. And, since this algorithm is iterative that means that it gets progressively higher (or lower) with each iteration. The way it is written ensures that the variance does not drift high or low just from running for more iterations. I'll add more explanation to the comment.

model.image.array[badPixels] = 0.
model.variance.array[badPixels] = 0.
model.image.array /= dcrNumSubfilters
model.variance.array /= dcrNumSubfilters
Copy link
Contributor

Choose a reason for hiding this comment

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

Really divide by dcrNumSubfilters not dcrNumSubfilters**2?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe so, yes. Since the subfilter images are treated as independent, when we divide an image into N subfilters I think each should be treated as having less information, and sqrt(N) worse signal to noise. I will add unit tests in DM-15342 and DM-15343 that will test this and hopefull clarify the expected behavior.

if not sensorRef.datasetExists(**patchArgDict):
self.log.warn("%(datasetType)s, tract=%(tract)s, patch=%(patch)s does not exist"
% patchArgDict)
continue

nPatchesFound += 1
Copy link
Contributor

Choose a reason for hiding this comment

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

nPatchesFound was incremented if the patch was found by the butler. This way if there was no data to make a template, it would raise. I think you meant to put your block that reads or builds a patch above nPatchedFound += 0.

self.log.info("Reading patch %s" % patchArgDict)
coaddPatch = sensorRef.get(**patchArgDict)
coaddExposure.getMaskedImage().assign(coaddPatch.getMaskedImage(), coaddPatch.getBBox())
if self.config.coaddName == 'dcr':
Copy link
Contributor

Choose a reason for hiding this comment

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

I not crazy about the "if dcr do these three things else do these other three things." It's fine for now, but will you help me refactor it per RFC-352 soon?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I quite agree that the "if dcr..." block is ugly, and I would strongly welcome any suggestions for how to change it. One possibility would be to modify the butler so that coaddPatch = sensorRef.get(**patchArgDict) would know to calculate and return the same thing as the DcrModel calculations, but I worry that would look surprising and magic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am also happy to help implement RFC-352 if that is useful, though DcrModel here is not a Task, so I'm not sure what needs to be done.

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant that I plan to refactor GetCoaddAsTemplateTask. I might need to create a DcrModel with your fromImage interface rather than your fromDataRef interface, and might need advice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it. Yes, I will of course be happy to help with that refactor.

continue
self.log.info("Reading patch %s" % patchArgDict)
coaddPatch = sensorRef.get(**patchArgDict)
coaddExposure.maskedImage.assign(coaddPatch.maskedImage, coaddPatch.getBBox())
Copy link
Member

Choose a reason for hiding this comment

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

Is this equivalent to coaddExposure.maskedImage[coaddPatch.getBBox()] = coaddPatch.maskedImage? If so, that'd be clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe it is equivalent in this instance, but I'd like to leave this as it is for consistency with assembleCoadd. If you'd like that changed, I (or someone else) could do that on a separate ticket for both ip_diffim and pipe_tasks, and possibly other packages as well.

@isullivan isullivan merged commit 4aca173 into master Aug 7, 2018
@ktlim ktlim deleted the tickets/DM-14738 branch August 25, 2018 06:44
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

3 participants