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

Muon parameters update #2670

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft

Muon parameters update #2670

wants to merge 12 commits into from

Conversation

jstvdk
Copy link
Contributor

@jstvdk jstvdk commented Dec 10, 2024

I added new functionality to the muon analysis as described in the Issue #2665 , specifically

  • new fields to the MuonParametersContainer
  • new methods to the ctapipe/image/muon/features.py
  • new tests for above mentioned methods in ctapipe/image/muon/tests/test_muon_features.py
  • additional code block in ctapipe/image/muon/processor.py to process and save new muon parameters

Added changes mainly follow existing code in lstchain/image/muon/muon_analysis.py, with one exception:

  • I redefined the variable num_pixels_in_ring - now it takes into account only pixels that survived the cleaning, contrary to what currently implemented in lstchain, where this variable contains all pixels inside the geometrical area of the ring.

@mexanick mexanick marked this pull request as draft December 10, 2024 10:06
@jstvdk jstvdk self-assigned this Dec 10, 2024
Copy link
Member

@maxnoe maxnoe left a comment

Choose a reason for hiding this comment

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

Hi @jstvdk

Thanks a lot for preparing this. This looks like a good starting point. I have a couple of first comments mainly about the names of the fields and their descriptions.

I will do second round on more technical issues of the code later.

@@ -1189,6 +1189,18 @@ class MuonParametersContainer(Container):
nan * u.deg**2,
"MSE of the deviation of all pixels after cleaning from the ring fit",
)
ring_size = Field(nan, "Number of pixels in the ring")
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 really number of pixels? The code below computes some of the pixel intensities.

If this is actually the sum of pixel charges, the name should be ring_intensity and the help string match what is actually computed.

@@ -1189,6 +1189,18 @@ class MuonParametersContainer(Container):
nan * u.deg**2,
"MSE of the deviation of all pixels after cleaning from the ring fit",
)
ring_size = Field(nan, "Number of pixels in the ring")
size_outside = Field(nan, "Number of pixels outside the ring")
Copy link
Member

Choose a reason for hiding this comment

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

same here: probably this should be intensity_outside_ring

@@ -1189,6 +1189,18 @@ class MuonParametersContainer(Container):
nan * u.deg**2,
"MSE of the deviation of all pixels after cleaning from the ring fit",
)
ring_size = Field(nan, "Number of pixels in the ring")
size_outside = Field(nan, "Number of pixels outside the ring")
num_pixels_in_ring = Field(nan, "Number of pixels in the ring")
Copy link
Member

Choose a reason for hiding this comment

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

We use the n_ prefix for variables that are numbers, not num_

ring_size = Field(nan, "Number of pixels in the ring")
size_outside = Field(nan, "Number of pixels outside the ring")
num_pixels_in_ring = Field(nan, "Number of pixels in the ring")
mean_pixel_outside_ring = Field(nan, "Mean pixel charge outside the ring")
Copy link
Member

Choose a reason for hiding this comment

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

there is an intensity or similar missing in the field name.

I'd call it mean_intensity_outside_ring

mean_pixel_outside_ring = Field(nan, "Mean pixel charge outside the ring")
standard_dev = Field(
nan * u.deg,
"Standard deviation of the light distribution along the ring radius.",
Copy link
Member

Choose a reason for hiding this comment

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

"along the ring radius" sounds like this is somehow using spatial information.

But I think this is just "of pixels on the ring", right?

image_mask,
)

assert ring_size > 0
Copy link
Member

Choose a reason for hiding this comment

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

I think this test is not definitive enough. Please consider writing a test actually being sensitive on changes other than the value being <= 0.

I.e. use the ring gaussian toymodel to create a ring with known properties:

class RingGaussian(ImageModel):

y0 = center_y.to_value(u.deg)
pix_x = pixel_x.to_value(u.deg)
pix_y = pixel_y.to_value(u.deg)
pixel_r = np.sqrt((pix_x - x0) ** 2 + (pix_y - y0) ** 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
pixel_r = np.sqrt((pix_x - x0) ** 2 + (pix_y - y0) ** 2)
pixel_r = np.hypot(pix_x - x0, pix_y - y0)

Comment on lines 258 to 261
x0 = center_x.to_value(u.deg)
y0 = center_y.to_value(u.deg)
pix_x = pixel_x.to_value(u.deg)
pix_y = pixel_y.to_value(u.deg)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need to convert and take the value here. Numpy works fine with unit quantities, and then the function will work no matter what unit the inputs are in.

This comment has been minimized.

n_pixels_in_ring: int
Number of pixels inside the ring integration area that passed the cleaning
mean_intensity_outside_ring: float
Mean intensity of the pixels outside the ring, but still close to it
Mean intensity of the pixels outside the integration area of the ring,
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 the same as l1201 of ctapipe.containers? If so, why the docstrings are different?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are the same, but I didn't want to duplicate the exact same text.
Or should I just duplicate the doc strings from ctapipe.containers into the doc strings in the methods from ctapipe.image.muon.features?

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this function simply should return MuonParametersContainer?
Also, the number of input parameters is very high, consider to wrap them into a structure (dict, container, ...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps this function simply should return MuonParametersContainer?

All this module in fact is returning just one MuonParametersContainer and I adopted already existing style where each method returning some logically/technically connected part of MuonParametersContainer. Should I reconsider this and return calculated parts of MuonParametersContainer from every method?

Also, the number of input parameters is very high, consider to wrap them into a structure (dict, container, ...)

Good point

This comment has been minimized.

x coordinates of the camera pixels.
pixel_y : array-like
y coordinates of the camera pixels.
Amplitude of image pixels.
Copy link
Contributor

Choose a reason for hiding this comment

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

"image" is missing?

)


def radial_light_distribution(center_x, center_y, pixel_x, pixel_y, image):
Copy link
Contributor

@mexanick mexanick Dec 19, 2024

Choose a reason for hiding this comment

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

Consider merging this and the above functions, implementing along the way unification of the return type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, let me repeat if I understood correctly. You are proposing to merge all the methods into one, which calculates and returns MuonParametersContainer?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes

This comment has been minimized.

1 similar comment
Copy link

Passed

Analysis Details

0 Issues

  • Bug 0 Bugs
  • Vulnerability 0 Vulnerabilities
  • Code Smell 0 Code Smells

Coverage and Duplications

  • Coverage 100.00% Coverage (94.10% Estimated after merge)
  • Duplications 0.00% Duplicated Code (0.70% Estimated after merge)

Project ID: cta-observatory_ctapipe_AY52EYhuvuGcMFidNyUs

View in SonarQube

@mexanick mexanick assigned mexanick and unassigned jstvdk Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants