Skip to content

Conversation

@benjaminhuth
Copy link
Member

Still WIP

--- END COMMIT MESSAGE ---

Any further description goes here, @-mentions are ok here!

  • Use a conventional commits prefix: quick summary
    • We mostly use feat, fix, refactor, docs, chore and build types.
  • A milestone will be assigned by one of the maintainers

benjaminhuth and others added 30 commits December 15, 2025 16:57
Implements Milestone 1 of the histogram refactoring:

- Add BoostHistogram1D and BoostHistogram2D wrapper classes
  - Simple API with fill(value) method
  - Support uniform, variable, and logarithmic binning
  - Zero ROOT dependencies in Framework

- Add BoostHistogramToRootConverter for output
  - toTH1F() converts 1D histograms to ROOT TH1F
  - toTH2F() converts 2D histograms to ROOT TH2F
  - Preserves metadata (name, title, axis titles)
  - Correctly handles variable binning

- Add comprehensive unit tests
  - BoostHistogramTests: Test wrapper functionality
  - BoostHistogramConversionTests: Test ROOT conversion
  - Tests cover uniform, variable, and logarithmic binning
  - All tests use concise test data (10 bins, 100 fills)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements Milestone 2 of the histogram refactoring:

- Add BoostProfileHistogram for profile histograms
  - Uses boost::histogram with weighted_mean accumulator
  - API: fill(x, y) to track mean of y for each x bin
  - Supports variable binning (uniform, logarithmic, custom)

- Add BoostEfficiency1D and BoostEfficiency2D
  - Track pass/total counts for efficiency calculation
  - Internally uses two histograms (passed and total)
  - API: fill(value, passed) for 1D, fill(x, y, passed) for 2D

- Add comprehensive unit tests
  - Profile histogram tests verify mean calculation
  - Efficiency tests verify pass/total tracking
  - All tests use concise data (10 bins, small fill counts)

- Zero ROOT dependencies in Framework layer
  - All classes use boost::histogram primitives only
  - Converters to ROOT will be added separately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Combines all boost::histogram wrapper classes into a single header/source:

- Move BoostProfileHistogram into BoostHistogramWrappers
  - Use boost::histogram::make_profile() instead of manual weighted_mean
  - Simpler, more idiomatic boost::histogram usage

- Move BoostEfficiency1D and BoostEfficiency2D into BoostHistogramWrappers
  - All histogram primitives now in one location

- Delete separate BoostProfileEfficiency files
  - Reduces file proliferation
  - Easier to maintain and discover histogram types

- Update test to include unified header
  - All tests still pass

All histogram wrappers (1D, 2D, Profile, Efficiency) are now in:
- Examples/Framework/include/ActsExamples/Validation/BoostHistogramWrappers.hpp
- Examples/Framework/src/Validation/BoostHistogramWrappers.cpp

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements converters for the remaining boost histogram types:

- Add toTProfile(BoostProfileHistogram) converter
  - Converts boost profile to ROOT TProfile
  - Reconstructs sum from mean and count for proper TProfile behavior
  - Preserves metadata (name, title, axis titles)

- Add toTEfficiency(BoostEfficiency1D) converter
  - Converts 1D efficiency to ROOT TEfficiency
  - Creates passed and total TH1F histograms internally
  - TEfficiency computes efficiency from pass/total ratio

- Add toTEfficiency(BoostEfficiency2D) converter
  - Converts 2D efficiency to ROOT TEfficiency
  - Uses TH2F for passed and total histograms
  - Handles global bin indexing for 2D efficiency lookup

- Add comprehensive conversion tests
  - Profile test verifies mean value preservation (2.0, 6.0, 10.0)
  - 1D efficiency test verifies 70% and 50% efficiency bins
  - 2D efficiency test verifies 75% and 50% efficiency bins
  - All tests verify metadata preservation and binning

All histogram conversion infrastructure is now complete for
Milestone 2. Tests pass successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed all type-specific converter function names (toTH1F, toTH2F,
toTProfile, toTEfficiency) to overloaded toRoot() functions.
This provides a cleaner API where the appropriate converter is selected
based on the input histogram type.

Updated all test call sites to use the new function names.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed loop variable types from std::size_t to int to match
the return type of boost::histogram::axis::size() (index_type).
This eliminates all compiler warnings while maintaining correctness.

