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

Irf maker and cut optimiser #2473

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

Irf maker and cut optimiser #2473

wants to merge 175 commits into from

Conversation

Tobychev
Copy link
Contributor

As we are planning to produce IRFs on events that were not used to select the GH cut, it makes sense to split the procedure generating IRFs into two tools. Because this splitting results in a large restructuring of the the previous PR on generating IRFs (#2315) that was basically working properly, I open a new PR to preserve the discussion on the old attempt and let its more or less functional code serve as easy reference.

@Tobychev Tobychev marked this pull request as draft November 24, 2023 09:45
ctapipe/irf/binning.py Outdated Show resolved Hide resolved
ctapipe/irf/irf_classes.py Outdated Show resolved Hide resolved
ctapipe/irf/irf_classes.py Outdated Show resolved Hide resolved
ctapipe/irf/irf_classes.py Outdated Show resolved Hide resolved
ctapipe/irf/irf_classes.py Outdated Show resolved Hide resolved
ctapipe/irf/binning.py Outdated Show resolved Hide resolved
ctapipe/irf/optimise.py Outdated Show resolved Hide resolved
def __init__(self, gh_cuts=None, offset_lim=None):
self.gh_cuts = gh_cuts
if gh_cuts:
self.gh_cuts.meta["extname"] = "GH_CUTS"
Copy link
Member

Choose a reason for hiding this comment

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

extname is the name of a FITS extension. You should't set this in the metadata of the table, but only when writing out, it's the name argument of write.

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 got

TypeError: write_table_fits() got an unexpected keyword argument 'name'

when I tried self.gh_cuts.write(out_name, name="GH_CUTS", format="fits", overwrite=overwrite) and I don't find anything about a name argument to table.write, do you mean I should manage the fits file more directly and just cast the tables to hdus?

ctapipe/irf/optimise.py Outdated Show resolved Hide resolved
ctapipe/irf/select.py Outdated Show resolved Hide resolved
ctapipe/irf/select.py Outdated Show resolved Hide resolved
ctapipe/irf/select.py Outdated Show resolved Hide resolved
ctapipe/irf/select.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/irf/irfs.py Outdated Show resolved Hide resolved
ctapipe/tools/make_irf.py Outdated Show resolved Hide resolved
ctapipe/irf/binning.py Outdated Show resolved Hide resolved
@maxnoe maxnoe mentioned this pull request Feb 23, 2024
src/ctapipe/irf/optimize.py Outdated Show resolved Hide resolved

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

… possibility to save an OptimizationResult with only gh cuts for now.
Copy link

Passed

Analysis Details

9 Issues

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

Coverage and Duplications

  • Coverage 96.40% Coverage (93.70% Estimated after merge)
  • Duplications 1.07% Duplicated Code (0.70% Estimated after merge)

Project ID: cta-observatory_ctapipe_AY52EYhuvuGcMFidNyUs

View in SonarQube

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 did a more detailed by-eye code review and have a few suggested changes. I will now do some more detailed testing by running the code, so may submit a second review shortly.

).tag(config=True)

energy_migration_linear_bins = Bool(
help="Bin energy migration ratio using linear bins",
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be useful to mention here what is the default if this is set to false. Looking at the code, it is geometric (logarithmic) bins. This could also be clearer as:

energy_migration_binning = CaselessStrEnum( 
    ['linear', 'logarithmic'],
     help="How energy bins are distributed between energy_migration_min and energy_migration_max", 
     default_value="logarithmic"
).tag(config=True)

).tag(config=True)

energy_migration_n_bins = Integer(
help="Number of bins in log scale for energy migration ratio",
Copy link
Contributor

Choose a reason for hiding this comment

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

log scale is incorrect if the user chooses energy_migration_linear_bins=True


@abstractmethod
def make_edisp_hdu(
self, events: QTable, point_like: bool, extname: str = "ENERGY MIGRATION"
Copy link
Contributor

@kosack kosack Jan 15, 2025

Choose a reason for hiding this comment

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

general comment for here and other places: since we have options point_like and source_is_pointlike, this is quite confusing. Maybe rename point_like to direction_cut_applied or spatial_selection_applied. That will make it much easier to follow. Also, this is more in line with the fact that we don't use the term "point-like IRFs" anymore, and instead use "SpatialSelection=None | RAD_MAX"

Copy link
Contributor

Choose a reason for hiding this comment

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

I will change it to spatial_selection_applied. I guess we should also change it accordingly in pyirf then, right?

"Do not compute background rate.",
),
**flag(
"point-like",
Copy link
Contributor

Choose a reason for hiding this comment

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

see earlier comment: "point-like/full-enclosure" terminology should be replaced to avoid confusion between point-like cuts vs point-like simulated sources. The flag could be spatial_selection_applied or similar

super().__init__(parent=parent, **kwargs)

@abstractmethod
def make_bias_resolution_hdu(
Copy link
Contributor

@kosack kosack Jan 15, 2025

Choose a reason for hiding this comment

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

Any reason to not just use __call__ like other Components? (same comment for all Components in this file). That would make the API similar to all other parts of ctapipe

Copy link
Contributor

Choose a reason for hiding this comment

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

No reason. I think __call__ would be better 👍 I will also change the benchmark and cut optimization components accordingly.

self,
signal_events: QTable,
background_events: QTable,
theta_cut: QTable,
Copy link
Contributor

@kosack kosack Jan 15, 2025

Choose a reason for hiding this comment

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

maybe to harmonize terminology, use spatial_selection_table?

Copy link
Contributor

Choose a reason for hiding this comment

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

Then we should probably not use "theta cut" anywhere anymore, right? So also rename it in the cut calculation components etc.

__all__ = ["EventLoader", "EventPreProcessor"]


class EventPreProcessor(QualityQuery):
Copy link
Contributor

Choose a reason for hiding this comment

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

preprocess is a word, so this should be EventPreprocessor,

Also generally we do not inherit from QualityQuery for in other components, but rather have the component contain a QualityQuery. That makes more semantic sense, as this class does much more than a QualityQuery.

Then you would have a config file much like other classes in ctapipe:

EventPreprocessor:

   EventQualityQuery:
       quality_critieria: 
          ...
   energy_reconstructor: ...

from enum import Enum

import astropy.units as u
from pyirf.spectral import CRAB_HEGRA, IRFDOC_ELECTRON_SPECTRUM, IRFDOC_PROTON_SPECTRUM
Copy link
Contributor

Choose a reason for hiding this comment

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

wasn't this moved to a new package? Or is that just handled inside pyirf?

target_spectrum=self.gamma_target_spectrum,
)
]
if self.optimization_algorithm != "PercentileCuts":
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be safer to use isinstance() here and elsewhere instead of a string compare to the class name, so that if we ever re-factor or rename classes, it gets updated correctly. But that would mean importing those sub-classes or the module, so not clear if that makes it messier.

if include_bkg:
assert isinstance(hdul["BACKGROUND"], fits.BinTableHDU)

os.remove(output_path) # Delete output file
Copy link
Contributor

Choose a reason for hiding this comment

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

use output_path.unlink() instead, so no need to import os.

@LukasBeiske
Copy link
Contributor

LukasBeiske commented Jan 15, 2025

I did a more detailed by-eye code review and have a few suggested changes. I will now do some more detailed testing by running the code, so may submit a second review shortly.

Thanks! I can also add an example config file (maybe containing all config options and their default values?) at ctapipe.resources, if you think that would make sense.

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.

4 participants