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

First step of implementing CEP-002: Change container structure #2204

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

maxnoe
Copy link
Member

@maxnoe maxnoe commented Jan 10, 2023

No description provided.

@maxnoe
Copy link
Member Author

maxnoe commented Jan 10, 2023

Before I continue changing everything, could you review the new container structure?

I think it's already a big step in the right direction, as the structure is much simpler, we could get rid of many indirections...

@maxnoe maxnoe requested a review from kosack January 11, 2023 08:28
@nbiederbeck
Copy link
Contributor

nbiederbeck commented Jan 11, 2023

This comment just looked at ctapipe/containers.py. In general I think the structure looks fine, it makes more sense as seen in the tests, but while we're at it, some comments:

  • For the EventContainers: and why do we have count?

  • Should there be a general MuonContainer?

  • Why does the TelescopePointingContainer have no ra/dec?
    Or why does ArrayPointingContainer have it?

  • Should we rename the ParticleClassificationContainer and TelescopeImpactParameterContainer to be more consistent with ReconstructedEnergyContainer and ReconstructedGeometryContainer? E.g. ReconstructedParticleContainer, ReconstructedImpactContainer.

  • Is Reconstructed[…].telescopes sensible to be None if Mono? Or should it just hold the corresponding tel_id and be of type int?

  • Is TelescopeTriggerContainer.n_trigger_pixels with default -1 sensible? Or is 0 better to have an unsigned int?

  • SimulationConfigContainer have many nans, but str seems more appropriate given the description. Or None.

  • TelescopeSimulationContainer.impact is not called true_impact.

  • MorphologyContainer, is -1 a better default than 0? Does it make a difference of default 0 and filled 0?

  • Is CameraTimingParametersContainer still needed?

  • LeakageContainer.intensity_width_{1,2} is ambiguously documented (intensity vs. fraction of intensity, as of the docstring).

  • There are some Camera-containers, which I think we can get rid of?

@maxnoe maxnoe changed the title Start working on inverted container structure Implement CEP-002: Change container structure to ArrayEvent -> TelescopeEvent -> Data Levels Jun 2, 2023
@maxnoe
Copy link
Member Author

maxnoe commented Jun 5, 2023

Why does the TelescopePointingContainer have no ra/dec?

Because all our telescopes are alt/az mounts, so this is the actual information that is monitored.

Or why does ArrayPointingContainer have it?

Because that's the reference point the array is tracking, which might be in sky-fixed coordinates.

TelescopeSimulationContainer.impact is not called true_impact.

Isn't this accomplished by adding the true_ prefix in the data writer?

Is TelescopeTriggerContainer.n_trigger_pixels with default -1 sensible? Or is 0 better to have an unsigned int?

I think it's important to distinguish invalid from valid data, 0 trigger pixels are possible (e.g. for pedestal events which are randomly triggered), so better distinguish. Same for the other positive integers.

@maxnoe
Copy link
Member Author

maxnoe commented Jun 5, 2023

For the EventContainers: and why do we have count?

Just nice to have I guess.

@maxnoe
Copy link
Member Author

maxnoe commented Jun 5, 2023

Is CameraTimingParametersContainer still needed?

That's connected to all the other Camera... containers and to #2141, we need them as long as we still support computing image parameters in CameraFrame

@StFroese
Copy link
Member

StFroese commented Jul 7, 2023

The ArrayEventContainer contains the DL2 data (geometry, energy, classification) of the event in the ArrayDL2Container.
It also contains the telescopes as a map of TelescopeEventContainer's which contains all data levels like r0... and also dl2. dl2 in this case is a TelescopeDL2Container which is a subclass of the ArrayDL2Container again.

Why do we save the array event reconstructions at telescope level again? This is a little bit confusing to me

@maxnoe
Copy link
Member Author

maxnoe commented Jul 7, 2023

Why do we save the array event reconstructions at telescope level again? This is a little bit confusing to me

The DL2TelescopeContainer is for monoscopic predictions, not for repeating the subarray info.

The inheritance here is just to get the same fields, but I agree that it's confusing that isinstance(DL2TelescopeContainer, DL2SubarrayContainer). I had an intermediate version where both just inherited from Container and then duplicated the field definitions.

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@@ -209,51 +210,49 @@ def _parameterize_image(
# parameterization
return default

def _process_telescope_event(self, event):
def _process_telescope_event(self, tel_event):
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd suggest adding type hints for functions like this while you are at it, especially for ones where the type changed.

def _process_telescope_event(self, tel_event: DL1TelescopeContainer):

That will make it more clear what is expected where, and also support language servers and mypy to do better completion, etc.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a TelescopeEventContainer, but yes, I'll add type hints for these. However, these are not terribly helpful, since at least my lsp only looks at the class variable, not the instance variables or rather assumes they are of the same type.

@StFroese
Copy link
Member

The inheritance here is just to get the same fields, but I agree that it's confusing that isinstance(DL2TelescopeContainer, DL2SubarrayContainer). I had an intermediate version where both just inherited from Container and then duplicated the field definitions.

Can we add a ReconstrucedShowerContainer which contains the fields and DL2{Telescope|Subarray}Container inherit from that?

@maxnoe
Copy link
Member Author

maxnoe commented Oct 31, 2023

Hi all,

I rebased this on the current main and squashed the commits into one, to ease follow-up rebases when we make updates to main.

I'd appreciate a fresh review now.

I suggest to first only review the container structure in ctapipe.containers (beware, this is collapsed by default) before reviewing any of the resulting code changes.

Once we are happy with the container structure and renaming, I'll fix up the rest of the code and we can commence the review there.

@@ -759,12 +748,11 @@ class SimulatedCameraContainer(Container):
)


