-
Notifications
You must be signed in to change notification settings - Fork 269
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
Variance calibration #2636
base: main
Are you sure you want to change the base?
Variance calibration #2636
Conversation
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
thanks for putting this together @ctoennis! In case I'm not missing something, I think we can (maybe should) apply this |
@TjarkMiener Yes, that should work. The calibration events would only need the sqrt coeficcients. Only thing is that this needs to be documented somewhere. |
Though, the changes to the variance extractor should then still be kept so that it works with the calibrator. |
@@ -73,6 +79,15 @@ class CameraCalibrator(TelescopeComponent): | |||
help="Name of the ImageExtractor subclass to be used.", | |||
).tag(config=True) | |||
|
|||
image_calibration_type = CaselessStrEnum( |
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.
see l.66
if ( | ||
self.apply_peak_time_shift.tel[tel_id] | ||
and remaining_shift is not None | ||
and self.image_calibration_type == "charge" |
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.
Do we really need to alter this condition?
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.
The variance extractor has no peak time, so applying the peak time shift otherwise throws an error
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.
Just check if dl1.peak_time is not None
instead of a specific extractor.
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.
@maxnoe that makes sense
calibrator(example_event) | ||
image = example_event.dl1.tel[tel_id].image | ||
assert image is not None | ||
assert image.shape == (1764,) |
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.
from where this shape comes? What telescope is 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.
That is from the example event. Not sure what telescope this is
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.
FlashCam from the number of pixels
src/ctapipe/image/extractor.py
Outdated
@@ -1308,7 +1308,7 @@ def __call__( | |||
self, waveforms, tel_id, selected_gain_channel, broken_pixels | |||
) -> DL1CameraContainer: | |||
container = DL1CameraContainer( | |||
image=np.nanvar(waveforms, dtype="float32", axis=2), | |||
image=np.nanvar(waveforms, dtype="float32", axis=2)[0], |
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.
We shall be able to work with multiple gains, why do you introduce this change?
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.
np.nanvar was giving me an extra dimension on top of the gain. I think I can fix this with the keepdims parameter
if self.image_calibration_type == "charge": | ||
dl1.image *= dl1_calib.relative_factor / dl1_calib.absolute_factor | ||
elif self.image_calibration_type == "variance": | ||
dl1.image *= np.sqrt( | ||
dl1_calib.relative_factor / dl1_calib.absolute_factor | ||
) |
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 could check here if the extractor.__class__.__name__
is VarianceExtractor
rather than passing the specific config parameter.
This comment has been minimized.
This comment has been minimized.
src/ctapipe/image/extractor.py
Outdated
@@ -1308,7 +1308,7 @@ def __call__( | |||
self, waveforms, tel_id, selected_gain_channel, broken_pixels | |||
) -> DL1CameraContainer: | |||
container = DL1CameraContainer( | |||
image=np.nanvar(waveforms, dtype="float32", axis=2), | |||
image=np.nanvar(waveforms, dtype="float32", keepdims=False, axis=2), |
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.
A bit weird that you need to set keepdims=False
explicitly, but ok.
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 will check again if i make it work without 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.
Should work without it:
x = np.random.uniform(size=(2,1800, 1000))
In [1]: np.nanvar(x, axis=2).shape
Out[2]: (2, 1800)
In [2]: np.nanvar(x, axis=2, keepdims=True).shape
Out[2]: (2, 1800, 1)
In [3]: np.nanvar(x, axis=2, keepdims=False).shape
Out[3]: (2, 1800)
calibrator(example_event) | ||
image = example_event.dl1.tel[tel_id].image | ||
assert image is not None | ||
assert image.shape == ( |
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.
Add a test with the LST (two gains)
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
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.
would it make sense to add a test for other extractor with the LST?
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 could use a parametrized test here to test all telescope types. (@pytest.mark.parametrized
). See for example the code in ctapipe/instrument/tests/test_telescope.py
This comment has been minimized.
This comment has been minimized.
docs/changes/2636.features.rst
Outdated
@@ -0,0 +1 @@ | |||
Makes changes to the CameraCalibrator in ctapipe.calib.camera.calibrator that allows it to correctly variance images generated with the VarianceExtractor |
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 describe the actual change, not just say "there are changes". Also there is a verb missing here (calibrate?)
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 added some explanation
You still need the peak_time check, right? |
Oh yes, that will be still needed |
I discussed with @mexanick offline yesterday. We might not want to run the tool for computing camera calibration coefficients twice and store two separated files (one for comics; one for pointing calibration), just to square one column here. What do you think? |
at least for now, I would avoid recomputation of the calibrations just for variance. With the current code, we can always have this possibility to test, if needed. |
calibrator(example_event) | ||
image = example_event.dl1.tel[tel_id].image | ||
assert image is not None | ||
assert image.shape == ( |
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 could use a parametrized test here to test all telescope types. (@pytest.mark.parametrized
). See for example the code in ctapipe/instrument/tests/test_telescope.py
i will change the test to check all cameras |
@kosack I used the camera_geometry fixture instead to check for all cameras. In the end I just need the geometry, so that should work well. |
I think there is an issue with the recent change to the changelog check (#2637). |
i switched it to a parametrized test for the different cameras now and caught the other test for name and switched it to isinstance |
if ( | ||
self.apply_peak_time_shift.tel[tel_id] | ||
and remaining_shift is not None | ||
and dl1.peak_time is not None |
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.
logically, I'd put the dl1.peak_time is not None
check first
This PR adds a trait to the CameraCalibrator called "image_calibration_type". This trait allows to switch the method of calibration between "charge" and "variance", with the former being the calibration method for the existing image extractors and the latter being the method to calibrate variance images.
I also made some small adjustment to the variance extractor so that it works in the CameraCalibrator.