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-42828: Add camera team crosstalk nonlinearity results #319

Merged
merged 20 commits into from
Apr 29, 2024
Merged

Conversation

plazas
Copy link
Contributor

@plazas plazas commented Apr 12, 2024

No description provided.

@plazas plazas requested a review from czwa April 12, 2024 19:03
Copy link
Contributor

@czwa czwa left a comment

Choose a reason for hiding this comment

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

Some comments, and I think there are details in the application step that need checking.

self.coeffErr = np.zeros(self.crosstalkShape)
self.coeffNum = np.zeros(self.crosstalkShape, dtype=int)
self.coeffValid = np.ones(self.crosstalkShape, dtype=bool)

Copy link
Contributor

Choose a reason for hiding this comment

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

This should initialize self.coeffsSqr as well.

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 do that in the next line:

# Quadratic terms, if any.
        self.coeffsSqr = np.zeros(self.crosstalkShape) if self.nAmp else None
        self.coeffErrSqr = np.zeros(self.crosstalkShape) if self.nAmp else None

Are you suggesting something else?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I found that up in the init. It should do it here as well. It'd be annoying to init with one nAmp value, and then re-initialize everything with the length of the detector, but I think the detector is more likely to be correct, and the other entries are re-initialized here.

# Add the nonlinear term
doSqrCrosstalk = self.config.doQuadraticCrosstalkCorrection
if doSqrCrosstalk and crosstalkCoeffsSqr is not None:
sImage.scaledPlus(coeffsSqr[ss, tt], tImage*tImage)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we do need a unit test for this. This step in particular is worrying to me. I know there are some math operations that an afw Image prevents to avoid allocating a new image in memory, and I thought multiplication like this was one of them (which is why there is scaledPlus, as that's an in-place operation).

Copy link
Contributor

Choose a reason for hiding this comment

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

If we're adding gain ratios, those also need to be applied at this step (and for the linear portion as well) if we're working in ADU.
The case for if doSqrCrosstalk and crosstalkCoeffsSqr is None should raise, but I'm not sure where that should be located. I think way down on line 904.
Finally, I don't think this method has access to self.config, as that's attached to the task, but this method is part of the calibration.

Copy link
Contributor Author

@plazas plazas Apr 17, 2024

Choose a reason for hiding this comment

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

This step in particular is worrying to me.

Yes, I think that tImage**tImage won't work, thanks for pointing that out. Is this your only worry with this line, or do you think that the use of scalePlus here is not adequate either?

Copy link
Contributor

Choose a reason for hiding this comment

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

scalePlus should be fine, as that's an in-place operator. I think you can do one operation outside of the loop:

mi2 = mi.clone()
mi2.scaledMultiplies(1.0, mi)

and pull the squared version as tImage2 = self.extractAmp(mi2, tAmp, sAmp, isTrimmed).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, thanks, I made some changes and pushed them.

self.ampGainRatios = np.zeros(self.crosstalkShape) if self.nAmp else None

# Units
self.crosstalkRatiosUnits = 'electrons' if self.nAmp else None
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious about this choice.

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 was just because the coefficients provided by Adam in this ticket are in those units. I'm happy to set the default to ADU, is that what we want? @erykoff

Copy link
Contributor

Choose a reason for hiding this comment

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

So the proper unit name is electron not electrons. (This should be fixed elsewhere as well). Adam's crosstalk coefficients were computed after applying gain so they are in units of electrons and not ADU. However, I don't think this should necessarily be the default if unspecified (though Chris should answer if previous crosstalk matrices were generated before or after gain correction).

Copy link
Contributor

Choose a reason for hiding this comment

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

(The proper unit name for ADU is adu)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@czwa, should we set the default to ADU? (adu in the code).

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 chaged the defalt to adu. Does "proper" mean "as in astropy", in this context?

Copy link
Contributor

Choose a reason for hiding this comment

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

All existing CT has been measured pre-gain application, without flats, so I think they should be in ADU.

Copy link
Contributor

@czwa czwa left a comment

Choose a reason for hiding this comment

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

One small addition that should hopefully not cause any problems.

@@ -384,7 +456,8 @@ def toTable(self):

if self.interChip:
interChipTable = Table([{'IC_SOURCE_DET': sourceDet,
'IC_COEFFS': self.interChip[sourceDet].reshape(self.nAmp*self.nAmp)}
'IC_COEFFS':
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a line length thing?

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 changed it a bit now. maybe it was black?

isr.crosstalk.run(self.exposure, crosstalk=calib)
self.checkSubtracted(self.exposure)

def testTaskAPI_NL(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you duplicate this test and have it use the IsrTaskLSST to get the config and the task? This should "Just Work," but I'd rather have a test that checks that the two tasks give the same results (the crosstalk task should be identical, so this is just checking that all of the config mechanics are working the same).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I had to add IsrTaskLSST to the __init__ in ip/isr in a separate commit so I could import it from the test. Tagging @aferte as a heads-up.

@plazas plazas merged commit 06d8191 into main Apr 29, 2024
2 checks passed
@plazas plazas deleted the tickets/DM-42828 branch April 29, 2024 18:00
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