class SimulatedEventContainer(Container):
class SimulationSubarrayContainer(Container):
shower = Field(
Copy link
Member Author

Choose a reason for hiding this comment

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

Right now, simulationsubarrayContainer has a single subcontainer, shower.

We could just attach the shower container at the SubarrayEventContainer to get rid of one level of indirection.

@ccossou
Copy link
Contributor

ccossou commented Nov 6, 2023

For the EventContainers: and why do we have count?

Just nice to have I guess.

On this part. This, to me, is related to how people parse the file and shouldn't be in the container itself, or if it is, should be hidden and not publicly exposed (even if in python, private just means harder to type). But that's a minor comment and not the main purpose of CEP-002.

)
for container in simulation.true_parameters.values():
Copy link
Contributor

Choose a reason for hiding this comment

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

If the prefix doesn't start with "true_", doesn't that mean there's something wrong with the file and we should raise an error rather than silently correcting it?

Copy link
Member Author

Choose a reason for hiding this comment

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

If the prefix doesn't start with "true_", doesn't that mean there's something wrong with the file

Has nothing to do with the input file, since the container is created by the _parametrize_image methods, but you are right, this is confusing.

I will check if it is needed / can be improved.

@ccossou
Copy link
Contributor

ccossou commented Nov 7, 2023

(Sorry, commented on file without realizing it wasn't container.py anymore, got carried away.)

@maxnoe maxnoe force-pushed the container_structure branch 3 times, most recently from 02e167c to 2a71a42 Compare April 30, 2024 13:17
@maxnoe
Copy link
Member Author

maxnoe commented Apr 30, 2024

Wow, resolving the conflicts here was no fun.... I'd really appreciate if we can tackle this one next.

I will do a self-review again and it would be nice if others could start reviewing the structure in src/ctapipe/containers.py

One particular issue (noted with a fixme in the CameraCalibrator) is that we (in accordance with the CTAO data model) moved the trigger information to dl0, but the SimTelEventSource and also other event source implementations are allowed to return event data with only R1 inside.

This has the issue of the CameraCalibrator.r1_to_dl0 method needing to fill trigger information... which it now does by checking if there is a pre-existing dl0 container. Not so nice conceptually.

I see two solutions:

  • Putting trigger info also at R1 so that e.g. CameraCalibrator can just forward it from r1 to dl0
  • Requiring event sources to provide dl0, removing the dvr step from CameraCalibrator so that it only deals with the calibration from dl0 to dl1

I think the latter is the option that is more closely aligned with how we expect actual CTAO operations to be.

Studies for DVR can still be done, if we for example at dvr options to simteleventsource or in an intermediate step.

This comment has been minimized.

description="DL2 reconstructed event properties",
)

pointing = Field(
Copy link
Member Author

Choose a reason for hiding this comment

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

Move into dl0?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure, is it very helpful?

Putting pointing in dl0 means you can't make geometry reconstruction using pure dl2 files, but maybe that's fine? Not sure what other costs there are.

Copy link
Member Author

Choose a reason for hiding this comment

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

DL2 files could always include the dl0 monitoring table. Independent of where this field is stored in the object, it is written to /dl0 in the hdf5 data files.

This comment has been minimized.

@maxnoe maxnoe force-pushed the container_structure branch 2 times, most recently from e475e40 to e6719b0 Compare April 30, 2024 13:47

This comment has been minimized.

1 similar comment

This comment has been minimized.

src/ctapipe/io/tableloader.py Show resolved Hide resolved
src/ctapipe/io/tableloader.py Show resolved Hide resolved
src/ctapipe/image/reducer.py Show resolved Hide resolved
src/ctapipe/instrument/trigger.py Show resolved Hide resolved
description="DL2 reconstructed event properties",
)

pointing = Field(
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure, is it very helpful?

Putting pointing in dl0 means you can't make geometry reconstruction using pure dl2 files, but maybe that's fine? Not sure what other costs there are.

src/ctapipe/io/datawriter.py Show resolved Hide resolved
src/ctapipe/io/datawriter.py Show resolved Hide resolved
src/ctapipe/io/datawriter.py Outdated Show resolved Hide resolved
src/ctapipe/io/hdf5eventsource.py Show resolved Hide resolved
kosack
kosack previously approved these changes Jul 10, 2024
Copy link
Contributor

@kosack kosack left a comment

Choose a reason for hiding this comment

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

I don't see any major problem.

@maxnoe maxnoe force-pushed the container_structure branch 4 times, most recently from f8939d0 to 7f603c4 Compare July 15, 2024 08:53
@maxnoe maxnoe force-pushed the container_structure branch 3 times, most recently from bbecf66 to 1a17ad8 Compare July 15, 2024 11:37

This comment has been minimized.

Copy link

Passed

Analysis Details

12 Issues

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

Coverage and Duplications

  • Coverage 96.30% Coverage (93.70% Estimated after merge)
  • Duplications 1.09% Duplicated Code (0.60% Estimated after merge)

Project ID: cta-observatory_ctapipe_AY52EYhuvuGcMFidNyUs

View in SonarQube

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.

Rename *Camera*Containers to *Telescope*Containers Discussion on restructuring Event Container structure
6 participants