Also removed unnecessary static_cast<int> operations on loop
variables that are now already int type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This is the first of 5 simple plot tools being refactored to use
boost::histogram wrappers instead of ROOT histograms directly.

**Infrastructure changes:**
- Move BoostHistogramToRootConverter from Io/Root to Framework/Validation
  (Framework already links to ROOT::Hist, this is just a utility)
- Add BoostHistogramWriteHelpers to provide write() functions that
  convert boost → ROOT → Write() → cleanup
- Add default constructor to BoostProfileHistogram for RAII pattern

**TrackQualityPlotTool changes:**
- Replace 6 TProfile* pointers with 6 BoostProfileHistogram objects
- Remove PlotHelpers::bookProf() calls, use direct construction
- Remove PlotHelpers::fillProf() calls, use .fill() directly
- Use BoostHistogramWriteHelpers::write() instead of ->Write()
- Remove clear() method entirely (RAII handles cleanup)

**Writer changes:**
- Remove TrackQualityPlotTool.clear() call from destructor (RAII)
- Remove {} initialization from Cache (requires default constructor)

**Benefits:**
- Cleaner memory management (no manual new/delete)
- Direct boost histogram API (no wrapper layer)
- Establishes pattern for remaining tools

All 11 histogram conversion tests pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…pendence

Moved BoostHistogramToRootConverter and BoostHistogramWriteHelpers from
Framework to Io/Root to preserve the architecture goal of keeping the
Framework layer ROOT-free. This ensures proper separation of concerns:
- Framework layer: ROOT-independent histogram collection
- Io/Root layer: ROOT-specific conversion and I/O

Changes:
- Moved converter files to Examples/Io/Root
- RootTrackFinderPerformanceWriter now converts and writes histograms directly
- TrackQualityPlotTool uses RAII pattern with boost histograms
- Fixed TProfile converter to call Sumw2() for proper initialization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Refactored TrackSummaryPlotTool following the same RAII pattern as
TrackQualityPlotTool. Plot tools now only collect data using boost
histograms, while ROOT conversion and I/O happens in the writers.

Changes:
- Changed Cache from TProfile* to BoostProfileHistogram objects
- Removed write() and clear() methods (RAII handles cleanup)
- Updated book() to construct BoostProfileHistogram directly
- Updated fill() to use .fill() method instead of PlotHelpers::fillProf()
- Updated RootTrackFinderPerformanceWriter to convert and write directly
- Updated RootTrackFitterPerformanceWriter to convert and write directly

All tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement projectionX() and projectionY() methods for Histogram2D class
using boost::histogram's algorithm::project. The methods project a 2D
histogram onto its X or Y axis respectively, returning a Histogram1D.

Add a private constructor to Histogram1D that accepts a boost histogram
directly, simplifying the projection implementation. The constructor is
marked private with Histogram2D as a friend to maintain encapsulation.

Include comprehensive unit tests for both projection methods verifying
metadata and bin contents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extends the AxisVariant to support logarithmic binning using
boost::histogram's built-in log transform. This allows creating
histograms with logarithmic scales without manually computing
bin edges.

The new BoostLogAxis type is added to the AxisVariant alongside
the existing BoostVariableAxis and BoostRegularAxis types.

The existing HistogramConverter in Plugins/Root already handles
the new axis type generically through its polymorphic bin edge
extraction.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Move extractBinEdges from anonymous namespace to public API in
ActsPlugins namespace. This allows ROOT writers to create ROOT
histograms directly from AxisVariant binning information.

This function works with all axis types (regular, variable, log)
by accessing the generic axis interface methods (bin(), lower(),
upper()).

Needed for removing ROOT dependencies from Examples/Framework
while allowing ROOT writers to create summary histograms with
proper binning.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Replace ROOT TEfficiency with Acts::Experimental::Efficiency from
Core/Utilities/Histogram.hpp. Changes include:
- Config: Use AxisVariant instead of PlotHelpers::Binning
- Cache: Use std::optional<Efficiency> for non-default-constructible types
- book(): Use .emplace() to construct optional histograms
- fill(): Use -> to dereference optional members
- Remove write() and clear() methods (will be implemented in ROOT writers)

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
benjaminhuth and others added 8 commits January 14, 2026 08:21
Replace ROOT TH2F and TEfficiency with Acts::Experimental types from
Core/Utilities/Histogram.hpp. Changes include:
- Config: Use AxisVariant instead of PlotHelpers::Binning
- Cache: Use std::optional<Histogram2> and Efficiency1
- book(): Use .emplace() to construct optional histograms
- fill(): Use ->fill({values}) API for Core histograms
- Remove write() and clear() methods

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Replace ROOT TProfile with Acts::Experimental::ProfileHistogram1 from
Core/Utilities/Histogram.hpp. Changes include:
- Config: Use AxisVariant instead of PlotHelpers::Binning
- Cache: Use std::optional<ProfileHistogram1>
- book(): Use .emplace() with sample axis title parameter
- fill(): Use ->fill({x}, value) API for profile histograms
- Remove write() and clear() methods

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Replace ROOT TProfile and TEfficiency with Acts::Experimental types
from Core/Utilities/Histogram.hpp. Changes include:
- Config: Use AxisVariant instead of PlotHelpers::Binning
- Cache: Use std::optional<ProfileHistogram1> and Efficiency1
- book(): Use .emplace() with sample axis title for profiles
- fill(): Use ->fill({values}) API for Core histograms
- Remove write() and clear() methods

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Replace ROOT TProfile with Acts::Experimental::ProfileHistogram1 from
Core/Utilities/Histogram.hpp. Changes include:
- Config: Use AxisVariant instead of PlotHelpers::Binning
- Cache: Use std::optional<ProfileHistogram1>
- book(): Use .emplace() with sample axis title parameter
- fill(): Use ->fill({x}, value) API for profile histograms
- Remove write() and clear() methods

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Replace std::optional<Histogram/Efficiency/ProfileHistogram> with direct
value members in all PlotTool Cache structs. Use direct assignment in
book() methods and remove -> dereference operators in fill() methods.

This simplifies the code and matches the pattern already used in
ResPlotTool and in vector members of other PlotTools.

Modified tools:
- EffPlotTool: 11 Efficiency members + 2 vectors
- FakePlotTool: 6 Histogram2 + 3 Efficiency1 members
- TrackSummaryPlotTool: 10 ProfileHistogram1 members
- DuplicationPlotTool: 3 ProfileHistogram1 + 3 Efficiency1 members
- TrackQualityPlotTool: 6 ProfileHistogram1 members

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions bot added Component - Core Affects the Core module Component - Examples Affects the Examples module Component - Plugins Affects one or more Plugins labels Jan 15, 2026
@github-actions github-actions bot added this to the next milestone Jan 15, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 15, 2026

📊: Physics performance monitoring for d7fd25d

Full contents

physmon summary

benjaminhuth and others added 4 commits January 16, 2026 15:12
…tibility

- Restore original histogram string names with underscores (e.g.,
  trackeff_vs_eta instead of trackEffVsEta) for ROOT file compatibility
- Add refinement step in RootTrackFitterPerformanceWriter to generate
  derived mean/width histograms (resmean_*, reswidth_*, pullmean_*,
  pullwidth_*) from 2D residual/pull histograms using PlotHelpers::anaHisto

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move ROOT-dependent sources (ScalingCalibrator, Helpers) to a new
Examples/Framework/ROOT subdirectory following the same pattern as
Examples/Framework/ML. The ROOT subdirectory is conditionally included
when ACTS_BUILD_EXAMPLES_ROOT is enabled.

The Sequencer thread-safety call to ROOT::EnableThreadSafety() is now
conditional on ACTS_EXAMPLES_WITH_ROOT being defined.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sonarqubecloud
Copy link

benjaminhuth and others added 2 commits January 23, 2026 15:35
DuplicationPlotTool and TrackQualityPlotTool were creating
ProfileHistogram1 objects without specifying a sample range. This caused
them to accept all values, while the old ROOT-based implementation used
TProfile with a Y range from the "Num" axis (-0.5 to 29.5), which would
filter outliers.

This change adds the same sample range filtering that TrackSummaryPlotTool
already had, matching the behavior of the original ROOT implementation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component - Core Affects the Core module Component - Examples Affects the Examples module Component - Plugins Affects one or more Plugins

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant