From 409dfe3d41e2be1a5bffa6a61cf9fa341f230d34 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Mon, 3 Aug 2026 23:17:01 -0400 Subject: [PATCH 01/31] Implement timeframe splitting support --- src/detectors/B0ECAL/B0ECAL.cc | 7 +- src/detectors/B0TRK/B0TRK.cc | 7 +- src/detectors/BEMC/BEMC.cc | 13 +- src/detectors/BHCAL/BHCAL.cc | 7 +- src/detectors/BTOF/BTOF.cc | 24 +- src/detectors/BTRK/BTRK.cc | 39 +- src/detectors/BVTX/BVTX.cc | 34 +- src/detectors/ECTOF/ECTOF.cc | 16 +- src/detectors/ECTRK/ECTRK.cc | 17 +- src/detectors/EEMC/EEMC.cc | 97 +- src/detectors/EHCAL/EHCAL.cc | 7 +- src/detectors/FEMC/FEMC.cc | 9 +- src/detectors/FHCAL/FHCAL.cc | 11 +- src/detectors/FOFFMTRK/FOFFMTRK.cc | 7 +- src/detectors/LOWQ2/LOWQ2.cc | 7 +- src/detectors/LUMISPECCAL/LUMISPECCAL.cc | 7 +- src/detectors/MPGD/MPGD.cc | 27 +- src/detectors/RPOTS/RPOTS.cc | 7 +- src/detectors/ZDC/ZDC.cc | 11 +- src/extensions/jana/JOmniFactoryGeneratorT.h | 20 +- src/global/CMakeLists.txt | 1 + src/global/splitting/CMakeLists.txt | 42 + .../splitting/CalRecTimeAlignmentFactory.h | 91 ++ src/global/splitting/TimeframeSplitter.h | 1392 +++++++++++++++++ .../splitting/TrkTimeAlignmentFactory.h | 95 ++ src/global/splitting/splitting.cc | 126 ++ src/services/io/podio/JEventProcessorPODIO.cc | 16 + src/services/io/podio/podio.cc | 20 +- 28 files changed, 2024 insertions(+), 133 deletions(-) create mode 100644 src/global/splitting/CMakeLists.txt create mode 100644 src/global/splitting/CalRecTimeAlignmentFactory.h create mode 100644 src/global/splitting/TimeframeSplitter.h create mode 100644 src/global/splitting/TrkTimeAlignmentFactory.h create mode 100644 src/global/splitting/splitting.cc diff --git a/src/detectors/B0ECAL/B0ECAL.cc b/src/detectors/B0ECAL/B0ECAL.cc index 667b52ec0f..530a9081c5 100644 --- a/src/detectors/B0ECAL/B0ECAL.cc +++ b/src/detectors/B0ECAL/B0ECAL.cc @@ -23,6 +23,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; app->Add(new JOmniFactoryGeneratorT( "B0ECalRawHits", {"EventHeader", "B0ECalHits"}, @@ -40,7 +43,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "B0ECalHits", }, - app)); + app, hit_level)); app->Add(new JOmniFactoryGeneratorT( "B0ECalRecHits", {"B0ECalRawHits"}, {"B0ECalRecHits"}, { @@ -55,7 +58,7 @@ void InitPlugin(JApplication* app) { .readout = "B0ECalHits", .sectorField = "sector", }, - app)); + app, hit_level)); app->Add(new JOmniFactoryGeneratorT( "B0ECalTruthProtoClusters", {"B0ECalRecHits", "B0ECalHits"}, {"B0ECalTruthProtoClusters"}, app)); diff --git a/src/detectors/B0TRK/B0TRK.cc b/src/detectors/B0TRK/B0TRK.cc index d7b53cc1fe..bdff05362d 100644 --- a/src/detectors/B0TRK/B0TRK.cc +++ b/src/detectors/B0TRK/B0TRK.cc @@ -18,6 +18,9 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Digitization app->Add(new JOmniFactoryGeneratorT( @@ -27,7 +30,7 @@ void InitPlugin(JApplication* app) { .threshold = 10.0 * dd4hep::keV, .timeResolution = 8, }, - app)); + app, hit_level)); // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( @@ -35,6 +38,6 @@ void InitPlugin(JApplication* app) { { .timeResolution = 8, }, - app)); + app, hit_level)); } } // extern "C" diff --git a/src/detectors/BEMC/BEMC.cc b/src/detectors/BEMC/BEMC.cc index 18945e83fd..63deda806b 100644 --- a/src/detectors/BEMC/BEMC.cc +++ b/src/detectors/BEMC/BEMC.cc @@ -45,6 +45,9 @@ extern "C" { void InitPlugin(JApplication* app) { using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; InitJANAPlugin(app); @@ -231,7 +234,7 @@ void InitPlugin(JApplication* app) { .readout = "EcalBarrelScFiHits", .fields = {"fiber", "z"}, }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalBarrelScFiRecHits", {"EcalBarrelScFiRawHits"}, {"EcalBarrelScFiRecHits"}, @@ -253,7 +256,7 @@ void InitPlugin(JApplication* app) { .maskPos = "xy", .maskPosFields = {"fiber", "z"}, }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalBarrelScFiProtoClusters", {"EcalBarrelScFiRecHits"}, {"EcalBarrelScFiProtoClusters"}, @@ -355,7 +358,7 @@ void InitPlugin(JApplication* app) { .readout = "EcalBarrelImagingHits", .timeWindow = EcalBarrelImaging_timeWindow, }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalBarrelImagingRawHits", {"EventHeader", "EcalBarrelImagingProcessedHits"}, @@ -372,7 +375,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "EcalBarrelImagingHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalBarrelImagingRecHits", {"EcalBarrelImagingRawHits"}, {"EcalBarrelImagingRecHits"}, @@ -389,7 +392,7 @@ void InitPlugin(JApplication* app) { .layerField = "layer", .sectorField = "sector", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalBarrelImagingProtoClusters", {"EcalBarrelImagingRecHits"}, diff --git a/src/detectors/BHCAL/BHCAL.cc b/src/detectors/BHCAL/BHCAL.cc index 04ebfdd430..83aee81a0f 100644 --- a/src/detectors/BHCAL/BHCAL.cc +++ b/src/detectors/BHCAL/BHCAL.cc @@ -27,6 +27,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Make sure digi and reco use the same value decltype(CalorimeterHitDigiConfig::capADC) HcalBarrel_capADC = 65536; //65536, 16bit ADC @@ -64,7 +67,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "HcalBarrelHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( @@ -82,7 +85,7 @@ void InitPlugin(JApplication* app) { .layerField = "", .sectorField = "", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); // -------------------------------------------------------------------- diff --git a/src/detectors/BTOF/BTOF.cc b/src/detectors/BTOF/BTOF.cc index 242dc74da0..7082b9f440 100644 --- a/src/detectors/BTOF/BTOF.cc +++ b/src/detectors/BTOF/BTOF.cc @@ -35,6 +35,26 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + + if (split_timeframes) { + // Produce the time-ordered hit and truth-relation collections consumed by + // TimeframeSplitter. Keep this path separate from the pulse digitization + // used by normal event reconstruction below. + app->Add(new JOmniFactoryGeneratorT( + "TOFBarrelRawHits", {"EventHeader", "TOFBarrelHits"}, + {"TOFBarrelRawHits", "TOFBarrelRawHitLinks", "TOFBarrelRawHitAssociations"}, + { + .threshold = 6.0 * dd4hep::keV, + .timeResolution = 0.025, // [ns] + }, + app, JEventLevel::Timeslice)); + + app->Add(new JOmniFactoryGeneratorT( + "TOFBarrelRecHits", {"TOFBarrelRawHits"}, {"TOFBarrelRecHits"}, {}, app, + JEventLevel::Timeslice)); + } // Convert raw digitized hits into calibrated hits // time walk correction is still TBD @@ -48,8 +68,8 @@ void InitPlugin(JApplication* app) { // Currently it's just a simple weighted average // More sophisticated algorithm TBD app->Add(new JOmniFactoryGeneratorT( - "TOFBarrelClusterHits", {"TOFBarrelSharedRecHits"}, // Input data collection tags - {"TOFBarrelClusterHits"}, // Output data tag + "TOFBarrelClusterHits", {split_timeframes ? "TOFBarrelRecHits" : "TOFBarrelSharedRecHits"}, + {"TOFBarrelClusterHits"}, // Output data tag { .readout = "TOFBarrelHits", .useAve = true, diff --git a/src/detectors/BTRK/BTRK.cc b/src/detectors/BTRK/BTRK.cc index 2b0497daad..0037ed2956 100644 --- a/src/detectors/BTRK/BTRK.cc +++ b/src/detectors/BTRK/BTRK.cc @@ -22,6 +22,9 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Digitization app->Add(new JOmniFactoryGeneratorT( @@ -30,24 +33,28 @@ void InitPlugin(JApplication* app) { { .threshold = 0.54 * dd4hep::keV, }, - app)); - - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelNoiseRawHits", {"EventHeader"}, {"SiBarrelNoiseRawHits"}, - {.addNoise = true, .noise_rate_per_pixel_per_event = 2.0e-7, .readout_name = "SiBarrelHits"}, - app)); - - app->Add(new JOmniFactoryGeneratorT>( - "SiBarrelRawHitsWithNoise", // Name of the combiner instance - {"SiBarrelRawHits", "SiBarrelNoiseRawHits"}, // Inputs: original + noise-only - {"SiBarrelRawHitsWithNoise"}, // Output: merged collection - {}, // default config - app)); + app, hit_level)); + + // Per-pixel noise occupancy for the barrel silicon tracker. Configurable via + // SiBarrelNoiseRawHits:noise_rate_per_pixel_per_event (default 2e-7). + if (!split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelNoiseRawHits", {"EventHeader"}, {"SiBarrelNoiseRawHits"}, + {.addNoise = true, .noise_rate_per_pixel_per_event = 2.0e-7, .readout_name = "SiBarrelHits"}, + app)); + + app->Add(new JOmniFactoryGeneratorT>( + "SiBarrelRawHitsWithNoise", // Name of the combiner instance + {"SiBarrelRawHits", "SiBarrelNoiseRawHits"}, // Inputs: original + noise-only + {"SiBarrelRawHitsWithNoise"}, // Output: merged collection + {}, // default config + app)); + } // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( - "SiBarrelTrackerRecHits", {"SiBarrelRawHitsWithNoise"}, {"SiBarrelTrackerRecHits"}, - {}, // default config - app)); + "SiBarrelTrackerRecHits", {split_timeframes ? "SiBarrelRawHits" : "SiBarrelRawHitsWithNoise"}, + {"SiBarrelTrackerRecHits"}, {}, // default config + app, hit_level)); } } // extern "C" diff --git a/src/detectors/BVTX/BVTX.cc b/src/detectors/BVTX/BVTX.cc index c15a0210cf..0f6b266414 100644 --- a/src/detectors/BVTX/BVTX.cc +++ b/src/detectors/BVTX/BVTX.cc @@ -23,6 +23,9 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Digitization app->Add(new JOmniFactoryGeneratorT( @@ -31,21 +34,26 @@ void InitPlugin(JApplication* app) { { .threshold = 0.54 * dd4hep::keV, }, - app)); - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexNoiseRawHits", {"EventHeader"}, {"SiBarrelVertexNoiseRawHits"}, - {.addNoise = true, - .noise_rate_per_pixel_per_event = 2.0e-7, - .readout_name = "VertexBarrelHits"}, - app)); - app->Add(new JOmniFactoryGeneratorT>( - "SiBarrelVertexRawHitsWithNoise", {"SiBarrelVertexRawHits", "SiBarrelVertexNoiseRawHits"}, - {"SiBarrelVertexRawHitsWithNoise"}, {}, app)); + app, hit_level)); + // Per-pixel noise occupancy for the vertex barrel. Configurable via + // SiBarrelVertexNoiseRawHits:noise_rate_per_pixel_per_event (default 2e-7). + if (!split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelVertexNoiseRawHits", {"EventHeader"}, {"SiBarrelVertexNoiseRawHits"}, + {.addNoise = true, + .noise_rate_per_pixel_per_event = 2.0e-7, + .readout_name = "VertexBarrelHits"}, + app)); + app->Add(new JOmniFactoryGeneratorT>( + "SiBarrelVertexRawHitsWithNoise", {"SiBarrelVertexRawHits", "SiBarrelVertexNoiseRawHits"}, + {"SiBarrelVertexRawHitsWithNoise"}, {}, app)); + } // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexRecHits", {"SiBarrelVertexRawHitsWithNoise"}, {"SiBarrelVertexRecHits"}, - {}, // default config - app)); + "SiBarrelVertexRecHits", + {split_timeframes ? "SiBarrelVertexRawHits" : "SiBarrelVertexRawHitsWithNoise"}, + {"SiBarrelVertexRecHits"}, {}, // default config + app, hit_level)); } } // extern "C" diff --git a/src/detectors/ECTOF/ECTOF.cc b/src/detectors/ECTOF/ECTOF.cc index 9bff9a0459..3da67142c6 100644 --- a/src/detectors/ECTOF/ECTOF.cc +++ b/src/detectors/ECTOF/ECTOF.cc @@ -30,13 +30,25 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + + if (split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "TOFEndcapRawHits", {"EventHeader", "TOFEndcapHits"}, + {"TOFEndcapRawHits", "TOFEndcapRawHitLinks", "TOFEndcapRawHitAssociations"}, + {.threshold = 6.0 * dd4hep::keV, .timeResolution = 0.025}, app, JEventLevel::Timeslice)); + app->Add(new JOmniFactoryGeneratorT( + "TOFEndcapRecHits", {"TOFEndcapRawHits"}, {"TOFEndcapRecHits"}, {.timeResolution = 0.025}, + app, JEventLevel::Timeslice)); + } // cluster all hits in a sensor into one hit location // Currently it's just a simple weighted average // More sophisticated algorithm TBD app->Add(new JOmniFactoryGeneratorT( - "TOFEndcapClusterHits", {"TOFEndcapSharedRecHits"}, // Input data collection tags - {"TOFEndcapClusterHits"}, // Output data tag + "TOFEndcapClusterHits", {split_timeframes ? "TOFEndcapRecHits" : "TOFEndcapSharedRecHits"}, + {"TOFEndcapClusterHits"}, // Output data tag { .readout = "TOFEndcapHits", .useAve = true, diff --git a/src/detectors/ECTRK/ECTRK.cc b/src/detectors/ECTRK/ECTRK.cc index b8eda7d508..d121b0a268 100644 --- a/src/detectors/ECTRK/ECTRK.cc +++ b/src/detectors/ECTRK/ECTRK.cc @@ -22,6 +22,9 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Digitization app->Add(new JOmniFactoryGeneratorT( @@ -30,8 +33,11 @@ void InitPlugin(JApplication* app) { { .threshold = 0.54 * dd4hep::keV, }, - app)); + app, hit_level)); + // Per-pixel noise occupancy for the endcap silicon tracker. Configurable via + // SiEndcapTrackerNoiseRawHits:noise_rate_per_pixel_per_event (default 2e-7). + if (!split_timeframes) { app->Add(new JOmniFactoryGeneratorT( "SiEndcapTrackerNoiseRawHits", {"EventHeader"}, {"SiEndcapTrackerNoiseRawHits"}, {.addNoise = true, @@ -41,10 +47,13 @@ void InitPlugin(JApplication* app) { app->Add(new JOmniFactoryGeneratorT>( "SiEndcapTrackerRawHitsWithNoise", {"SiEndcapTrackerRawHits", "SiEndcapTrackerNoiseRawHits"}, {"SiEndcapTrackerRawHitsWithNoise"}, {}, app)); + } + // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerRecHits", {"SiEndcapTrackerRawHitsWithNoise"}, {"SiEndcapTrackerRecHits"}, - {}, // default config - app)); + "SiEndcapTrackerRecHits", + {split_timeframes ? "SiEndcapTrackerRawHits" : "SiEndcapTrackerRawHitsWithNoise"}, + {"SiEndcapTrackerRecHits"}, {}, // default config + app, hit_level)); } } // extern "C" diff --git a/src/detectors/EEMC/EEMC.cc b/src/detectors/EEMC/EEMC.cc index c432bce26c..ca5395098e 100644 --- a/src/detectors/EEMC/EEMC.cc +++ b/src/detectors/EEMC/EEMC.cc @@ -28,6 +28,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Make sure digi and reco use the same value decltype(CalorimeterHitDigiConfig::capADC) EcalEndcapN_capADC = 16384; //65536, 16bit ADC @@ -59,7 +62,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "EcalEndcapNHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalEndcapNRecHits", {"EcalEndcapNRawHits"}, {"EcalEndcapNRecHits"}, @@ -74,7 +77,7 @@ void InitPlugin(JApplication* app) { .sampFrac = "0.96", .readout = "EcalEndcapNHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalEndcapNTruthProtoClusters", {"EcalEndcapNRecHits", "EcalEndcapNHits"}, @@ -144,56 +147,62 @@ void InitPlugin(JApplication* app) { )); app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNClustersWithoutPID", + split_timeframes ? "EcalEndcapNClusters" : "EcalEndcapNClustersWithoutPID", {"EcalEndcapNClustersWithoutPIDAndShapes", "EcalEndcapNClusterAssociationsWithoutPIDAndShapes"}, - {"EcalEndcapNClustersWithoutPID", "EcalEndcapNClusterLinksWithoutPID", - "EcalEndcapNClusterAssociationsWithoutPID"}, + split_timeframes ? std::vector{"EcalEndcapNClusters", "EcalEndcapNClusterLinks", + "EcalEndcapNClusterAssociations"} + : std::vector{"EcalEndcapNClustersWithoutPID", + "EcalEndcapNClusterLinksWithoutPID", + "EcalEndcapNClusterAssociationsWithoutPID"}, {.energyWeight = "log", .logWeightBase = 3.6}, app)); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNParticleIDPreML", - { - "EcalEndcapNClustersWithoutPID", - "EcalEndcapNClusterAssociationsWithoutPID", - }, - { - "EcalEndcapNParticleIDInput_features", - "EcalEndcapNParticleIDTarget", - }, - app)); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNParticleIDInference", - { - "EcalEndcapNParticleIDInput_features", - }, - { - "EcalEndcapNParticleIDOutput_label", - "EcalEndcapNParticleIDOutput_probability_tensor", - }, - { - .modelPath = "calibrations/onnx/EcalEndcapN_pi_rejection.onnx", - }, - app)); - app->Add(new JOmniFactoryGeneratorT( - "EcalEndcapNParticleIDPostML", - { - "EcalEndcapNClustersWithoutPID", - "EcalEndcapNClusterAssociationsWithoutPID", - "EcalEndcapNParticleIDOutput_probability_tensor", - }, + if (!split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNParticleIDPreML", + { + "EcalEndcapNClustersWithoutPID", + "EcalEndcapNClusterAssociationsWithoutPID", + }, + { + "EcalEndcapNParticleIDInput_features", + "EcalEndcapNParticleIDTarget", + }, + app)); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNParticleIDInference", + { + "EcalEndcapNParticleIDInput_features", + }, + { + "EcalEndcapNParticleIDOutput_label", + "EcalEndcapNParticleIDOutput_probability_tensor", + }, + { + .modelPath = "calibrations/onnx/EcalEndcapN_pi_rejection.onnx", + }, + app)); + app->Add(new JOmniFactoryGeneratorT( + "EcalEndcapNParticleIDPostML", + { + "EcalEndcapNClustersWithoutPID", + "EcalEndcapNClusterAssociationsWithoutPID", + "EcalEndcapNParticleIDOutput_probability_tensor", + }, - { - "EcalEndcapNClusters", - "EcalEndcapNClusterLinks", - "EcalEndcapNClusterAssociations", - "EcalEndcapNClusterParticleIDs", - }, - app)); + { + "EcalEndcapNClusters", + "EcalEndcapNClusterLinks", + "EcalEndcapNClusterAssociations", + "EcalEndcapNClusterParticleIDs", + }, + app)); + } app->Add(new JOmniFactoryGeneratorT( "EcalEndcapNSplitMergeProtoClusters", - {"EcalEndcapNTrackClusterMatches", "EcalEndcapNClustersWithoutPID", + {"EcalEndcapNTrackClusterMatches", + split_timeframes ? "EcalEndcapNClusters" : "EcalEndcapNClustersWithoutPID", "CalorimeterTrackProjections"}, {"EcalEndcapNSplitMergeProtoClusters", "EcalEndcapNTrackSplitMergeProtoClusterLinks"}, {.minSigCut = -1.0, diff --git a/src/detectors/EHCAL/EHCAL.cc b/src/detectors/EHCAL/EHCAL.cc index 03d69ceaf3..da758b4e43 100644 --- a/src/detectors/EHCAL/EHCAL.cc +++ b/src/detectors/EHCAL/EHCAL.cc @@ -25,6 +25,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Make sure digi and reco use the same value decltype(CalorimeterHitDigiConfig::capADC) HcalEndcapN_capADC = 32768; // assuming 15 bit ADC like FHCal @@ -50,7 +53,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "HcalEndcapNHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "HcalEndcapNRecHits", {"HcalEndcapNRawHits"}, {"HcalEndcapNRecHits"}, @@ -67,7 +70,7 @@ void InitPlugin(JApplication* app) { "0.0095", // from latest study - implement at level of reco hits rather than clusters .readout = "HcalEndcapNHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "HcalEndcapNMergedHits", {"HcalEndcapNRecHits"}, {"HcalEndcapNMergedHits"}, diff --git a/src/detectors/FEMC/FEMC.cc b/src/detectors/FEMC/FEMC.cc index b101023ac1..7dc28a37b6 100644 --- a/src/detectors/FEMC/FEMC.cc +++ b/src/detectors/FEMC/FEMC.cc @@ -33,6 +33,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; auto log_service = app->GetService(); auto mLog = log_service->logger("FEMC"); @@ -89,7 +92,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "EcalEndcapPHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); } else if (EcalEndcapP_homogeneousFlag == 2) { app->Add(new JOmniFactoryGeneratorT( @@ -115,7 +118,7 @@ void InitPlugin(JApplication* app) { .readout = "EcalEndcapPHits", .fields = {"fiber_x", "fiber_y"}, }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); } @@ -134,7 +137,7 @@ void InitPlugin(JApplication* app) { .sampFrac = "1.00", // already taken care in DIGI code above .readout = "EcalEndcapPHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalEndcapPTruthProtoClusters", {"EcalEndcapPRecHits", "EcalEndcapPHits"}, diff --git a/src/detectors/FHCAL/FHCAL.cc b/src/detectors/FHCAL/FHCAL.cc index 3702f6ee3c..5790400bf4 100644 --- a/src/detectors/FHCAL/FHCAL.cc +++ b/src/detectors/FHCAL/FHCAL.cc @@ -29,6 +29,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Make sure digi and reco use the same value decltype(CalorimeterHitDigiConfig::capADC) HcalEndcapPInsert_capADC = 32768; @@ -53,7 +56,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "HcalEndcapPInsertHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "HcalEndcapPInsertRecHits", {"HcalEndcapPInsertRawHits"}, {"HcalEndcapPInsertRecHits"}, @@ -70,7 +73,7 @@ void InitPlugin(JApplication* app) { .readout = "HcalEndcapPInsertHits", .layerField = "layer", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "HcalEndcapPInsertMergedHits", {"HcalEndcapPInsertRecHits"}, {"HcalEndcapPInsertMergedHits"}, @@ -194,7 +197,7 @@ void InitPlugin(JApplication* app) { .readout = "LFHCALHits", .fields = {"layerz"}, }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "LFHCALRecHits", {"LFHCALRawHits"}, {"LFHCALRecHits"}, @@ -210,7 +213,7 @@ void InitPlugin(JApplication* app) { .readout = "LFHCALHits", .layerField = "rlayerz", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "LFHCALTruthProtoClusters", {"LFHCALRecHits", "LFHCALHits"}, {"LFHCALTruthProtoClusters"}, diff --git a/src/detectors/FOFFMTRK/FOFFMTRK.cc b/src/detectors/FOFFMTRK/FOFFMTRK.cc index 5ff1a6d710..727ed7ffce 100644 --- a/src/detectors/FOFFMTRK/FOFFMTRK.cc +++ b/src/detectors/FOFFMTRK/FOFFMTRK.cc @@ -19,6 +19,9 @@ extern "C" { void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; //Digitized hits, especially for thresholds app->Add(new JOmniFactoryGeneratorT( @@ -29,14 +32,14 @@ void InitPlugin(JApplication* app) { .threshold = 10.0 * dd4hep::keV, .timeResolution = 8, }, - app)); + app, hit_level)); app->Add(new JOmniFactoryGeneratorT( "ForwardOffMTrackerRecHits", {"ForwardOffMTrackerRawHits"}, {"ForwardOffMTrackerRecHits"}, { .timeResolution = 8, }, - app)); + app, hit_level)); app->Add(new JOmniFactoryGeneratorT( "ForwardOffMRecParticles", {"MCParticles", "ForwardOffMTrackerRecHits"}, diff --git a/src/detectors/LOWQ2/LOWQ2.cc b/src/detectors/LOWQ2/LOWQ2.cc index 4ef8cffa8f..905c063209 100644 --- a/src/detectors/LOWQ2/LOWQ2.cc +++ b/src/detectors/LOWQ2/LOWQ2.cc @@ -45,6 +45,9 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; std::string readout = "TaggerTrackerHits"; @@ -96,7 +99,7 @@ void InitPlugin(JApplication* app) { .threshold = 1.5 * edm4eic::unit::keV, .timeResolution = 2 * edm4eic::unit::ns, }, - app)); + app, hit_level)); // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( @@ -104,7 +107,7 @@ void InitPlugin(JApplication* app) { { .timeResolution = 2, }, - app)); + app, hit_level)); // Divide collection based on geometry segmentation labels // This should really be done before digitization as summing hits in the same cell couldn't even be mixed between layers. At the moment just prep for clustering. diff --git a/src/detectors/LUMISPECCAL/LUMISPECCAL.cc b/src/detectors/LUMISPECCAL/LUMISPECCAL.cc index 8fd5a33eac..8014a989c3 100644 --- a/src/detectors/LUMISPECCAL/LUMISPECCAL.cc +++ b/src/detectors/LUMISPECCAL/LUMISPECCAL.cc @@ -23,6 +23,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; app->Add(new JOmniFactoryGeneratorT( "EcalLumiSpecRawHits", {"EventHeader", "EcalLumiSpecHits"}, @@ -38,7 +41,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "EcalLumiSpecHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalLumiSpecRecHits", {"EcalLumiSpecRawHits"}, {"EcalLumiSpecRecHits"}, @@ -53,7 +56,7 @@ void InitPlugin(JApplication* app) { .sampFrac = "1.0", .readout = "EcalLumiSpecHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalLumiSpecTruthProtoClusters", {"EcalLumiSpecRecHits", "EcalLumiSpecHits"}, diff --git a/src/detectors/MPGD/MPGD.cc b/src/detectors/MPGD/MPGD.cc index 4c2879dcca..0b9d9bebb6 100644 --- a/src/detectors/MPGD/MPGD.cc +++ b/src/detectors/MPGD/MPGD.cc @@ -40,6 +40,9 @@ void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // ***** PIXEL or 2DSTRIP DIGITIZATION? // - This determines which of the MPGDTrackerDigi or SiliconTrackerDigi @@ -106,7 +109,7 @@ void InitPlugin(JApplication* app) { .threshold = 100 * dd4hep::eV, .timeResolution = 10, }, - app)); + app, hit_level)); } else { // Configuration parameters MPGDTrackerDigiConfig digi_cfg; @@ -131,7 +134,7 @@ void InitPlugin(JApplication* app) { app->Add(new JOmniFactoryGeneratorT( "MPGDBarrelRawHits", {"EventHeader", "MPGDBarrelHits"}, {"MPGDBarrelRawHits", "MPGDBarrelRawHitLinks", "MPGDBarrelRawHitAssociations"}, digi_cfg, - app)); + app, hit_level)); } // Convert raw digitized hits into hits with geometry info (ready for tracking) @@ -142,7 +145,7 @@ void InitPlugin(JApplication* app) { { .timeResolution = 10, }, - app)); + app, hit_level)); } else { MPGDHitReconstructionConfig reco_cfg; reco_cfg.readout = "MPGDBarrelHits"; @@ -151,7 +154,7 @@ void InitPlugin(JApplication* app) { app->Add(new JOmniFactoryGeneratorT( "MPGDBarrelRecHits", {"MPGDBarrelRawHits"}, // Input data collection tags {"MPGDBarrelRecHits"}, // Output data tag - reco_cfg, app)); + reco_cfg, app, hit_level)); } // ***** OuterMPGDBarrel @@ -165,7 +168,7 @@ void InitPlugin(JApplication* app) { .threshold = 100 * dd4hep::eV, .timeResolution = 10, }, - app)); + app, hit_level)); } else { MPGDTrackerDigiConfig digi_cfg; digi_cfg.readout = "OuterMPGDBarrelHits"; @@ -186,7 +189,7 @@ void InitPlugin(JApplication* app) { "OuterMPGDBarrelRawHits", {"EventHeader", "OuterMPGDBarrelHits"}, {"OuterMPGDBarrelRawHits", "OuterMPGDBarrelRawHitLinks", "OuterMPGDBarrelRawHitAssociations"}, - digi_cfg, app)); + digi_cfg, app, hit_level)); } // Convert raw digitized hits into hits with geometry info (ready for tracking) @@ -197,7 +200,7 @@ void InitPlugin(JApplication* app) { { .timeResolution = 10, }, - app)); + app, hit_level)); } else { MPGDHitReconstructionConfig reco_cfg; reco_cfg.readout = "OuterMPGDBarrelHits"; @@ -206,7 +209,7 @@ void InitPlugin(JApplication* app) { app->Add(new JOmniFactoryGeneratorT( "OuterMPGDBarrelRecHits", {"OuterMPGDBarrelRawHits"}, // Input data collection tags {"OuterMPGDBarrelRecHits"}, // Output data tag - reco_cfg, app)); + reco_cfg, app, hit_level)); } // ***** "BackwardMPGDEndcap" @@ -219,7 +222,7 @@ void InitPlugin(JApplication* app) { .threshold = 100 * dd4hep::eV, .timeResolution = 10, }, - app)); + app, hit_level)); // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( @@ -228,7 +231,7 @@ void InitPlugin(JApplication* app) { { .timeResolution = 10, }, - app)); + app, hit_level)); // ""ForwardMPGDEndcap" // Digitization @@ -240,7 +243,7 @@ void InitPlugin(JApplication* app) { .threshold = 100 * dd4hep::eV, .timeResolution = 10, }, - app)); + app, hit_level)); // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( @@ -249,6 +252,6 @@ void InitPlugin(JApplication* app) { { .timeResolution = 10, }, - app)); + app, hit_level)); } } // extern "C" diff --git a/src/detectors/RPOTS/RPOTS.cc b/src/detectors/RPOTS/RPOTS.cc index c28d68e920..2de5721628 100644 --- a/src/detectors/RPOTS/RPOTS.cc +++ b/src/detectors/RPOTS/RPOTS.cc @@ -21,6 +21,9 @@ extern "C" { void InitPlugin(JApplication* app) { InitJANAPlugin(app); using namespace eicrecon; + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; MatrixTransferStaticConfig recon_cfg; PolynomialMatrixReconstructionConfig recon_poly_cfg; @@ -33,14 +36,14 @@ void InitPlugin(JApplication* app) { .threshold = 10.0 * dd4hep::keV, .timeResolution = 8, }, - app)); + app, hit_level)); app->Add(new JOmniFactoryGeneratorT( "ForwardRomanPotRecHits", {"ForwardRomanPotRawHits"}, {"ForwardRomanPotRecHits"}, { .timeResolution = 8, }, - app)); + app, hit_level)); app->Add(new JOmniFactoryGeneratorT( "ForwardRomanPotStaticRecParticles", diff --git a/src/detectors/ZDC/ZDC.cc b/src/detectors/ZDC/ZDC.cc index cc4c528ffb..127e09c8aa 100644 --- a/src/detectors/ZDC/ZDC.cc +++ b/src/detectors/ZDC/ZDC.cc @@ -26,6 +26,9 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // LYSO part of the ZDC app->Add(new JOmniFactoryGeneratorT( @@ -43,7 +46,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "EcalFarForwardZDCHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalFarForwardZDCRecHits", {"EcalFarForwardZDCRawHits"}, {"EcalFarForwardZDCRecHits"}, @@ -58,7 +61,7 @@ void InitPlugin(JApplication* app) { .sampFrac = "1.0", .readout = "EcalFarForwardZDCHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( "EcalFarForwardZDCTruthProtoClusters", {"EcalFarForwardZDCRecHits", "EcalFarForwardZDCHits"}, @@ -152,7 +155,7 @@ void InitPlugin(JApplication* app) { .corrMeanScale = "1.0", .readout = "HcalFarForwardZDCHits", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( @@ -170,7 +173,7 @@ void InitPlugin(JApplication* app) { .layerField = "layer", .sectorField = "system", }, - app // TODO: Remove me once fixed + app, hit_level // TODO: Remove me once fixed )); app->Add(new JOmniFactoryGeneratorT( diff --git a/src/extensions/jana/JOmniFactoryGeneratorT.h b/src/extensions/jana/JOmniFactoryGeneratorT.h index f5846bf4fc..1326b3b51e 100644 --- a/src/extensions/jana/JOmniFactoryGeneratorT.h +++ b/src/extensions/jana/JOmniFactoryGeneratorT.h @@ -18,6 +18,7 @@ template class JOmniFactoryGeneratorT : public JFactoryGenerato std::vector m_default_input_tags; std::vector m_default_output_tags; FactoryConfigType m_default_cfg; /// Must be properly copyable! + JEventLevel m_level = JEventLevel::PhysicsEvent; }; struct UntypedWiring { @@ -30,21 +31,25 @@ template class JOmniFactoryGeneratorT : public JFactoryGenerato public: explicit JOmniFactoryGeneratorT(std::string tag, std::vector default_input_tags, std::vector default_output_tags, - FactoryConfigType cfg, JApplication* app) { + FactoryConfigType cfg, JApplication* app, + JEventLevel level = JEventLevel::PhysicsEvent) { m_app = app; m_wirings.push_back({.m_tag = tag, .m_default_input_tags = default_input_tags, .m_default_output_tags = default_output_tags, - .m_default_cfg = cfg}); + .m_default_cfg = cfg, + .m_level = level}); }; explicit JOmniFactoryGeneratorT(std::string tag, std::vector default_input_tags, - std::vector default_output_tags, JApplication* app) { + std::vector default_output_tags, JApplication* app, + JEventLevel level = JEventLevel::PhysicsEvent) { m_app = app; m_wirings.push_back({.m_tag = tag, .m_default_input_tags = default_input_tags, .m_default_output_tags = default_output_tags, - .m_default_cfg = {}}); + .m_default_cfg = {}, + .m_level = level}); } explicit JOmniFactoryGeneratorT(JApplication* app) : m_app(app) {} @@ -55,7 +60,8 @@ template class JOmniFactoryGeneratorT : public JFactoryGenerato m_wirings.push_back({.m_tag = tag, .m_default_input_tags = default_input_tags, .m_default_output_tags = default_output_tags, - .m_default_cfg = cfg}); + .m_default_cfg = cfg, + .m_level = JEventLevel::PhysicsEvent}); } void AddWiring(std::string tag, std::vector default_input_tags, @@ -70,7 +76,8 @@ template class JOmniFactoryGeneratorT : public JFactoryGenerato m_wirings.push_back({.m_tag = tag, .m_default_input_tags = default_input_tags, .m_default_output_tags = default_output_tags, - .m_default_cfg = config}); + .m_default_cfg = config, + .m_level = JEventLevel::PhysicsEvent}); } void GenerateFactories(JFactorySet* factory_set) override { @@ -82,6 +89,7 @@ template class JOmniFactoryGeneratorT : public JFactoryGenerato factory->SetPluginName(this->GetPluginName()); factory->SetFactoryName(JTypeInfo::demangle()); factory->config() = wiring.m_default_cfg; + factory->SetLevel(wiring.m_level); // Set up all of the wiring prereqs so that Init() can do its thing // Specifically, it needs valid input/output tags, a valid logger, and diff --git a/src/global/CMakeLists.txt b/src/global/CMakeLists.txt index bdca9fd35e..4c75d68823 100644 --- a/src/global/CMakeLists.txt +++ b/src/global/CMakeLists.txt @@ -4,3 +4,4 @@ add_subdirectory(particle_flow) add_subdirectory(pid) add_subdirectory(pid_lut) add_subdirectory(beam) +add_subdirectory(splitting) diff --git a/src/global/splitting/CMakeLists.txt b/src/global/splitting/CMakeLists.txt new file mode 100644 index 0000000000..b33f1de1da --- /dev/null +++ b/src/global/splitting/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.16) + +if(JANA_VERSION VERSION_LESS "2.4.3") + + message(STATUS "Skipping `splitting` plugin because JANA_VERSION < 2.4.3") + +else() + + get_filename_component(PLUGIN_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) + + # Function creates ${PLUGIN_NAME}_plugin and ${PLUGIN_NAME}_library targets + # Setting default includes, libraries and installation paths + plugin_add(${PLUGIN_NAME} PLUGIN_USE_CC_ONLY) + + # The macro grabs sources as *.cc *.cpp *.c and headers as *.h *.hh *.hpp Then + # correctly sets sources for ${_name}_plugin and ${_name}_library targets Adds + # headers to the correct installation directory + plugin_glob_all(${PLUGIN_NAME}) + + # Find dependencies + plugin_add_cern_root(${PLUGIN_NAME}) + plugin_add_event_model(${PLUGIN_NAME}) + + # Add include directories (works same as target_include_directories) + # plugin_include_directories(${PLUGIN_NAME} SYSTEM PUBLIC ... ) + + # Add libraries (same as target_include_directories but for both plugin and + # library) + plugin_link_libraries(${PLUGIN_NAME} algorithms_digi_library + algorithms_tracking_library) + # + # Add include directories (works same as target_include_directories) + # plugin_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR} + # SYSTEM PUBLIC ${podio_INCLUDE_DIR} ${EDM4HEP_INCLUDE_DIR} + # ${DD4hep_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} ${EDM4EIC_INCLUDE_DIRS}) + # + # Add libraries (works same as target_include_directories) + # plugin_link_libraries(${PLUGIN_NAME} ${ROOT_LIBRARIES} + # algorithms_tracking_library EDM4HEP::edm4hep EDM4EIC::edm4eic spdlog::spdlog + # Boost::boost ${ROOT_EG_LIBRARY}) + +endif() diff --git a/src/global/splitting/CalRecTimeAlignmentFactory.h b/src/global/splitting/CalRecTimeAlignmentFactory.h new file mode 100644 index 0000000000..2256a3016f --- /dev/null +++ b/src/global/splitting/CalRecTimeAlignmentFactory.h @@ -0,0 +1,91 @@ +// Copyright 2024, Jefferson Science Associates, LLC. +// Subject to the terms in the LICENSE file found in the top-level directory. + +#pragma once + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +struct CalRecTimeAlignmentFactory : public JOmniFactory { + JEventLevel m_factory_level; + + std::vector m_simcalorechit_collection_names = {"B0ECalRecHits", + "EcalBarrelImagingRecHits", + "EcalBarrelScFiRecHits", + "EcalEndcapNRecHits", + "EcalEndcapPRecHits", + "EcalFarForwardZDCRecHits", + "EcalLumiSpecRecHits", + "HcalBarrelRecHits", + "HcalEndcapNRecHits", + "HcalEndcapPInsertRecHits", + "HcalFarForwardZDCRecHits", + "LFHCALRecHits"}; + + std::vector m_simcalorechit_collection_names_aligned = { + "B0ECalRecHits_aligned", + "EcalBarrelImagingRecHits_aligned", + "EcalBarrelScFiRecHits_aligned", + "EcalEndcapNRecHits_aligned", + "EcalEndcapPRecHits_aligned", + "EcalFarForwardZDCRecHits_aligned", + "EcalLumiSpecRecHits_aligned", + "HcalBarrelRecHits_aligned", + "HcalEndcapNRecHits_aligned", + "HcalEndcapPInsertRecHits_aligned", + "HcalFarForwardZDCRecHits_aligned", + "LFHCALRecHits_aligned"}; + + VariadicPodioInput m_calorechit_in{ + this, m_simcalorechit_collection_names}; + + VariadicPodioOutput m_calorechit_out{ + this, m_simcalorechit_collection_names_aligned}; + + Double_t m_time_offset = 0.0; // Time offset to apply to hits + + void Configure() {} + + void ChangeRun(int32_t /*run_nr*/) {} + + void Process(int64_t /*run_number*/, uint64_t /*event_number*/) { + + for (size_t coll_index = 0; coll_index < m_calorechit_in().size(); ++coll_index) { + const auto* coll_in = m_calorechit_in().at(coll_index); + auto& coll_out = m_calorechit_out().at(coll_index); + + if (coll_in != nullptr) { + std::vector sorted_hits; // for edm4eic (After digitization) + for (const auto& hit : *coll_in) { + edm4eic::MutableCalorimeterHit copiedHit = + hit.clone(); // for edm4eic (After digitization) + + Double_t hitR = std::sqrt(hit.getPosition()[0] * hit.getPosition()[0] + + hit.getPosition()[1] * hit.getPosition()[1] + + hit.getPosition()[2] * hit.getPosition()[2]); + Double_t calibTime = hitR * 0.0034; + copiedHit.setTime(hit.getTime() - calibTime); + sorted_hits.push_back(copiedHit); + } + + std::sort(sorted_hits.begin(), sorted_hits.end(), + [](const auto& a, const auto& b) { return a.getTime() < b.getTime(); }); + + for (const auto& hit : sorted_hits) { + coll_out->push_back(hit); + } + } + } + } +}; diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h new file mode 100644 index 0000000000..64d104d40b --- /dev/null +++ b/src/global/splitting/TimeframeSplitter.h @@ -0,0 +1,1392 @@ +// Copyright 2024, Jefferson Science Associates, LLC. +// Subject to the terms in the LICENSE file found in the top-level directory. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TMath.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct TimeframeSplitter : public JEventUnfolder { + + Parameter timeframe_width{this, "timeframe_width", 2000.0, + "Width of each timeframe in ns"}; + Parameter timesplit_width{this, "timesplit_width", 20.0, "Width of each timeslice in ns"}; + Parameter timeResolution_SiMaps{this, "timeResolution_Silicon", 2000.0, + "time resolution of Silicon detector in ns"}; + Parameter timeResolution_MPGD{this, "timeResolution_MPGD", 30.0, + "time resolution of MPGD detector in ns"}; + // Parameter timeResolution_ACLGad{this, "timeResolution_TOF", 0.03, + // "time resolution of TOF detector in ns"}; + Parameter timeResolution_ACLGad{this, "timeResolution_TOF", 20.0, + "time resolution of TOF detector in ns"}; + Parameter timeResolution_EMCal{this, "timeResolution_EMCal", 20.0, + "time resolution of EMCal detector in ns"}; + bool m_use_timeframe = false; // Use timeframes to split events, or use timeslices + + Int_t m_OrigTFCount = 0; //QA + Int_t m_NewEventCount = 0; //QA + Int_t m_PhysCount = 0; //QA + + size_t m_event_number_ts = 0; // Event number for the current timeslice + size_t m_event_number_orig = 0; // Event number for the current timeslice + std::vector m_vTargetEvent; // List of original event numbers for each timeslice + + static constexpr Int_t kEtaPhiBins = 10; + static constexpr Int_t kInvalidEtaPhiBin = -1; + + using EtaPhiGrid = std::array, kEtaPhiBins>; + using EtaPhiTimeGrid = std::array, kEtaPhiBins>; + using EtaPhiEnergyGrid = std::array, kEtaPhiBins>; + + enum TrkCollectionIndex : size_t { + kTrkB0 = 0, + kTrkTOFBarrel = 1, + kTrkTOFEndcap = 2, + kTrkMPGDBarrel = 3, + kTrkOuterMPGDBarrel = 4, + kTrkBackwardMPGD = 5, + kTrkForwardMPGD = 6, + kTrkSiBarrelVertex = 7, + kTrkSiBarrel = 8, + kTrkSiEndcap = 9, + kTrkTagger = 10, + kTrkForwardRomanPot = 11, + kTrkForwardOffMTracker = 12 + }; + + enum CalRecCollectionIndex : size_t { + kCalB0ECal = 0, + kCalBarrelImg = 1, + kCalBarrelScifi = 2, + kCalEndcapN = 3, + kCalEndcapP = 4, + kCalZDC = 5, + kCalLumi = 6 + }; + + std::vector m_trackerhit_collection_names = { + "B0TrackerRecHits_aligned", "TOFBarrelRecHits_aligned", + "TOFEndcapRecHits_aligned", "MPGDBarrelRecHits_aligned", + "OuterMPGDBarrelRecHits_aligned", "BackwardMPGDEndcapRecHits_aligned", + "ForwardMPGDEndcapRecHits_aligned", "SiBarrelVertexRecHits_aligned", + "SiBarrelTrackerRecHits_aligned", "SiEndcapTrackerRecHits_aligned", + "TaggerTrackerRecHits_aligned", "ForwardRomanPotRecHits_aligned", + "ForwardOffMTrackerRecHits_aligned"}; + + // "RICHEndcapNRecHits_aligned" + // "DIRCBarRecHits_aligned", + // "DRICHRecHits_aligned", + + std::vector m_trackerhit_collection_names_out = { + "B0TrackerRecHits", "TOFBarrelRecHits", "TOFEndcapRecHits", + "MPGDBarrelRecHits", "OuterMPGDBarrelRecHits", "BackwardMPGDEndcapRecHits", + "ForwardMPGDEndcapRecHits", "SiBarrelVertexRecHits", "SiBarrelTrackerRecHits", + "SiEndcapTrackerRecHits", "TaggerTrackerRecHits", "ForwardRomanPotRecHits", + "ForwardOffMTrackerRecHits"}; + + // "RICHEndcapNRecHits" + // "DIRCBarRecHits", + // "DRICHRecHits", + + std::vector m_simtrackerhitAsso_collection_names = { + "B0TrackerRawHitAssociations", "TOFBarrelRawHitAssociations", + "TOFEndcapRawHitAssociations", "MPGDBarrelRawHitAssociations", + "OuterMPGDBarrelRawHitAssociations", "BackwardMPGDEndcapRawHitAssociations", + "ForwardMPGDEndcapRawHitAssociations", "SiBarrelVertexRawHitAssociations", + "SiBarrelRawHitAssociations", "SiEndcapTrackerRawHitAssociations", + "TaggerTrackerRawHitAssociations", "ForwardRomanPotRawHitAssociations", + "ForwardOffMTrackerRawHitAssociations"}; + + // "RICHEndcapNRawHitAssociations" + // "DIRCBarRawHitsAssociations", + // "DRICHRawHitAssociations", + + std::vector m_simtrackerhitAsso_collection_names_out = { + "B0TrackerRawHitAssociations", "TOFBarrelRawHitAssociations", + "TOFEndcapRawHitAssociations", "MPGDBarrelRawHitAssociations", + "OuterMPGDBarrelRawHitAssociations", "BackwardMPGDEndcapRawHitAssociations", + "ForwardMPGDEndcapRawHitAssociations", "SiBarrelVertexRawHitAssociations", + "SiBarrelRawHitAssociations", "SiEndcapTrackerRawHitAssociations", + "TaggerTrackerRawHitAssociations", "ForwardRomanPotRawHitAssociations", + "ForwardOffMTrackerRawHitAssociations"}; + // "RICHEndcapNRawHitsAssociations" + // "DIRCBarRawHitAssociations", + // "DRICHRawHitsAssociations", + + std::vector m_rawhitlink_collection_names = { + "B0TrackerRawHitLinks", "TOFBarrelRawHitLinks", "TOFEndcapRawHitLinks", + "MPGDBarrelRawHitLinks", "OuterMPGDBarrelRawHitLinks", "BackwardMPGDEndcapRawHitLinks", + "ForwardMPGDEndcapRawHitLinks", "SiBarrelVertexRawHitLinks", "SiBarrelRawHitLinks", + "SiEndcapTrackerRawHitLinks", "TaggerTrackerRawHitLinks", "ForwardRomanPotRawHitLinks", + "ForwardOffMTrackerRawHitLinks"}; + // "RICHEndcapNRawHitsLinks" + // "DIRCBarRawHitLinks", + // "DRICHRawHitLinks", + + std::vector m_rawhitlink_collection_names_out = { + "B0TrackerRawHitLinks", "TOFBarrelRawHitLinks", "TOFEndcapRawHitLinks", + "MPGDBarrelRawHitLinks", "OuterMPGDBarrelRawHitLinks", "BackwardMPGDEndcapRawHitLinks", + "ForwardMPGDEndcapRawHitLinks", "SiBarrelVertexRawHitLinks", "SiBarrelRawHitLinks", + "SiEndcapTrackerRawHitLinks", "TaggerTrackerRawHitLinks", "ForwardRomanPotRawHitLinks", + "ForwardOffMTrackerRawHitLinks"}; + // "RICHEndcapNRawHitsLinks" + // "DIRCBarRawHitLinks", + // "DRICHRawHitsLinks", + + std::vector m_simtrackerhit_collection_names_out = { + "B0TrackerHits", "TOFBarrelHits", "TOFEndcapHits", + "MPGDBarrelHits", "OuterMPGDBarrelHits", "BackwardMPGDEndcapHits", + "ForwardMPGDEndcapHits", "VertexBarrelHits", "SiBarrelHits", + "TrackerEndcapHits", "TaggerTrackerHits", "ForwardRomanPotHits", + "ForwardOffMTrackerHits"}; + + std::vector m_rawhit_collection_names = { + "B0TrackerRawHits", "TOFBarrelRawHits", "TOFEndcapRawHits", + "MPGDBarrelRawHits", "OuterMPGDBarrelRawHits", "BackwardMPGDEndcapRawHits", + "ForwardMPGDEndcapRawHits", "SiBarrelVertexRawHits", "SiBarrelRawHits", + "SiEndcapTrackerRawHits", "TaggerTrackerRawHits", "ForwardRomanPotRawHits", + "ForwardOffMTrackerRawHits"}; + // "RICHEndcapNRawHits" + // "DIRCBarRawHits", + // "DRICHRawHits", + + std::vector m_rawhit_collection_names_out = { + "B0TrackerRawHits", "TOFBarrelRawHits", "TOFEndcapRawHits", + "MPGDBarrelRawHits", "OuterMPGDBarrelRawHits", "BackwardMPGDEndcapRawHits", + "ForwardMPGDEndcapRawHits", "SiBarrelVertexRawHits", "SiBarrelRawHits", + "SiEndcapTrackerRawHits", "TaggerTrackerRawHits", "ForwardRomanPotRawHits", + "ForwardOffMTrackerRawHits"}; + // "ForwardOffMTrackerRawHits", + // "RICHEndcapNRawHits" + // "DIRCBarRawHits", + // "DRICHRawHits", + + std::vector m_calorawhit_collection_names_in = {"B0ECalRawHits", + "EcalBarrelImagingRawHits", + "EcalBarrelScFiRawHits", + "EcalEndcapNRawHits", + "EcalEndcapPRawHits", + "EcalFarForwardZDCRawHits", + "EcalLumiSpecRawHits", + "HcalBarrelRawHits", + "HcalEndcapNRawHits", + "HcalEndcapPInsertRawHits", + "HcalFarForwardZDCRawHits", + "LFHCALRawHits"}; + + std::vector m_calorawhit_collection_names_out = {"B0ECalRawHits", + "EcalBarrelImagingRawHits", + "EcalBarrelScFiRawHits", + "EcalEndcapNRawHits", + "EcalEndcapPRawHits", + "EcalFarForwardZDCRawHits", + "EcalLumiSpecRawHits", + "HcalBarrelRawHits", + "HcalEndcapNRawHits", + "HcalEndcapPInsertRawHits", + "HcalFarForwardZDCRawHits", + "LFHCALRawHits"}; + + std::vector m_calorawhitlink_collection_names = {"B0ECalRawHitLinks", + "EcalBarrelImagingRawHitLinks", + "EcalBarrelScFiRawHitLinks", + "EcalEndcapNRawHitLinks", + "EcalEndcapPRawHitLinks", + "EcalFarForwardZDCRawHitLinks", + "EcalLumiSpecRawHitLinks", + "HcalBarrelRawHitLinks", + "HcalEndcapNRawHitLinks", + "HcalEndcapPInsertRawHitLinks", + "HcalFarForwardZDCRawHitLinks", + "LFHCALRawHitLinks"}; + + std::vector m_simcalorimeterhit_collection_names_out = { + "B0ECalHits", "EcalBarrelImagingHits", "EcalBarrelScFiHits", "EcalEndcapNHits", + "EcalEndcapPHits", "EcalFarForwardZDCHits", "EcalLumiSpecHits", "HcalBarrelHits", + "HcalEndcapNHits", "HcalEndcapPInsertHits", "HcalFarForwardZDCHits", "LFHCALHits"}; + + std::vector m_calorechit_collection_names_in = {"B0ECalRecHits_aligned", + "EcalBarrelImagingRecHits_aligned", + "EcalBarrelScFiRecHits_aligned", + "EcalEndcapNRecHits_aligned", + "EcalEndcapPRecHits_aligned", + "EcalFarForwardZDCRecHits_aligned", + "EcalLumiSpecRecHits_aligned", + "HcalBarrelRecHits_aligned", + "HcalEndcapNRecHits_aligned", + "HcalEndcapPInsertRecHits_aligned", + "HcalFarForwardZDCRecHits_aligned", + "LFHCALRecHits_aligned"}; + + std::vector m_calorechit_collection_names_out = {"B0ECalRecHits", + "EcalBarrelImagingRecHits", + "EcalBarrelScFiRecHits", + "EcalEndcapNRecHits", + "EcalEndcapPRecHits", + "EcalFarForwardZDCRecHits", + "EcalLumiSpecRecHits", + "HcalBarrelRecHits", + "HcalEndcapNRecHits", + "HcalEndcapPInsertRecHits", + "HcalFarForwardZDCRecHits", + "LFHCALRecHits"}; + + std::vector m_calorechitassociation_collection_names_in = { + "B0ECalRawHitAssociations", + "EcalBarrelImagingRawHitAssociations", + "EcalBarrelScFiRawHitAssociations", + "EcalEndcapNRawHitAssociations", + "EcalEndcapPRawHitAssociations", + "EcalFarForwardZDCRawHitAssociations", + "EcalLumiSpecRawHitAssociations", + "HcalBarrelRawHitAssociations", + "HcalEndcapNRawHitAssociations", + "HcalEndcapPInsertRawHitAssociations", + "HcalFarForwardZDCRawHitAssociations", + "LFHCALRawHitAssociations"}; + + std::vector m_calorechitassociation_collection_names_out = { + "B0ECalRawHitAssociations", + "EcalBarrelImagingRawHitAssociations", + "EcalBarrelScFiRawHitAssociations", + "EcalEndcapNRawHitAssociations", + "EcalEndcapPRawHitAssociations", + "EcalFarForwardZDCRawHitAssociations", + "EcalLumiSpecRawHitAssociations", + "HcalBarrelRawHitAssociations", + "HcalEndcapNRawHitAssociations", + "HcalEndcapPInsertRawHitAssociations", + "HcalFarForwardZDCRawHitAssociations", + "LFHCALRawHitAssociations"}; + + // std::vector m_calohitcontribution_collection_names = { + // "B0ECalHitsContributions", + // "EcalBarrelImagingHitsContributions", + // "EcalBarrelScFiHitsContributions", + // "EcalEndcapNHitsContributions", + // "EcalEndcapPHitsContributions", + // "EcalEndcapPInsertHitsContributions", + // "EcalLumiSpecHitsContributions", + // "EcalFarForwardZDCHitsContributions", + // "HcalBarrelHitsContributions", + // "HcalEndcapNHitsContributions", + // "HcalEndcapPInsertHitsContributions", + // "HcalFarForwardZDCHitsContributions", + // "LFHCALHitsContributions", + // "LumiDirectPCALHitsContributions"}; + + std::vector m_calocluster_collection_names_in = { + "B0ECalClusters_aligned", + "EcalBarrelClusters_aligned", + "EcalEndcapNClusters_aligned", + "EcalEndcapPClusters_aligned", + }; + // "EcalFarForwardZDCClusters_aligned", + // "EcalLumiSpecClusters_aligned", + // "HcalBarrelClusters_aligned", + // "HcalEndcapNClusters_aligned", + // "HcalEndcapPInsertClusters_aligned", + // "HcalFarForwardZDCClusters_aligned", + // "LFHCALClusters_aligned", + // "EcalBarrelImagingClusters_aligned", + // "EcalBarrelScFiClusters_aligned", + // "EcalEndcapNImagingClusters_aligned", + // "EcalEndcapPImagingClusters_aligned", + // "EcalFarForwardZDCImagingClusters_aligned", + // "EcalLumiSpecImagingClusters_aligned" + + std::vector m_calocluster_collection_names_out = { + "B0ECalClusters", + "EcalBarrelClusters", + "EcalEndcapNClusters", + "EcalEndcapPClusters", + }; + // "EcalFarForwardZDCClusters", + // "EcalLumiSpecClusters", + // "HcalBarrelClusters", + // "HcalEndcapNClusters", + // "HcalEndcapPInsertClusters", + // "HcalFarForwardZDCClusters", + // "LFHCALClusters", + // "EcalBarrelImagingClusters", + // "EcalBarrelScFiClusters", + // "EcalEndcapNImagingClusters", + // "EcalEndcapPImagingClusters", + // "EcalFarForwardZDCImagingClusters", + // "EcalLumiSpecImagingClusters" + + std::vector m_caloclusterassociation_collection_names_in = { + "B0ECalClusterAssociations", + "EcalBarrelClusterAssociations", + "EcalEndcapNClusterAssociations", + "EcalEndcapPClusterAssociations", + }; + // "HcalBarrelClusterAssociations", + // "HcalEndcapNClusterAssociations", + // "HcalEndcapPInsertClusterAssociations", + // "HcalFarForwardZDCClusterAssociations", + // "LFHCALClusterAssociations", + // "EcalBarrelImagingClusterAssociations", + // "EcalBarrelScFiClusterAssociations", + + std::vector m_caloclusterassociation_collection_names_out = { + "B0ECalClusterAssociations", + "EcalBarrelClusterAssociations", + "EcalEndcapNClusterAssociations", + "EcalEndcapPClusterAssociations", + }; + // "HcalBarrelClusterAssociations", + // "HcalEndcapNClusterAssociations", + // "HcalEndcapPInsertClusterAssociations", + // "HcalFarForwardZDCClusterAssociations", + // "LFHCALClusterAssociations", + // "EcalBarrelImagingClusterAssociations", + // "EcalBarrelScFiClusterAssociations", + + PodioInput m_event_header_in{this, + {.name = "EventHeader", .is_optional = true}}; + PodioOutput m_event_header_out{this, "EventHeader"}; + + PodioInput m_mcparticles_in{this, {.name = "MCParticles"}}; + PodioOutput m_mcparticles_out{this, "MCParticles"}; + + VariadicPodioInput m_trackerhits_in{ + this, {.names = m_trackerhit_collection_names, .is_optional = true}}; + VariadicPodioOutput m_trackerhits_out{this, + m_trackerhit_collection_names_out}; + + VariadicPodioInput m_trackerhitsAsso_in{ + this, {.names = m_simtrackerhitAsso_collection_names, .is_optional = true}}; + VariadicPodioOutput m_trackerhitsAsso_out{ + this, m_simtrackerhitAsso_collection_names_out}; + + VariadicPodioOutput m_rawhitlinks_out{ + this, m_rawhitlink_collection_names_out}; + VariadicPodioOutput m_simtrackerhits_out{ + this, m_simtrackerhit_collection_names_out}; + + VariadicPodioInput m_rawhit_in{ + this, {.names = m_rawhit_collection_names, .is_optional = true}}; + VariadicPodioOutput m_rawhit_out{this, m_rawhit_collection_names_out}; + + // VariadicPodioInput m_simcalorimeterhits_in{ + // this, {.names = m_simcalorimeterhit_collection_names, .is_optional = true}}; + // VariadicPodioOutput m_simcalorimeterhits_out{ + // this, m_simcalorimeterhit_collection_names}; + + // VariadicPodioInput m_calohitcontributions_in{ + // this, {.names = m_calohitcontribution_collection_names, .is_optional = true}}; + // VariadicPodioOutput m_calohitcontributions_out{ + // this, m_calohitcontribution_collection_names}; + + VariadicPodioInput m_calorawhit_in{ + this, {.names = m_calorawhit_collection_names_in, .is_optional = true}}; + VariadicPodioOutput m_calorawhit_out{ + this, m_calorawhit_collection_names_out}; + + VariadicPodioOutput m_calorawhitlinks_out{ + this, m_calorawhitlink_collection_names}; + VariadicPodioOutput m_simcalorimeterhits_out{ + this, m_simcalorimeterhit_collection_names_out}; + + VariadicPodioInput m_calorechit_in{ + this, {.names = m_calorechit_collection_names_in, .is_optional = true}}; + VariadicPodioOutput m_calorechit_out{this, + m_calorechit_collection_names_out}; + + VariadicPodioInput m_calorechitassociation_in{ + this, {.names = m_calorechitassociation_collection_names_in, .is_optional = true}}; + VariadicPodioOutput m_calorechitassociation_out{ + this, m_calorechitassociation_collection_names_out}; + + // VariadicPodioInput m_calocluster_in{ + // this, {.names = m_calocluster_collection_names_in, .is_optional = true}}; + // VariadicPodioOutput m_calocluster_out{ + // this, m_calocluster_collection_names_out}; + + // VariadicPodioInput m_caloclusterassociation_in{ + // this, {.names = m_caloclusterassociation_collection_names_in, .is_optional = true}}; + // VariadicPodioOutput m_caloclusterassociation_out{ + // this, m_caloclusterassociation_collection_names_out}; + + PodioOutput m_event_header_ts_out{this, "EventHeader_TS"}; + PodioOutput m_event_header_phy_out{this, "EventHeader_PHY"}; + PodioOutput m_event_header_bkg_out{this, "EventHeader_BKG"}; + + // For QA + PodioOutput m_ecalhitsintower_phy_out{this, "ECalHitsInTower_PHY"}; + PodioOutput m_ecalhitsintower_bkg_out{this, "ECalHitsInTower_BKG"}; + + PodioOutput m_ecaltowers_phy_out{this, "ECalTowers_PHY"}; + PodioOutput m_ecaltowers_bkg_out{this, "ECalTowers_BKG"}; + + TimeframeSplitter() { + SetTypeName(NAME_OF_THIS); + SetParentLevel(JEventLevel::Timeslice); + SetChildLevel(JEventLevel::PhysicsEvent); + } + + // std::vector> + // m_hitStartIndices_simTracker; + + std::vector> + m_hitStartIndices_simTracker; + std::vector> + m_hitStartIndices_simCalorimeter; + + // == Global Variables ======================= + size_t m_triggerDetSize = 10; // Number of detectors used for triggering + // Int_t m_detId[10] = {12, 13, 1, 4, 8, 9, 11, 14, 15, 16}; // TOF and MPGD, Silicon excluded + Int_t m_detId[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // TOF and MPGD, Silicon excluded + + bool bInitialLoop = true; + std::vector> m_vOrigHitId; + std::vector> m_vSameTSHitId; + + Int_t m_multiTriggerThreshold[4] = {1, 4, 20, 20}; + size_t iniTrkHitPoint[15] = {0}; // B0Trk, + size_t iniCalHitPoint[15] = {0}; // B0Trk, + bool m_bDetLastHits[10] = {false, false, false, false, false, false, false, false, false, false}; + + bool m_bOnceTriggered = false; + bool m_bScanedAllTimeWindows = false; + + Int_t targetDetId = 0; + size_t iTimeSlice = 0; + std::vector m_vPhysCooTimes = {}; + // == Global Variables ======================= + + struct TimeWindowSummary { + size_t count = 0; + Double_t time_sum = 0.0; + size_t next_start_index = 0; + + Double_t average_time() const { return count == 0 ? 0.0 : time_sum / count; } + }; + + static bool overlaps_time_window(Double_t hit_time, Double_t resolution, Double_t window_start, + Double_t window_end) { + return hit_time + resolution > window_start && hit_time - resolution < window_end; + } + static bool is_after_time_window(Double_t hit_time, Double_t resolution, Double_t window_end) { + return hit_time - resolution >= window_end; + } + + static bool isValidEtaPhiBin(Int_t etaBin, Int_t phiBin) { + return 0 <= etaBin && etaBin < kEtaPhiBins && 0 <= phiBin && phiBin < kEtaPhiBins; + } + + static bool is_hit_in_time_slice(Double_t hit_time, Double_t time_resolution, + Double_t time_slice_start, Double_t time_slice_end) { + return !(hit_time + time_resolution < time_slice_start || + hit_time - time_resolution > time_slice_end); + } + + template + inline void etaPhiCalc(const HitT& hit, Double_t& hitEta, Double_t& hitPhi) { + const Double_t hitX = hit.getPosition()[0]; + const Double_t hitY = hit.getPosition()[1]; + const Double_t hitZ = hit.getPosition()[2]; + const Double_t hitR = TMath::Sqrt(hitX * hitX + hitY * hitY + hitZ * hitZ); + if (hitR <= 0.0) { + hitEta = 0.0; + hitPhi = 0.0; + return; + } + const Double_t cosTheta = std::clamp(hitZ / hitR, -1.0, 1.0); + const Double_t hitTheta = TMath::ACos(cosTheta); + hitEta = -TMath::Log(TMath::Tan(hitTheta / 2.0)); + hitPhi = TMath::ATan2(hitY, hitX); + } + + static std::pair etaPhiBins(Double_t hitEta, Double_t hitPhi, Double_t etaMin, + Double_t etaMax, Int_t bShift) { + const Double_t etaBinWidth = (etaMax - etaMin) / kEtaPhiBins; + const Double_t phiMin = -TMath::Pi(); + const Double_t phiMax = TMath::Pi(); + const Double_t phiBinWidth = (phiMax - phiMin) / kEtaPhiBins; + + const Double_t halfEtaBin = 0.5 * etaBinWidth * bShift; + const Double_t halfPhiBin = 0.5 * phiBinWidth * bShift; + const Double_t shiftedEtaMin = etaMin + halfEtaBin; + const Double_t shiftedEtaMax = etaMax + halfEtaBin; + const Double_t shiftedPhiMin = phiMin + halfPhiBin; + const Double_t shiftedPhiMax = phiMax + halfPhiBin; + + if (hitEta < shiftedEtaMin || hitEta >= shiftedEtaMax || hitPhi < shiftedPhiMin || + hitPhi >= shiftedPhiMax) { + return {kInvalidEtaPhiBin, kInvalidEtaPhiBin}; + } + + const Int_t etaBin = static_cast(std::floor((hitEta - shiftedEtaMin) / etaBinWidth)); + const Int_t phiBin = static_cast(std::floor((hitPhi - shiftedPhiMin) / phiBinWidth)); + return {etaBin, phiBin}; + } + + template + void fillEtaPhiGrids(const CollectionT* hits, size_t& iniHitID, Double_t timeResolution, + Double_t timeSliceStart, Double_t timeSliceEnd, EtaPhiGrid& grid, + EtaPhiGrid& gridShifted, EtaPhiTimeGrid& gridTime, + EtaPhiTimeGrid& gridShiftedTime, BinFunc binFunc) { + if (hits == nullptr) + return; + + const size_t hitCount = hits->size(); + for (size_t iHit = iniHitID; iHit < hitCount; ++iHit) { + const auto& hit = hits->at(iHit); + const Double_t hitT = hit.getTime(); + if (hitT - timeResolution > timeSliceEnd) { + iniHitID = iHit; + break; + } + if (!is_hit_in_time_slice(hitT, timeResolution, timeSliceStart, timeSliceEnd)) + continue; + + Double_t hitEta = 0.0; + Double_t hitPhi = 0.0; + etaPhiCalc(hit, hitEta, hitPhi); + + const auto [eta0, phi0] = binFunc(hitEta, hitPhi, 0); + const auto [eta1, phi1] = binFunc(hitEta, hitPhi, 1); + if (isValidEtaPhiBin(eta0, phi0)) { + grid[eta0][phi0]++; + gridTime[eta0][phi0] += hitT; + } + if (isValidEtaPhiBin(eta1, phi1)) { + gridShifted[eta1][phi1]++; + gridShiftedTime[eta1][phi1] += hitT; + } + // std::cout << "TF:TS = " << m_TFCount << " <><><><><> etaBin:phiBin = " << eta0 << ":" << phi0 << " | " << eta1 << ":" << phi1 << std::endl; + } + } + + template + void fillEtaPhiGridsMatched(const CollectionT* collection, size_t& iniHitID, + Double_t timeResolution, Double_t timeSliceStart, + Double_t timeSliceEnd, const EtaPhiGrid& baseGrid, + const EtaPhiGrid& baseGridShifted, EtaPhiGrid& compGrid, + EtaPhiGrid& compGridShifted, Int_t baseThreshold, + EtaPhiTimeGrid& compGridTime, EtaPhiTimeGrid& compGridShiftedTime, + BinFunc binFunc) { + if (collection == nullptr) + return; + + const size_t hitCount = collection->size(); + for (size_t iHit = iniHitID; iHit < hitCount; ++iHit) { + const Double_t hitT = collection->at(iHit).getTime(); + if (hitT - timeResolution > timeSliceEnd) { + iniHitID = iHit; + break; + } + if (!is_hit_in_time_slice(hitT, timeResolution, timeSliceStart, timeSliceEnd)) + continue; + + Double_t hitEta = 0.0; + Double_t hitPhi = 0.0; + etaPhiCalc(collection->at(iHit), hitEta, hitPhi); + + const auto [eta0, phi0] = binFunc(hitEta, hitPhi, 0); + const auto [eta1, phi1] = binFunc(hitEta, hitPhi, 1); + if (isValidEtaPhiBin(eta0, phi0) && baseGrid[eta0][phi0] >= baseThreshold) { + compGrid[eta0][phi0]++; + compGridTime[eta0][phi0] += hitT; + } + if (isValidEtaPhiBin(eta1, phi1) && baseGridShifted[eta1][phi1] >= baseThreshold) { + compGridShifted[eta1][phi1]++; + compGridShiftedTime[eta1][phi1] += hitT; + } + } + } + + static size_t countGridCellsWithMultiplicity(const EtaPhiGrid& grid0, + const EtaPhiGrid& gridShifted, + const EtaPhiTimeGrid& gridTime0, + const EtaPhiTimeGrid& gridShiftedTime, + Int_t threshold, Double_t& averageTime) { + size_t count = 0; + Double_t timeSum = 0.0; + for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { + for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { + if (grid0[iEta][iPhi] >= threshold || gridShifted[iEta][iPhi] >= threshold) { + count++; + if (grid0[iEta][iPhi] >= threshold) { + timeSum += gridTime0[iEta][iPhi] / grid0[iEta][iPhi]; + } else if (gridShifted[iEta][iPhi] >= threshold) { + timeSum += gridShiftedTime[iEta][iPhi] / gridShifted[iEta][iPhi]; + } + } + } + } + averageTime = count > 0 ? timeSum / count : 0.0; + return count; + } + + static Double_t averageSelectedTriggerTime(const std::array& values, + const std::array& times, + std::initializer_list indices, + Double_t fallbackTime) { + size_t count = 0; + Double_t timeSum = 0.0; + for (const size_t index : indices) { + if (values[index] <= 0.0) + continue; + timeSum += times[index]; + count++; + } + return count > 0 ? timeSum / count : fallbackTime; + } + + Double_t tracker_time_resolution(size_t detector_id) { + if (detector_id < 3) + return timeResolution_ACLGad(); + if (detector_id < 7) + return timeResolution_MPGD(); + return timeResolution_SiMaps(); + } + + template + TimeWindowSummary count_hits_in_window(const CollectionT* collection, size_t start_index, + Double_t resolution, Double_t window_start, + Double_t window_end) const { + TimeWindowSummary summary; + summary.next_start_index = start_index; + if (collection == nullptr) + return summary; + + for (size_t i = start_index; i < collection->size(); ++i) { + const auto& hit = collection->at(i); + const Double_t hit_time = hit.getTime(); + if (is_after_time_window(hit_time, resolution, window_end)) + break; + if (overlaps_time_window(hit_time, resolution, window_start, window_end)) { + ++summary.count; + summary.time_sum += hit_time; + summary.next_start_index = i; + } + } + return summary; + } + + template + static void copy_tracker_hit_with_relations( + const edm4eic::TrackerHit& tracker_hit, + const edm4eic::MCRecoTrackerHitAssociationCollection* associations, + TrackerHitOutputT& tracker_hits_out, RawHitOutputT& raw_hits_out, + AssociationOutputT& associations_out, + std::unique_ptr& sim_hits_out, + std::unique_ptr& links_out, + std::unique_ptr& mc_particles_out) { + auto copied_tracker_hit = tracker_hit.clone(); + copied_tracker_hit.setRawHit(edm4eic::RawTrackerHit()); + + if (associations == nullptr || !tracker_hit.getRawHit().isAvailable()) { + tracker_hits_out->push_back(copied_tracker_hit); + return; + } + + const auto raw_hit_id = tracker_hit.getRawHit().getObjectID(); + auto copied_raw_hit = tracker_hit.getRawHit().clone(); + raw_hits_out->push_back(copied_raw_hit); + copied_tracker_hit.setRawHit(copied_raw_hit); + + for (const auto& association : *associations) { + const auto association_raw_hit = association.getRawHit(); + if (!association_raw_hit.isAvailable() || association_raw_hit.getObjectID() != raw_hit_id) { + continue; + } + if (!association.getSimHit().isAvailable()) + continue; + + const auto sim_hit = association.getSimHit(); + auto copied_sim_hit = sim_hit.clone(false); + if (sim_hit.getParticle().isAvailable()) { + const auto particle_id = sim_hit.getParticle().getObjectID(); + if (particle_id.index >= 0 && + static_cast(particle_id.index) < mc_particles_out->size()) { + copied_sim_hit.setParticle((*mc_particles_out)[particle_id.index]); + } + } + sim_hits_out->push_back(copied_sim_hit); + + auto copied_association = associations_out->create(); + copied_association.setWeight(association.getWeight()); + copied_association.setRawHit(copied_raw_hit); + copied_association.setSimHit(copied_sim_hit); + + auto copied_link = links_out->create(); + copied_link.setWeight(association.getWeight()); + copied_link.setFrom(copied_raw_hit); + copied_link.setTo(copied_sim_hit); + } + + tracker_hits_out->push_back(copied_tracker_hit); + } + + static std::pair backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { + // MPGD backward Endcap range -3.6 < eta < -1.72, +5%: -3.78 < eta < -1.634 + const Double_t etaMin = -3.78; + const Double_t etaMax = -1.634; + return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); + } + + static std::pair barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { + // MPGD barrel In range -1.49 < eta < 1.722, +5%: -1.56 < eta < 1.81 + // MPGD barrel Out range -1.56 < eta < 1.61, +5%: -1.64 < eta < 1.70 + // TOF barrel range -1.39 < eta < 1.39, +5%: -1.46 < eta < 1.46 + // ECal barrel range -1.71 < eta < 1.31, +5%: -1.80 < eta < 1.38 + const Double_t etaMin = -1.80; + const Double_t etaMax = 1.81; + return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); + } + + static std::pair forwardEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, + Int_t bShift) { + // MPGD forward Endcap range 2.0 < eta < 3.35, +5%: 1.90 < eta < 3.52 + // TOF forward Endcap range 1.86 < eta < 3.85, +5%: 1.77 < eta < 4.04 + // ECal forward Endcap range 1.4 < eta < 3.5, +5%: 1.33 < eta < 3.68 + const Double_t etaMin = 1.77; + const Double_t etaMax = 4.04; + return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); + } + + Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override { + // For QA + std::vector> vECalHitInTowerPhy; + std::vector> vECalHitInTowerBkg; + std::vector> vECalTowersPhy; + std::vector> vECalTowersBkg; + // For QA + + float m_timeframe_width = timeframe_width(); + float m_timesplit_width = timesplit_width(); + + Bool_t m_bTrigger = false; + + const auto trackerHitCollsIn = m_trackerhits_in(); + const auto caloRecHitCollsIn = m_calorechit_in(); + const auto trkAssoCollsIn = m_trackerhitsAsso_in(); + const auto calrecAssoCollsIn = m_calorechitassociation_in(); + + // == s == Register hits of TOF and MPGD detectors in the time slice ================== + if (child_idx == 0) { + m_OrigTFCount++; + // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ + m_vPhysCooTimes.clear(); + + Double_t prevMCTime = -9999.0; // temp check mc particle times + for (const auto& mcparticle : *m_mcparticles_in()) { + // if (mcparticle.parents_begin() != 0) + // if(mcparticle.parents_size() > 0) continue; + + if (mcparticle.getGeneratorStatus() != 1) + continue; + if (std::abs(prevMCTime - mcparticle.getTime()) < 50.) + continue; + Double_t mcCollTime = mcparticle.getTime(); + m_vPhysCooTimes.push_back(mcCollTime); + prevMCTime = mcCollTime; + } + std::sort(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); + auto last = std::unique(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); + m_vPhysCooTimes.erase(last, m_vPhysCooTimes.end()); + for (size_t iPhysT = 0; iPhysT < m_vPhysCooTimes.size(); ++iPhysT) { + Double_t physCollTime = m_vPhysCooTimes[iPhysT]; + Double_t tsTime = iPhysT * timesplit_width(); + // std::cout << "111<><>><><<><><<><<><><><> TF:TS = " << parent.GetEventNumber() << " : " << child_idx << ", physCollTime: " << physCollTime << ", tsTime: " << tsTime << std::endl; + } + + // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ + } + // == e == Register hits of TOF and MPGD detectors in the time slice ================== + + // == s == Time frame scan loop ========================================================== + Double_t timesliceT0 = -999.0; + Bool_t bTimesliceTrigger = false; + + Bool_t bMutipliTriggers[6] = {false, false, false, false, false, false}; + Double_t multipliTrigTime[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Double_t tsTimeS = child_idx * m_timesplit_width; + // Double_t tsTimeE = (child_idx + 1) * m_timesplit_width; + Double_t tsTimeS = iTimeSlice * m_timesplit_width; + Double_t tsTimeE = (iTimeSlice + 1) * m_timesplit_width; + while (1) { + tsTimeS = iTimeSlice * m_timesplit_width; + tsTimeE = (iTimeSlice + 1) * m_timesplit_width; + if (tsTimeE > m_timeframe_width) + break; + iTimeSlice++; + + // == s == Multiplisity threshold Triggers ======================================= + + // == s == Multiplisity Single Triggers ======================================= + std::array singleTrig{}; + std::array singleTrigTime{}; + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " Trigger1 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + // s // EndCap Cal Trigger + EtaPhiGrid backEndCalGrid{}; + EtaPhiGrid backEndCalGridShifted{}; + EtaPhiTimeGrid backEndIntTimesEtaPhi = {}; + EtaPhiTimeGrid backEndIntTimesEtaPhiShifted = {}; + fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapN), iniCalHitPoint[kCalEndcapN], + timeResolution_EMCal(), tsTimeS, tsTimeE, backEndCalGrid, + backEndCalGridShifted, backEndIntTimesEtaPhi, backEndIntTimesEtaPhiShifted, + backEndEtaPhiBins); + singleTrig[0] = countGridCellsWithMultiplicity( + backEndCalGrid, backEndCalGridShifted, backEndIntTimesEtaPhi, + backEndIntTimesEtaPhiShifted, 10, singleTrigTime[0]); + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger2 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + // s // EndCap Cal+Trk Match Trigger + EtaPhiGrid backEndTrkGrid = {}; + EtaPhiGrid backEndTrkGridShifted = {}; + EtaPhiTimeGrid backEndIntTimesEtaPhiMatched = {}; + EtaPhiTimeGrid backEndIntTimesEtaPhiMatchedShifted = {}; + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkBackwardMPGD), + iniTrkHitPoint[kTrkBackwardMPGD], timeResolution_MPGD(), tsTimeS, + tsTimeE, backEndCalGrid, backEndCalGridShifted, backEndTrkGrid, + backEndTrkGridShifted, 10, backEndIntTimesEtaPhiMatched, + backEndIntTimesEtaPhiMatchedShifted, backEndEtaPhiBins); + singleTrig[1] = countGridCellsWithMultiplicity( + backEndTrkGrid, backEndTrkGridShifted, backEndIntTimesEtaPhiMatched, + backEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[1]); + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger3 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + EtaPhiGrid barrelCalGrid = {}; + EtaPhiGrid barrelCalGridShifted = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhi = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhiShifted = {}; + fillEtaPhiGrids(caloRecHitCollsIn.at(kCalBarrelScifi), iniCalHitPoint[kCalBarrelScifi], + timeResolution_EMCal(), tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, + barrelIntTimesEtaPhi, barrelIntTimesEtaPhiShifted, barrelEtaPhiBins); + singleTrig[2] = + countGridCellsWithMultiplicity(barrelCalGrid, barrelCalGridShifted, barrelIntTimesEtaPhi, + barrelIntTimesEtaPhiShifted, 10, singleTrigTime[2]); + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger4 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + EtaPhiGrid barrelTrkGrid = {}; + EtaPhiGrid barrelTrkGridShifted = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhiMatched = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhiMatchedShifted = {}; + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkMPGDBarrel), iniTrkHitPoint[kTrkMPGDBarrel], + timeResolution_MPGD(), tsTimeS, tsTimeE, barrelCalGrid, + barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, + barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, + barrelEtaPhiBins); + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkOuterMPGDBarrel), + iniTrkHitPoint[kTrkOuterMPGDBarrel], timeResolution_MPGD(), tsTimeS, + tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, + barrelTrkGridShifted, 5, barrelIntTimesEtaPhiMatched, + barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFBarrel), iniTrkHitPoint[kTrkTOFBarrel], + timeResolution_ACLGad(), tsTimeS, tsTimeE, barrelCalGrid, + barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, + barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, + barrelEtaPhiBins); + singleTrig[3] = countGridCellsWithMultiplicity( + barrelTrkGrid, barrelTrkGridShifted, barrelIntTimesEtaPhiMatched, + barrelIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[3]); + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger5 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + EtaPhiGrid frontEndCalGrid = {}; + EtaPhiGrid frontEndCalGridShifted = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhi = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhiShifted = {}; + fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapP), iniCalHitPoint[kCalEndcapP], + timeResolution_EMCal(), tsTimeS, tsTimeE, frontEndCalGrid, + frontEndCalGridShifted, frontEndIntTimesEtaPhi, frontEndIntTimesEtaPhiShifted, + forwardEndEtaPhiBins); + singleTrig[4] = countGridCellsWithMultiplicity( + frontEndCalGrid, frontEndCalGridShifted, frontEndIntTimesEtaPhi, + frontEndIntTimesEtaPhiShifted, 10, singleTrigTime[4]); + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger6 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + EtaPhiGrid frontEndTrkGrid = {}; + EtaPhiGrid frontEndTrkGridShifted = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhiMatched = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhiMatchedShifted = {}; + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkForwardMPGD), iniTrkHitPoint[kTrkForwardMPGD], + timeResolution_MPGD(), tsTimeS, tsTimeE, frontEndCalGrid, + frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, + frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, + forwardEndEtaPhiBins); + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFEndcap), iniTrkHitPoint[kTrkTOFEndcap], + timeResolution_ACLGad(), tsTimeS, tsTimeE, frontEndCalGrid, + frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, + frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, + forwardEndEtaPhiBins); + singleTrig[5] = countGridCellsWithMultiplicity( + frontEndTrkGrid, frontEndTrkGridShifted, frontEndIntTimesEtaPhiMatched, + frontEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[5]); + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger7 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + const auto hitsB0 = count_hits_in_window(trackerHitCollsIn.at(kTrkB0), iniTrkHitPoint[kTrkB0], + timeResolution_ACLGad(), tsTimeS, tsTimeE); + iniTrkHitPoint[kTrkB0] = hitsB0.next_start_index; + singleTrig[6] = hitsB0.count; + singleTrigTime[6] = hitsB0.average_time(); + + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger8 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; + Double_t totalZDCEnergy = 0.0; + Double_t totalZDCEnergyTime = 0.0; + const auto* recHitsZDCECal = caloRecHitCollsIn.at(kCalZDC); + if (recHitsZDCECal != nullptr) { + for (size_t iHit = iniCalHitPoint[kCalZDC]; iHit < recHitsZDCECal->size(); ++iHit) { + const auto& hit = recHitsZDCECal->at(iHit); + const Double_t hitTime = hit.getTime(); + if (hitTime - timeResolution_EMCal() > tsTimeE) + break; + if (is_hit_in_time_slice(hitTime, timeResolution_EMCal(), tsTimeS, tsTimeE)) { + totalZDCEnergy += hit.getEnergy(); + totalZDCEnergyTime += hit.getEnergy() * hitTime; + iniCalHitPoint[kCalZDC] = iHit; + } + } + } + singleTrig[7] = totalZDCEnergy; + singleTrigTime[7] = totalZDCEnergy > 0.0 ? totalZDCEnergyTime / totalZDCEnergy : 0.0; + + const Double_t etaPhiCalTriggerSum = singleTrig[0] + singleTrig[2] + singleTrig[4]; + const Double_t etaPhiCalTrkTriggerSum = singleTrig[1] + singleTrig[3] + singleTrig[5]; + bMutipliTriggers[0] = etaPhiCalTrkTriggerSum > 0 && singleTrig[6] > 4; + bMutipliTriggers[1] = etaPhiCalTrkTriggerSum > 0 && singleTrig[7] > 50; + bMutipliTriggers[2] = etaPhiCalTriggerSum > 0 && singleTrig[6] > 4; + bMutipliTriggers[3] = etaPhiCalTriggerSum > 0 && singleTrig[7] > 0.005; + bMutipliTriggers[4] = etaPhiCalTrkTriggerSum > 1; + bMutipliTriggers[5] = etaPhiCalTriggerSum > 2; + + // /??? QA + Int_t physEventWeight = 2; + for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { + const Double_t physCollTime = *it; + if ((physCollTime + 20 > tsTimeS - 20) && (physCollTime - 10 < tsTimeE + 30)) { + physEventWeight = 1; + break; + } + } + Int_t numOfECalTowersX5 = 0; + Int_t numOfECalTowersX10 = 0; + for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { + for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { + if (backEndCalGrid[iEta][iPhi] > 0 || barrelCalGrid[iEta][iPhi] > 0 || + frontEndCalGrid[iEta][iPhi] > 0) { + if (physEventWeight == 1) { + + std::vector vECalHitInTowerPhyRow = {backEndCalGrid[iEta][iPhi], + barrelCalGrid[iEta][iPhi], + frontEndCalGrid[iEta][iPhi]}; + vECalHitInTowerPhy.push_back(vECalHitInTowerPhyRow); + + if (backEndCalGrid[iEta][iPhi] > 4) { + numOfECalTowersX5++; + if (backEndCalGrid[iEta][iPhi] > 9) + numOfECalTowersX10++; + } + if (barrelCalGrid[iEta][iPhi] > 4) { + numOfECalTowersX5++; + if (barrelCalGrid[iEta][iPhi] > 9) + numOfECalTowersX10++; + } + if (frontEndCalGrid[iEta][iPhi] > 4) { + numOfECalTowersX5++; + if (frontEndCalGrid[iEta][iPhi] > 9) + numOfECalTowersX10++; + } + } else { + std::vector vECalHitInTowerBkgRow = {backEndCalGrid[iEta][iPhi], + barrelCalGrid[iEta][iPhi], + frontEndCalGrid[iEta][iPhi]}; + vECalHitInTowerBkg.push_back(vECalHitInTowerBkgRow); + + if (backEndCalGrid[iEta][iPhi] > 4) { + numOfECalTowersX5++; + if (backEndCalGrid[iEta][iPhi] > 9) + numOfECalTowersX10++; + } + if (barrelCalGrid[iEta][iPhi] > 4) { + numOfECalTowersX5++; + if (barrelCalGrid[iEta][iPhi] > 9) + numOfECalTowersX10++; + } + if (frontEndCalGrid[iEta][iPhi] > 4) { + numOfECalTowersX5++; + if (frontEndCalGrid[iEta][iPhi] > 9) + numOfECalTowersX10++; + } + } + } + } + } + if (physEventWeight == 1) + vECalTowersPhy.push_back( + {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); + else if (physEventWeight == 2) + vECalTowersBkg.push_back( + {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); + // /??? QA + + if (!bMutipliTriggers[0] && !bMutipliTriggers[1] && !bMutipliTriggers[2] && + !bMutipliTriggers[3] && !bMutipliTriggers[4] && !bMutipliTriggers[5]) + continue; + + const Double_t fallbackTriggerTime = 0.5 * (tsTimeS + tsTimeE); + if (bMutipliTriggers[0]) + multipliTrigTime[0] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 6}, + fallbackTriggerTime); + if (bMutipliTriggers[1]) + multipliTrigTime[1] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 7}, + fallbackTriggerTime); + if (bMutipliTriggers[2]) + multipliTrigTime[2] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 6}, + fallbackTriggerTime); + if (bMutipliTriggers[3]) + multipliTrigTime[3] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 7}, + fallbackTriggerTime); + if (bMutipliTriggers[4]) + multipliTrigTime[4] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5}, fallbackTriggerTime); + if (bMutipliTriggers[5]) + multipliTrigTime[5] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4}, fallbackTriggerTime); + Double_t multiTrigCount = 0; + Double_t totalTrigTime = 0.0; + for (size_t iTrig = 0; iTrig < 6; ++iTrig) { + if (bMutipliTriggers[iTrig]) { + totalTrigTime += multipliTrigTime[iTrig]; + multiTrigCount++; + } + } + timesliceT0 = multiTrigCount > 0 ? totalTrigTime / multiTrigCount : fallbackTriggerTime; + + // == s == Multiplisity Single Triggers ======================================= + + // == s == Geometrical Coincidence Triggers ===================================== + // === Geometrical Coincidence === + // == e == Geometrical Coincidence Triggers ===================================== + + if (bMutipliTriggers[0] || bMutipliTriggers[1] || bMutipliTriggers[2] || + bMutipliTriggers[3] || bMutipliTriggers[4] || bMutipliTriggers[5]) + bTimesliceTrigger = + true; // ???? temporary, need to be removed after geometrical coincidence trigger is implemented + if (bTimesliceTrigger) + break; + } + // == e == Time frame scan loop ========================================================== + + // /??? QA <><><><><><><><><><><><><><> + if (!vECalHitInTowerPhy.empty()) { + auto& oECalHitsInTowerPhy = m_ecalhitsintower_phy_out(); + auto& oECalTowersPHY = m_ecaltowers_phy_out(); + for (size_t iTower = 0; iTower < vECalHitInTowerPhy.size(); ++iTower) { + auto entry = oECalHitsInTowerPhy->create(); + entry.setEventNumber(vECalHitInTowerPhy[iTower][0]); + entry.setRunNumber(vECalHitInTowerPhy[iTower][1]); + entry.setTimeStamp(vECalHitInTowerPhy[iTower][2]); + } + for (size_t iTower = 0; iTower < vECalTowersPhy.size(); ++iTower) { + auto entry = oECalTowersPHY->create(); + entry.setEventNumber(vECalTowersPhy[iTower][0]); + entry.setRunNumber(vECalTowersPhy[iTower][1]); + entry.setTimeStamp(vECalTowersPhy[iTower][2]); + } + } + if (!vECalHitInTowerBkg.empty()) { + auto& oECalHitsInTowerBkg = m_ecalhitsintower_bkg_out(); + auto& oECalTowersBkg = m_ecaltowers_bkg_out(); + for (size_t iTower = 0; iTower < vECalHitInTowerBkg.size(); ++iTower) { + auto entry = oECalHitsInTowerBkg->create(); + entry.setEventNumber(vECalHitInTowerBkg[iTower][0]); + entry.setRunNumber(vECalHitInTowerBkg[iTower][1]); + entry.setTimeStamp(vECalHitInTowerBkg[iTower][2]); + } + for (size_t iTower = 0; iTower < vECalTowersBkg.size(); ++iTower) { + auto entry = oECalTowersBkg->create(); + entry.setEventNumber(vECalTowersBkg[iTower][0]); + entry.setRunNumber(vECalTowersBkg[iTower][1]); + entry.setTimeStamp(vECalTowersBkg[iTower][2]); + } + } + // /??? QA <><><><><><><><><><><><><<>><><><><>< + + m_bTrigger = bTimesliceTrigger; + if (bTimesliceTrigger) { + m_bOnceTriggered = true; + // For now, a one-to-one relationship between timeslices and events + child.SetEventNumber(m_NewEventCount); + child.SetRunNumber(parent.GetRunNumber()); + m_NewEventCount++; + // Clone truth particles before detector relations so every child SimTrackerHit can + // point to an MCParticle owned by this PhysicsEvent rather than by the parent Timeslice. + for (const auto& mcparticle : *m_mcparticles_in()) { + m_mcparticles_out()->push_back(mcparticle.clone(false)); + } + + // == s == Register Tracker Hits ======================================================= + for (size_t trkDetID = 0; trkDetID < trackerHitCollsIn.size(); ++trkDetID) { + const auto* trkCollIn = trackerHitCollsIn.at(trkDetID); + + if (trkCollIn == nullptr) + continue; + auto& trkCollOut = m_trackerhits_out().at(trkDetID); + const Double_t detTimeReso = tracker_time_resolution(trkDetID); + const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); + auto& rawCollOut = m_rawhit_out().at(trkDetID); + auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); + + for (size_t iHit = 0; iHit < trkCollIn->size(); ++iHit) { + const auto& trkHit = trkCollIn->at(iHit); + + const Double_t hitT = trkHit.getTime(); + if (!overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { + continue; + } + + iniTrkHitPoint[trkDetID] = iHit; + copy_tracker_hit_with_relations(trkHit, trkAssoCollIn, trkCollOut, rawCollOut, + trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), + m_rawhitlinks_out().at(trkDetID), m_mcparticles_out()); + } + } + // == e == Register Tracker Hits ======================================================= + + // == s == Register Calo Rec Hits ======================================================= + for (size_t calDetID = 0; calDetID < caloRecHitCollsIn.size(); ++calDetID) { + const auto* caloInColl = caloRecHitCollsIn.at(calDetID); + if (caloInColl == nullptr) + continue; + auto& caloOutColl = m_calorechit_out().at(calDetID); + + const auto* caloInCollAsso = calrecAssoCollsIn.at(calDetID); + if (caloInCollAsso == nullptr) + continue; + + for (size_t iCalHit = 0; iCalHit < caloInColl->size(); ++iCalHit) { + const auto& caloHit = caloInColl->at(iCalHit); + + Double_t detTimeReso = timeResolution_EMCal(); + + Double_t hitT = caloHit.getTime(); + + if (hitT - detTimeReso > timesliceT0 + 30.) + continue; + if (overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { + // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " CaloDetID = " << calDetID << " iCalHit = " << iCalHit << " hitT = " << hitT << std::endl; + auto copiedCaloHit = caloHit.clone(); + copiedCaloHit.setRawHit(edm4hep::RawCalorimeterHit()); + + const auto rawHitFromRec = caloHit.getRawHit(); + if (rawHitFromRec.isAvailable()) { + auto& rawCollOut = m_calorawhit_out().at(calDetID); + auto copiedRawHit = rawHitFromRec.clone(); + rawCollOut->push_back(copiedRawHit); + copiedCaloHit.setRawHit(copiedRawHit); + + auto& assocCollOut = m_calorechitassociation_out().at(calDetID); + auto& linkCollOut = m_calorawhitlinks_out().at(calDetID); + auto& simCollOut = m_simcalorimeterhits_out().at(calDetID); + const auto rawHitID = rawHitFromRec.getObjectID(); + + for (const auto& assoc : *caloInCollAsso) { + const auto assocRawID = assoc.getRawHit().getObjectID(); + if (rawHitID != assocRawID || !assoc.getSimHit().isAvailable()) + continue; + + auto copiedSimHit = assoc.getSimHit().clone(false); + simCollOut->push_back(copiedSimHit); + + auto copiedAssoc = assocCollOut->create(); + copiedAssoc.setWeight(assoc.getWeight()); + copiedAssoc.setRawHit(copiedRawHit); + copiedAssoc.setSimHit(copiedSimHit); + + auto copiedLink = linkCollOut->create(); + copiedLink.setWeight(assoc.getWeight()); + copiedLink.setFrom(copiedRawHit); + copiedLink.setTo(copiedSimHit); + } + } + + caloOutColl->push_back(copiedCaloHit); + iniCalHitPoint[calDetID] = iCalHit; + } + } + } + // == e == Register Calo Rec Hits ======================================================= + + // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><><>> + // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ + Int_t physEventWeight = 2; + for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { + const Double_t physCollTime = *it; + if ((physCollTime + 20 > timesliceT0 - 10) && (physCollTime - 10 < timesliceT0 + 30)) { + physEventWeight = 1; + m_vPhysCooTimes.erase(it); + break; + } + } + + edm4hep::MutableEventHeader event_header_ts; + event_header_ts.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_ts.setEventNumber(m_event_number_ts); + event_header_ts.setTimeStamp(iTimeSlice); + event_header_ts.setWeight(physEventWeight); + // event_header_ts.setWeight(memoryUsage); // Just a dummy weight for now + m_event_header_ts_out()->push_back(event_header_ts); + m_event_number_ts++; + + if (physEventWeight == 1) { + edm4hep::MutableEventHeader event_header_bkg; + event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_bkg.setEventNumber(m_event_number_ts); + event_header_bkg.setTimeStamp(iTimeSlice); + event_header_bkg.setWeight(1); + m_event_header_bkg_out()->push_back(event_header_bkg); + + edm4hep::MutableEventHeader event_header_phy; + event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_phy.setEventNumber(m_event_number_ts); + event_header_phy.setTimeStamp(iTimeSlice); + event_header_phy.setWeight(2); + m_event_header_phy_out()->push_back(event_header_phy); + for (size_t iTrig = 0; iTrig < 6; ++iTrig) { + if (bMutipliTriggers[iTrig]) { + edm4hep::MutableEventHeader event_header_phy; + event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_phy.setEventNumber(m_event_number_ts); + event_header_phy.setTimeStamp(iTimeSlice); + event_header_phy.setWeight(iTrig + 3); + m_event_header_phy_out()->push_back(event_header_phy); + } + } + m_PhysCount++; + } else if (physEventWeight == 2) { + edm4hep::MutableEventHeader event_header_phy; + event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_phy.setEventNumber(m_event_number_ts); + event_header_phy.setTimeStamp(iTimeSlice); + event_header_phy.setWeight(1); + m_event_header_phy_out()->push_back(event_header_phy); + + edm4hep::MutableEventHeader event_header_bkg; + event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_bkg.setEventNumber(m_event_number_ts); + event_header_bkg.setTimeStamp(iTimeSlice); + event_header_bkg.setWeight(2); + m_event_header_bkg_out()->push_back(event_header_bkg); + for (size_t iTrig = 0; iTrig < 6; ++iTrig) { + if (bMutipliTriggers[iTrig]) { + edm4hep::MutableEventHeader event_header_bkg; + event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_bkg.setEventNumber(m_event_number_ts); + event_header_bkg.setTimeStamp(iTimeSlice); + event_header_bkg.setWeight(iTrig + 3); + m_event_header_bkg_out()->push_back(event_header_bkg); + } + } + } + + // Insert an independent EventHeader object into the physics event. + // A subset header would keep a reference to the parent frame collection. + edm4hep::MutableEventHeader event_header; + if (m_event_header_in() != nullptr && !m_event_header_in()->empty()) { + const auto& event_header_in = m_event_header_in()->at(0); + event_header.setRunNumber(event_header_in.getRunNumber()); + event_header.setEventNumber(event_header_in.getEventNumber()); + event_header.setTimeStamp(event_header_in.getTimeStamp()); + event_header.setWeight(event_header_in.getWeight()); + } else { + event_header.setRunNumber(child.GetRunNumber()); + event_header.setEventNumber(child.GetEventNumber()); + event_header.setTimeStamp(iTimeSlice); + event_header.setWeight(physEventWeight); + } + m_event_header_out()->push_back(event_header); + // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ + + // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><>> + } + + if (tsTimeE > m_timeframe_width) + m_bScanedAllTimeWindows = true; + if (m_bScanedAllTimeWindows) { + bInitialLoop = true; + m_bOnceTriggered = false; + + m_vPhysCooTimes.clear(); + std::vector().swap(m_vPhysCooTimes); + + m_bScanedAllTimeWindows = false; + iTimeSlice = 0; + targetDetId = 0; + for (auto& start_point : iniTrkHitPoint) { + start_point = 0; + } + for (auto& start_point : iniCalHitPoint) { + start_point = 0; + } + + if (m_bTrigger) + return Result::NextChildNextParent; + else + return Result::KeepChildNextParent; + } else if (m_bTrigger) { + child_idx++; + return Result::NextChildKeepParent; + } + return Result::KeepChildNextParent; + } + + inline void thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, + Int_t& thetaID2, Int_t& phiID2) { + Double_t hitX = hit.getPosition()[0]; + Double_t hitY = hit.getPosition()[1]; + Double_t hitZ = hit.getPosition()[2]; + const Double_t hitR = TMath::Sqrt(hitX * hitX + hitY * hitY + hitZ * hitZ); + if (hitR <= 0.0) { + thetaID1 = 0; + thetaID2 = 0; + phiID1 = 0; + phiID2 = 0; + return; + } + + const Double_t cosTheta = std::clamp(hitZ / hitR, -1.0, 1.0); + const Double_t hitTheta = TMath::ACos(cosTheta); + + Double_t hitPhi = TMath::ATan2(hitY, hitX) + 2 * TMath::Pi(); + if (hitPhi < 0) + hitPhi += 2 * TMath::Pi(); + thetaID1 = hitTheta / (TMath::Pi() / 12.); + thetaID2 = (hitTheta + TMath::Pi() / 24.) / (TMath::Pi() / 12.); + phiID1 = hitPhi / (TMath::Pi() / 8.); + phiID2 = (hitPhi + TMath::Pi() / 16.) / (TMath::Pi() / 8.); + } +}; diff --git a/src/global/splitting/TrkTimeAlignmentFactory.h b/src/global/splitting/TrkTimeAlignmentFactory.h new file mode 100644 index 0000000000..7e47f0dbbb --- /dev/null +++ b/src/global/splitting/TrkTimeAlignmentFactory.h @@ -0,0 +1,95 @@ +// Copyright 2024, Jefferson Science Associates, LLC. +// Subject to the terms in the LICENSE file found in the top-level directory. + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +struct timeAlignmentFactory : public JOmniFactory { + JEventLevel m_factory_level; + + std::vector m_trackerhit_collection_names = { + "TOFBarrelRecHits", "TOFEndcapRecHits", "MPGDBarrelRecHits", + "OuterMPGDBarrelRecHits", "BackwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits", + "SiBarrelVertexRecHits", "SiBarrelTrackerRecHits", "SiEndcapTrackerRecHits", + "B0TrackerRecHits", "TaggerTrackerRecHits", "ForwardRomanPotRecHits", + "ForwardOffMTrackerRecHits"}; + + // "DRICHRecHits" + // "DIRCBarRecHits", + // "RICHEndcapNRecHits_TK" // PFRICH + + std::vector m_trackerhit_collection_names_aligned = { + "TOFBarrelRecHits_aligned", "TOFEndcapRecHits_aligned", + "MPGDBarrelRecHits_aligned", "OuterMPGDBarrelRecHits_aligned", + "BackwardMPGDEndcapRecHits_aligned", "ForwardMPGDEndcapRecHits_aligned", + "SiBarrelVertexRecHits_aligned", "SiBarrelTrackerRecHits_aligned", + "SiEndcapTrackerRecHits_aligned", "B0TrackerRecHits_aligned", + "TaggerTrackerRecHits_aligned", "ForwardRomanPotRecHits_aligned", + "ForwardOffMTrackerRecHits_aligned"}; + + // "DRICHRecHits_aligned" + // "DIRCBarRecHits_aligned", + // "RICHEndcapNRecHits_TK_aligned" // PFRICH + + VariadicPodioInput m_trackerhits_in{this, + m_trackerhit_collection_names}; + + VariadicPodioOutput m_trackerhits_out{this, + m_trackerhit_collection_names_aligned}; + + Double_t m_time_offset = 0.0; // Time offset to apply to hits + + void Configure() {} + + void ChangeRun(int32_t /*run_nr*/) {} + + void Process(int64_t /*run_number*/, uint64_t /*event_number*/) { + for (size_t coll_index = 0; coll_index < m_trackerhits_in().size(); ++coll_index) { + const auto* coll_in = m_trackerhits_in().at(coll_index); + auto& coll_out = m_trackerhits_out().at(coll_index); + + if (coll_in != nullptr) { + // std::vector sorted_hits; // for edm4hep (G4Hit level) + std::vector sorted_hits; // for edm4eic (After digitization) + for (const auto& hit : *coll_in) { + // edm4hep::MutableSimTrackerHit copiedHit = hit.clone(); // for edm4hep (G4Hit level) + edm4eic::MutableTrackerHit copiedHit = hit.clone(); // for edm4eic (After digitization) + + Double_t hitR = std::sqrt(hit.getPosition()[0] * hit.getPosition()[0] + + hit.getPosition()[1] * hit.getPosition()[1] + + hit.getPosition()[2] * hit.getPosition()[2]); + Double_t calibTime = hitR * 0.0034; + copiedHit.setTime(hit.getTime() - calibTime); + sorted_hits.push_back(copiedHit); + + // std::cout << ">>> Detector " << m_trackerhit_collection_names.at(coll_index) + // << " Original Time: " << hit.getTime() + // << " Calibrated Time: " << hit.getTime() - calibTime << std::endl; + } + + std::sort(sorted_hits.begin(), sorted_hits.end(), + [](const auto& a, const auto& b) { return a.getTime() < b.getTime(); }); + + for (const auto& hit : sorted_hits) { + coll_out->push_back(hit); + } + } + } + } +}; diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc new file mode 100644 index 0000000000..55149cee3a --- /dev/null +++ b/src/global/splitting/splitting.cc @@ -0,0 +1,126 @@ +// Copyright 2024, Jefferson Science Associates, LLC. +// Subject to the terms in the LICENSE file found in the top-level directory. +// kuma edit + +#include +#include "extensions/jana/JOmniFactoryGeneratorT.h" + +// #include "HitChecker.h" +#include "TrkTimeAlignmentFactory.h" +#include "CalRecTimeAlignmentFactory.h" +// #include "CalTimeAlignmentFactory.h" +#include "TimeframeSplitter.h" + +extern "C" { +void InitPlugin(JApplication* app) { + + std::vector m_simtrackerhit_collection_names_aligned = { + "TOFBarrelRecHits_aligned", "TOFEndcapRecHits_aligned", + "MPGDBarrelRecHits_aligned", "OuterMPGDBarrelRecHits_aligned", + "BackwardMPGDEndcapRecHits_aligned", "ForwardMPGDEndcapRecHits_aligned", + "SiBarrelVertexRecHits_aligned", "SiBarrelTrackerRecHits_aligned", + "SiEndcapTrackerRecHits_aligned", "B0TrackerRecHits_aligned", + "TaggerTrackerRecHits_aligned", "ForwardRomanPotRecHits_aligned", + "ForwardOffMTrackerRecHits_aligned"}; + // "RICHEndcapNRecHits_TK_aligned" + // "DIRCBarRecHits_TK_aligned", + // "DRICHRecHits_TK_aligned", + + std::vector m_simtrackerhit_collection_names = { + "TOFBarrelRecHits", "TOFEndcapRecHits", "MPGDBarrelRecHits", + "OuterMPGDBarrelRecHits", "BackwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits", + "SiBarrelVertexRecHits", "SiBarrelTrackerRecHits", "SiEndcapTrackerRecHits", + "B0TrackerRecHits", "TaggerTrackerRecHits", "ForwardRomanPotRecHits", + "ForwardOffMTrackerRecHits"}; + // "RICHEndcapNRecHits_TK" + // "DIRCBarRecHits_TK", + // "DRICHRecHits_TK" + + std::vector m_simcalorechit_collection_names = {"B0ECalRecHits", + "EcalBarrelImagingRecHits", + "EcalBarrelScFiRecHits", + "EcalEndcapNRecHits", + "EcalEndcapPRecHits", + "EcalFarForwardZDCRecHits", + "EcalLumiSpecRecHits", + "HcalBarrelRecHits", + "HcalEndcapNRecHits", + "HcalEndcapPInsertRecHits", + "HcalFarForwardZDCRecHits", + "LFHCALRecHits"}; + + std::vector m_simcalorechit_collection_names_aligned = { + "B0ECalRecHits_aligned", + "EcalBarrelImagingRecHits_aligned", + "EcalBarrelScFiRecHits_aligned", + "EcalEndcapNRecHits_aligned", + "EcalEndcapPRecHits_aligned", + "EcalFarForwardZDCRecHits_aligned", + "EcalLumiSpecRecHits_aligned", + "HcalBarrelRecHits_aligned", + "HcalEndcapNRecHits_aligned", + "HcalEndcapPInsertRecHits_aligned", + "HcalFarForwardZDCRecHits_aligned", + "LFHCALRecHits_aligned"}; + + std::vector m_simcalocluster_collection_names_aligned = { + "B0ECalClusters_TK_aligned", "EcalBarrelClusters_TK_aligned", + "EcalEndcapNClusters_TK_aligned", "EcalEndcapPClusters_TK_aligned"}; + // "EcalFarForwardZDCClusters_TK_aligned", + // "EcalLumiSpecClusters_TK_aligned", + // "HcalBarrelClusters_TK_aligned", + // "HcalEndcapNClusters_TK_aligned", + // "HcalEndcapPInsertClusters_TK_aligned", + // "HcalFarForwardZDCClusters_TK_aligned", + // "LFHCALClusters_TK_aligned" + + std::vector m_simcalocluster_collection_names = { + "B0ECalClusters_TK", "EcalBarrelClusters_TK", "EcalEndcapNClusters_TK", + "EcalEndcapPClusters_TK"}; + + InitJANAPlugin(app); + + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + if (!split_timeframes) { + return; + } + app->Add(new JOmniFactoryGeneratorT( + "timeAlignment", m_simtrackerhit_collection_names, m_simtrackerhit_collection_names_aligned, + app, JEventLevel::Timeslice)); + + app->Add(new JOmniFactoryGeneratorT( + "CalRecTimeAlignment", m_simcalorechit_collection_names, + m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); + + // app->Add(new JOmniFactoryGeneratorT( + // JOmniFactoryGeneratorT::TypedWiring{ + // .m_tag = "CalTimeAlignment", + // .m_default_input_tags = m_simcalocluster_collection_names, + // .m_default_output_tags = m_simcalocluster_collection_names_aligned, + // .level = JEventLevel::Timeslice, + // }, + // app)); + + // Unfolder that takes timeframes and splits them into physics events. + app->Add(new TimeframeSplitter()); + + // app->Add(new JOmniFactoryGeneratorT( + // JOmniFactoryGeneratorT::TypedWiring{ + // .m_tag = "timeframe_hit_checker", + // .m_default_input_tags = {"TOFBarrelRecHits"}, + // .m_default_output_tags = {"hitChecker_TF"}, + // .level = JEventLevel::Timeslice, + // }, + // app)); + + // app->Add(new JOmniFactoryGeneratorT( + // JOmniFactoryGeneratorT::TypedWiring{ + // .m_tag = "timeslice_hit_checker", + // .m_default_input_tags = {"TOFBarrelRecHits"}, + // .m_default_output_tags = {"hitChecker_TS"}, + // .level = JEventLevel::PhysicsEvent, + // }, + // app)); +} +} // "C" diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index 27b4f83d14..0ce8312e2d 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -516,7 +516,23 @@ JEventProcessorPODIO::JEventProcessorPODIO() { "BarrelChargedCandidateParticlesAlpha", "EndcapPChargedCandidateParticlesAlpha", "EndcapPInsertChargedCandidateParticlesAlpha", + + "EventHeader_PHY", + "EventHeader_BKG", }; + + // TimeframeSplitter rebuilds these relation targets in each child PhysicsEvent. Persist + // them together with the default RawHit associations and links so no relation points back + // into the parent Timeslice frame. + if (japp->GetParameterValue("split_timeframes")) { + output_collections.insert( + output_collections.end(), + {"TOFBarrelRecHits", "TOFEndcapRecHits", "TOFBarrelRawHits", "TOFEndcapRawHits", + "B0ECalHits", "EcalBarrelImagingHits", "EcalBarrelScFiHits", "EcalEndcapNHits", + "EcalEndcapPHits", "EcalFarForwardZDCHits", "EcalLumiSpecHits", "HcalBarrelHits", + "HcalEndcapNHits", "HcalEndcapPInsertHits", "HcalFarForwardZDCHits", "LFHCALHits"}); + } + std::vector output_exclude_collections; // need to get as vector, then convert to set japp->SetDefaultParameter( "podio:output_collections", output_collections, diff --git a/src/services/io/podio/podio.cc b/src/services/io/podio/podio.cc index 47622f0609..82b617124d 100644 --- a/src/services/io/podio/podio.cc +++ b/src/services/io/podio/podio.cc @@ -13,17 +13,33 @@ #include "JEventSourceManagedPODIO.h" #include "JEventSourcePODIO.h" +namespace { + +template +class LeveledEventSourceGeneratorT : public JEventSourceGeneratorT { +public: + explicit LeveledEventSourceGeneratorT(JEventLevel level) { this->SetLevel(level); } +}; + +} // namespace + // Make this a JANA plugin extern "C" { void InitPlugin(JApplication* app) { InitJANAPlugin(app); + const bool split_timeframes = + app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); + const auto source_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; + // Check if managed mode is requested if (app->GetJParameterManager()->Exists("podio:managed_socket_path")) { - app->Add(new JEventSourceManagedPODIO("", app)); + auto* source = new JEventSourceManagedPODIO("", app); + source->SetLevel(source_level); + app->Add(source); app->Add(new JEventProcessorManagedPODIO()); } else { - app->Add(new JEventSourceGeneratorT()); + app->Add(new LeveledEventSourceGeneratorT(source_level)); app->Add(new JEventProcessorPODIO()); } } From 1d2f7fc43e8638ef655d321775c5d3a8859423ba Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Mon, 3 Aug 2026 23:49:34 -0400 Subject: [PATCH 02/31] Fix splitting plugin compiler warnings --- .../splitting/CalRecTimeAlignmentFactory.h | 4 +- src/global/splitting/TimeframeSplitter.h | 229 +++++++++--------- .../splitting/TrkTimeAlignmentFactory.h | 4 +- 3 files changed, 117 insertions(+), 120 deletions(-) diff --git a/src/global/splitting/CalRecTimeAlignmentFactory.h b/src/global/splitting/CalRecTimeAlignmentFactory.h index 2256a3016f..e8e99cab61 100644 --- a/src/global/splitting/CalRecTimeAlignmentFactory.h +++ b/src/global/splitting/CalRecTimeAlignmentFactory.h @@ -57,9 +57,9 @@ struct CalRecTimeAlignmentFactory : public JOmniFactory m_caloclusterassociation_out{ // this, m_caloclusterassociation_collection_names_out}; - PodioOutput m_event_header_ts_out{this, "EventHeader_TS"}; PodioOutput m_event_header_phy_out{this, "EventHeader_PHY"}; PodioOutput m_event_header_bkg_out{this, "EventHeader_BKG"}; @@ -784,11 +783,17 @@ struct TimeframeSplitter : public JEventUnfolder { std::vector> vECalTowersBkg; // For QA - float m_timeframe_width = timeframe_width(); - float m_timesplit_width = timesplit_width(); + const float m_timeframe_width = timeframe_width(); + const float m_timesplit_width = timesplit_width(); Bool_t m_bTrigger = false; + // Materialize these output collections even when no timeslice triggers, + // so the output schema is available from the first event. + (void)m_event_header_out(); + (void)m_event_header_phy_out(); + (void)m_event_header_bkg_out(); + const auto trackerHitCollsIn = m_trackerhits_in(); const auto caloRecHitCollsIn = m_calorechit_in(); const auto trkAssoCollsIn = m_trackerhitsAsso_in(); @@ -816,11 +821,11 @@ struct TimeframeSplitter : public JEventUnfolder { std::sort(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); auto last = std::unique(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); m_vPhysCooTimes.erase(last, m_vPhysCooTimes.end()); - for (size_t iPhysT = 0; iPhysT < m_vPhysCooTimes.size(); ++iPhysT) { - Double_t physCollTime = m_vPhysCooTimes[iPhysT]; - Double_t tsTime = iPhysT * timesplit_width(); - // std::cout << "111<><>><><<><><<><<><><><> TF:TS = " << parent.GetEventNumber() << " : " << child_idx << ", physCollTime: " << physCollTime << ", tsTime: " << tsTime << std::endl; - } + // for (size_t iPhysT = 0; iPhysT < m_vPhysCooTimes.size(); ++iPhysT) { + // Double_t physCollTime = m_vPhysCooTimes[iPhysT]; + // Double_t tsTime = iPhysT * timesplit_width(); + // // std::cout << "111<><>><><<><><<><<><><><> TF:TS = " << parent.GetEventNumber() << " : " << child_idx << ", physCollTime: " << physCollTime << ", tsTime: " << tsTime << std::endl; + // } // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ } @@ -984,73 +989,73 @@ struct TimeframeSplitter : public JEventUnfolder { bMutipliTriggers[5] = etaPhiCalTriggerSum > 2; // /??? QA - Int_t physEventWeight = 2; - for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { - const Double_t physCollTime = *it; - if ((physCollTime + 20 > tsTimeS - 20) && (physCollTime - 10 < tsTimeE + 30)) { - physEventWeight = 1; - break; - } - } - Int_t numOfECalTowersX5 = 0; - Int_t numOfECalTowersX10 = 0; - for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { - for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { - if (backEndCalGrid[iEta][iPhi] > 0 || barrelCalGrid[iEta][iPhi] > 0 || - frontEndCalGrid[iEta][iPhi] > 0) { - if (physEventWeight == 1) { - - std::vector vECalHitInTowerPhyRow = {backEndCalGrid[iEta][iPhi], - barrelCalGrid[iEta][iPhi], - frontEndCalGrid[iEta][iPhi]}; - vECalHitInTowerPhy.push_back(vECalHitInTowerPhyRow); - - if (backEndCalGrid[iEta][iPhi] > 4) { - numOfECalTowersX5++; - if (backEndCalGrid[iEta][iPhi] > 9) - numOfECalTowersX10++; - } - if (barrelCalGrid[iEta][iPhi] > 4) { - numOfECalTowersX5++; - if (barrelCalGrid[iEta][iPhi] > 9) - numOfECalTowersX10++; - } - if (frontEndCalGrid[iEta][iPhi] > 4) { - numOfECalTowersX5++; - if (frontEndCalGrid[iEta][iPhi] > 9) - numOfECalTowersX10++; - } - } else { - std::vector vECalHitInTowerBkgRow = {backEndCalGrid[iEta][iPhi], - barrelCalGrid[iEta][iPhi], - frontEndCalGrid[iEta][iPhi]}; - vECalHitInTowerBkg.push_back(vECalHitInTowerBkgRow); - - if (backEndCalGrid[iEta][iPhi] > 4) { - numOfECalTowersX5++; - if (backEndCalGrid[iEta][iPhi] > 9) - numOfECalTowersX10++; - } - if (barrelCalGrid[iEta][iPhi] > 4) { - numOfECalTowersX5++; - if (barrelCalGrid[iEta][iPhi] > 9) - numOfECalTowersX10++; - } - if (frontEndCalGrid[iEta][iPhi] > 4) { - numOfECalTowersX5++; - if (frontEndCalGrid[iEta][iPhi] > 9) - numOfECalTowersX10++; - } - } - } - } - } - if (physEventWeight == 1) - vECalTowersPhy.push_back( - {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); - else if (physEventWeight == 2) - vECalTowersBkg.push_back( - {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); + // Int_t physEventWeight = 2; + // for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { + // const Double_t physCollTime = *it; + // if ((physCollTime + 20 > tsTimeS - 20) && (physCollTime - 10 < tsTimeE + 30)) { + // physEventWeight = 1; + // break; + // } + // } + // Int_t numOfECalTowersX5 = 0; + // Int_t numOfECalTowersX10 = 0; + // for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { + // for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { + // if (backEndCalGrid[iEta][iPhi] > 0 || barrelCalGrid[iEta][iPhi] > 0 || + // frontEndCalGrid[iEta][iPhi] > 0) { + // if (physEventWeight == 1) { + + // std::vector vECalHitInTowerPhyRow = {backEndCalGrid[iEta][iPhi], + // barrelCalGrid[iEta][iPhi], + // frontEndCalGrid[iEta][iPhi]}; + // vECalHitInTowerPhy.push_back(vECalHitInTowerPhyRow); + + // if (backEndCalGrid[iEta][iPhi] > 4) { + // numOfECalTowersX5++; + // if (backEndCalGrid[iEta][iPhi] > 9) + // numOfECalTowersX10++; + // } + // if (barrelCalGrid[iEta][iPhi] > 4) { + // numOfECalTowersX5++; + // if (barrelCalGrid[iEta][iPhi] > 9) + // numOfECalTowersX10++; + // } + // if (frontEndCalGrid[iEta][iPhi] > 4) { + // numOfECalTowersX5++; + // if (frontEndCalGrid[iEta][iPhi] > 9) + // numOfECalTowersX10++; + // } + // } else { + // std::vector vECalHitInTowerBkgRow = {backEndCalGrid[iEta][iPhi], + // barrelCalGrid[iEta][iPhi], + // frontEndCalGrid[iEta][iPhi]}; + // vECalHitInTowerBkg.push_back(vECalHitInTowerBkgRow); + + // if (backEndCalGrid[iEta][iPhi] > 4) { + // numOfECalTowersX5++; + // if (backEndCalGrid[iEta][iPhi] > 9) + // numOfECalTowersX10++; + // } + // if (barrelCalGrid[iEta][iPhi] > 4) { + // numOfECalTowersX5++; + // if (barrelCalGrid[iEta][iPhi] > 9) + // numOfECalTowersX10++; + // } + // if (frontEndCalGrid[iEta][iPhi] > 4) { + // numOfECalTowersX5++; + // if (frontEndCalGrid[iEta][iPhi] > 9) + // numOfECalTowersX10++; + // } + // } + // } + // } + // } + // if (physEventWeight == 1) + // vECalTowersPhy.push_back( + // {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); + // else if (physEventWeight == 2) + // vECalTowersBkg.push_back( + // {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); // /??? QA if (!bMutipliTriggers[0] && !bMutipliTriggers[1] && !bMutipliTriggers[2] && @@ -1102,38 +1107,38 @@ struct TimeframeSplitter : public JEventUnfolder { // == e == Time frame scan loop ========================================================== // /??? QA <><><><><><><><><><><><><><> - if (!vECalHitInTowerPhy.empty()) { - auto& oECalHitsInTowerPhy = m_ecalhitsintower_phy_out(); - auto& oECalTowersPHY = m_ecaltowers_phy_out(); - for (size_t iTower = 0; iTower < vECalHitInTowerPhy.size(); ++iTower) { - auto entry = oECalHitsInTowerPhy->create(); - entry.setEventNumber(vECalHitInTowerPhy[iTower][0]); - entry.setRunNumber(vECalHitInTowerPhy[iTower][1]); - entry.setTimeStamp(vECalHitInTowerPhy[iTower][2]); - } - for (size_t iTower = 0; iTower < vECalTowersPhy.size(); ++iTower) { - auto entry = oECalTowersPHY->create(); - entry.setEventNumber(vECalTowersPhy[iTower][0]); - entry.setRunNumber(vECalTowersPhy[iTower][1]); - entry.setTimeStamp(vECalTowersPhy[iTower][2]); - } - } - if (!vECalHitInTowerBkg.empty()) { - auto& oECalHitsInTowerBkg = m_ecalhitsintower_bkg_out(); - auto& oECalTowersBkg = m_ecaltowers_bkg_out(); - for (size_t iTower = 0; iTower < vECalHitInTowerBkg.size(); ++iTower) { - auto entry = oECalHitsInTowerBkg->create(); - entry.setEventNumber(vECalHitInTowerBkg[iTower][0]); - entry.setRunNumber(vECalHitInTowerBkg[iTower][1]); - entry.setTimeStamp(vECalHitInTowerBkg[iTower][2]); - } - for (size_t iTower = 0; iTower < vECalTowersBkg.size(); ++iTower) { - auto entry = oECalTowersBkg->create(); - entry.setEventNumber(vECalTowersBkg[iTower][0]); - entry.setRunNumber(vECalTowersBkg[iTower][1]); - entry.setTimeStamp(vECalTowersBkg[iTower][2]); - } - } + // if (!vECalHitInTowerPhy.empty()) { + // auto& oECalHitsInTowerPhy = m_ecalhitsintower_phy_out(); + // auto& oECalTowersPHY = m_ecaltowers_phy_out(); + // for (size_t iTower = 0; iTower < vECalHitInTowerPhy.size(); ++iTower) { + // auto entry = oECalHitsInTowerPhy->create(); + // entry.setEventNumber(vECalHitInTowerPhy[iTower][0]); + // entry.setRunNumber(vECalHitInTowerPhy[iTower][1]); + // entry.setTimeStamp(vECalHitInTowerPhy[iTower][2]); + // } + // for (size_t iTower = 0; iTower < vECalTowersPhy.size(); ++iTower) { + // auto entry = oECalTowersPHY->create(); + // entry.setEventNumber(vECalTowersPhy[iTower][0]); + // entry.setRunNumber(vECalTowersPhy[iTower][1]); + // entry.setTimeStamp(vECalTowersPhy[iTower][2]); + // } + // } + // if (!vECalHitInTowerBkg.empty()) { + // auto& oECalHitsInTowerBkg = m_ecalhitsintower_bkg_out(); + // auto& oECalTowersBkg = m_ecaltowers_bkg_out(); + // for (size_t iTower = 0; iTower < vECalHitInTowerBkg.size(); ++iTower) { + // auto entry = oECalHitsInTowerBkg->create(); + // entry.setEventNumber(vECalHitInTowerBkg[iTower][0]); + // entry.setRunNumber(vECalHitInTowerBkg[iTower][1]); + // entry.setTimeStamp(vECalHitInTowerBkg[iTower][2]); + // } + // for (size_t iTower = 0; iTower < vECalTowersBkg.size(); ++iTower) { + // auto entry = oECalTowersBkg->create(); + // entry.setEventNumber(vECalTowersBkg[iTower][0]); + // entry.setRunNumber(vECalTowersBkg[iTower][1]); + // entry.setTimeStamp(vECalTowersBkg[iTower][2]); + // } + // } // /??? QA <><><><><><><><><><><><><<>><><><><>< m_bTrigger = bTimesliceTrigger; @@ -1253,15 +1258,6 @@ struct TimeframeSplitter : public JEventUnfolder { } } - edm4hep::MutableEventHeader event_header_ts; - event_header_ts.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_ts.setEventNumber(m_event_number_ts); - event_header_ts.setTimeStamp(iTimeSlice); - event_header_ts.setWeight(physEventWeight); - // event_header_ts.setWeight(memoryUsage); // Just a dummy weight for now - m_event_header_ts_out()->push_back(event_header_ts); - m_event_number_ts++; - if (physEventWeight == 1) { edm4hep::MutableEventHeader event_header_bkg; event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); @@ -1312,6 +1308,7 @@ struct TimeframeSplitter : public JEventUnfolder { } } } + m_event_number_ts++; // Insert an independent EventHeader object into the physics event. // A subset header would keep a reference to the parent frame collection. diff --git a/src/global/splitting/TrkTimeAlignmentFactory.h b/src/global/splitting/TrkTimeAlignmentFactory.h index 7e47f0dbbb..2c852d1d15 100644 --- a/src/global/splitting/TrkTimeAlignmentFactory.h +++ b/src/global/splitting/TrkTimeAlignmentFactory.h @@ -57,9 +57,9 @@ struct timeAlignmentFactory : public JOmniFactory { void Configure() {} - void ChangeRun(int32_t /*run_nr*/) {} + void ChangeRun(int32_t /*run_nr*/) override {} - void Process(int64_t /*run_number*/, uint64_t /*event_number*/) { + void Process(int32_t /*run_number*/, uint64_t /*event_number*/) override { for (size_t coll_index = 0; coll_index < m_trackerhits_in().size(); ++coll_index) { const auto* coll_in = m_trackerhits_in().at(coll_index); auto& coll_out = m_trackerhits_out().at(coll_index); From 9a01c5b4936524e92794840d809efdd4d93841bf Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2026 03:52:12 +0000 Subject: [PATCH 03/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/global/splitting/TimeframeSplitter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 7331aebf6c..8c2c6d2b03 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -51,8 +51,8 @@ struct TimeframeSplitter : public JEventUnfolder { bool m_use_timeframe = false; // Use timeframes to split events, or use timeslices Int_t m_OrigTFCount = 0; //QA - Int_t m_NewEventCount = 0; //QA - Int_t m_PhysCount = 0; //QA + Int_t m_NewEventCount = 0; //QA + Int_t m_PhysCount = 0; //QA size_t m_event_number_ts = 0; // Event number for the current timeslice size_t m_event_number_orig = 0; // Event number for the current timeslice From b73d352fdb3d0ea7d218cc4c9014e2a911bef667 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2026 04:49:13 +0000 Subject: [PATCH 04/31] fix: iwyu [skip ci] --- src/detectors/B0ECAL/B0ECAL.cc | 2 ++ src/detectors/B0TRK/B0TRK.cc | 2 ++ src/detectors/BEMC/BEMC.cc | 1 + src/detectors/BHCAL/BHCAL.cc | 2 ++ src/detectors/BTOF/BTOF.cc | 1 + src/detectors/BTRK/BTRK.cc | 2 ++ src/detectors/BVTX/BVTX.cc | 2 ++ src/detectors/ECTOF/ECTOF.cc | 1 + src/detectors/ECTRK/ECTRK.cc | 2 ++ src/detectors/EEMC/EEMC.cc | 2 ++ src/detectors/EHCAL/EHCAL.cc | 2 ++ src/detectors/FEMC/FEMC.cc | 1 + src/detectors/FHCAL/FHCAL.cc | 2 ++ src/detectors/FOFFMTRK/FOFFMTRK.cc | 2 ++ src/detectors/LOWQ2/LOWQ2.cc | 1 + src/detectors/LUMISPECCAL/LUMISPECCAL.cc | 2 ++ src/detectors/MPGD/MPGD.cc | 1 + src/detectors/RPOTS/RPOTS.cc | 2 ++ src/detectors/ZDC/ZDC.cc | 2 ++ src/global/splitting/splitting.cc | 11 ++++++++--- src/services/io/podio/podio.cc | 2 ++ 21 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/detectors/B0ECAL/B0ECAL.cc b/src/detectors/B0ECAL/B0ECAL.cc index 530a9081c5..18f7023c5c 100644 --- a/src/detectors/B0ECAL/B0ECAL.cc +++ b/src/detectors/B0ECAL/B0ECAL.cc @@ -2,7 +2,9 @@ // Copyright (C) 2022 - 2025 Whitney Armstrong, Sylvester Joosten, Chao Peng, David Lawrence, Wouter Deconinck, Kolja Kauder, Nathan Brei, Dmitry Kalinkin, Derek Anderson, Michael Pitt #include +#include #include +#include #include #include #include diff --git a/src/detectors/B0TRK/B0TRK.cc b/src/detectors/B0TRK/B0TRK.cc index bdff05362d..6e98776112 100644 --- a/src/detectors/B0TRK/B0TRK.cc +++ b/src/detectors/B0TRK/B0TRK.cc @@ -4,7 +4,9 @@ // #include +#include #include +#include #include #include #include diff --git a/src/detectors/BEMC/BEMC.cc b/src/detectors/BEMC/BEMC.cc index 63deda806b..f13e27c01a 100644 --- a/src/detectors/BEMC/BEMC.cc +++ b/src/detectors/BEMC/BEMC.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/src/detectors/BHCAL/BHCAL.cc b/src/detectors/BHCAL/BHCAL.cc index 83aee81a0f..a3e6a94d45 100644 --- a/src/detectors/BHCAL/BHCAL.cc +++ b/src/detectors/BHCAL/BHCAL.cc @@ -2,7 +2,9 @@ // Copyright (C) 2022 - 2024 David Lawrence, Derek Anderson, Wouter Deconinck #include +#include #include +#include #include #include #include diff --git a/src/detectors/BTOF/BTOF.cc b/src/detectors/BTOF/BTOF.cc index 7082b9f440..3808af9c81 100644 --- a/src/detectors/BTOF/BTOF.cc +++ b/src/detectors/BTOF/BTOF.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/src/detectors/BTRK/BTRK.cc b/src/detectors/BTRK/BTRK.cc index 0037ed2956..c0f41c5762 100644 --- a/src/detectors/BTRK/BTRK.cc +++ b/src/detectors/BTRK/BTRK.cc @@ -4,7 +4,9 @@ // #include +#include #include +#include #include #include #include diff --git a/src/detectors/BVTX/BVTX.cc b/src/detectors/BVTX/BVTX.cc index 0f6b266414..6f6fed1980 100644 --- a/src/detectors/BVTX/BVTX.cc +++ b/src/detectors/BVTX/BVTX.cc @@ -5,7 +5,9 @@ // #include +#include #include +#include #include #include #include diff --git a/src/detectors/ECTOF/ECTOF.cc b/src/detectors/ECTOF/ECTOF.cc index 3da67142c6..1cf3c6b642 100644 --- a/src/detectors/ECTOF/ECTOF.cc +++ b/src/detectors/ECTOF/ECTOF.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/src/detectors/ECTRK/ECTRK.cc b/src/detectors/ECTRK/ECTRK.cc index d121b0a268..0c17b790d0 100644 --- a/src/detectors/ECTRK/ECTRK.cc +++ b/src/detectors/ECTRK/ECTRK.cc @@ -4,7 +4,9 @@ // #include +#include #include +#include #include #include #include diff --git a/src/detectors/EEMC/EEMC.cc b/src/detectors/EEMC/EEMC.cc index ca5395098e..fb276fb7af 100644 --- a/src/detectors/EEMC/EEMC.cc +++ b/src/detectors/EEMC/EEMC.cc @@ -2,7 +2,9 @@ // Copyright (C) 2022 - 2025 Sylvester Joosten, Chao, Chao Peng, Whitney Armstrong, Thomas Britton, David Lawrence, Dhevan Gangadharan, Wouter Deconinck, Dmitry Kalinkin, Derek Anderson #include +#include #include +#include #include #include #include diff --git a/src/detectors/EHCAL/EHCAL.cc b/src/detectors/EHCAL/EHCAL.cc index da758b4e43..04410df7b9 100644 --- a/src/detectors/EHCAL/EHCAL.cc +++ b/src/detectors/EHCAL/EHCAL.cc @@ -2,7 +2,9 @@ // Copyright (C) 2022 - 2025 Sylvester Joosten, Chao, Chao Peng, Whitney Armstrong, David Lawrence, Friederike Bock, Nathan Brei, Wouter Deconinck, Dmitry Kalinkin, Derek Anderson #include +#include #include +#include #include #include #include diff --git a/src/detectors/FEMC/FEMC.cc b/src/detectors/FEMC/FEMC.cc index 7dc28a37b6..4ad0b6d27c 100644 --- a/src/detectors/FEMC/FEMC.cc +++ b/src/detectors/FEMC/FEMC.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/src/detectors/FHCAL/FHCAL.cc b/src/detectors/FHCAL/FHCAL.cc index 5790400bf4..20cb17d10e 100644 --- a/src/detectors/FHCAL/FHCAL.cc +++ b/src/detectors/FHCAL/FHCAL.cc @@ -2,7 +2,9 @@ // Copyright (C) 2023 - 2025 Friederike Bock, Wouter Deconinck #include +#include #include +#include #include #include #include diff --git a/src/detectors/FOFFMTRK/FOFFMTRK.cc b/src/detectors/FOFFMTRK/FOFFMTRK.cc index 727ed7ffce..066b7117b9 100644 --- a/src/detectors/FOFFMTRK/FOFFMTRK.cc +++ b/src/detectors/FOFFMTRK/FOFFMTRK.cc @@ -4,7 +4,9 @@ // #include +#include #include +#include #include #include #include diff --git a/src/detectors/LOWQ2/LOWQ2.cc b/src/detectors/LOWQ2/LOWQ2.cc index 905c063209..5bacccde72 100644 --- a/src/detectors/LOWQ2/LOWQ2.cc +++ b/src/detectors/LOWQ2/LOWQ2.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/src/detectors/LUMISPECCAL/LUMISPECCAL.cc b/src/detectors/LUMISPECCAL/LUMISPECCAL.cc index 8014a989c3..2c9e8b145b 100644 --- a/src/detectors/LUMISPECCAL/LUMISPECCAL.cc +++ b/src/detectors/LUMISPECCAL/LUMISPECCAL.cc @@ -2,7 +2,9 @@ // Copyright (C) 2022 - 2025 Sylvester Joosten, Chao, Chao Peng, Whitney Armstrong, David Lawrence, Dhevan Gangadharan, Nathan Brei,, Wouter Deconinck, Dmitry Kalinkin, Derek Anderson #include +#include #include +#include #include #include #include diff --git a/src/detectors/MPGD/MPGD.cc b/src/detectors/MPGD/MPGD.cc index 0b9d9bebb6..3c4a6e2c97 100644 --- a/src/detectors/MPGD/MPGD.cc +++ b/src/detectors/MPGD/MPGD.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/src/detectors/RPOTS/RPOTS.cc b/src/detectors/RPOTS/RPOTS.cc index 2de5721628..3b660b4566 100644 --- a/src/detectors/RPOTS/RPOTS.cc +++ b/src/detectors/RPOTS/RPOTS.cc @@ -4,7 +4,9 @@ // #include +#include #include +#include #include #include #include diff --git a/src/detectors/ZDC/ZDC.cc b/src/detectors/ZDC/ZDC.cc index 127e09c8aa..c2f0d8a768 100644 --- a/src/detectors/ZDC/ZDC.cc +++ b/src/detectors/ZDC/ZDC.cc @@ -2,7 +2,9 @@ // Copyright (C) 2021 - 2025, Chao Peng, Sylvester Joosten, Whitney Armstrong, David Lawrence, Friederike Bock, Wouter Deconinck, Nathan Brei, Sebouh Paul, Dmitry Kalinkin, Barak Schmookler #include +#include #include +#include #include #include #include diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index 55149cee3a..769a8b06a2 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -3,13 +3,18 @@ // kuma edit #include -#include "extensions/jana/JOmniFactoryGeneratorT.h" +#include +#include +#include +#include +#include -// #include "HitChecker.h" -#include "TrkTimeAlignmentFactory.h" #include "CalRecTimeAlignmentFactory.h" // #include "CalTimeAlignmentFactory.h" #include "TimeframeSplitter.h" +// #include "HitChecker.h" +#include "TrkTimeAlignmentFactory.h" +#include "extensions/jana/JOmniFactoryGeneratorT.h" extern "C" { void InitPlugin(JApplication* app) { diff --git a/src/services/io/podio/podio.cc b/src/services/io/podio/podio.cc index 82b617124d..766cb68fcc 100644 --- a/src/services/io/podio/podio.cc +++ b/src/services/io/podio/podio.cc @@ -3,9 +3,11 @@ // // +#include #include #include #include +#include #include #include "JEventProcessorManagedPODIO.h" From 1437f6f1f20104917e6afd893d236682fd6748e0 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Tue, 4 Aug 2026 11:52:29 -0400 Subject: [PATCH 05/31] fix copilot review about optimize association loop --- src/global/splitting/TimeframeSplitter.h | 232 +++++++++++++++-------- 1 file changed, 148 insertions(+), 84 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 8c2c6d2b03..c87828d6bd 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "TMath.h" @@ -490,22 +492,73 @@ struct TimeframeSplitter : public JEventUnfolder { Double_t average_time() const { return count == 0 ? 0.0 : time_sum / count; } }; - static bool overlaps_time_window(Double_t hit_time, Double_t resolution, Double_t window_start, + using TrackerAssociationIndex = + std::unordered_map>; + using CalorimeterAssociationIndex = + std::unordered_map>; + + + static std::uint64_t object_id_key(const podio::ObjectID& object_id) { + const auto collection_id = + static_cast(static_cast(object_id.collectionID)); + const auto index = + static_cast(static_cast(object_id.index)); + + return (collection_id << 32U) | index; + } + + static TrackerAssociationIndex buildTrkAssoId( + const edm4eic::MCRecoTrackerHitAssociationCollection* associations) { + + TrackerAssociationIndex index; + if (associations == nullptr) return index; + index.reserve(associations->size()); + + for (size_t assoId = 0; assoId < associations->size(); ++assoId) { + const auto association = associations->at(assoId); + const auto raw_hit = association.getRawHit(); + if (!raw_hit.isAvailable()) continue; + index[object_id_key(raw_hit.getObjectID())].push_back(assoId); + } + + return index; + } + + static CalorimeterAssociationIndex buildCalAssoId( + const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations) { + + CalorimeterAssociationIndex index; + if (associations == nullptr) return index; + index.reserve(associations->size()); + + for (size_t assoId = 0; assoId < associations->size(); ++assoId) { + const auto association = associations->at(assoId); + const auto raw_hit = association.getRawHit(); + if (!raw_hit.isAvailable()) continue; + index[object_id_key(raw_hit.getObjectID())].push_back(assoId); + } + + return index; + } + + + + static bool overlaps_time_window(Double_t hitTime, Double_t resolution, Double_t window_start, Double_t window_end) { - return hit_time + resolution > window_start && hit_time - resolution < window_end; + return hitTime + resolution > window_start && hitTime - resolution < window_end; } - static bool is_after_time_window(Double_t hit_time, Double_t resolution, Double_t window_end) { - return hit_time - resolution >= window_end; + static bool is_after_time_window(Double_t hitTime, Double_t resolution, Double_t window_end) { + return hitTime - resolution >= window_end; } static bool isValidEtaPhiBin(Int_t etaBin, Int_t phiBin) { return 0 <= etaBin && etaBin < kEtaPhiBins && 0 <= phiBin && phiBin < kEtaPhiBins; } - static bool is_hit_in_time_slice(Double_t hit_time, Double_t time_resolution, + static bool is_hit_in_time_slice(Double_t hitTime, Double_t time_resolution, Double_t time_slice_start, Double_t time_slice_end) { - return !(hit_time + time_resolution < time_slice_start || - hit_time - time_resolution > time_slice_end); + return !(hitTime + time_resolution < time_slice_start || + hitTime - time_resolution > time_slice_end); } template @@ -681,12 +734,12 @@ struct TimeframeSplitter : public JEventUnfolder { for (size_t i = start_index; i < collection->size(); ++i) { const auto& hit = collection->at(i); - const Double_t hit_time = hit.getTime(); - if (is_after_time_window(hit_time, resolution, window_end)) + const Double_t hitTime = hit.getTime(); + if (is_after_time_window(hitTime, resolution, window_end)) break; - if (overlaps_time_window(hit_time, resolution, window_start, window_end)) { + if (overlaps_time_window(hitTime, resolution, window_start, window_end)) { ++summary.count; - summary.time_sum += hit_time; + summary.time_sum += hitTime; summary.next_start_index = i; } } @@ -697,55 +750,64 @@ struct TimeframeSplitter : public JEventUnfolder { static void copy_tracker_hit_with_relations( const edm4eic::TrackerHit& tracker_hit, const edm4eic::MCRecoTrackerHitAssociationCollection* associations, - TrackerHitOutputT& tracker_hits_out, RawHitOutputT& raw_hits_out, + const TrackerAssociationIndex& association_index, + TrackerHitOutputT& tracker_hits_out, + RawHitOutputT& raw_hits_out, AssociationOutputT& associations_out, - std::unique_ptr& sim_hits_out, + std::unique_ptr& simHits_out, std::unique_ptr& links_out, std::unique_ptr& mc_particles_out) { - auto copied_tracker_hit = tracker_hit.clone(); - copied_tracker_hit.setRawHit(edm4eic::RawTrackerHit()); + + auto trackerHitCopied = tracker_hit.clone(); + trackerHitCopied.setRawHit(edm4eic::RawTrackerHit()); if (associations == nullptr || !tracker_hit.getRawHit().isAvailable()) { - tracker_hits_out->push_back(copied_tracker_hit); + tracker_hits_out->push_back(trackerHitCopied); return; } - const auto raw_hit_id = tracker_hit.getRawHit().getObjectID(); - auto copied_raw_hit = tracker_hit.getRawHit().clone(); - raw_hits_out->push_back(copied_raw_hit); - copied_tracker_hit.setRawHit(copied_raw_hit); + const auto rawHitId = tracker_hit.getRawHit().getObjectID(); - for (const auto& association : *associations) { - const auto association_raw_hit = association.getRawHit(); - if (!association_raw_hit.isAvailable() || association_raw_hit.getObjectID() != raw_hit_id) { - continue; - } - if (!association.getSimHit().isAvailable()) - continue; + auto rawHitCopied = tracker_hit.getRawHit().clone(); + raw_hits_out->push_back(rawHitCopied); + trackerHitCopied.setRawHit(rawHitCopied); + + const auto assocIterCal = + association_index.find(object_id_key(rawHitId)); + + if (assocIterCal != association_index.end()) { + for (const size_t index : assocIterCal->second) { + const auto association = associations->at(index); + + if (!association.getSimHit().isAvailable()) continue; + + const auto simHit = association.getSimHit(); + auto simHitCopied = simHit.clone(false); - const auto sim_hit = association.getSimHit(); - auto copied_sim_hit = sim_hit.clone(false); - if (sim_hit.getParticle().isAvailable()) { - const auto particle_id = sim_hit.getParticle().getObjectID(); - if (particle_id.index >= 0 && - static_cast(particle_id.index) < mc_particles_out->size()) { - copied_sim_hit.setParticle((*mc_particles_out)[particle_id.index]); + if (simHit.getParticle().isAvailable()) { + const auto mcPIndex = simHit.getParticle().getObjectID(); + + if (mcPIndex.index >= 0 && + static_cast(mcPIndex.index) < mc_particles_out->size()) { + simHitCopied.setParticle((*mc_particles_out)[mcPIndex.index]); + } } - } - sim_hits_out->push_back(copied_sim_hit); - auto copied_association = associations_out->create(); - copied_association.setWeight(association.getWeight()); - copied_association.setRawHit(copied_raw_hit); - copied_association.setSimHit(copied_sim_hit); + simHits_out->push_back(simHitCopied); - auto copied_link = links_out->create(); - copied_link.setWeight(association.getWeight()); - copied_link.setFrom(copied_raw_hit); - copied_link.setTo(copied_sim_hit); + auto copied_association = associations_out->create(); + copied_association.setWeight(association.getWeight()); + copied_association.setRawHit(rawHitCopied); + copied_association.setSimHit(simHitCopied); + + auto copied_link = links_out->create(); + copied_link.setWeight(association.getWeight()); + copied_link.setFrom(rawHitCopied); + copied_link.setTo(simHitCopied); + } } - tracker_hits_out->push_back(copied_tracker_hit); + tracker_hits_out->push_back(trackerHitCopied); } static std::pair backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { @@ -776,12 +838,12 @@ struct TimeframeSplitter : public JEventUnfolder { } Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override { - // For QA - std::vector> vECalHitInTowerPhy; - std::vector> vECalHitInTowerBkg; - std::vector> vECalTowersPhy; - std::vector> vECalTowersBkg; - // For QA + // For QA ??? + // std::vector> vECalHitInTowerPhy; + // std::vector> vECalHitInTowerBkg; + // std::vector> vECalTowersPhy; + // std::vector> vECalTowersBkg; + // For QA ??? const float m_timeframe_width = timeframe_width(); const float m_timesplit_width = timesplit_width(); @@ -1162,9 +1224,12 @@ struct TimeframeSplitter : public JEventUnfolder { continue; auto& trkCollOut = m_trackerhits_out().at(trkDetID); const Double_t detTimeReso = tracker_time_resolution(trkDetID); - const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); - auto& rawCollOut = m_rawhit_out().at(trkDetID); - auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); + const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); + auto& rawCollOut = m_rawhit_out().at(trkDetID); + auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); + + const auto tracker_assoId = + buildTrkAssoId(trkAssoCollIn); for (size_t iHit = 0; iHit < trkCollIn->size(); ++iHit) { const auto& trkHit = trkCollIn->at(iHit); @@ -1175,9 +1240,10 @@ struct TimeframeSplitter : public JEventUnfolder { } iniTrkHitPoint[trkDetID] = iHit; - copy_tracker_hit_with_relations(trkHit, trkAssoCollIn, trkCollOut, rawCollOut, - trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), - m_rawhitlinks_out().at(trkDetID), m_mcparticles_out()); + copy_tracker_hit_with_relations( + trkHit, trkAssoCollIn, tracker_assoId, trkCollOut, rawCollOut, + trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), m_rawhitlinks_out().at(trkDetID), + m_mcparticles_out()); } } // == e == Register Tracker Hits ======================================================= @@ -1185,23 +1251,21 @@ struct TimeframeSplitter : public JEventUnfolder { // == s == Register Calo Rec Hits ======================================================= for (size_t calDetID = 0; calDetID < caloRecHitCollsIn.size(); ++calDetID) { const auto* caloInColl = caloRecHitCollsIn.at(calDetID); - if (caloInColl == nullptr) - continue; + if (caloInColl == nullptr) continue; auto& caloOutColl = m_calorechit_out().at(calDetID); const auto* caloInCollAsso = calrecAssoCollsIn.at(calDetID); - if (caloInCollAsso == nullptr) - continue; + if (caloInCollAsso == nullptr) continue; + + const auto associIdCal = buildCalAssoId(caloInCollAsso); for (size_t iCalHit = 0; iCalHit < caloInColl->size(); ++iCalHit) { const auto& caloHit = caloInColl->at(iCalHit); Double_t detTimeReso = timeResolution_EMCal(); - Double_t hitT = caloHit.getTime(); - if (hitT - detTimeReso > timesliceT0 + 30.) - continue; + if (hitT - detTimeReso > timesliceT0 + 30.) continue; if (overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " CaloDetID = " << calDetID << " iCalHit = " << iCalHit << " hitT = " << hitT << std::endl; auto copiedCaloHit = caloHit.clone(); @@ -1219,23 +1283,27 @@ struct TimeframeSplitter : public JEventUnfolder { auto& simCollOut = m_simcalorimeterhits_out().at(calDetID); const auto rawHitID = rawHitFromRec.getObjectID(); - for (const auto& assoc : *caloInCollAsso) { - const auto assocRawID = assoc.getRawHit().getObjectID(); - if (rawHitID != assocRawID || !assoc.getSimHit().isAvailable()) - continue; + const auto assocIterCal = associIdCal.find(object_id_key(rawHitID)); + + if (assocIterCal != associIdCal.end()) { + for (const size_t association_index : assocIterCal->second) { + const auto assoc = caloInCollAsso->at(association_index); + + if (!assoc.getSimHit().isAvailable()) continue; - auto copiedSimHit = assoc.getSimHit().clone(false); - simCollOut->push_back(copiedSimHit); + auto copiedSimHit = assoc.getSimHit().clone(false); + simCollOut->push_back(copiedSimHit); - auto copiedAssoc = assocCollOut->create(); - copiedAssoc.setWeight(assoc.getWeight()); - copiedAssoc.setRawHit(copiedRawHit); - copiedAssoc.setSimHit(copiedSimHit); + auto copiedAssoc = assocCollOut->create(); + copiedAssoc.setWeight(assoc.getWeight()); + copiedAssoc.setRawHit(copiedRawHit); + copiedAssoc.setSimHit(copiedSimHit); - auto copiedLink = linkCollOut->create(); - copiedLink.setWeight(assoc.getWeight()); - copiedLink.setFrom(copiedRawHit); - copiedLink.setTo(copiedSimHit); + auto copiedLink = linkCollOut->create(); + copiedLink.setWeight(assoc.getWeight()); + copiedLink.setFrom(copiedRawHit); + copiedLink.setTo(copiedSimHit); + } } } @@ -1343,12 +1411,8 @@ struct TimeframeSplitter : public JEventUnfolder { m_bScanedAllTimeWindows = false; iTimeSlice = 0; targetDetId = 0; - for (auto& start_point : iniTrkHitPoint) { - start_point = 0; - } - for (auto& start_point : iniCalHitPoint) { - start_point = 0; - } + for (auto& start_point : iniTrkHitPoint) start_point = 0; + for (auto& start_point : iniCalHitPoint) start_point = 0; if (m_bTrigger) return Result::NextChildNextParent; From ccbd1a8b6f0c86272043aa89e9ac5a923a0d4eae Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Tue, 4 Aug 2026 13:41:08 -0400 Subject: [PATCH 06/31] fix: cache timeframe association indices per parent --- src/global/splitting/TimeframeSplitter.h | 113 +++++++++++++---------- src/global/splitting/splitting.cc | 28 +++--- src/utilities/eicrecon/eicrecon.cc | 1 + 3 files changed, 80 insertions(+), 62 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index c87828d6bd..934d770233 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -492,57 +492,58 @@ struct TimeframeSplitter : public JEventUnfolder { Double_t average_time() const { return count == 0 ? 0.0 : time_sum / count; } }; - using TrackerAssociationIndex = - std::unordered_map>; - using CalorimeterAssociationIndex = - std::unordered_map>; - + using TrackerAssociationIndex = std::unordered_map>; + using CalorimeterAssociationIndex = std::unordered_map>; + + std::vector m_tracker_association_indices; + std::vector m_calorimeter_association_indices; static std::uint64_t object_id_key(const podio::ObjectID& object_id) { const auto collection_id = static_cast(static_cast(object_id.collectionID)); - const auto index = - static_cast(static_cast(object_id.index)); + const auto index = static_cast(static_cast(object_id.index)); return (collection_id << 32U) | index; } - static TrackerAssociationIndex buildTrkAssoId( - const edm4eic::MCRecoTrackerHitAssociationCollection* associations) { + static TrackerAssociationIndex + buildTrkAssoId(const edm4eic::MCRecoTrackerHitAssociationCollection* associations) { TrackerAssociationIndex index; - if (associations == nullptr) return index; + if (associations == nullptr) + return index; index.reserve(associations->size()); for (size_t assoId = 0; assoId < associations->size(); ++assoId) { const auto association = associations->at(assoId); const auto raw_hit = association.getRawHit(); - if (!raw_hit.isAvailable()) continue; + if (!raw_hit.isAvailable()) + continue; index[object_id_key(raw_hit.getObjectID())].push_back(assoId); } return index; } - static CalorimeterAssociationIndex buildCalAssoId( - const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations) { + static CalorimeterAssociationIndex + buildCalAssoId(const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations) { CalorimeterAssociationIndex index; - if (associations == nullptr) return index; + if (associations == nullptr) + return index; index.reserve(associations->size()); for (size_t assoId = 0; assoId < associations->size(); ++assoId) { const auto association = associations->at(assoId); const auto raw_hit = association.getRawHit(); - if (!raw_hit.isAvailable()) continue; + if (!raw_hit.isAvailable()) + continue; index[object_id_key(raw_hit.getObjectID())].push_back(assoId); } return index; } - - static bool overlaps_time_window(Double_t hitTime, Double_t resolution, Double_t window_start, Double_t window_end) { return hitTime + resolution > window_start && hitTime - resolution < window_end; @@ -733,7 +734,7 @@ struct TimeframeSplitter : public JEventUnfolder { return summary; for (size_t i = start_index; i < collection->size(); ++i) { - const auto& hit = collection->at(i); + const auto& hit = collection->at(i); const Double_t hitTime = hit.getTime(); if (is_after_time_window(hitTime, resolution, window_end)) break; @@ -750,10 +751,8 @@ struct TimeframeSplitter : public JEventUnfolder { static void copy_tracker_hit_with_relations( const edm4eic::TrackerHit& tracker_hit, const edm4eic::MCRecoTrackerHitAssociationCollection* associations, - const TrackerAssociationIndex& association_index, - TrackerHitOutputT& tracker_hits_out, - RawHitOutputT& raw_hits_out, - AssociationOutputT& associations_out, + const TrackerAssociationIndex& association_index, TrackerHitOutputT& tracker_hits_out, + RawHitOutputT& raw_hits_out, AssociationOutputT& associations_out, std::unique_ptr& simHits_out, std::unique_ptr& links_out, std::unique_ptr& mc_particles_out) { @@ -772,16 +771,16 @@ struct TimeframeSplitter : public JEventUnfolder { raw_hits_out->push_back(rawHitCopied); trackerHitCopied.setRawHit(rawHitCopied); - const auto assocIterCal = - association_index.find(object_id_key(rawHitId)); + const auto assocIterCal = association_index.find(object_id_key(rawHitId)); if (assocIterCal != association_index.end()) { for (const size_t index : assocIterCal->second) { const auto association = associations->at(index); - if (!association.getSimHit().isAvailable()) continue; + if (!association.getSimHit().isAvailable()) + continue; - const auto simHit = association.getSimHit(); + const auto simHit = association.getSimHit(); auto simHitCopied = simHit.clone(false); if (simHit.getParticle().isAvailable()) { @@ -864,6 +863,22 @@ struct TimeframeSplitter : public JEventUnfolder { // == s == Register hits of TOF and MPGD detectors in the time slice ================== if (child_idx == 0) { m_OrigTFCount++; + + // Association collections belong to the parent Timeslice and remain valid for all + // of its children. Build each lookup once per parent instead of rebuilding the full + // index for every triggered PhysicsEvent. + m_tracker_association_indices.clear(); + m_tracker_association_indices.reserve(trkAssoCollsIn.size()); + for (const auto* associations : trkAssoCollsIn) { + m_tracker_association_indices.push_back(buildTrkAssoId(associations)); + } + + m_calorimeter_association_indices.clear(); + m_calorimeter_association_indices.reserve(calrecAssoCollsIn.size()); + for (const auto* associations : calrecAssoCollsIn) { + m_calorimeter_association_indices.push_back(buildCalAssoId(associations)); + } + // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ m_vPhysCooTimes.clear(); @@ -1224,12 +1239,9 @@ struct TimeframeSplitter : public JEventUnfolder { continue; auto& trkCollOut = m_trackerhits_out().at(trkDetID); const Double_t detTimeReso = tracker_time_resolution(trkDetID); - const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); - auto& rawCollOut = m_rawhit_out().at(trkDetID); - auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); - - const auto tracker_assoId = - buildTrkAssoId(trkAssoCollIn); + const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); + auto& rawCollOut = m_rawhit_out().at(trkDetID); + auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); for (size_t iHit = 0; iHit < trkCollIn->size(); ++iHit) { const auto& trkHit = trkCollIn->at(iHit); @@ -1241,9 +1253,9 @@ struct TimeframeSplitter : public JEventUnfolder { iniTrkHitPoint[trkDetID] = iHit; copy_tracker_hit_with_relations( - trkHit, trkAssoCollIn, tracker_assoId, trkCollOut, rawCollOut, - trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), m_rawhitlinks_out().at(trkDetID), - m_mcparticles_out()); + trkHit, trkAssoCollIn, m_tracker_association_indices.at(trkDetID), trkCollOut, + rawCollOut, trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), + m_rawhitlinks_out().at(trkDetID), m_mcparticles_out()); } } // == e == Register Tracker Hits ======================================================= @@ -1251,21 +1263,22 @@ struct TimeframeSplitter : public JEventUnfolder { // == s == Register Calo Rec Hits ======================================================= for (size_t calDetID = 0; calDetID < caloRecHitCollsIn.size(); ++calDetID) { const auto* caloInColl = caloRecHitCollsIn.at(calDetID); - if (caloInColl == nullptr) continue; + if (caloInColl == nullptr) + continue; auto& caloOutColl = m_calorechit_out().at(calDetID); const auto* caloInCollAsso = calrecAssoCollsIn.at(calDetID); - if (caloInCollAsso == nullptr) continue; - - const auto associIdCal = buildCalAssoId(caloInCollAsso); + if (caloInCollAsso == nullptr) + continue; for (size_t iCalHit = 0; iCalHit < caloInColl->size(); ++iCalHit) { const auto& caloHit = caloInColl->at(iCalHit); Double_t detTimeReso = timeResolution_EMCal(); - Double_t hitT = caloHit.getTime(); + Double_t hitT = caloHit.getTime(); - if (hitT - detTimeReso > timesliceT0 + 30.) continue; + if (hitT - detTimeReso > timesliceT0 + 30.) + continue; if (overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " CaloDetID = " << calDetID << " iCalHit = " << iCalHit << " hitT = " << hitT << std::endl; auto copiedCaloHit = caloHit.clone(); @@ -1283,13 +1296,15 @@ struct TimeframeSplitter : public JEventUnfolder { auto& simCollOut = m_simcalorimeterhits_out().at(calDetID); const auto rawHitID = rawHitFromRec.getObjectID(); - const auto assocIterCal = associIdCal.find(object_id_key(rawHitID)); + const auto& association_index = m_calorimeter_association_indices.at(calDetID); + const auto assocIterCal = association_index.find(object_id_key(rawHitID)); - if (assocIterCal != associIdCal.end()) { - for (const size_t association_index : assocIterCal->second) { - const auto assoc = caloInCollAsso->at(association_index); + if (assocIterCal != association_index.end()) { + for (const size_t association_position : assocIterCal->second) { + const auto assoc = caloInCollAsso->at(association_position); - if (!assoc.getSimHit().isAvailable()) continue; + if (!assoc.getSimHit().isAvailable()) + continue; auto copiedSimHit = assoc.getSimHit().clone(false); simCollOut->push_back(copiedSimHit); @@ -1411,8 +1426,10 @@ struct TimeframeSplitter : public JEventUnfolder { m_bScanedAllTimeWindows = false; iTimeSlice = 0; targetDetId = 0; - for (auto& start_point : iniTrkHitPoint) start_point = 0; - for (auto& start_point : iniCalHitPoint) start_point = 0; + for (auto& start_point : iniTrkHitPoint) + start_point = 0; + for (auto& start_point : iniCalHitPoint) + start_point = 0; if (m_bTrigger) return Result::NextChildNextParent; diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index 769a8b06a2..de3dad3f11 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -68,20 +68,20 @@ void InitPlugin(JApplication* app) { "HcalFarForwardZDCRecHits_aligned", "LFHCALRecHits_aligned"}; - std::vector m_simcalocluster_collection_names_aligned = { - "B0ECalClusters_TK_aligned", "EcalBarrelClusters_TK_aligned", - "EcalEndcapNClusters_TK_aligned", "EcalEndcapPClusters_TK_aligned"}; - // "EcalFarForwardZDCClusters_TK_aligned", - // "EcalLumiSpecClusters_TK_aligned", - // "HcalBarrelClusters_TK_aligned", - // "HcalEndcapNClusters_TK_aligned", - // "HcalEndcapPInsertClusters_TK_aligned", - // "HcalFarForwardZDCClusters_TK_aligned", - // "LFHCALClusters_TK_aligned" - - std::vector m_simcalocluster_collection_names = { - "B0ECalClusters_TK", "EcalBarrelClusters_TK", "EcalEndcapNClusters_TK", - "EcalEndcapPClusters_TK"}; + // std::vector m_simcalocluster_collection_names_aligned = { + // "B0ECalClusters_TK_aligned", "EcalBarrelClusters_TK_aligned", + // "EcalEndcapNClusters_TK_aligned", "EcalEndcapPClusters_TK_aligned"}; + // // "EcalFarForwardZDCClusters_TK_aligned", + // // "EcalLumiSpecClusters_TK_aligned", + // // "HcalBarrelClusters_TK_aligned", + // // "HcalEndcapNClusters_TK_aligned", + // // "HcalEndcapPInsertClusters_TK_aligned", + // // "HcalFarForwardZDCClusters_TK_aligned", + // // "LFHCALClusters_TK_aligned" + + // std::vector m_simcalocluster_collection_names = { + // "B0ECalClusters_TK", "EcalBarrelClusters_TK", "EcalEndcapNClusters_TK", + // "EcalEndcapPClusters_TK"}; InitJANAPlugin(app); diff --git a/src/utilities/eicrecon/eicrecon.cc b/src/utilities/eicrecon/eicrecon.cc index 34a4757c84..3762a1e259 100644 --- a/src/utilities/eicrecon/eicrecon.cc +++ b/src/utilities/eicrecon/eicrecon.cc @@ -50,6 +50,7 @@ std::vector EICRECON_DEFAULT_PLUGINS = { "ECTOF", "LOWQ2", "LUMISPECCAL", + "splitting", "podio", "janatop", // clang-format on From a71113077683a56cb38fb93ebae4abff56b35117 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Sun, 9 Aug 2026 21:16:27 -0400 Subject: [PATCH 07/31] refactor: separate timeframe splitting and time alignment implementations --- src/global/splitting/CMakeLists.txt | 61 +- src/global/splitting/CalRecTimeAlignment.h | 24 + .../splitting/CalRecTimeAlignmentFactory.h | 47 +- src/global/splitting/RecHitTimeAlignment.h | 63 ++ src/global/splitting/TimeframeSplitter.cc | 674 +++++++++++++ src/global/splitting/TimeframeSplitter.h | 908 +----------------- src/global/splitting/TrkTimeAlignment.h | 23 + .../splitting/TrkTimeAlignmentFactory.h | 55 +- src/global/splitting/splitting.cc | 55 +- 9 files changed, 866 insertions(+), 1044 deletions(-) create mode 100644 src/global/splitting/CalRecTimeAlignment.h create mode 100644 src/global/splitting/RecHitTimeAlignment.h create mode 100644 src/global/splitting/TimeframeSplitter.cc create mode 100644 src/global/splitting/TrkTimeAlignment.h diff --git a/src/global/splitting/CMakeLists.txt b/src/global/splitting/CMakeLists.txt index b33f1de1da..699af0b1da 100644 --- a/src/global/splitting/CMakeLists.txt +++ b/src/global/splitting/CMakeLists.txt @@ -1,42 +1,33 @@ -cmake_minimum_required(VERSION 3.16) -if(JANA_VERSION VERSION_LESS "2.4.3") +get_filename_component(PLUGIN_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) - message(STATUS "Skipping `splitting` plugin because JANA_VERSION < 2.4.3") +# Function creates ${PLUGIN_NAME}_plugin and ${PLUGIN_NAME}_library targets +# Setting default includes, libraries and installation paths +plugin_add(${PLUGIN_NAME} PLUGIN_USE_CC_ONLY) -else() +# The macro grabs sources as *.cc *.cpp *.c and headers as *.h *.hh *.hpp Then +# correctly sets sources for ${_name}_plugin and ${_name}_library targets Adds +# headers to the correct installation directory +plugin_glob_all(${PLUGIN_NAME}) - get_filename_component(PLUGIN_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) +# Find dependencies +plugin_add_cern_root(${PLUGIN_NAME}) +plugin_add_event_model(${PLUGIN_NAME}) - # Function creates ${PLUGIN_NAME}_plugin and ${PLUGIN_NAME}_library targets - # Setting default includes, libraries and installation paths - plugin_add(${PLUGIN_NAME} PLUGIN_USE_CC_ONLY) +# Add include directories (works same as target_include_directories) +# plugin_include_directories(${PLUGIN_NAME} SYSTEM PUBLIC ... ) - # The macro grabs sources as *.cc *.cpp *.c and headers as *.h *.hh *.hpp Then - # correctly sets sources for ${_name}_plugin and ${_name}_library targets Adds - # headers to the correct installation directory - plugin_glob_all(${PLUGIN_NAME}) - - # Find dependencies - plugin_add_cern_root(${PLUGIN_NAME}) - plugin_add_event_model(${PLUGIN_NAME}) - - # Add include directories (works same as target_include_directories) - # plugin_include_directories(${PLUGIN_NAME} SYSTEM PUBLIC ... ) - - # Add libraries (same as target_include_directories but for both plugin and - # library) - plugin_link_libraries(${PLUGIN_NAME} algorithms_digi_library +# Add libraries (same as target_include_directories but for both plugin and +# library) +plugin_link_libraries(${PLUGIN_NAME} algorithms_digi_library algorithms_tracking_library) - # - # Add include directories (works same as target_include_directories) - # plugin_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR} - # SYSTEM PUBLIC ${podio_INCLUDE_DIR} ${EDM4HEP_INCLUDE_DIR} - # ${DD4hep_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} ${EDM4EIC_INCLUDE_DIRS}) - # - # Add libraries (works same as target_include_directories) - # plugin_link_libraries(${PLUGIN_NAME} ${ROOT_LIBRARIES} - # algorithms_tracking_library EDM4HEP::edm4hep EDM4EIC::edm4eic spdlog::spdlog - # Boost::boost ${ROOT_EG_LIBRARY}) - -endif() +# +# Add include directories (works same as target_include_directories) +# plugin_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR} +# SYSTEM PUBLIC ${podio_INCLUDE_DIR} ${EDM4HEP_INCLUDE_DIR} +# ${DD4hep_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} ${EDM4EIC_INCLUDE_DIRS}) +# +# Add libraries (works same as target_include_directories) +# plugin_link_libraries(${PLUGIN_NAME} ${ROOT_LIBRARIES} +# algorithms_tracking_library EDM4HEP::edm4hep EDM4EIC::edm4eic spdlog::spdlog +# Boost::boost ${ROOT_EG_LIBRARY}) diff --git a/src/global/splitting/CalRecTimeAlignment.h b/src/global/splitting/CalRecTimeAlignment.h new file mode 100644 index 0000000000..cdceefbf7d --- /dev/null +++ b/src/global/splitting/CalRecTimeAlignment.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov + +#pragma once + +#include +#include + +#include "RecHitTimeAlignment.h" + +namespace eicrecon { + +class CalRecTimeAlignment + : public RecHitTimeAlignment { +public: + CalRecTimeAlignment(std::string_view name) + : RecHitTimeAlignment{name, + "inputCalorimeterHits", + "outputCalorimeterHits", + "Align reconstructed calorimeter hit times."} {} +}; + +} // namespace eicrecon diff --git a/src/global/splitting/CalRecTimeAlignmentFactory.h b/src/global/splitting/CalRecTimeAlignmentFactory.h index e8e99cab61..405b6a7ca9 100644 --- a/src/global/splitting/CalRecTimeAlignmentFactory.h +++ b/src/global/splitting/CalRecTimeAlignmentFactory.h @@ -1,25 +1,24 @@ -// Copyright 2024, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov #pragma once -#include -#include +#include #include #include -#include #include - -#include -#include -#include -#include #include +#include "CalRecTimeAlignment.h" + struct CalRecTimeAlignmentFactory : public JOmniFactory { + using AlgoT = eicrecon::CalRecTimeAlignment; + JEventLevel m_factory_level; + std::unique_ptr m_algo; + std::vector m_simcalorechit_collection_names = {"B0ECalRecHits", "EcalBarrelImagingRecHits", "EcalBarrelScFiRecHits", @@ -53,9 +52,11 @@ struct CalRecTimeAlignmentFactory : public JOmniFactory m_calorechit_out{ this, m_simcalorechit_collection_names_aligned}; - Double_t m_time_offset = 0.0; // Time offset to apply to hits - - void Configure() {} + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } void ChangeRun(int32_t /*run_nr*/) override {} @@ -66,25 +67,7 @@ struct CalRecTimeAlignmentFactory : public JOmniFactory sorted_hits; // for edm4eic (After digitization) - for (const auto& hit : *coll_in) { - edm4eic::MutableCalorimeterHit copiedHit = - hit.clone(); // for edm4eic (After digitization) - - Double_t hitR = std::sqrt(hit.getPosition()[0] * hit.getPosition()[0] + - hit.getPosition()[1] * hit.getPosition()[1] + - hit.getPosition()[2] * hit.getPosition()[2]); - Double_t calibTime = hitR * 0.0034; - copiedHit.setTime(hit.getTime() - calibTime); - sorted_hits.push_back(copiedHit); - } - - std::sort(sorted_hits.begin(), sorted_hits.end(), - [](const auto& a, const auto& b) { return a.getTime() < b.getTime(); }); - - for (const auto& hit : sorted_hits) { - coll_out->push_back(hit); - } + m_algo->process({coll_in}, {coll_out.get()}); } } } diff --git a/src/global/splitting/RecHitTimeAlignment.h b/src/global/splitting/RecHitTimeAlignment.h new file mode 100644 index 0000000000..66245c0241 --- /dev/null +++ b/src/global/splitting/RecHitTimeAlignment.h @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace eicrecon { + +template +using RecHitTimeAlignmentAlgorithm = + algorithms::Algorithm, algorithms::Output>; + +template +class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm { +public: + using AlgorithmT = RecHitTimeAlignmentAlgorithm; + + RecHitTimeAlignment(std::string_view name, std::string input_name, std::string output_name, + std::string description) + : AlgorithmT{name, {std::move(input_name)}, {std::move(output_name)}, + std::move(description)} {} + + void init() final {} + + void process(const typename AlgorithmT::Input& input, + const typename AlgorithmT::Output& output) const final { + const auto [hits_in] = input; + auto [hits_out] = output; + + std::vector sorted_hits; + sorted_hits.reserve(hits_in->size()); + for (const auto& hit : *hits_in) { + MutableHitT copied_hit = hit.clone(); + const auto position = hit.getPosition(); + const auto hit_r = std::sqrt(position[0] * position[0] + + position[1] * position[1] + position[2] * position[2]); + const auto calibrated_time = hit_r * m_refInverseVelocity; + copied_hit.setTime(hit.getTime() - calibrated_time); + sorted_hits.push_back(copied_hit); + } + + std::sort(sorted_hits.begin(), sorted_hits.end(), + [](const auto& lhs, const auto& rhs) { return lhs.getTime() < rhs.getTime(); }); + + for (const auto& hit : sorted_hits) { + hits_out->push_back(hit); + } + } + + private: + double m_refInverseVelocity = 0.0034; // ns/mm + +}; + +} // namespace eicrecon diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc new file mode 100644 index 0000000000..9877b5ebb0 --- /dev/null +++ b/src/global/splitting/TimeframeSplitter.cc @@ -0,0 +1,674 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov + +#include "TimeframeSplitter.h" + +#include + +TimeframeSplitter::TimeframeSplitter() { + SetTypeName(NAME_OF_THIS); + SetParentLevel(JEventLevel::Timeslice); + SetChildLevel(JEventLevel::PhysicsEvent); +} + +std::uint64_t TimeframeSplitter::object_id_key(const podio::ObjectID& object_id) { + const auto collection_id = + static_cast(static_cast(object_id.collectionID)); + const auto index = static_cast(static_cast(object_id.index)); + + return (collection_id << 32U) | index; +} + +TimeframeSplitter::TrackerAssociationIndex + TimeframeSplitter::buildTrkAssoId(const edm4eic::MCRecoTrackerHitAssociationCollection* associations) { + + TrackerAssociationIndex index; + if (associations == nullptr) + return index; + index.reserve(associations->size()); + + for (size_t assoId = 0; assoId < associations->size(); ++assoId) { + const auto association = associations->at(assoId); + const auto raw_hit = association.getRawHit(); + if (!raw_hit.isAvailable()) + continue; + index[object_id_key(raw_hit.getObjectID())].push_back(assoId); + } + + return index; +} + +TimeframeSplitter::CalorimeterAssociationIndex + TimeframeSplitter::buildCalAssoId(const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations) { + + CalorimeterAssociationIndex index; + if (associations == nullptr) + return index; + index.reserve(associations->size()); + + for (size_t assoId = 0; assoId < associations->size(); ++assoId) { + const auto association = associations->at(assoId); + const auto raw_hit = association.getRawHit(); + if (!raw_hit.isAvailable()) + continue; + index[object_id_key(raw_hit.getObjectID())].push_back(assoId); + } + + return index; +} + +bool TimeframeSplitter::overlaps_time_window(Double_t hitTime, Double_t resolution, Double_t window_start, + Double_t window_end) { + return hitTime + resolution > window_start && hitTime - resolution < window_end; +} + +bool TimeframeSplitter::is_after_time_window(Double_t hitTime, Double_t resolution, Double_t window_end) { + return hitTime - resolution >= window_end; +} + +bool TimeframeSplitter::isValidEtaPhiBin(Int_t etaBin, Int_t phiBin) { + return 0 <= etaBin && etaBin < kEtaPhiBins && 0 <= phiBin && phiBin < kEtaPhiBins; +} + +bool TimeframeSplitter::is_hit_in_time_slice(Double_t hitTime, Double_t time_resolution, + Double_t time_slice_start, Double_t time_slice_end) { + return !(hitTime + time_resolution < time_slice_start || + hitTime - time_resolution > time_slice_end); +} + +std::pair TimeframeSplitter::etaPhiBins(Double_t hitEta, Double_t hitPhi, Double_t etaMin, + Double_t etaMax, Int_t bShift) { + const Double_t etaBinWidth = (etaMax - etaMin) / kEtaPhiBins; + const Double_t phiMin = -TMath::Pi(); + const Double_t phiMax = TMath::Pi(); + const Double_t phiBinWidth = (phiMax - phiMin) / kEtaPhiBins; + + const Double_t halfEtaBin = 0.5 * etaBinWidth * bShift; + const Double_t halfPhiBin = 0.5 * phiBinWidth * bShift; + const Double_t shiftedEtaMin = etaMin + halfEtaBin; + const Double_t shiftedEtaMax = etaMax + halfEtaBin; + const Double_t shiftedPhiMin = phiMin + halfPhiBin; + const Double_t shiftedPhiMax = phiMax + halfPhiBin; + + if (hitEta < shiftedEtaMin || hitEta >= shiftedEtaMax || hitPhi < shiftedPhiMin || + hitPhi >= shiftedPhiMax) { + return {kInvalidEtaPhiBin, kInvalidEtaPhiBin}; + } + + const Int_t etaBin = static_cast(std::floor((hitEta - shiftedEtaMin) / etaBinWidth)); + const Int_t phiBin = static_cast(std::floor((hitPhi - shiftedPhiMin) / phiBinWidth)); + return {etaBin, phiBin}; +} + +size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0, + const EtaPhiGrid& gridShifted, + const EtaPhiTimeGrid& gridTime0, + const EtaPhiTimeGrid& gridShiftedTime, + Int_t threshold, Double_t& averageTime) { + size_t count = 0; + Double_t timeSum = 0.0; + for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { + for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { + if (grid0[iEta][iPhi] >= threshold || gridShifted[iEta][iPhi] >= threshold) { + count++; + if (grid0[iEta][iPhi] >= threshold) { + timeSum += gridTime0[iEta][iPhi] / grid0[iEta][iPhi]; + } else if (gridShifted[iEta][iPhi] >= threshold) { + timeSum += gridShiftedTime[iEta][iPhi] / gridShifted[iEta][iPhi]; + } + } + } + } + averageTime = count > 0 ? timeSum / count : 0.0; + return count; +} + +Double_t TimeframeSplitter::averageSelectedTriggerTime(const std::array& values, + const std::array& times, + std::initializer_list indices, + Double_t fallbackTime) { + size_t count = 0; + Double_t timeSum = 0.0; + for (const size_t index : indices) { + if (values[index] <= 0.0) + continue; + timeSum += times[index]; + count++; + } + return count > 0 ? timeSum / count : fallbackTime; +} + +Double_t TimeframeSplitter::tracker_time_resolution(size_t detector_id) { + if (detector_id < 3) + return timeResolution_ACLGad(); + if (detector_id < 7) + return timeResolution_MPGD(); + return timeResolution_SiMaps(); +} + +std::pair TimeframeSplitter::backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { + // MPGD backward Endcap range -3.6 < eta < -1.72, +5%: -3.78 < eta < -1.634 + const Double_t etaMin = -3.78; + const Double_t etaMax = -1.634; + return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); +} + +std::pair TimeframeSplitter::barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { + // MPGD barrel In range -1.49 < eta < 1.722, +5%: -1.56 < eta < 1.81 + // MPGD barrel Out range -1.56 < eta < 1.61, +5%: -1.64 < eta < 1.70 + // TOF barrel range -1.39 < eta < 1.39, +5%: -1.46 < eta < 1.46 + // ECal barrel range -1.71 < eta < 1.31, +5%: -1.80 < eta < 1.38 + const Double_t etaMin = -1.80; + const Double_t etaMax = 1.81; + return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); +} + +std::pair TimeframeSplitter::forwardEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, + Int_t bShift) { + // MPGD forward Endcap range 2.0 < eta < 3.35, +5%: 1.90 < eta < 3.52 + // TOF forward Endcap range 1.86 < eta < 3.85, +5%: 1.77 < eta < 4.04 + // ECal forward Endcap range 1.4 < eta < 3.5, +5%: 1.33 < eta < 3.68 + const Double_t etaMin = 1.77; + const Double_t etaMax = 4.04; + return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); +} + +TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent& child, + int child_idx) { + const float m_timeframe_width = timeframe_width(); + const float m_timesplit_width = timesplit_width(); + const Double_t time_resolution_mpgd = timeResolution_MPGD(); + const Double_t time_resolution_tof = timeResolution_ACLGad(); + const Double_t time_resolution_emcal = timeResolution_EMCal(); + + Bool_t m_bTrigger = false; + + // Materialize these output collections even when no timeslice triggers, + // so the output schema is available from the first event. + (void)m_event_header_out(); + (void)m_event_header_phy_out(); + (void)m_event_header_bkg_out(); + + const auto trackerHitCollsIn = m_trackerhits_in(); + const auto caloRecHitCollsIn = m_calorechit_in(); + const auto trkAssoCollsIn = m_trackerhitsAsso_in(); + const auto calrecAssoCollsIn = m_calorechitassociation_in(); + + // == s == Register hits of TOF and MPGD detectors in the time slice ================== + if (child_idx == 0) { + m_OrigTFCount++; + + // Association collections belong to the parent Timeslice and remain valid for all + // of its children. Build each lookup once per parent instead of rebuilding the full + // index for every triggered PhysicsEvent. + m_tracker_association_indices.clear(); + m_tracker_association_indices.reserve(trkAssoCollsIn.size()); + for (const auto* associations : trkAssoCollsIn) { + m_tracker_association_indices.push_back(buildTrkAssoId(associations)); + } + + m_calorimeter_association_indices.clear(); + m_calorimeter_association_indices.reserve(calrecAssoCollsIn.size()); + for (const auto* associations : calrecAssoCollsIn) { + m_calorimeter_association_indices.push_back(buildCalAssoId(associations)); + } + + // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ + m_vPhysCooTimes.clear(); + + Double_t prevMCTime = -9999.0; // temp check mc particle times + for (const auto& mcparticle : *m_mcparticles_in()) { + if (mcparticle.getGeneratorStatus() != 1) + continue; + if (std::abs(prevMCTime - mcparticle.getTime()) < 50.) + continue; + Double_t mcCollTime = mcparticle.getTime(); + m_vPhysCooTimes.push_back(mcCollTime); + prevMCTime = mcCollTime; + } + std::sort(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); + auto last = std::unique(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); + m_vPhysCooTimes.erase(last, m_vPhysCooTimes.end()); + // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ + } + // == e == Register hits of TOF and MPGD detectors in the time slice ================== + + // == s == Time frame scan loop ========================================================== + Double_t timesliceT0 = -999.0; + Bool_t bTimesliceTrigger = false; + + Bool_t bMutipliTriggers[6] = {false, false, false, false, false, false}; + Double_t multipliTrigTime[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + Double_t tsTimeS = iTimeSlice * m_timesplit_width; + Double_t tsTimeE = (iTimeSlice + 1) * m_timesplit_width; + while (1) { + tsTimeS = iTimeSlice * m_timesplit_width; + tsTimeE = (iTimeSlice + 1) * m_timesplit_width; + if (tsTimeE > m_timeframe_width) + break; + iTimeSlice++; + + // == s == Multiplisity threshold Triggers ======================================= + + // == s == Multiplisity Single Triggers ======================================= + std::array singleTrig{}; + std::array singleTrigTime{}; + + // s // EndCap Cal Trigger + EtaPhiGrid backEndCalGrid{}; + EtaPhiGrid backEndCalGridShifted{}; + EtaPhiTimeGrid backEndIntTimesEtaPhi = {}; + EtaPhiTimeGrid backEndIntTimesEtaPhiShifted = {}; + fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapN), iniCalHitPoint[kCalEndcapN], + time_resolution_emcal, tsTimeS, tsTimeE, backEndCalGrid, + backEndCalGridShifted, backEndIntTimesEtaPhi, backEndIntTimesEtaPhiShifted, + backEndEtaPhiBins); + singleTrig[0] = countGridCellsWithMultiplicity( + backEndCalGrid, backEndCalGridShifted, backEndIntTimesEtaPhi, + backEndIntTimesEtaPhiShifted, 10, singleTrigTime[0]); + + // s // EndCap Cal+Trk Match Trigger + EtaPhiGrid backEndTrkGrid = {}; + EtaPhiGrid backEndTrkGridShifted = {}; + EtaPhiTimeGrid backEndIntTimesEtaPhiMatched = {}; + EtaPhiTimeGrid backEndIntTimesEtaPhiMatchedShifted = {}; + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkBackwardMPGD), + iniTrkHitPoint[kTrkBackwardMPGD], time_resolution_mpgd, tsTimeS, + tsTimeE, backEndCalGrid, backEndCalGridShifted, backEndTrkGrid, + backEndTrkGridShifted, 10, backEndIntTimesEtaPhiMatched, + backEndIntTimesEtaPhiMatchedShifted, backEndEtaPhiBins); + singleTrig[1] = countGridCellsWithMultiplicity( + backEndTrkGrid, backEndTrkGridShifted, backEndIntTimesEtaPhiMatched, + backEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[1]); + + EtaPhiGrid barrelCalGrid = {}; + EtaPhiGrid barrelCalGridShifted = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhi = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhiShifted = {}; + fillEtaPhiGrids(caloRecHitCollsIn.at(kCalBarrelScifi), iniCalHitPoint[kCalBarrelScifi], + time_resolution_emcal, tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, + barrelIntTimesEtaPhi, barrelIntTimesEtaPhiShifted, barrelEtaPhiBins); + singleTrig[2] = + countGridCellsWithMultiplicity(barrelCalGrid, barrelCalGridShifted, barrelIntTimesEtaPhi, + barrelIntTimesEtaPhiShifted, 10, singleTrigTime[2]); + + EtaPhiGrid barrelTrkGrid = {}; + EtaPhiGrid barrelTrkGridShifted = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhiMatched = {}; + EtaPhiTimeGrid barrelIntTimesEtaPhiMatchedShifted = {}; + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkMPGDBarrel), iniTrkHitPoint[kTrkMPGDBarrel], + time_resolution_mpgd, tsTimeS, tsTimeE, barrelCalGrid, + barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, + barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, + barrelEtaPhiBins); + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkOuterMPGDBarrel), + iniTrkHitPoint[kTrkOuterMPGDBarrel], time_resolution_mpgd, tsTimeS, + tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, + barrelTrkGridShifted, 5, barrelIntTimesEtaPhiMatched, + barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFBarrel), iniTrkHitPoint[kTrkTOFBarrel], + time_resolution_tof, tsTimeS, tsTimeE, barrelCalGrid, + barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, + barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, + barrelEtaPhiBins); + singleTrig[3] = countGridCellsWithMultiplicity( + barrelTrkGrid, barrelTrkGridShifted, barrelIntTimesEtaPhiMatched, + barrelIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[3]); + + EtaPhiGrid frontEndCalGrid = {}; + EtaPhiGrid frontEndCalGridShifted = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhi = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhiShifted = {}; + fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapP), iniCalHitPoint[kCalEndcapP], + time_resolution_emcal, tsTimeS, tsTimeE, frontEndCalGrid, + frontEndCalGridShifted, frontEndIntTimesEtaPhi, frontEndIntTimesEtaPhiShifted, + forwardEndEtaPhiBins); + singleTrig[4] = countGridCellsWithMultiplicity( + frontEndCalGrid, frontEndCalGridShifted, frontEndIntTimesEtaPhi, + frontEndIntTimesEtaPhiShifted, 10, singleTrigTime[4]); + + EtaPhiGrid frontEndTrkGrid = {}; + EtaPhiGrid frontEndTrkGridShifted = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhiMatched = {}; + EtaPhiTimeGrid frontEndIntTimesEtaPhiMatchedShifted = {}; + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkForwardMPGD), iniTrkHitPoint[kTrkForwardMPGD], + time_resolution_mpgd, tsTimeS, tsTimeE, frontEndCalGrid, + frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, + frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, + forwardEndEtaPhiBins); + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFEndcap), iniTrkHitPoint[kTrkTOFEndcap], + time_resolution_tof, tsTimeS, tsTimeE, frontEndCalGrid, + frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, + frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, + forwardEndEtaPhiBins); + singleTrig[5] = countGridCellsWithMultiplicity( + frontEndTrkGrid, frontEndTrkGridShifted, frontEndIntTimesEtaPhiMatched, + frontEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[5]); + + const auto hitsB0 = count_hits_in_window(trackerHitCollsIn.at(kTrkB0), iniTrkHitPoint[kTrkB0], + time_resolution_tof, tsTimeS, tsTimeE); + iniTrkHitPoint[kTrkB0] = hitsB0.next_start_index; + singleTrig[6] = hitsB0.count; + singleTrigTime[6] = hitsB0.average_time(); + + Double_t totalZDCEnergy = 0.0; + Double_t totalZDCEnergyTime = 0.0; + const auto* recHitsZDCECal = caloRecHitCollsIn.at(kCalZDC); + if (recHitsZDCECal != nullptr) { + for (size_t iHit = iniCalHitPoint[kCalZDC]; iHit < recHitsZDCECal->size(); ++iHit) { + const auto& hit = recHitsZDCECal->at(iHit); + const Double_t hitTime = hit.getTime(); + if (hitTime - time_resolution_emcal > tsTimeE) + break; + if (is_hit_in_time_slice(hitTime, time_resolution_emcal, tsTimeS, tsTimeE)) { + totalZDCEnergy += hit.getEnergy(); + totalZDCEnergyTime += hit.getEnergy() * hitTime; + iniCalHitPoint[kCalZDC] = iHit; + } + } + } + singleTrig[7] = totalZDCEnergy; + singleTrigTime[7] = totalZDCEnergy > 0.0 ? totalZDCEnergyTime / totalZDCEnergy : 0.0; + + const Double_t etaPhiCalTriggerSum = singleTrig[0] + singleTrig[2] + singleTrig[4]; + const Double_t etaPhiCalTrkTriggerSum = singleTrig[1] + singleTrig[3] + singleTrig[5]; + bMutipliTriggers[0] = etaPhiCalTrkTriggerSum > 0 && singleTrig[6] > 4; + bMutipliTriggers[1] = etaPhiCalTrkTriggerSum > 0 && singleTrig[7] > 50; + bMutipliTriggers[2] = etaPhiCalTriggerSum > 0 && singleTrig[6] > 4; + bMutipliTriggers[3] = etaPhiCalTriggerSum > 0 && singleTrig[7] > 0.005; + bMutipliTriggers[4] = etaPhiCalTrkTriggerSum > 1; + bMutipliTriggers[5] = etaPhiCalTriggerSum > 2; + + if (!bMutipliTriggers[0] && !bMutipliTriggers[1] && !bMutipliTriggers[2] && + !bMutipliTriggers[3] && !bMutipliTriggers[4] && !bMutipliTriggers[5]) + continue; + + const Double_t fallbackTriggerTime = 0.5 * (tsTimeS + tsTimeE); + if (bMutipliTriggers[0]) + multipliTrigTime[0] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 6}, + fallbackTriggerTime); + if (bMutipliTriggers[1]) + multipliTrigTime[1] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 7}, + fallbackTriggerTime); + if (bMutipliTriggers[2]) + multipliTrigTime[2] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 6}, + fallbackTriggerTime); + if (bMutipliTriggers[3]) + multipliTrigTime[3] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 7}, + fallbackTriggerTime); + if (bMutipliTriggers[4]) + multipliTrigTime[4] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5}, fallbackTriggerTime); + if (bMutipliTriggers[5]) + multipliTrigTime[5] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4}, fallbackTriggerTime); + Double_t multiTrigCount = 0; + Double_t totalTrigTime = 0.0; + for (size_t iTrig = 0; iTrig < 6; ++iTrig) { + if (bMutipliTriggers[iTrig]) { + totalTrigTime += multipliTrigTime[iTrig]; + multiTrigCount++; + } + } + timesliceT0 = multiTrigCount > 0 ? totalTrigTime / multiTrigCount : fallbackTriggerTime; + + // == s == Multiplisity Single Triggers ======================================= + + if (bMutipliTriggers[0] || bMutipliTriggers[1] || bMutipliTriggers[2] || + bMutipliTriggers[3] || bMutipliTriggers[4] || bMutipliTriggers[5]) + bTimesliceTrigger = + true; // ???? temporary, need to be removed after geometrical coincidence trigger is implemented + if (bTimesliceTrigger) + break; + } + // == e == Time frame scan loop ========================================================== + + + m_bTrigger = bTimesliceTrigger; + if (bTimesliceTrigger) { + m_bOnceTriggered = true; + // For now, a one-to-one relationship between timeslices and events + child.SetEventNumber(m_NewEventCount); + child.SetRunNumber(parent.GetRunNumber()); + m_NewEventCount++; + // Clone truth particles before detector relations so every child SimTrackerHit can + // point to an MCParticle owned by this PhysicsEvent rather than by the parent Timeslice. + for (const auto& mcparticle : *m_mcparticles_in()) { + m_mcparticles_out()->push_back(mcparticle.clone(false)); + } + + // == s == Register Tracker Hits ======================================================= + for (size_t trkDetID = 0; trkDetID < trackerHitCollsIn.size(); ++trkDetID) { + const auto* trkCollIn = trackerHitCollsIn.at(trkDetID); + + if (trkCollIn == nullptr) + continue; + auto& trkCollOut = m_trackerhits_out().at(trkDetID); + const Double_t detTimeReso = tracker_time_resolution(trkDetID); + const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); + auto& rawCollOut = m_rawhit_out().at(trkDetID); + auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); + + for (size_t iHit = 0; iHit < trkCollIn->size(); ++iHit) { + const auto& trkHit = trkCollIn->at(iHit); + + const Double_t hitT = trkHit.getTime(); + if (!overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { + continue; + } + + iniTrkHitPoint[trkDetID] = iHit; + copy_tracker_hit_with_relations( + trkHit, trkAssoCollIn, m_tracker_association_indices.at(trkDetID), trkCollOut, + rawCollOut, trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), + m_rawhitlinks_out().at(trkDetID), m_mcparticles_out()); + } + } + // == e == Register Tracker Hits ======================================================= + + // == s == Register Calo Rec Hits ======================================================= + for (size_t calDetID = 0; calDetID < caloRecHitCollsIn.size(); ++calDetID) { + const auto* caloInColl = caloRecHitCollsIn.at(calDetID); + if (caloInColl == nullptr) + continue; + auto& caloOutColl = m_calorechit_out().at(calDetID); + + const auto* caloInCollAsso = calrecAssoCollsIn.at(calDetID); + if (caloInCollAsso == nullptr) + continue; + + for (size_t iCalHit = 0; iCalHit < caloInColl->size(); ++iCalHit) { + const auto& caloHit = caloInColl->at(iCalHit); + + Double_t detTimeReso = time_resolution_emcal; + Double_t hitT = caloHit.getTime(); + + if (hitT - detTimeReso > timesliceT0 + 30.) + continue; + if (overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { + auto copiedCaloHit = caloHit.clone(); + copiedCaloHit.setRawHit(edm4hep::RawCalorimeterHit()); + + const auto rawHitFromRec = caloHit.getRawHit(); + if (rawHitFromRec.isAvailable()) { + auto& rawCollOut = m_calorawhit_out().at(calDetID); + auto copiedRawHit = rawHitFromRec.clone(); + rawCollOut->push_back(copiedRawHit); + copiedCaloHit.setRawHit(copiedRawHit); + + auto& assocCollOut = m_calorechitassociation_out().at(calDetID); + auto& linkCollOut = m_calorawhitlinks_out().at(calDetID); + auto& simCollOut = m_simcalorimeterhits_out().at(calDetID); + const auto rawHitID = rawHitFromRec.getObjectID(); + + const auto& association_index = m_calorimeter_association_indices.at(calDetID); + const auto assocIterCal = association_index.find(object_id_key(rawHitID)); + + if (assocIterCal != association_index.end()) { + for (const size_t association_position : assocIterCal->second) { + const auto assoc = caloInCollAsso->at(association_position); + + if (!assoc.getSimHit().isAvailable()) + continue; + + auto copiedSimHit = assoc.getSimHit().clone(false); + simCollOut->push_back(copiedSimHit); + + auto copiedAssoc = assocCollOut->create(); + copiedAssoc.setWeight(assoc.getWeight()); + copiedAssoc.setRawHit(copiedRawHit); + copiedAssoc.setSimHit(copiedSimHit); + + auto copiedLink = linkCollOut->create(); + copiedLink.setWeight(assoc.getWeight()); + copiedLink.setFrom(copiedRawHit); + copiedLink.setTo(copiedSimHit); + } + } + } + + caloOutColl->push_back(copiedCaloHit); + iniCalHitPoint[calDetID] = iCalHit; + } + } + } + // == e == Register Calo Rec Hits ======================================================= + + // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><><>> + // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ + Int_t physEventWeight = 2; + for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { + const Double_t physCollTime = *it; + if ((physCollTime + 20 > timesliceT0 - 10) && (physCollTime - 10 < timesliceT0 + 30)) { + physEventWeight = 1; + m_vPhysCooTimes.erase(it); + break; + } + } + + if (physEventWeight == 1) { + edm4hep::MutableEventHeader event_header_bkg; + event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_bkg.setEventNumber(m_event_number_ts); + event_header_bkg.setTimeStamp(iTimeSlice); + event_header_bkg.setWeight(1); + m_event_header_bkg_out()->push_back(event_header_bkg); + + edm4hep::MutableEventHeader event_header_phy; + event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_phy.setEventNumber(m_event_number_ts); + event_header_phy.setTimeStamp(iTimeSlice); + event_header_phy.setWeight(2); + m_event_header_phy_out()->push_back(event_header_phy); + for (size_t iTrig = 0; iTrig < 6; ++iTrig) { + if (bMutipliTriggers[iTrig]) { + edm4hep::MutableEventHeader event_header_phy; + event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_phy.setEventNumber(m_event_number_ts); + event_header_phy.setTimeStamp(iTimeSlice); + event_header_phy.setWeight(iTrig + 3); + m_event_header_phy_out()->push_back(event_header_phy); + } + } + m_PhysCount++; + } else if (physEventWeight == 2) { + edm4hep::MutableEventHeader event_header_phy; + event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_phy.setEventNumber(m_event_number_ts); + event_header_phy.setTimeStamp(iTimeSlice); + event_header_phy.setWeight(1); + m_event_header_phy_out()->push_back(event_header_phy); + + edm4hep::MutableEventHeader event_header_bkg; + event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_bkg.setEventNumber(m_event_number_ts); + event_header_bkg.setTimeStamp(iTimeSlice); + event_header_bkg.setWeight(2); + m_event_header_bkg_out()->push_back(event_header_bkg); + for (size_t iTrig = 0; iTrig < 6; ++iTrig) { + if (bMutipliTriggers[iTrig]) { + edm4hep::MutableEventHeader event_header_bkg; + event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); + event_header_bkg.setEventNumber(m_event_number_ts); + event_header_bkg.setTimeStamp(iTimeSlice); + event_header_bkg.setWeight(iTrig + 3); + m_event_header_bkg_out()->push_back(event_header_bkg); + } + } + } + m_event_number_ts++; + + // Insert an independent EventHeader object into the physics event. + // A subset header would keep a reference to the parent frame collection. + edm4hep::MutableEventHeader event_header; + if (m_event_header_in() != nullptr && !m_event_header_in()->empty()) { + const auto& event_header_in = m_event_header_in()->at(0); + event_header.setRunNumber(event_header_in.getRunNumber()); + event_header.setEventNumber(event_header_in.getEventNumber()); + event_header.setTimeStamp(event_header_in.getTimeStamp()); + event_header.setWeight(event_header_in.getWeight()); + } else { + event_header.setRunNumber(child.GetRunNumber()); + event_header.setEventNumber(child.GetEventNumber()); + event_header.setTimeStamp(iTimeSlice); + event_header.setWeight(physEventWeight); + } + m_event_header_out()->push_back(event_header); + // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ + + // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><>> + } + + if (tsTimeE > m_timeframe_width) + m_bScanedAllTimeWindows = true; + if (m_bScanedAllTimeWindows) { + bInitialLoop = true; + m_bOnceTriggered = false; + + m_vPhysCooTimes.clear(); + + m_bScanedAllTimeWindows = false; + iTimeSlice = 0; + targetDetId = 0; + for (auto& start_point : iniTrkHitPoint) + start_point = 0; + for (auto& start_point : iniCalHitPoint) + start_point = 0; + + if (m_bTrigger) + return Result::NextChildNextParent; + else + return Result::KeepChildNextParent; + } else if (m_bTrigger) { + child_idx++; + return Result::NextChildKeepParent; + } + return Result::KeepChildNextParent; +} + +void TimeframeSplitter::thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, + Int_t& thetaID2, Int_t& phiID2) { + Double_t hitX = hit.getPosition()[0]; + Double_t hitY = hit.getPosition()[1]; + Double_t hitZ = hit.getPosition()[2]; + const Double_t hitR = TMath::Sqrt(hitX * hitX + hitY * hitY + hitZ * hitZ); + if (hitR <= 0.0) { + thetaID1 = 0; + thetaID2 = 0; + phiID1 = 0; + phiID2 = 0; + return; + } + + const Double_t cosTheta = std::clamp(hitZ / hitR, -1.0, 1.0); + const Double_t hitTheta = TMath::ACos(cosTheta); + + Double_t hitPhi = TMath::ATan2(hitY, hitX) + 2 * TMath::Pi(); + if (hitPhi < 0) + hitPhi += 2 * TMath::Pi(); + thetaID1 = hitTheta / (TMath::Pi() / 12.); + thetaID2 = (hitTheta + TMath::Pi() / 24.) / (TMath::Pi() / 12.); + phiID1 = hitPhi / (TMath::Pi() / 8.); + phiID2 = (hitPhi + TMath::Pi() / 16.) / (TMath::Pi() / 8.); +} diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 934d770233..470714ad06 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -1,11 +1,10 @@ -// Copyright 2024, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov #pragma once #include #include -#include #include #include #include @@ -24,6 +23,7 @@ #include #include +#include #include #include #include @@ -44,8 +44,6 @@ struct TimeframeSplitter : public JEventUnfolder { "time resolution of Silicon detector in ns"}; Parameter timeResolution_MPGD{this, "timeResolution_MPGD", 30.0, "time resolution of MPGD detector in ns"}; - // Parameter timeResolution_ACLGad{this, "timeResolution_TOF", 0.03, - // "time resolution of TOF detector in ns"}; Parameter timeResolution_ACLGad{this, "timeResolution_TOF", 20.0, "time resolution of TOF detector in ns"}; Parameter timeResolution_EMCal{this, "timeResolution_EMCal", 20.0, @@ -288,89 +286,7 @@ struct TimeframeSplitter : public JEventUnfolder { "HcalFarForwardZDCRawHitAssociations", "LFHCALRawHitAssociations"}; - // std::vector m_calohitcontribution_collection_names = { - // "B0ECalHitsContributions", - // "EcalBarrelImagingHitsContributions", - // "EcalBarrelScFiHitsContributions", - // "EcalEndcapNHitsContributions", - // "EcalEndcapPHitsContributions", - // "EcalEndcapPInsertHitsContributions", - // "EcalLumiSpecHitsContributions", - // "EcalFarForwardZDCHitsContributions", - // "HcalBarrelHitsContributions", - // "HcalEndcapNHitsContributions", - // "HcalEndcapPInsertHitsContributions", - // "HcalFarForwardZDCHitsContributions", - // "LFHCALHitsContributions", - // "LumiDirectPCALHitsContributions"}; - - std::vector m_calocluster_collection_names_in = { - "B0ECalClusters_aligned", - "EcalBarrelClusters_aligned", - "EcalEndcapNClusters_aligned", - "EcalEndcapPClusters_aligned", - }; - // "EcalFarForwardZDCClusters_aligned", - // "EcalLumiSpecClusters_aligned", - // "HcalBarrelClusters_aligned", - // "HcalEndcapNClusters_aligned", - // "HcalEndcapPInsertClusters_aligned", - // "HcalFarForwardZDCClusters_aligned", - // "LFHCALClusters_aligned", - // "EcalBarrelImagingClusters_aligned", - // "EcalBarrelScFiClusters_aligned", - // "EcalEndcapNImagingClusters_aligned", - // "EcalEndcapPImagingClusters_aligned", - // "EcalFarForwardZDCImagingClusters_aligned", - // "EcalLumiSpecImagingClusters_aligned" - - std::vector m_calocluster_collection_names_out = { - "B0ECalClusters", - "EcalBarrelClusters", - "EcalEndcapNClusters", - "EcalEndcapPClusters", - }; - // "EcalFarForwardZDCClusters", - // "EcalLumiSpecClusters", - // "HcalBarrelClusters", - // "HcalEndcapNClusters", - // "HcalEndcapPInsertClusters", - // "HcalFarForwardZDCClusters", - // "LFHCALClusters", - // "EcalBarrelImagingClusters", - // "EcalBarrelScFiClusters", - // "EcalEndcapNImagingClusters", - // "EcalEndcapPImagingClusters", - // "EcalFarForwardZDCImagingClusters", - // "EcalLumiSpecImagingClusters" - - std::vector m_caloclusterassociation_collection_names_in = { - "B0ECalClusterAssociations", - "EcalBarrelClusterAssociations", - "EcalEndcapNClusterAssociations", - "EcalEndcapPClusterAssociations", - }; - // "HcalBarrelClusterAssociations", - // "HcalEndcapNClusterAssociations", - // "HcalEndcapPInsertClusterAssociations", - // "HcalFarForwardZDCClusterAssociations", - // "LFHCALClusterAssociations", - // "EcalBarrelImagingClusterAssociations", - // "EcalBarrelScFiClusterAssociations", - - std::vector m_caloclusterassociation_collection_names_out = { - "B0ECalClusterAssociations", - "EcalBarrelClusterAssociations", - "EcalEndcapNClusterAssociations", - "EcalEndcapPClusterAssociations", - }; - // "HcalBarrelClusterAssociations", - // "HcalEndcapNClusterAssociations", - // "HcalEndcapPInsertClusterAssociations", - // "HcalFarForwardZDCClusterAssociations", - // "LFHCALClusterAssociations", - // "EcalBarrelImagingClusterAssociations", - // "EcalBarrelScFiClusterAssociations", + PodioInput m_event_header_in{this, {.name = "EventHeader", .is_optional = true}}; @@ -398,16 +314,6 @@ struct TimeframeSplitter : public JEventUnfolder { this, {.names = m_rawhit_collection_names, .is_optional = true}}; VariadicPodioOutput m_rawhit_out{this, m_rawhit_collection_names_out}; - // VariadicPodioInput m_simcalorimeterhits_in{ - // this, {.names = m_simcalorimeterhit_collection_names, .is_optional = true}}; - // VariadicPodioOutput m_simcalorimeterhits_out{ - // this, m_simcalorimeterhit_collection_names}; - - // VariadicPodioInput m_calohitcontributions_in{ - // this, {.names = m_calohitcontribution_collection_names, .is_optional = true}}; - // VariadicPodioOutput m_calohitcontributions_out{ - // this, m_calohitcontribution_collection_names}; - VariadicPodioInput m_calorawhit_in{ this, {.names = m_calorawhit_collection_names_in, .is_optional = true}}; VariadicPodioOutput m_calorawhit_out{ @@ -428,15 +334,6 @@ struct TimeframeSplitter : public JEventUnfolder { VariadicPodioOutput m_calorechitassociation_out{ this, m_calorechitassociation_collection_names_out}; - // VariadicPodioInput m_calocluster_in{ - // this, {.names = m_calocluster_collection_names_in, .is_optional = true}}; - // VariadicPodioOutput m_calocluster_out{ - // this, m_calocluster_collection_names_out}; - - // VariadicPodioInput m_caloclusterassociation_in{ - // this, {.names = m_caloclusterassociation_collection_names_in, .is_optional = true}}; - // VariadicPodioOutput m_caloclusterassociation_out{ - // this, m_caloclusterassociation_collection_names_out}; PodioOutput m_event_header_phy_out{this, "EventHeader_PHY"}; PodioOutput m_event_header_bkg_out{this, "EventHeader_BKG"}; @@ -448,14 +345,8 @@ struct TimeframeSplitter : public JEventUnfolder { PodioOutput m_ecaltowers_phy_out{this, "ECalTowers_PHY"}; PodioOutput m_ecaltowers_bkg_out{this, "ECalTowers_BKG"}; - TimeframeSplitter() { - SetTypeName(NAME_OF_THIS); - SetParentLevel(JEventLevel::Timeslice); - SetChildLevel(JEventLevel::PhysicsEvent); - } + TimeframeSplitter(); - // std::vector> - // m_hitStartIndices_simTracker; std::vector> m_hitStartIndices_simTracker; @@ -463,13 +354,7 @@ struct TimeframeSplitter : public JEventUnfolder { m_hitStartIndices_simCalorimeter; // == Global Variables ======================= - size_t m_triggerDetSize = 10; // Number of detectors used for triggering - // Int_t m_detId[10] = {12, 13, 1, 4, 8, 9, 11, 14, 15, 16}; // TOF and MPGD, Silicon excluded - Int_t m_detId[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // TOF and MPGD, Silicon excluded - bool bInitialLoop = true; - std::vector> m_vOrigHitId; - std::vector> m_vSameTSHitId; Int_t m_multiTriggerThreshold[4] = {1, 4, 20, 20}; size_t iniTrkHitPoint[15] = {0}; // B0Trk, @@ -498,69 +383,22 @@ struct TimeframeSplitter : public JEventUnfolder { std::vector m_tracker_association_indices; std::vector m_calorimeter_association_indices; - static std::uint64_t object_id_key(const podio::ObjectID& object_id) { - const auto collection_id = - static_cast(static_cast(object_id.collectionID)); - const auto index = static_cast(static_cast(object_id.index)); - - return (collection_id << 32U) | index; - } + static std::uint64_t object_id_key(const podio::ObjectID& object_id); static TrackerAssociationIndex - buildTrkAssoId(const edm4eic::MCRecoTrackerHitAssociationCollection* associations) { - - TrackerAssociationIndex index; - if (associations == nullptr) - return index; - index.reserve(associations->size()); - - for (size_t assoId = 0; assoId < associations->size(); ++assoId) { - const auto association = associations->at(assoId); - const auto raw_hit = association.getRawHit(); - if (!raw_hit.isAvailable()) - continue; - index[object_id_key(raw_hit.getObjectID())].push_back(assoId); - } - - return index; - } + buildTrkAssoId(const edm4eic::MCRecoTrackerHitAssociationCollection* associations); static CalorimeterAssociationIndex - buildCalAssoId(const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations) { - - CalorimeterAssociationIndex index; - if (associations == nullptr) - return index; - index.reserve(associations->size()); - - for (size_t assoId = 0; assoId < associations->size(); ++assoId) { - const auto association = associations->at(assoId); - const auto raw_hit = association.getRawHit(); - if (!raw_hit.isAvailable()) - continue; - index[object_id_key(raw_hit.getObjectID())].push_back(assoId); - } - - return index; - } + buildCalAssoId(const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations); static bool overlaps_time_window(Double_t hitTime, Double_t resolution, Double_t window_start, - Double_t window_end) { - return hitTime + resolution > window_start && hitTime - resolution < window_end; - } - static bool is_after_time_window(Double_t hitTime, Double_t resolution, Double_t window_end) { - return hitTime - resolution >= window_end; - } + Double_t window_end); + static bool is_after_time_window(Double_t hitTime, Double_t resolution, Double_t window_end); - static bool isValidEtaPhiBin(Int_t etaBin, Int_t phiBin) { - return 0 <= etaBin && etaBin < kEtaPhiBins && 0 <= phiBin && phiBin < kEtaPhiBins; - } + static bool isValidEtaPhiBin(Int_t etaBin, Int_t phiBin); static bool is_hit_in_time_slice(Double_t hitTime, Double_t time_resolution, - Double_t time_slice_start, Double_t time_slice_end) { - return !(hitTime + time_resolution < time_slice_start || - hitTime - time_resolution > time_slice_end); - } + Double_t time_slice_start, Double_t time_slice_end); template inline void etaPhiCalc(const HitT& hit, Double_t& hitEta, Double_t& hitPhi) { @@ -580,28 +418,7 @@ struct TimeframeSplitter : public JEventUnfolder { } static std::pair etaPhiBins(Double_t hitEta, Double_t hitPhi, Double_t etaMin, - Double_t etaMax, Int_t bShift) { - const Double_t etaBinWidth = (etaMax - etaMin) / kEtaPhiBins; - const Double_t phiMin = -TMath::Pi(); - const Double_t phiMax = TMath::Pi(); - const Double_t phiBinWidth = (phiMax - phiMin) / kEtaPhiBins; - - const Double_t halfEtaBin = 0.5 * etaBinWidth * bShift; - const Double_t halfPhiBin = 0.5 * phiBinWidth * bShift; - const Double_t shiftedEtaMin = etaMin + halfEtaBin; - const Double_t shiftedEtaMax = etaMax + halfEtaBin; - const Double_t shiftedPhiMin = phiMin + halfPhiBin; - const Double_t shiftedPhiMax = phiMax + halfPhiBin; - - if (hitEta < shiftedEtaMin || hitEta >= shiftedEtaMax || hitPhi < shiftedPhiMin || - hitPhi >= shiftedPhiMax) { - return {kInvalidEtaPhiBin, kInvalidEtaPhiBin}; - } - - const Int_t etaBin = static_cast(std::floor((hitEta - shiftedEtaMin) / etaBinWidth)); - const Int_t phiBin = static_cast(std::floor((hitPhi - shiftedPhiMin) / phiBinWidth)); - return {etaBin, phiBin}; - } + Double_t etaMax, Int_t bShift); template void fillEtaPhiGrids(const CollectionT* hits, size_t& iniHitID, Double_t timeResolution, @@ -636,7 +453,6 @@ struct TimeframeSplitter : public JEventUnfolder { gridShifted[eta1][phi1]++; gridShiftedTime[eta1][phi1] += hitT; } - // std::cout << "TF:TS = " << m_TFCount << " <><><><><> etaBin:phiBin = " << eta0 << ":" << phi0 << " | " << eta1 << ":" << phi1 << std::endl; } } @@ -682,47 +498,14 @@ struct TimeframeSplitter : public JEventUnfolder { const EtaPhiGrid& gridShifted, const EtaPhiTimeGrid& gridTime0, const EtaPhiTimeGrid& gridShiftedTime, - Int_t threshold, Double_t& averageTime) { - size_t count = 0; - Double_t timeSum = 0.0; - for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { - for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { - if (grid0[iEta][iPhi] >= threshold || gridShifted[iEta][iPhi] >= threshold) { - count++; - if (grid0[iEta][iPhi] >= threshold) { - timeSum += gridTime0[iEta][iPhi] / grid0[iEta][iPhi]; - } else if (gridShifted[iEta][iPhi] >= threshold) { - timeSum += gridShiftedTime[iEta][iPhi] / gridShifted[iEta][iPhi]; - } - } - } - } - averageTime = count > 0 ? timeSum / count : 0.0; - return count; - } + Int_t threshold, Double_t& averageTime); static Double_t averageSelectedTriggerTime(const std::array& values, const std::array& times, std::initializer_list indices, - Double_t fallbackTime) { - size_t count = 0; - Double_t timeSum = 0.0; - for (const size_t index : indices) { - if (values[index] <= 0.0) - continue; - timeSum += times[index]; - count++; - } - return count > 0 ? timeSum / count : fallbackTime; - } + Double_t fallbackTime); - Double_t tracker_time_resolution(size_t detector_id) { - if (detector_id < 3) - return timeResolution_ACLGad(); - if (detector_id < 7) - return timeResolution_MPGD(); - return timeResolution_SiMaps(); - } + Double_t tracker_time_resolution(size_t detector_id); template TimeWindowSummary count_hits_in_window(const CollectionT* collection, size_t start_index, @@ -809,662 +592,15 @@ struct TimeframeSplitter : public JEventUnfolder { tracker_hits_out->push_back(trackerHitCopied); } - static std::pair backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { - // MPGD backward Endcap range -3.6 < eta < -1.72, +5%: -3.78 < eta < -1.634 - const Double_t etaMin = -3.78; - const Double_t etaMax = -1.634; - return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); - } + static std::pair backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift); - static std::pair barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { - // MPGD barrel In range -1.49 < eta < 1.722, +5%: -1.56 < eta < 1.81 - // MPGD barrel Out range -1.56 < eta < 1.61, +5%: -1.64 < eta < 1.70 - // TOF barrel range -1.39 < eta < 1.39, +5%: -1.46 < eta < 1.46 - // ECal barrel range -1.71 < eta < 1.31, +5%: -1.80 < eta < 1.38 - const Double_t etaMin = -1.80; - const Double_t etaMax = 1.81; - return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); - } + static std::pair barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift); static std::pair forwardEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, - Int_t bShift) { - // MPGD forward Endcap range 2.0 < eta < 3.35, +5%: 1.90 < eta < 3.52 - // TOF forward Endcap range 1.86 < eta < 3.85, +5%: 1.77 < eta < 4.04 - // ECal forward Endcap range 1.4 < eta < 3.5, +5%: 1.33 < eta < 3.68 - const Double_t etaMin = 1.77; - const Double_t etaMax = 4.04; - return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); - } - - Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override { - // For QA ??? - // std::vector> vECalHitInTowerPhy; - // std::vector> vECalHitInTowerBkg; - // std::vector> vECalTowersPhy; - // std::vector> vECalTowersBkg; - // For QA ??? - - const float m_timeframe_width = timeframe_width(); - const float m_timesplit_width = timesplit_width(); - - Bool_t m_bTrigger = false; - - // Materialize these output collections even when no timeslice triggers, - // so the output schema is available from the first event. - (void)m_event_header_out(); - (void)m_event_header_phy_out(); - (void)m_event_header_bkg_out(); - - const auto trackerHitCollsIn = m_trackerhits_in(); - const auto caloRecHitCollsIn = m_calorechit_in(); - const auto trkAssoCollsIn = m_trackerhitsAsso_in(); - const auto calrecAssoCollsIn = m_calorechitassociation_in(); - - // == s == Register hits of TOF and MPGD detectors in the time slice ================== - if (child_idx == 0) { - m_OrigTFCount++; - - // Association collections belong to the parent Timeslice and remain valid for all - // of its children. Build each lookup once per parent instead of rebuilding the full - // index for every triggered PhysicsEvent. - m_tracker_association_indices.clear(); - m_tracker_association_indices.reserve(trkAssoCollsIn.size()); - for (const auto* associations : trkAssoCollsIn) { - m_tracker_association_indices.push_back(buildTrkAssoId(associations)); - } - - m_calorimeter_association_indices.clear(); - m_calorimeter_association_indices.reserve(calrecAssoCollsIn.size()); - for (const auto* associations : calrecAssoCollsIn) { - m_calorimeter_association_indices.push_back(buildCalAssoId(associations)); - } + Int_t bShift); - // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ - m_vPhysCooTimes.clear(); + Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override; - Double_t prevMCTime = -9999.0; // temp check mc particle times - for (const auto& mcparticle : *m_mcparticles_in()) { - // if (mcparticle.parents_begin() != 0) - // if(mcparticle.parents_size() > 0) continue; - - if (mcparticle.getGeneratorStatus() != 1) - continue; - if (std::abs(prevMCTime - mcparticle.getTime()) < 50.) - continue; - Double_t mcCollTime = mcparticle.getTime(); - m_vPhysCooTimes.push_back(mcCollTime); - prevMCTime = mcCollTime; - } - std::sort(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); - auto last = std::unique(m_vPhysCooTimes.begin(), m_vPhysCooTimes.end()); - m_vPhysCooTimes.erase(last, m_vPhysCooTimes.end()); - // for (size_t iPhysT = 0; iPhysT < m_vPhysCooTimes.size(); ++iPhysT) { - // Double_t physCollTime = m_vPhysCooTimes[iPhysT]; - // Double_t tsTime = iPhysT * timesplit_width(); - // // std::cout << "111<><>><><<><><<><<><><><> TF:TS = " << parent.GetEventNumber() << " : " << child_idx << ", physCollTime: " << physCollTime << ", tsTime: " << tsTime << std::endl; - // } - - // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ - } - // == e == Register hits of TOF and MPGD detectors in the time slice ================== - - // == s == Time frame scan loop ========================================================== - Double_t timesliceT0 = -999.0; - Bool_t bTimesliceTrigger = false; - - Bool_t bMutipliTriggers[6] = {false, false, false, false, false, false}; - Double_t multipliTrigTime[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - - // Double_t tsTimeS = child_idx * m_timesplit_width; - // Double_t tsTimeE = (child_idx + 1) * m_timesplit_width; - Double_t tsTimeS = iTimeSlice * m_timesplit_width; - Double_t tsTimeE = (iTimeSlice + 1) * m_timesplit_width; - while (1) { - tsTimeS = iTimeSlice * m_timesplit_width; - tsTimeE = (iTimeSlice + 1) * m_timesplit_width; - if (tsTimeE > m_timeframe_width) - break; - iTimeSlice++; - - // == s == Multiplisity threshold Triggers ======================================= - - // == s == Multiplisity Single Triggers ======================================= - std::array singleTrig{}; - std::array singleTrigTime{}; - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " Trigger1 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - // s // EndCap Cal Trigger - EtaPhiGrid backEndCalGrid{}; - EtaPhiGrid backEndCalGridShifted{}; - EtaPhiTimeGrid backEndIntTimesEtaPhi = {}; - EtaPhiTimeGrid backEndIntTimesEtaPhiShifted = {}; - fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapN), iniCalHitPoint[kCalEndcapN], - timeResolution_EMCal(), tsTimeS, tsTimeE, backEndCalGrid, - backEndCalGridShifted, backEndIntTimesEtaPhi, backEndIntTimesEtaPhiShifted, - backEndEtaPhiBins); - singleTrig[0] = countGridCellsWithMultiplicity( - backEndCalGrid, backEndCalGridShifted, backEndIntTimesEtaPhi, - backEndIntTimesEtaPhiShifted, 10, singleTrigTime[0]); - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger2 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - // s // EndCap Cal+Trk Match Trigger - EtaPhiGrid backEndTrkGrid = {}; - EtaPhiGrid backEndTrkGridShifted = {}; - EtaPhiTimeGrid backEndIntTimesEtaPhiMatched = {}; - EtaPhiTimeGrid backEndIntTimesEtaPhiMatchedShifted = {}; - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkBackwardMPGD), - iniTrkHitPoint[kTrkBackwardMPGD], timeResolution_MPGD(), tsTimeS, - tsTimeE, backEndCalGrid, backEndCalGridShifted, backEndTrkGrid, - backEndTrkGridShifted, 10, backEndIntTimesEtaPhiMatched, - backEndIntTimesEtaPhiMatchedShifted, backEndEtaPhiBins); - singleTrig[1] = countGridCellsWithMultiplicity( - backEndTrkGrid, backEndTrkGridShifted, backEndIntTimesEtaPhiMatched, - backEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[1]); - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger3 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - EtaPhiGrid barrelCalGrid = {}; - EtaPhiGrid barrelCalGridShifted = {}; - EtaPhiTimeGrid barrelIntTimesEtaPhi = {}; - EtaPhiTimeGrid barrelIntTimesEtaPhiShifted = {}; - fillEtaPhiGrids(caloRecHitCollsIn.at(kCalBarrelScifi), iniCalHitPoint[kCalBarrelScifi], - timeResolution_EMCal(), tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, - barrelIntTimesEtaPhi, barrelIntTimesEtaPhiShifted, barrelEtaPhiBins); - singleTrig[2] = - countGridCellsWithMultiplicity(barrelCalGrid, barrelCalGridShifted, barrelIntTimesEtaPhi, - barrelIntTimesEtaPhiShifted, 10, singleTrigTime[2]); - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger4 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - EtaPhiGrid barrelTrkGrid = {}; - EtaPhiGrid barrelTrkGridShifted = {}; - EtaPhiTimeGrid barrelIntTimesEtaPhiMatched = {}; - EtaPhiTimeGrid barrelIntTimesEtaPhiMatchedShifted = {}; - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkMPGDBarrel), iniTrkHitPoint[kTrkMPGDBarrel], - timeResolution_MPGD(), tsTimeS, tsTimeE, barrelCalGrid, - barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, - barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, - barrelEtaPhiBins); - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkOuterMPGDBarrel), - iniTrkHitPoint[kTrkOuterMPGDBarrel], timeResolution_MPGD(), tsTimeS, - tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, - barrelTrkGridShifted, 5, barrelIntTimesEtaPhiMatched, - barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFBarrel), iniTrkHitPoint[kTrkTOFBarrel], - timeResolution_ACLGad(), tsTimeS, tsTimeE, barrelCalGrid, - barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, - barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, - barrelEtaPhiBins); - singleTrig[3] = countGridCellsWithMultiplicity( - barrelTrkGrid, barrelTrkGridShifted, barrelIntTimesEtaPhiMatched, - barrelIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[3]); - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger5 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - EtaPhiGrid frontEndCalGrid = {}; - EtaPhiGrid frontEndCalGridShifted = {}; - EtaPhiTimeGrid frontEndIntTimesEtaPhi = {}; - EtaPhiTimeGrid frontEndIntTimesEtaPhiShifted = {}; - fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapP), iniCalHitPoint[kCalEndcapP], - timeResolution_EMCal(), tsTimeS, tsTimeE, frontEndCalGrid, - frontEndCalGridShifted, frontEndIntTimesEtaPhi, frontEndIntTimesEtaPhiShifted, - forwardEndEtaPhiBins); - singleTrig[4] = countGridCellsWithMultiplicity( - frontEndCalGrid, frontEndCalGridShifted, frontEndIntTimesEtaPhi, - frontEndIntTimesEtaPhiShifted, 10, singleTrigTime[4]); - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger6 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - EtaPhiGrid frontEndTrkGrid = {}; - EtaPhiGrid frontEndTrkGridShifted = {}; - EtaPhiTimeGrid frontEndIntTimesEtaPhiMatched = {}; - EtaPhiTimeGrid frontEndIntTimesEtaPhiMatchedShifted = {}; - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkForwardMPGD), iniTrkHitPoint[kTrkForwardMPGD], - timeResolution_MPGD(), tsTimeS, tsTimeE, frontEndCalGrid, - frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, - frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, - forwardEndEtaPhiBins); - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFEndcap), iniTrkHitPoint[kTrkTOFEndcap], - timeResolution_ACLGad(), tsTimeS, tsTimeE, frontEndCalGrid, - frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, - frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, - forwardEndEtaPhiBins); - singleTrig[5] = countGridCellsWithMultiplicity( - frontEndTrkGrid, frontEndTrkGridShifted, frontEndIntTimesEtaPhiMatched, - frontEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[5]); - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger7 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - const auto hitsB0 = count_hits_in_window(trackerHitCollsIn.at(kTrkB0), iniTrkHitPoint[kTrkB0], - timeResolution_ACLGad(), tsTimeS, tsTimeE); - iniTrkHitPoint[kTrkB0] = hitsB0.next_start_index; - singleTrig[6] = hitsB0.count; - singleTrigTime[6] = hitsB0.average_time(); - - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " <><><><><> Trigger8 <<><><><><><><><><><><><><<><><><><><><><><><><><><> "<< std::endl; - Double_t totalZDCEnergy = 0.0; - Double_t totalZDCEnergyTime = 0.0; - const auto* recHitsZDCECal = caloRecHitCollsIn.at(kCalZDC); - if (recHitsZDCECal != nullptr) { - for (size_t iHit = iniCalHitPoint[kCalZDC]; iHit < recHitsZDCECal->size(); ++iHit) { - const auto& hit = recHitsZDCECal->at(iHit); - const Double_t hitTime = hit.getTime(); - if (hitTime - timeResolution_EMCal() > tsTimeE) - break; - if (is_hit_in_time_slice(hitTime, timeResolution_EMCal(), tsTimeS, tsTimeE)) { - totalZDCEnergy += hit.getEnergy(); - totalZDCEnergyTime += hit.getEnergy() * hitTime; - iniCalHitPoint[kCalZDC] = iHit; - } - } - } - singleTrig[7] = totalZDCEnergy; - singleTrigTime[7] = totalZDCEnergy > 0.0 ? totalZDCEnergyTime / totalZDCEnergy : 0.0; - - const Double_t etaPhiCalTriggerSum = singleTrig[0] + singleTrig[2] + singleTrig[4]; - const Double_t etaPhiCalTrkTriggerSum = singleTrig[1] + singleTrig[3] + singleTrig[5]; - bMutipliTriggers[0] = etaPhiCalTrkTriggerSum > 0 && singleTrig[6] > 4; - bMutipliTriggers[1] = etaPhiCalTrkTriggerSum > 0 && singleTrig[7] > 50; - bMutipliTriggers[2] = etaPhiCalTriggerSum > 0 && singleTrig[6] > 4; - bMutipliTriggers[3] = etaPhiCalTriggerSum > 0 && singleTrig[7] > 0.005; - bMutipliTriggers[4] = etaPhiCalTrkTriggerSum > 1; - bMutipliTriggers[5] = etaPhiCalTriggerSum > 2; - - // /??? QA - // Int_t physEventWeight = 2; - // for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { - // const Double_t physCollTime = *it; - // if ((physCollTime + 20 > tsTimeS - 20) && (physCollTime - 10 < tsTimeE + 30)) { - // physEventWeight = 1; - // break; - // } - // } - // Int_t numOfECalTowersX5 = 0; - // Int_t numOfECalTowersX10 = 0; - // for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { - // for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { - // if (backEndCalGrid[iEta][iPhi] > 0 || barrelCalGrid[iEta][iPhi] > 0 || - // frontEndCalGrid[iEta][iPhi] > 0) { - // if (physEventWeight == 1) { - - // std::vector vECalHitInTowerPhyRow = {backEndCalGrid[iEta][iPhi], - // barrelCalGrid[iEta][iPhi], - // frontEndCalGrid[iEta][iPhi]}; - // vECalHitInTowerPhy.push_back(vECalHitInTowerPhyRow); - - // if (backEndCalGrid[iEta][iPhi] > 4) { - // numOfECalTowersX5++; - // if (backEndCalGrid[iEta][iPhi] > 9) - // numOfECalTowersX10++; - // } - // if (barrelCalGrid[iEta][iPhi] > 4) { - // numOfECalTowersX5++; - // if (barrelCalGrid[iEta][iPhi] > 9) - // numOfECalTowersX10++; - // } - // if (frontEndCalGrid[iEta][iPhi] > 4) { - // numOfECalTowersX5++; - // if (frontEndCalGrid[iEta][iPhi] > 9) - // numOfECalTowersX10++; - // } - // } else { - // std::vector vECalHitInTowerBkgRow = {backEndCalGrid[iEta][iPhi], - // barrelCalGrid[iEta][iPhi], - // frontEndCalGrid[iEta][iPhi]}; - // vECalHitInTowerBkg.push_back(vECalHitInTowerBkgRow); - - // if (backEndCalGrid[iEta][iPhi] > 4) { - // numOfECalTowersX5++; - // if (backEndCalGrid[iEta][iPhi] > 9) - // numOfECalTowersX10++; - // } - // if (barrelCalGrid[iEta][iPhi] > 4) { - // numOfECalTowersX5++; - // if (barrelCalGrid[iEta][iPhi] > 9) - // numOfECalTowersX10++; - // } - // if (frontEndCalGrid[iEta][iPhi] > 4) { - // numOfECalTowersX5++; - // if (frontEndCalGrid[iEta][iPhi] > 9) - // numOfECalTowersX10++; - // } - // } - // } - // } - // } - // if (physEventWeight == 1) - // vECalTowersPhy.push_back( - // {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); - // else if (physEventWeight == 2) - // vECalTowersBkg.push_back( - // {numOfECalTowersX5, numOfECalTowersX10, static_cast(singleTrig[7] * 1000000)}); - // /??? QA - - if (!bMutipliTriggers[0] && !bMutipliTriggers[1] && !bMutipliTriggers[2] && - !bMutipliTriggers[3] && !bMutipliTriggers[4] && !bMutipliTriggers[5]) - continue; - - const Double_t fallbackTriggerTime = 0.5 * (tsTimeS + tsTimeE); - if (bMutipliTriggers[0]) - multipliTrigTime[0] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 6}, - fallbackTriggerTime); - if (bMutipliTriggers[1]) - multipliTrigTime[1] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 7}, - fallbackTriggerTime); - if (bMutipliTriggers[2]) - multipliTrigTime[2] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 6}, - fallbackTriggerTime); - if (bMutipliTriggers[3]) - multipliTrigTime[3] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 7}, - fallbackTriggerTime); - if (bMutipliTriggers[4]) - multipliTrigTime[4] = - averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5}, fallbackTriggerTime); - if (bMutipliTriggers[5]) - multipliTrigTime[5] = - averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4}, fallbackTriggerTime); - Double_t multiTrigCount = 0; - Double_t totalTrigTime = 0.0; - for (size_t iTrig = 0; iTrig < 6; ++iTrig) { - if (bMutipliTriggers[iTrig]) { - totalTrigTime += multipliTrigTime[iTrig]; - multiTrigCount++; - } - } - timesliceT0 = multiTrigCount > 0 ? totalTrigTime / multiTrigCount : fallbackTriggerTime; - - // == s == Multiplisity Single Triggers ======================================= - - // == s == Geometrical Coincidence Triggers ===================================== - // === Geometrical Coincidence === - // == e == Geometrical Coincidence Triggers ===================================== - - if (bMutipliTriggers[0] || bMutipliTriggers[1] || bMutipliTriggers[2] || - bMutipliTriggers[3] || bMutipliTriggers[4] || bMutipliTriggers[5]) - bTimesliceTrigger = - true; // ???? temporary, need to be removed after geometrical coincidence trigger is implemented - if (bTimesliceTrigger) - break; - } - // == e == Time frame scan loop ========================================================== - - // /??? QA <><><><><><><><><><><><><><> - // if (!vECalHitInTowerPhy.empty()) { - // auto& oECalHitsInTowerPhy = m_ecalhitsintower_phy_out(); - // auto& oECalTowersPHY = m_ecaltowers_phy_out(); - // for (size_t iTower = 0; iTower < vECalHitInTowerPhy.size(); ++iTower) { - // auto entry = oECalHitsInTowerPhy->create(); - // entry.setEventNumber(vECalHitInTowerPhy[iTower][0]); - // entry.setRunNumber(vECalHitInTowerPhy[iTower][1]); - // entry.setTimeStamp(vECalHitInTowerPhy[iTower][2]); - // } - // for (size_t iTower = 0; iTower < vECalTowersPhy.size(); ++iTower) { - // auto entry = oECalTowersPHY->create(); - // entry.setEventNumber(vECalTowersPhy[iTower][0]); - // entry.setRunNumber(vECalTowersPhy[iTower][1]); - // entry.setTimeStamp(vECalTowersPhy[iTower][2]); - // } - // } - // if (!vECalHitInTowerBkg.empty()) { - // auto& oECalHitsInTowerBkg = m_ecalhitsintower_bkg_out(); - // auto& oECalTowersBkg = m_ecaltowers_bkg_out(); - // for (size_t iTower = 0; iTower < vECalHitInTowerBkg.size(); ++iTower) { - // auto entry = oECalHitsInTowerBkg->create(); - // entry.setEventNumber(vECalHitInTowerBkg[iTower][0]); - // entry.setRunNumber(vECalHitInTowerBkg[iTower][1]); - // entry.setTimeStamp(vECalHitInTowerBkg[iTower][2]); - // } - // for (size_t iTower = 0; iTower < vECalTowersBkg.size(); ++iTower) { - // auto entry = oECalTowersBkg->create(); - // entry.setEventNumber(vECalTowersBkg[iTower][0]); - // entry.setRunNumber(vECalTowersBkg[iTower][1]); - // entry.setTimeStamp(vECalTowersBkg[iTower][2]); - // } - // } - // /??? QA <><><><><><><><><><><><><<>><><><><>< - - m_bTrigger = bTimesliceTrigger; - if (bTimesliceTrigger) { - m_bOnceTriggered = true; - // For now, a one-to-one relationship between timeslices and events - child.SetEventNumber(m_NewEventCount); - child.SetRunNumber(parent.GetRunNumber()); - m_NewEventCount++; - // Clone truth particles before detector relations so every child SimTrackerHit can - // point to an MCParticle owned by this PhysicsEvent rather than by the parent Timeslice. - for (const auto& mcparticle : *m_mcparticles_in()) { - m_mcparticles_out()->push_back(mcparticle.clone(false)); - } - - // == s == Register Tracker Hits ======================================================= - for (size_t trkDetID = 0; trkDetID < trackerHitCollsIn.size(); ++trkDetID) { - const auto* trkCollIn = trackerHitCollsIn.at(trkDetID); - - if (trkCollIn == nullptr) - continue; - auto& trkCollOut = m_trackerhits_out().at(trkDetID); - const Double_t detTimeReso = tracker_time_resolution(trkDetID); - const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); - auto& rawCollOut = m_rawhit_out().at(trkDetID); - auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); - - for (size_t iHit = 0; iHit < trkCollIn->size(); ++iHit) { - const auto& trkHit = trkCollIn->at(iHit); - - const Double_t hitT = trkHit.getTime(); - if (!overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { - continue; - } - - iniTrkHitPoint[trkDetID] = iHit; - copy_tracker_hit_with_relations( - trkHit, trkAssoCollIn, m_tracker_association_indices.at(trkDetID), trkCollOut, - rawCollOut, trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), - m_rawhitlinks_out().at(trkDetID), m_mcparticles_out()); - } - } - // == e == Register Tracker Hits ======================================================= - - // == s == Register Calo Rec Hits ======================================================= - for (size_t calDetID = 0; calDetID < caloRecHitCollsIn.size(); ++calDetID) { - const auto* caloInColl = caloRecHitCollsIn.at(calDetID); - if (caloInColl == nullptr) - continue; - auto& caloOutColl = m_calorechit_out().at(calDetID); - - const auto* caloInCollAsso = calrecAssoCollsIn.at(calDetID); - if (caloInCollAsso == nullptr) - continue; - - for (size_t iCalHit = 0; iCalHit < caloInColl->size(); ++iCalHit) { - const auto& caloHit = caloInColl->at(iCalHit); - - Double_t detTimeReso = timeResolution_EMCal(); - Double_t hitT = caloHit.getTime(); - - if (hitT - detTimeReso > timesliceT0 + 30.) - continue; - if (overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { - // std::cout << "TF:TS = " << m_TFCount << ":" << child_idx << " CaloDetID = " << calDetID << " iCalHit = " << iCalHit << " hitT = " << hitT << std::endl; - auto copiedCaloHit = caloHit.clone(); - copiedCaloHit.setRawHit(edm4hep::RawCalorimeterHit()); - - const auto rawHitFromRec = caloHit.getRawHit(); - if (rawHitFromRec.isAvailable()) { - auto& rawCollOut = m_calorawhit_out().at(calDetID); - auto copiedRawHit = rawHitFromRec.clone(); - rawCollOut->push_back(copiedRawHit); - copiedCaloHit.setRawHit(copiedRawHit); - - auto& assocCollOut = m_calorechitassociation_out().at(calDetID); - auto& linkCollOut = m_calorawhitlinks_out().at(calDetID); - auto& simCollOut = m_simcalorimeterhits_out().at(calDetID); - const auto rawHitID = rawHitFromRec.getObjectID(); - - const auto& association_index = m_calorimeter_association_indices.at(calDetID); - const auto assocIterCal = association_index.find(object_id_key(rawHitID)); - - if (assocIterCal != association_index.end()) { - for (const size_t association_position : assocIterCal->second) { - const auto assoc = caloInCollAsso->at(association_position); - - if (!assoc.getSimHit().isAvailable()) - continue; - - auto copiedSimHit = assoc.getSimHit().clone(false); - simCollOut->push_back(copiedSimHit); - - auto copiedAssoc = assocCollOut->create(); - copiedAssoc.setWeight(assoc.getWeight()); - copiedAssoc.setRawHit(copiedRawHit); - copiedAssoc.setSimHit(copiedSimHit); - - auto copiedLink = linkCollOut->create(); - copiedLink.setWeight(assoc.getWeight()); - copiedLink.setFrom(copiedRawHit); - copiedLink.setTo(copiedSimHit); - } - } - } - - caloOutColl->push_back(copiedCaloHit); - iniCalHitPoint[calDetID] = iCalHit; - } - } - } - // == e == Register Calo Rec Hits ======================================================= - - // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><><>> - // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ - Int_t physEventWeight = 2; - for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { - const Double_t physCollTime = *it; - if ((physCollTime + 20 > timesliceT0 - 10) && (physCollTime - 10 < timesliceT0 + 30)) { - physEventWeight = 1; - m_vPhysCooTimes.erase(it); - break; - } - } - - if (physEventWeight == 1) { - edm4hep::MutableEventHeader event_header_bkg; - event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_bkg.setEventNumber(m_event_number_ts); - event_header_bkg.setTimeStamp(iTimeSlice); - event_header_bkg.setWeight(1); - m_event_header_bkg_out()->push_back(event_header_bkg); - - edm4hep::MutableEventHeader event_header_phy; - event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_phy.setEventNumber(m_event_number_ts); - event_header_phy.setTimeStamp(iTimeSlice); - event_header_phy.setWeight(2); - m_event_header_phy_out()->push_back(event_header_phy); - for (size_t iTrig = 0; iTrig < 6; ++iTrig) { - if (bMutipliTriggers[iTrig]) { - edm4hep::MutableEventHeader event_header_phy; - event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_phy.setEventNumber(m_event_number_ts); - event_header_phy.setTimeStamp(iTimeSlice); - event_header_phy.setWeight(iTrig + 3); - m_event_header_phy_out()->push_back(event_header_phy); - } - } - m_PhysCount++; - } else if (physEventWeight == 2) { - edm4hep::MutableEventHeader event_header_phy; - event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_phy.setEventNumber(m_event_number_ts); - event_header_phy.setTimeStamp(iTimeSlice); - event_header_phy.setWeight(1); - m_event_header_phy_out()->push_back(event_header_phy); - - edm4hep::MutableEventHeader event_header_bkg; - event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_bkg.setEventNumber(m_event_number_ts); - event_header_bkg.setTimeStamp(iTimeSlice); - event_header_bkg.setWeight(2); - m_event_header_bkg_out()->push_back(event_header_bkg); - for (size_t iTrig = 0; iTrig < 6; ++iTrig) { - if (bMutipliTriggers[iTrig]) { - edm4hep::MutableEventHeader event_header_bkg; - event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_bkg.setEventNumber(m_event_number_ts); - event_header_bkg.setTimeStamp(iTimeSlice); - event_header_bkg.setWeight(iTrig + 3); - m_event_header_bkg_out()->push_back(event_header_bkg); - } - } - } - m_event_number_ts++; - - // Insert an independent EventHeader object into the physics event. - // A subset header would keep a reference to the parent frame collection. - edm4hep::MutableEventHeader event_header; - if (m_event_header_in() != nullptr && !m_event_header_in()->empty()) { - const auto& event_header_in = m_event_header_in()->at(0); - event_header.setRunNumber(event_header_in.getRunNumber()); - event_header.setEventNumber(event_header_in.getEventNumber()); - event_header.setTimeStamp(event_header_in.getTimeStamp()); - event_header.setWeight(event_header_in.getWeight()); - } else { - event_header.setRunNumber(child.GetRunNumber()); - event_header.setEventNumber(child.GetEventNumber()); - event_header.setTimeStamp(iTimeSlice); - event_header.setWeight(physEventWeight); - } - m_event_header_out()->push_back(event_header); - // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ - - // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><>> - } - - if (tsTimeE > m_timeframe_width) - m_bScanedAllTimeWindows = true; - if (m_bScanedAllTimeWindows) { - bInitialLoop = true; - m_bOnceTriggered = false; - - m_vPhysCooTimes.clear(); - std::vector().swap(m_vPhysCooTimes); - - m_bScanedAllTimeWindows = false; - iTimeSlice = 0; - targetDetId = 0; - for (auto& start_point : iniTrkHitPoint) - start_point = 0; - for (auto& start_point : iniCalHitPoint) - start_point = 0; - - if (m_bTrigger) - return Result::NextChildNextParent; - else - return Result::KeepChildNextParent; - } else if (m_bTrigger) { - child_idx++; - return Result::NextChildKeepParent; - } - return Result::KeepChildNextParent; - } - - inline void thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, - Int_t& thetaID2, Int_t& phiID2) { - Double_t hitX = hit.getPosition()[0]; - Double_t hitY = hit.getPosition()[1]; - Double_t hitZ = hit.getPosition()[2]; - const Double_t hitR = TMath::Sqrt(hitX * hitX + hitY * hitY + hitZ * hitZ); - if (hitR <= 0.0) { - thetaID1 = 0; - thetaID2 = 0; - phiID1 = 0; - phiID2 = 0; - return; - } - - const Double_t cosTheta = std::clamp(hitZ / hitR, -1.0, 1.0); - const Double_t hitTheta = TMath::ACos(cosTheta); - - Double_t hitPhi = TMath::ATan2(hitY, hitX) + 2 * TMath::Pi(); - if (hitPhi < 0) - hitPhi += 2 * TMath::Pi(); - thetaID1 = hitTheta / (TMath::Pi() / 12.); - thetaID2 = (hitTheta + TMath::Pi() / 24.) / (TMath::Pi() / 12.); - phiID1 = hitPhi / (TMath::Pi() / 8.); - phiID2 = (hitPhi + TMath::Pi() / 16.) / (TMath::Pi() / 8.); - } + void thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, + Int_t& thetaID2, Int_t& phiID2); }; diff --git a/src/global/splitting/TrkTimeAlignment.h b/src/global/splitting/TrkTimeAlignment.h new file mode 100644 index 0000000000..1a161f20f9 --- /dev/null +++ b/src/global/splitting/TrkTimeAlignment.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov + +#pragma once + +#include +#include + +#include "RecHitTimeAlignment.h" + +namespace eicrecon { + +class TrkTimeAlignment + : public RecHitTimeAlignment { +public: + TrkTimeAlignment(std::string_view name) + : RecHitTimeAlignment{name, + "inputTrackerHits", + "outputTrackerHits", + "Align reconstructed tracker hit times."} {} +}; + +} // namespace eicrecon diff --git a/src/global/splitting/TrkTimeAlignmentFactory.h b/src/global/splitting/TrkTimeAlignmentFactory.h index 2c852d1d15..b0a222e006 100644 --- a/src/global/splitting/TrkTimeAlignmentFactory.h +++ b/src/global/splitting/TrkTimeAlignmentFactory.h @@ -1,28 +1,24 @@ -// Copyright 2024, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov #pragma once -#include -#include -#include +#include #include #include -#include #include +#include -#include -#include -#include -#include +#include "TrkTimeAlignment.h" -#include -#include +struct TrkTimeAlignmentFactory : public JOmniFactory { + using AlgoT = eicrecon::TrkTimeAlignment; -struct timeAlignmentFactory : public JOmniFactory { JEventLevel m_factory_level; + std::unique_ptr m_algo; + std::vector m_trackerhit_collection_names = { "TOFBarrelRecHits", "TOFEndcapRecHits", "MPGDBarrelRecHits", "OuterMPGDBarrelRecHits", "BackwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits", @@ -53,9 +49,11 @@ struct timeAlignmentFactory : public JOmniFactory { VariadicPodioOutput m_trackerhits_out{this, m_trackerhit_collection_names_aligned}; - Double_t m_time_offset = 0.0; // Time offset to apply to hits - - void Configure() {} + void Configure() { + m_algo = std::make_unique(GetPrefix()); + m_algo->level(static_cast(logger()->level())); + m_algo->init(); + } void ChangeRun(int32_t /*run_nr*/) override {} @@ -65,30 +63,7 @@ struct timeAlignmentFactory : public JOmniFactory { auto& coll_out = m_trackerhits_out().at(coll_index); if (coll_in != nullptr) { - // std::vector sorted_hits; // for edm4hep (G4Hit level) - std::vector sorted_hits; // for edm4eic (After digitization) - for (const auto& hit : *coll_in) { - // edm4hep::MutableSimTrackerHit copiedHit = hit.clone(); // for edm4hep (G4Hit level) - edm4eic::MutableTrackerHit copiedHit = hit.clone(); // for edm4eic (After digitization) - - Double_t hitR = std::sqrt(hit.getPosition()[0] * hit.getPosition()[0] + - hit.getPosition()[1] * hit.getPosition()[1] + - hit.getPosition()[2] * hit.getPosition()[2]); - Double_t calibTime = hitR * 0.0034; - copiedHit.setTime(hit.getTime() - calibTime); - sorted_hits.push_back(copiedHit); - - // std::cout << ">>> Detector " << m_trackerhit_collection_names.at(coll_index) - // << " Original Time: " << hit.getTime() - // << " Calibrated Time: " << hit.getTime() - calibTime << std::endl; - } - - std::sort(sorted_hits.begin(), sorted_hits.end(), - [](const auto& a, const auto& b) { return a.getTime() < b.getTime(); }); - - for (const auto& hit : sorted_hits) { - coll_out->push_back(hit); - } + m_algo->process({coll_in}, {coll_out.get()}); } } } diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index de3dad3f11..9ffe914f15 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -1,6 +1,5 @@ -// Copyright 2024, Jefferson Science Associates, LLC. -// Subject to the terms in the LICENSE file found in the top-level directory. -// kuma edit +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov #include #include @@ -10,9 +9,7 @@ #include #include "CalRecTimeAlignmentFactory.h" -// #include "CalTimeAlignmentFactory.h" #include "TimeframeSplitter.h" -// #include "HitChecker.h" #include "TrkTimeAlignmentFactory.h" #include "extensions/jana/JOmniFactoryGeneratorT.h" @@ -27,9 +24,6 @@ void InitPlugin(JApplication* app) { "SiEndcapTrackerRecHits_aligned", "B0TrackerRecHits_aligned", "TaggerTrackerRecHits_aligned", "ForwardRomanPotRecHits_aligned", "ForwardOffMTrackerRecHits_aligned"}; - // "RICHEndcapNRecHits_TK_aligned" - // "DIRCBarRecHits_TK_aligned", - // "DRICHRecHits_TK_aligned", std::vector m_simtrackerhit_collection_names = { "TOFBarrelRecHits", "TOFEndcapRecHits", "MPGDBarrelRecHits", @@ -37,9 +31,6 @@ void InitPlugin(JApplication* app) { "SiBarrelVertexRecHits", "SiBarrelTrackerRecHits", "SiEndcapTrackerRecHits", "B0TrackerRecHits", "TaggerTrackerRecHits", "ForwardRomanPotRecHits", "ForwardOffMTrackerRecHits"}; - // "RICHEndcapNRecHits_TK" - // "DIRCBarRecHits_TK", - // "DRICHRecHits_TK" std::vector m_simcalorechit_collection_names = {"B0ECalRecHits", "EcalBarrelImagingRecHits", @@ -68,20 +59,6 @@ void InitPlugin(JApplication* app) { "HcalFarForwardZDCRecHits_aligned", "LFHCALRecHits_aligned"}; - // std::vector m_simcalocluster_collection_names_aligned = { - // "B0ECalClusters_TK_aligned", "EcalBarrelClusters_TK_aligned", - // "EcalEndcapNClusters_TK_aligned", "EcalEndcapPClusters_TK_aligned"}; - // // "EcalFarForwardZDCClusters_TK_aligned", - // // "EcalLumiSpecClusters_TK_aligned", - // // "HcalBarrelClusters_TK_aligned", - // // "HcalEndcapNClusters_TK_aligned", - // // "HcalEndcapPInsertClusters_TK_aligned", - // // "HcalFarForwardZDCClusters_TK_aligned", - // // "LFHCALClusters_TK_aligned" - - // std::vector m_simcalocluster_collection_names = { - // "B0ECalClusters_TK", "EcalBarrelClusters_TK", "EcalEndcapNClusters_TK", - // "EcalEndcapPClusters_TK"}; InitJANAPlugin(app); @@ -90,7 +67,8 @@ void InitPlugin(JApplication* app) { if (!split_timeframes) { return; } - app->Add(new JOmniFactoryGeneratorT( + + app->Add(new JOmniFactoryGeneratorT( "timeAlignment", m_simtrackerhit_collection_names, m_simtrackerhit_collection_names_aligned, app, JEventLevel::Timeslice)); @@ -98,34 +76,9 @@ void InitPlugin(JApplication* app) { "CalRecTimeAlignment", m_simcalorechit_collection_names, m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); - // app->Add(new JOmniFactoryGeneratorT( - // JOmniFactoryGeneratorT::TypedWiring{ - // .m_tag = "CalTimeAlignment", - // .m_default_input_tags = m_simcalocluster_collection_names, - // .m_default_output_tags = m_simcalocluster_collection_names_aligned, - // .level = JEventLevel::Timeslice, - // }, - // app)); - // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); - // app->Add(new JOmniFactoryGeneratorT( - // JOmniFactoryGeneratorT::TypedWiring{ - // .m_tag = "timeframe_hit_checker", - // .m_default_input_tags = {"TOFBarrelRecHits"}, - // .m_default_output_tags = {"hitChecker_TF"}, - // .level = JEventLevel::Timeslice, - // }, - // app)); - // app->Add(new JOmniFactoryGeneratorT( - // JOmniFactoryGeneratorT::TypedWiring{ - // .m_tag = "timeslice_hit_checker", - // .m_default_input_tags = {"TOFBarrelRecHits"}, - // .m_default_output_tags = {"hitChecker_TS"}, - // .level = JEventLevel::PhysicsEvent, - // }, - // app)); } } // "C" From 7311db99a8226e7913e30410a28b21a579a9f9ba Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Sun, 9 Aug 2026 19:18:14 -0400 Subject: [PATCH 08/31] ci: add timeframe splitting runtime test --- .github/workflows/linux-eic-shell.yml | 86 +++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index 5663ebe064..d9e31a0f27 100644 --- a/.github/workflows/linux-eic-shell.yml +++ b/.github/workflows/linux-eic-shell.yml @@ -1321,6 +1321,92 @@ jobs: if-no-files-found: error include-hidden-files: true + eicrecon-timeframe-splitting: + runs-on: ubuntu-24.04 + needs: + - build + - npsim-dis + strategy: + matrix: + include: + - CXX: clang++ + beam: 10x100 + minq2: 1000 + detector_config: craterlake_tracking_only + sanitizer: ASAN + + - CXX: clang++ + beam: 10x100 + minq2: 1000 + detector_config: craterlake_tracking_only + sanitizer: TSAN + nthreads: 4 + + steps: + - name: Checkout .github and scripts + uses: actions/checkout@v7 + with: + sparse-checkout: | + .github + src/scripts + + - name: Download install directory + uses: actions/download-artifact@v8 + with: + name: install-${{ matrix.CXX }}-eic-shell-Release-${{ env.platform }}-${{ env.release }}-${{ matrix.sanitizer }} + + - name: Unarchive install directory + run: tar -xaf install.tar.zst + + - name: Download simulation input + uses: actions/download-artifact@v8 + with: + name: sim_dis_${{ matrix.beam }}_minQ2=${{ matrix.minq2 }}_${{ matrix.detector_config }}.edm4hep.rnt.root + + - name: Setup cvmfs + uses: cvmfs-contrib/github-action-cvmfs@v5 + + - name: Run EICrecon with timeframe splitting + uses: eic/run-cvmfs-osg-eic-shell@main + with: + organization: "${{ env.organization }}" + platform-release: "${{ env.platform }}:${{ env.release }}" + setup: "/opt/detector/epic-${{ env.detector-version }}/bin/thisepic.sh" + run: | + echo "::add-matcher::${{github.workspace}}/.github/ubsan.json" + echo "::add-matcher::${{github.workspace}}/.github/eicrecon.json" + + export DETECTOR_CONFIG=${DETECTOR}_${{ matrix.detector_config }} + export LD_LIBRARY_PATH=$PWD/install/lib:$LD_LIBRARY_PATH + export JANA_PLUGIN_PATH=$PWD/install/lib/EICrecon/plugins:/usr/local/plugins + + prmon --json-summary timeframe_splitter_${{matrix.sanitizer}}.prmon.json -- \ + $PWD/install/bin/eicrecon \ + ${{env.JANA_OPTIONS}} \ + ${{matrix.nthreads > 1 && format('-Pnthreads={0}', matrix.nthreads) || ''}} \ + -Ppodio:output_file=timeframe_splitter_${{matrix.sanitizer}}.edm4eic.root \ + sim_dis_${{matrix.beam}}_minQ2=${{matrix.minq2}}_${{ matrix.detector_config }}.edm4hep.rnt.root \ + -Psplit_timeframes=true + + - name: Verify output file + run: | + test -s timeframe_splitter_${{matrix.sanitizer}}.edm4eic.root + + - name: Upload output + uses: actions/upload-artifact@v7 + with: + name: timeframe_splitter_${{matrix.sanitizer}}.edm4eic.root + path: timeframe_splitter_${{matrix.sanitizer}}.edm4eic.root + if-no-files-found: error + + - name: Upload prmon report + uses: actions/upload-artifact@v7 + with: + name: timeframe_splitter_${{matrix.sanitizer}}.prmon.json + path: timeframe_splitter_${{matrix.sanitizer}}.prmon.json + if-no-files-found: error + + compare-single-multi-threaded: runs-on: ubuntu-24.04 needs: From c828d7275a0ea3252922eb85b369f6dd5e2aeb50 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 01:28:38 +0000 Subject: [PATCH 09/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/detectors/BTRK/BTRK.cc | 4 +- src/global/splitting/CMakeLists.txt | 3 +- src/global/splitting/CalRecTimeAlignment.h | 9 +- src/global/splitting/RecHitTimeAlignment.h | 17 ++-- src/global/splitting/TimeframeSplitter.cc | 106 ++++++++++----------- src/global/splitting/TimeframeSplitter.h | 8 +- src/global/splitting/TrkTimeAlignment.h | 4 +- src/global/splitting/splitting.cc | 3 - 8 files changed, 71 insertions(+), 83 deletions(-) diff --git a/src/detectors/BTRK/BTRK.cc b/src/detectors/BTRK/BTRK.cc index c0f41c5762..0a6c1275e0 100644 --- a/src/detectors/BTRK/BTRK.cc +++ b/src/detectors/BTRK/BTRK.cc @@ -42,7 +42,9 @@ void InitPlugin(JApplication* app) { if (!split_timeframes) { app->Add(new JOmniFactoryGeneratorT( "SiBarrelNoiseRawHits", {"EventHeader"}, {"SiBarrelNoiseRawHits"}, - {.addNoise = true, .noise_rate_per_pixel_per_event = 2.0e-7, .readout_name = "SiBarrelHits"}, + {.addNoise = true, + .noise_rate_per_pixel_per_event = 2.0e-7, + .readout_name = "SiBarrelHits"}, app)); app->Add(new JOmniFactoryGeneratorT>( diff --git a/src/global/splitting/CMakeLists.txt b/src/global/splitting/CMakeLists.txt index 699af0b1da..74613b3963 100644 --- a/src/global/splitting/CMakeLists.txt +++ b/src/global/splitting/CMakeLists.txt @@ -1,4 +1,3 @@ - get_filename_component(PLUGIN_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) # Function creates ${PLUGIN_NAME}_plugin and ${PLUGIN_NAME}_library targets @@ -20,7 +19,7 @@ plugin_add_event_model(${PLUGIN_NAME}) # Add libraries (same as target_include_directories but for both plugin and # library) plugin_link_libraries(${PLUGIN_NAME} algorithms_digi_library - algorithms_tracking_library) + algorithms_tracking_library) # # Add include directories (works same as target_include_directories) # plugin_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR} diff --git a/src/global/splitting/CalRecTimeAlignment.h b/src/global/splitting/CalRecTimeAlignment.h index cdceefbf7d..8d88133c71 100644 --- a/src/global/splitting/CalRecTimeAlignment.h +++ b/src/global/splitting/CalRecTimeAlignment.h @@ -10,14 +10,11 @@ namespace eicrecon { -class CalRecTimeAlignment - : public RecHitTimeAlignment { +class CalRecTimeAlignment : public RecHitTimeAlignment { public: CalRecTimeAlignment(std::string_view name) - : RecHitTimeAlignment{name, - "inputCalorimeterHits", - "outputCalorimeterHits", + : RecHitTimeAlignment{name, "inputCalorimeterHits", "outputCalorimeterHits", "Align reconstructed calorimeter hit times."} {} }; diff --git a/src/global/splitting/RecHitTimeAlignment.h b/src/global/splitting/RecHitTimeAlignment.h index 66245c0241..2937a18bd1 100644 --- a/src/global/splitting/RecHitTimeAlignment.h +++ b/src/global/splitting/RecHitTimeAlignment.h @@ -25,8 +25,8 @@ class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm RecHitTimeAlignment(std::string_view name, std::string input_name, std::string output_name, std::string description) - : AlgorithmT{name, {std::move(input_name)}, {std::move(output_name)}, - std::move(description)} {} + : AlgorithmT{ + name, {std::move(input_name)}, {std::move(output_name)}, std::move(description)} {} void init() final {} @@ -38,10 +38,10 @@ class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm std::vector sorted_hits; sorted_hits.reserve(hits_in->size()); for (const auto& hit : *hits_in) { - MutableHitT copied_hit = hit.clone(); - const auto position = hit.getPosition(); - const auto hit_r = std::sqrt(position[0] * position[0] + - position[1] * position[1] + position[2] * position[2]); + MutableHitT copied_hit = hit.clone(); + const auto position = hit.getPosition(); + const auto hit_r = std::sqrt(position[0] * position[0] + position[1] * position[1] + + position[2] * position[2]); const auto calibrated_time = hit_r * m_refInverseVelocity; copied_hit.setTime(hit.getTime() - calibrated_time); sorted_hits.push_back(copied_hit); @@ -55,9 +55,8 @@ class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm } } - private: - double m_refInverseVelocity = 0.0034; // ns/mm - +private: + double m_refInverseVelocity = 0.0034; // ns/mm }; } // namespace eicrecon diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 9877b5ebb0..77ca01f5c1 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -19,8 +19,8 @@ std::uint64_t TimeframeSplitter::object_id_key(const podio::ObjectID& object_id) return (collection_id << 32U) | index; } -TimeframeSplitter::TrackerAssociationIndex - TimeframeSplitter::buildTrkAssoId(const edm4eic::MCRecoTrackerHitAssociationCollection* associations) { +TimeframeSplitter::TrackerAssociationIndex TimeframeSplitter::buildTrkAssoId( + const edm4eic::MCRecoTrackerHitAssociationCollection* associations) { TrackerAssociationIndex index; if (associations == nullptr) @@ -38,8 +38,8 @@ TimeframeSplitter::TrackerAssociationIndex return index; } -TimeframeSplitter::CalorimeterAssociationIndex - TimeframeSplitter::buildCalAssoId(const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations) { +TimeframeSplitter::CalorimeterAssociationIndex TimeframeSplitter::buildCalAssoId( + const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations) { CalorimeterAssociationIndex index; if (associations == nullptr) @@ -57,12 +57,13 @@ TimeframeSplitter::CalorimeterAssociationIndex return index; } -bool TimeframeSplitter::overlaps_time_window(Double_t hitTime, Double_t resolution, Double_t window_start, - Double_t window_end) { +bool TimeframeSplitter::overlaps_time_window(Double_t hitTime, Double_t resolution, + Double_t window_start, Double_t window_end) { return hitTime + resolution > window_start && hitTime - resolution < window_end; } -bool TimeframeSplitter::is_after_time_window(Double_t hitTime, Double_t resolution, Double_t window_end) { +bool TimeframeSplitter::is_after_time_window(Double_t hitTime, Double_t resolution, + Double_t window_end) { return hitTime - resolution >= window_end; } @@ -71,13 +72,14 @@ bool TimeframeSplitter::isValidEtaPhiBin(Int_t etaBin, Int_t phiBin) { } bool TimeframeSplitter::is_hit_in_time_slice(Double_t hitTime, Double_t time_resolution, - Double_t time_slice_start, Double_t time_slice_end) { + Double_t time_slice_start, Double_t time_slice_end) { return !(hitTime + time_resolution < time_slice_start || hitTime - time_resolution > time_slice_end); } -std::pair TimeframeSplitter::etaPhiBins(Double_t hitEta, Double_t hitPhi, Double_t etaMin, - Double_t etaMax, Int_t bShift) { +std::pair TimeframeSplitter::etaPhiBins(Double_t hitEta, Double_t hitPhi, + Double_t etaMin, Double_t etaMax, + Int_t bShift) { const Double_t etaBinWidth = (etaMax - etaMin) / kEtaPhiBins; const Double_t phiMin = -TMath::Pi(); const Double_t phiMax = TMath::Pi(); @@ -101,10 +103,10 @@ std::pair TimeframeSplitter::etaPhiBins(Double_t hitEta, Double_t } size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0, - const EtaPhiGrid& gridShifted, - const EtaPhiTimeGrid& gridTime0, - const EtaPhiTimeGrid& gridShiftedTime, - Int_t threshold, Double_t& averageTime) { + const EtaPhiGrid& gridShifted, + const EtaPhiTimeGrid& gridTime0, + const EtaPhiTimeGrid& gridShiftedTime, + Int_t threshold, Double_t& averageTime) { size_t count = 0; Double_t timeSum = 0.0; for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { @@ -124,9 +126,9 @@ size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0 } Double_t TimeframeSplitter::averageSelectedTriggerTime(const std::array& values, - const std::array& times, - std::initializer_list indices, - Double_t fallbackTime) { + const std::array& times, + std::initializer_list indices, + Double_t fallbackTime) { size_t count = 0; Double_t timeSum = 0.0; for (const size_t index : indices) { @@ -146,14 +148,16 @@ Double_t TimeframeSplitter::tracker_time_resolution(size_t detector_id) { return timeResolution_SiMaps(); } -std::pair TimeframeSplitter::backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { +std::pair TimeframeSplitter::backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, + Int_t bShift) { // MPGD backward Endcap range -3.6 < eta < -1.72, +5%: -3.78 < eta < -1.634 const Double_t etaMin = -3.78; const Double_t etaMax = -1.634; return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); } -std::pair TimeframeSplitter::barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift) { +std::pair TimeframeSplitter::barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, + Int_t bShift) { // MPGD barrel In range -1.49 < eta < 1.722, +5%: -1.56 < eta < 1.81 // MPGD barrel Out range -1.56 < eta < 1.61, +5%: -1.64 < eta < 1.70 // TOF barrel range -1.39 < eta < 1.39, +5%: -1.46 < eta < 1.46 @@ -164,7 +168,7 @@ std::pair TimeframeSplitter::barrelEtaPhiBins(Double_t hitEta, Dou } std::pair TimeframeSplitter::forwardEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, - Int_t bShift) { + Int_t bShift) { // MPGD forward Endcap range 2.0 < eta < 3.35, +5%: 1.90 < eta < 3.52 // TOF forward Endcap range 1.86 < eta < 3.85, +5%: 1.77 < eta < 4.04 // ECal forward Endcap range 1.4 < eta < 3.5, +5%: 1.33 < eta < 3.68 @@ -261,23 +265,22 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid backEndIntTimesEtaPhi = {}; EtaPhiTimeGrid backEndIntTimesEtaPhiShifted = {}; fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapN), iniCalHitPoint[kCalEndcapN], - time_resolution_emcal, tsTimeS, tsTimeE, backEndCalGrid, - backEndCalGridShifted, backEndIntTimesEtaPhi, backEndIntTimesEtaPhiShifted, - backEndEtaPhiBins); - singleTrig[0] = countGridCellsWithMultiplicity( - backEndCalGrid, backEndCalGridShifted, backEndIntTimesEtaPhi, - backEndIntTimesEtaPhiShifted, 10, singleTrigTime[0]); + time_resolution_emcal, tsTimeS, tsTimeE, backEndCalGrid, backEndCalGridShifted, + backEndIntTimesEtaPhi, backEndIntTimesEtaPhiShifted, backEndEtaPhiBins); + singleTrig[0] = + countGridCellsWithMultiplicity(backEndCalGrid, backEndCalGridShifted, backEndIntTimesEtaPhi, + backEndIntTimesEtaPhiShifted, 10, singleTrigTime[0]); // s // EndCap Cal+Trk Match Trigger EtaPhiGrid backEndTrkGrid = {}; EtaPhiGrid backEndTrkGridShifted = {}; EtaPhiTimeGrid backEndIntTimesEtaPhiMatched = {}; EtaPhiTimeGrid backEndIntTimesEtaPhiMatchedShifted = {}; - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkBackwardMPGD), - iniTrkHitPoint[kTrkBackwardMPGD], time_resolution_mpgd, tsTimeS, - tsTimeE, backEndCalGrid, backEndCalGridShifted, backEndTrkGrid, - backEndTrkGridShifted, 10, backEndIntTimesEtaPhiMatched, - backEndIntTimesEtaPhiMatchedShifted, backEndEtaPhiBins); + fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkBackwardMPGD), iniTrkHitPoint[kTrkBackwardMPGD], + time_resolution_mpgd, tsTimeS, tsTimeE, backEndCalGrid, + backEndCalGridShifted, backEndTrkGrid, backEndTrkGridShifted, 10, + backEndIntTimesEtaPhiMatched, backEndIntTimesEtaPhiMatchedShifted, + backEndEtaPhiBins); singleTrig[1] = countGridCellsWithMultiplicity( backEndTrkGrid, backEndTrkGridShifted, backEndIntTimesEtaPhiMatched, backEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[1]); @@ -297,21 +300,19 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiGrid barrelTrkGridShifted = {}; EtaPhiTimeGrid barrelIntTimesEtaPhiMatched = {}; EtaPhiTimeGrid barrelIntTimesEtaPhiMatchedShifted = {}; - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkMPGDBarrel), iniTrkHitPoint[kTrkMPGDBarrel], - time_resolution_mpgd, tsTimeS, tsTimeE, barrelCalGrid, - barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, - barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, - barrelEtaPhiBins); + fillEtaPhiGridsMatched( + trackerHitCollsIn.at(kTrkMPGDBarrel), iniTrkHitPoint[kTrkMPGDBarrel], time_resolution_mpgd, + tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, + 5, barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkOuterMPGDBarrel), iniTrkHitPoint[kTrkOuterMPGDBarrel], time_resolution_mpgd, tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); - fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFBarrel), iniTrkHitPoint[kTrkTOFBarrel], - time_resolution_tof, tsTimeS, tsTimeE, barrelCalGrid, - barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, - barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, - barrelEtaPhiBins); + fillEtaPhiGridsMatched( + trackerHitCollsIn.at(kTrkTOFBarrel), iniTrkHitPoint[kTrkTOFBarrel], time_resolution_tof, + tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, + 5, barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); singleTrig[3] = countGridCellsWithMultiplicity( barrelTrkGrid, barrelTrkGridShifted, barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[3]); @@ -386,17 +387,17 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent const Double_t fallbackTriggerTime = 0.5 * (tsTimeS + tsTimeE); if (bMutipliTriggers[0]) - multipliTrigTime[0] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 6}, - fallbackTriggerTime); + multipliTrigTime[0] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 6}, fallbackTriggerTime); if (bMutipliTriggers[1]) - multipliTrigTime[1] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 7}, - fallbackTriggerTime); + multipliTrigTime[1] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 7}, fallbackTriggerTime); if (bMutipliTriggers[2]) - multipliTrigTime[2] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 6}, - fallbackTriggerTime); + multipliTrigTime[2] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 6}, fallbackTriggerTime); if (bMutipliTriggers[3]) - multipliTrigTime[3] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 7}, - fallbackTriggerTime); + multipliTrigTime[3] = + averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4, 7}, fallbackTriggerTime); if (bMutipliTriggers[4]) multipliTrigTime[4] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5}, fallbackTriggerTime); @@ -415,8 +416,8 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent // == s == Multiplisity Single Triggers ======================================= - if (bMutipliTriggers[0] || bMutipliTriggers[1] || bMutipliTriggers[2] || - bMutipliTriggers[3] || bMutipliTriggers[4] || bMutipliTriggers[5]) + if (bMutipliTriggers[0] || bMutipliTriggers[1] || bMutipliTriggers[2] || bMutipliTriggers[3] || + bMutipliTriggers[4] || bMutipliTriggers[5]) bTimesliceTrigger = true; // ???? temporary, need to be removed after geometrical coincidence trigger is implemented if (bTimesliceTrigger) @@ -424,7 +425,6 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent } // == e == Time frame scan loop ========================================================== - m_bTrigger = bTimesliceTrigger; if (bTimesliceTrigger) { m_bOnceTriggered = true; @@ -648,7 +648,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent } void TimeframeSplitter::thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, - Int_t& thetaID2, Int_t& phiID2) { + Int_t& thetaID2, Int_t& phiID2) { Double_t hitX = hit.getPosition()[0]; Double_t hitY = hit.getPosition()[1]; Double_t hitZ = hit.getPosition()[2]; diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 470714ad06..f28574ac57 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -286,8 +286,6 @@ struct TimeframeSplitter : public JEventUnfolder { "HcalFarForwardZDCRawHitAssociations", "LFHCALRawHitAssociations"}; - - PodioInput m_event_header_in{this, {.name = "EventHeader", .is_optional = true}}; PodioOutput m_event_header_out{this, "EventHeader"}; @@ -334,7 +332,6 @@ struct TimeframeSplitter : public JEventUnfolder { VariadicPodioOutput m_calorechitassociation_out{ this, m_calorechitassociation_collection_names_out}; - PodioOutput m_event_header_phy_out{this, "EventHeader_PHY"}; PodioOutput m_event_header_bkg_out{this, "EventHeader_BKG"}; @@ -347,7 +344,6 @@ struct TimeframeSplitter : public JEventUnfolder { TimeframeSplitter(); - std::vector> m_hitStartIndices_simTracker; std::vector> @@ -601,6 +597,6 @@ struct TimeframeSplitter : public JEventUnfolder { Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override; - void thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, - Int_t& thetaID2, Int_t& phiID2); + void thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, Int_t& thetaID2, + Int_t& phiID2); }; diff --git a/src/global/splitting/TrkTimeAlignment.h b/src/global/splitting/TrkTimeAlignment.h index 1a161f20f9..fb1b889d1c 100644 --- a/src/global/splitting/TrkTimeAlignment.h +++ b/src/global/splitting/TrkTimeAlignment.h @@ -14,9 +14,7 @@ class TrkTimeAlignment : public RecHitTimeAlignment { public: TrkTimeAlignment(std::string_view name) - : RecHitTimeAlignment{name, - "inputTrackerHits", - "outputTrackerHits", + : RecHitTimeAlignment{name, "inputTrackerHits", "outputTrackerHits", "Align reconstructed tracker hit times."} {} }; diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index 9ffe914f15..32116c0fce 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -59,7 +59,6 @@ void InitPlugin(JApplication* app) { "HcalFarForwardZDCRecHits_aligned", "LFHCALRecHits_aligned"}; - InitJANAPlugin(app); const bool split_timeframes = @@ -78,7 +77,5 @@ void InitPlugin(JApplication* app) { // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); - - } } // "C" From 49fee5e7eb5392967fcb33437647ddcfcde976d0 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Mon, 10 Aug 2026 15:38:47 -0400 Subject: [PATCH 10/31] fix: preserve timeframe splitting levels for silicon trackers --- src/detectors/BVTX/BVTX.cc | 43 +++++++++++++------------- src/detectors/ECTRK/ECTRK.cc | 58 +++++++++++++++++++----------------- 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/src/detectors/BVTX/BVTX.cc b/src/detectors/BVTX/BVTX.cc index 6f6fed1980..ac6a91c958 100644 --- a/src/detectors/BVTX/BVTX.cc +++ b/src/detectors/BVTX/BVTX.cc @@ -29,27 +29,28 @@ void InitPlugin(JApplication* app) { app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexRawHits", {"EventHeader", "VertexBarrelHits"}, - {"SiBarrelVertexRawHits", "SiBarrelVertexRawHitLinks", "SiBarrelVertexRawHitAssociations"}, - { - .threshold = 0.54 * dd4hep::keV, - }, - app, hit_level)); - // Per-pixel noise occupancy for the vertex barrel. Configurable via - // SiBarrelVertexNoiseRawHits:noise_rate_per_pixel_per_event (default 2e-7). - if (!split_timeframes) { - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexNoiseRawHits", {"EventHeader"}, {"SiBarrelVertexNoiseRawHits"}, - {.addNoise = true, - .noise_rate_per_pixel_per_event = 2.0e-7, - .readout_name = "VertexBarrelHits"}, - app)); - app->Add(new JOmniFactoryGeneratorT>( - "SiBarrelVertexRawHitsWithNoise", {"SiBarrelVertexRawHits", "SiBarrelVertexNoiseRawHits"}, - {"SiBarrelVertexRawHitsWithNoise"}, {}, app)); - } + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelVertexRawHits", {"EventHeader", "VertexBarrelHits"}, + {"SiBarrelVertexRawHits", "SiBarrelVertexRawHitLinks", "SiBarrelVertexRawHitAssociations"}, + { + .threshold = 0.54 * dd4hep::keV, + }, + app, hit_level)); + + if (!split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelVertexNoiseRawHits", {"EventHeader"}, {"SiBarrelVertexNoiseRawHits"}, + {.addNoise = true, + .noise_rate_per_pixel_per_event = 2.0e-7, + .readout_name = "VertexBarrelHits"}, + app)); + + app->Add(new JOmniFactoryGeneratorT>( + "SiBarrelVertexRawHitsWithNoise", + {"SiBarrelVertexRawHits", "SiBarrelVertexNoiseRawHits"}, + {"SiBarrelVertexRawHitsWithNoise"}, {}, app)); + } // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( diff --git a/src/detectors/ECTRK/ECTRK.cc b/src/detectors/ECTRK/ECTRK.cc index 0c17b790d0..fb4abd9d71 100644 --- a/src/detectors/ECTRK/ECTRK.cc +++ b/src/detectors/ECTRK/ECTRK.cc @@ -29,33 +29,35 @@ void InitPlugin(JApplication* app) { const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Digitization - app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerRawHits", {"EventHeader", "TrackerEndcapHits"}, - {"SiEndcapTrackerRawHits", "SiEndcapTrackerRawHitLinks", "SiEndcapTrackerRawHitAssociations"}, - { - .threshold = 0.54 * dd4hep::keV, - }, - app, hit_level)); - - // Per-pixel noise occupancy for the endcap silicon tracker. Configurable via - // SiEndcapTrackerNoiseRawHits:noise_rate_per_pixel_per_event (default 2e-7). - if (!split_timeframes) { - app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerNoiseRawHits", {"EventHeader"}, {"SiEndcapTrackerNoiseRawHits"}, - {.addNoise = true, - .noise_rate_per_pixel_per_event = 2.0e-7, - .readout_name = "TrackerEndcapHits"}, - app)); - app->Add(new JOmniFactoryGeneratorT>( - "SiEndcapTrackerRawHitsWithNoise", {"SiEndcapTrackerRawHits", "SiEndcapTrackerNoiseRawHits"}, - {"SiEndcapTrackerRawHitsWithNoise"}, {}, app)); - } - - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerRecHits", - {split_timeframes ? "SiEndcapTrackerRawHits" : "SiEndcapTrackerRawHitsWithNoise"}, - {"SiEndcapTrackerRecHits"}, {}, // default config - app, hit_level)); + app->Add(new JOmniFactoryGeneratorT( + "SiEndcapTrackerRawHits", {"EventHeader", "TrackerEndcapHits"}, + {"SiEndcapTrackerRawHits", "SiEndcapTrackerRawHitLinks", + "SiEndcapTrackerRawHitAssociations"}, + { + .threshold = 0.54 * dd4hep::keV, + }, + app, hit_level)); + + if (!split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "SiEndcapTrackerNoiseRawHits", {"EventHeader"}, {"SiEndcapTrackerNoiseRawHits"}, + {.addNoise = true, + .noise_rate_per_pixel_per_event = 2.0e-7, + .readout_name = "TrackerEndcapHits"}, + app)); + + app->Add(new JOmniFactoryGeneratorT>( + "SiEndcapTrackerRawHitsWithNoise", + {"SiEndcapTrackerRawHits", "SiEndcapTrackerNoiseRawHits"}, + {"SiEndcapTrackerRawHitsWithNoise"}, {}, app)); + } + + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "SiEndcapTrackerRecHits", + {split_timeframes ? "SiEndcapTrackerRawHits" : "SiEndcapTrackerRawHitsWithNoise"}, + {"SiEndcapTrackerRecHits"}, {}, // default config + app, hit_level)); + } } // extern "C" From 0e839da31e3d6f1183cb738f31acfb174927e6d7 Mon Sep 17 00:00:00 2001 From: epic-capybara <139920704+epic-capybara@users.noreply.github.com> Date: Mon, 10 Aug 2026 14:44:21 -0400 Subject: [PATCH 11/31] Add timeframe splitting framework to EICrecon (fix: iwyu) (#2849) This PR applies the include-what-you-use fixes as suggested by https://github.com/eic/EICrecon/actions/runs/31347878130. Please merge this PR into the branch `timeframe_splitting_dev` to resolve failures in PR #2824. Auto-generated by [create-pull-request][1] [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/global/splitting/TimeframeSplitter.cc | 5 +++ src/global/splitting/TimeframeSplitter.h | 47 +++++++++++++---------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 77ca01f5c1..be66ac6c69 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -3,6 +3,11 @@ #include "TimeframeSplitter.h" +#include +#include +#include +#include +#include #include TimeframeSplitter::TimeframeSplitter() { diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index f28574ac57..dc03ed7bd1 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -3,38 +3,43 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include #include +#include #include #include #include +#include #include +#include #include -#include -#include #include "TMath.h" -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - struct TimeframeSplitter : public JEventUnfolder { Parameter timeframe_width{this, "timeframe_width", 2000.0, From af6d50f4385a73dd8bda34865d80cd28bfabace1 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka <41865066+11kumaoka@users.noreply.github.com> Date: Tue, 11 Aug 2026 05:14:03 +0900 Subject: [PATCH 12/31] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/global/splitting/TimeframeSplitter.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index dc03ed7bd1..a23ed98bc3 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -522,10 +522,15 @@ struct TimeframeSplitter : public JEventUnfolder { const Double_t hitTime = hit.getTime(); if (is_after_time_window(hitTime, resolution, window_end)) break; + + // Drop hits which cannot overlap the next window (which begins at window_end) + if (hitTime + resolution < window_end) { + summary.next_start_index = i + 1; + } + if (overlaps_time_window(hitTime, resolution, window_start, window_end)) { ++summary.count; summary.time_sum += hitTime; - summary.next_start_index = i; } } return summary; From c90ea2c3d111a1c9948b819db01a12fb5df4fb70 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 21:10:08 +0000 Subject: [PATCH 13/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/detectors/BVTX/BVTX.cc | 43 ++++++++++++++++++------------------ src/detectors/ECTRK/ECTRK.cc | 40 ++++++++++++++++----------------- 2 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/detectors/BVTX/BVTX.cc b/src/detectors/BVTX/BVTX.cc index ac6a91c958..6c03ff2800 100644 --- a/src/detectors/BVTX/BVTX.cc +++ b/src/detectors/BVTX/BVTX.cc @@ -29,28 +29,27 @@ void InitPlugin(JApplication* app) { app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; - // Digitization - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexRawHits", {"EventHeader", "VertexBarrelHits"}, - {"SiBarrelVertexRawHits", "SiBarrelVertexRawHitLinks", "SiBarrelVertexRawHitAssociations"}, - { - .threshold = 0.54 * dd4hep::keV, - }, - app, hit_level)); - - if (!split_timeframes) { - app->Add(new JOmniFactoryGeneratorT( - "SiBarrelVertexNoiseRawHits", {"EventHeader"}, {"SiBarrelVertexNoiseRawHits"}, - {.addNoise = true, - .noise_rate_per_pixel_per_event = 2.0e-7, - .readout_name = "VertexBarrelHits"}, - app)); - - app->Add(new JOmniFactoryGeneratorT>( - "SiBarrelVertexRawHitsWithNoise", - {"SiBarrelVertexRawHits", "SiBarrelVertexNoiseRawHits"}, - {"SiBarrelVertexRawHitsWithNoise"}, {}, app)); - } + // Digitization + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelVertexRawHits", {"EventHeader", "VertexBarrelHits"}, + {"SiBarrelVertexRawHits", "SiBarrelVertexRawHitLinks", "SiBarrelVertexRawHitAssociations"}, + { + .threshold = 0.54 * dd4hep::keV, + }, + app, hit_level)); + + if (!split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "SiBarrelVertexNoiseRawHits", {"EventHeader"}, {"SiBarrelVertexNoiseRawHits"}, + {.addNoise = true, + .noise_rate_per_pixel_per_event = 2.0e-7, + .readout_name = "VertexBarrelHits"}, + app)); + + app->Add(new JOmniFactoryGeneratorT>( + "SiBarrelVertexRawHitsWithNoise", {"SiBarrelVertexRawHits", "SiBarrelVertexNoiseRawHits"}, + {"SiBarrelVertexRawHitsWithNoise"}, {}, app)); + } // Convert raw digitized hits into hits with geometry info (ready for tracking) app->Add(new JOmniFactoryGeneratorT( diff --git a/src/detectors/ECTRK/ECTRK.cc b/src/detectors/ECTRK/ECTRK.cc index fb4abd9d71..1c6a394df7 100644 --- a/src/detectors/ECTRK/ECTRK.cc +++ b/src/detectors/ECTRK/ECTRK.cc @@ -29,35 +29,33 @@ void InitPlugin(JApplication* app) { const auto hit_level = split_timeframes ? JEventLevel::Timeslice : JEventLevel::PhysicsEvent; // Digitization - app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerRawHits", {"EventHeader", "TrackerEndcapHits"}, - {"SiEndcapTrackerRawHits", "SiEndcapTrackerRawHitLinks", - "SiEndcapTrackerRawHitAssociations"}, - { - .threshold = 0.54 * dd4hep::keV, - }, - app, hit_level)); - - if (!split_timeframes) { + app->Add(new JOmniFactoryGeneratorT( + "SiEndcapTrackerRawHits", {"EventHeader", "TrackerEndcapHits"}, + {"SiEndcapTrackerRawHits", "SiEndcapTrackerRawHitLinks", "SiEndcapTrackerRawHitAssociations"}, + { + .threshold = 0.54 * dd4hep::keV, + }, + app, hit_level)); + + if (!split_timeframes) { app->Add(new JOmniFactoryGeneratorT( "SiEndcapTrackerNoiseRawHits", {"EventHeader"}, {"SiEndcapTrackerNoiseRawHits"}, {.addNoise = true, - .noise_rate_per_pixel_per_event = 2.0e-7, - .readout_name = "TrackerEndcapHits"}, + .noise_rate_per_pixel_per_event = 2.0e-7, + .readout_name = "TrackerEndcapHits"}, app)); app->Add(new JOmniFactoryGeneratorT>( "SiEndcapTrackerRawHitsWithNoise", {"SiEndcapTrackerRawHits", "SiEndcapTrackerNoiseRawHits"}, {"SiEndcapTrackerRawHitsWithNoise"}, {}, app)); - } - - // Convert raw digitized hits into hits with geometry info (ready for tracking) - app->Add(new JOmniFactoryGeneratorT( - "SiEndcapTrackerRecHits", - {split_timeframes ? "SiEndcapTrackerRawHits" : "SiEndcapTrackerRawHitsWithNoise"}, - {"SiEndcapTrackerRecHits"}, {}, // default config - app, hit_level)); - + } + + // Convert raw digitized hits into hits with geometry info (ready for tracking) + app->Add(new JOmniFactoryGeneratorT( + "SiEndcapTrackerRecHits", + {split_timeframes ? "SiEndcapTrackerRawHits" : "SiEndcapTrackerRawHitsWithNoise"}, + {"SiEndcapTrackerRecHits"}, {}, // default config + app, hit_level)); } } // extern "C" From 6fcd19e07194d602cb72275dbd3a3750380a378b Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Tue, 11 Aug 2026 17:58:24 -0400 Subject: [PATCH 14/31] refactor: apply algorithm/factory way for hit time alignment module and move to meta --- src/algorithms/meta/RecHitTimeAlignment.h | 64 ++++++++++++++++ .../meta/RecHitTimeAlignmentConfig.h | 12 +++ .../meta/RecHitTimeAlignment_factory.h | 50 +++++++++++++ src/global/splitting/CalRecTimeAlignment.h | 21 ------ .../splitting/CalRecTimeAlignmentFactory.h | 74 ------------------- src/global/splitting/RecHitTimeAlignment.h | 62 ---------------- src/global/splitting/TrkTimeAlignment.h | 21 ------ .../splitting/TrkTimeAlignmentFactory.h | 70 ------------------ src/global/splitting/splitting.cc | 11 ++- 9 files changed, 133 insertions(+), 252 deletions(-) create mode 100644 src/algorithms/meta/RecHitTimeAlignment.h create mode 100644 src/algorithms/meta/RecHitTimeAlignmentConfig.h create mode 100644 src/factories/meta/RecHitTimeAlignment_factory.h delete mode 100644 src/global/splitting/CalRecTimeAlignment.h delete mode 100644 src/global/splitting/CalRecTimeAlignmentFactory.h delete mode 100644 src/global/splitting/RecHitTimeAlignment.h delete mode 100644 src/global/splitting/TrkTimeAlignment.h delete mode 100644 src/global/splitting/TrkTimeAlignmentFactory.h diff --git a/src/algorithms/meta/RecHitTimeAlignment.h b/src/algorithms/meta/RecHitTimeAlignment.h new file mode 100644 index 0000000000..259d631b32 --- /dev/null +++ b/src/algorithms/meta/RecHitTimeAlignment.h @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov + +#pragma once + +#include +#include +#include +#include + +#include + +#include "algorithms/interfaces/WithPodConfig.h" +#include "algorithms/meta/RecHitTimeAlignmentConfig.h" + +namespace eicrecon { + +template +using RecHitTimeAlignmentAlgorithm = + algorithms::Algorithm, + algorithms::Output>; + +template +class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm, + public WithPodConfig { +public: + using AlgorithmT = RecHitTimeAlignmentAlgorithm; + + explicit RecHitTimeAlignment(std::string_view name) + : AlgorithmT{name, + {"inputHits"}, + {"outputHits"}, + "Correct reconstructed hit times for propagation and sort by time."} {} + + void init() final {} + + void process(const typename AlgorithmT::Input& input, + const typename AlgorithmT::Output& output) const final { + const auto [hits_in] = input; + auto [hits_out] = output; + + std::vector sorted_hits; + sorted_hits.reserve(hits_in->size()); + for (const auto& hit : *hits_in) { + auto copied_hit = hit.clone(); + const auto position = hit.getPosition(); + const auto radius = std::sqrt(position[0] * position[0] + position[1] * position[1] + + position[2] * position[2]); + const auto average_time_of_flight = radius * this->m_cfg.reference_inverse_velocity; + copied_hit.setTime(hit.getTime() - average_time_of_flight); + sorted_hits.push_back(copied_hit); + } + + std::stable_sort(sorted_hits.begin(), sorted_hits.end(), [](const auto& lhs, const auto& rhs) { + return lhs.getTime() < rhs.getTime(); + }); + + for (const auto& hit : sorted_hits) { + hits_out->push_back(hit); + } + } +}; + +} // namespace eicrecon diff --git a/src/algorithms/meta/RecHitTimeAlignmentConfig.h b/src/algorithms/meta/RecHitTimeAlignmentConfig.h new file mode 100644 index 0000000000..b572e535ae --- /dev/null +++ b/src/algorithms/meta/RecHitTimeAlignmentConfig.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov + +#pragma once + +namespace eicrecon { + +struct RecHitTimeAlignmentConfig { + double reference_inverse_velocity = 0.0034; // ns/mm estimated by MC average time of flight / distance from IP to calorimeter +}; + +} // namespace eicrecon diff --git a/src/factories/meta/RecHitTimeAlignment_factory.h b/src/factories/meta/RecHitTimeAlignment_factory.h new file mode 100644 index 0000000000..ec7b9c5e1c --- /dev/null +++ b/src/factories/meta/RecHitTimeAlignment_factory.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov + +#pragma once + +#include +#include +#include + +#include "algorithms/meta/RecHitTimeAlignment.h" +#include "extensions/jana/JOmniFactory.h" + +namespace eicrecon { + +template +class RecHitTimeAlignment_factory + : public JOmniFactory, RecHitTimeAlignmentConfig> { +public: + using FactoryT = + JOmniFactory, RecHitTimeAlignmentConfig>; + using AlgoT = RecHitTimeAlignment; + +private: + std::unique_ptr m_algo; + + typename FactoryT::template VariadicPodioInput m_hits_in{this}; + typename FactoryT::template VariadicPodioOutput m_hits_out{this}; + + typename FactoryT::template ParameterRef m_reference_inverse_velocity{ + this, "referenceInverseVelocity", this->config().reference_inverse_velocity}; + +public: + void Configure() { + m_algo = std::make_unique(this->GetPrefix()); + m_algo->level(static_cast(this->logger()->level())); + m_algo->applyConfig(this->config()); + m_algo->init(); + } + + void Process(int32_t /* run_number */, uint64_t /* event_number */) { + for (std::size_t index = 0; index < m_hits_in().size(); ++index) { + const auto* hits_in = m_hits_in().at(index); + if (hits_in != nullptr) { + m_algo->process({hits_in}, {m_hits_out().at(index).get()}); + } + } + } +}; + +} // namespace eicrecon diff --git a/src/global/splitting/CalRecTimeAlignment.h b/src/global/splitting/CalRecTimeAlignment.h deleted file mode 100644 index 8d88133c71..0000000000 --- a/src/global/splitting/CalRecTimeAlignment.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov - -#pragma once - -#include -#include - -#include "RecHitTimeAlignment.h" - -namespace eicrecon { - -class CalRecTimeAlignment : public RecHitTimeAlignment { -public: - CalRecTimeAlignment(std::string_view name) - : RecHitTimeAlignment{name, "inputCalorimeterHits", "outputCalorimeterHits", - "Align reconstructed calorimeter hit times."} {} -}; - -} // namespace eicrecon diff --git a/src/global/splitting/CalRecTimeAlignmentFactory.h b/src/global/splitting/CalRecTimeAlignmentFactory.h deleted file mode 100644 index 405b6a7ca9..0000000000 --- a/src/global/splitting/CalRecTimeAlignmentFactory.h +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov - -#pragma once - -#include -#include -#include - -#include -#include - -#include "CalRecTimeAlignment.h" - -struct CalRecTimeAlignmentFactory : public JOmniFactory { - using AlgoT = eicrecon::CalRecTimeAlignment; - - JEventLevel m_factory_level; - - std::unique_ptr m_algo; - - std::vector m_simcalorechit_collection_names = {"B0ECalRecHits", - "EcalBarrelImagingRecHits", - "EcalBarrelScFiRecHits", - "EcalEndcapNRecHits", - "EcalEndcapPRecHits", - "EcalFarForwardZDCRecHits", - "EcalLumiSpecRecHits", - "HcalBarrelRecHits", - "HcalEndcapNRecHits", - "HcalEndcapPInsertRecHits", - "HcalFarForwardZDCRecHits", - "LFHCALRecHits"}; - - std::vector m_simcalorechit_collection_names_aligned = { - "B0ECalRecHits_aligned", - "EcalBarrelImagingRecHits_aligned", - "EcalBarrelScFiRecHits_aligned", - "EcalEndcapNRecHits_aligned", - "EcalEndcapPRecHits_aligned", - "EcalFarForwardZDCRecHits_aligned", - "EcalLumiSpecRecHits_aligned", - "HcalBarrelRecHits_aligned", - "HcalEndcapNRecHits_aligned", - "HcalEndcapPInsertRecHits_aligned", - "HcalFarForwardZDCRecHits_aligned", - "LFHCALRecHits_aligned"}; - - VariadicPodioInput m_calorechit_in{ - this, m_simcalorechit_collection_names}; - - VariadicPodioOutput m_calorechit_out{ - this, m_simcalorechit_collection_names_aligned}; - - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int32_t /*run_nr*/) override {} - - void Process(int32_t /*run_number*/, uint64_t /*event_number*/) override { - - for (size_t coll_index = 0; coll_index < m_calorechit_in().size(); ++coll_index) { - const auto* coll_in = m_calorechit_in().at(coll_index); - auto& coll_out = m_calorechit_out().at(coll_index); - - if (coll_in != nullptr) { - m_algo->process({coll_in}, {coll_out.get()}); - } - } - } -}; diff --git a/src/global/splitting/RecHitTimeAlignment.h b/src/global/splitting/RecHitTimeAlignment.h deleted file mode 100644 index 2937a18bd1..0000000000 --- a/src/global/splitting/RecHitTimeAlignment.h +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include - -namespace eicrecon { - -template -using RecHitTimeAlignmentAlgorithm = - algorithms::Algorithm, algorithms::Output>; - -template -class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm { -public: - using AlgorithmT = RecHitTimeAlignmentAlgorithm; - - RecHitTimeAlignment(std::string_view name, std::string input_name, std::string output_name, - std::string description) - : AlgorithmT{ - name, {std::move(input_name)}, {std::move(output_name)}, std::move(description)} {} - - void init() final {} - - void process(const typename AlgorithmT::Input& input, - const typename AlgorithmT::Output& output) const final { - const auto [hits_in] = input; - auto [hits_out] = output; - - std::vector sorted_hits; - sorted_hits.reserve(hits_in->size()); - for (const auto& hit : *hits_in) { - MutableHitT copied_hit = hit.clone(); - const auto position = hit.getPosition(); - const auto hit_r = std::sqrt(position[0] * position[0] + position[1] * position[1] + - position[2] * position[2]); - const auto calibrated_time = hit_r * m_refInverseVelocity; - copied_hit.setTime(hit.getTime() - calibrated_time); - sorted_hits.push_back(copied_hit); - } - - std::sort(sorted_hits.begin(), sorted_hits.end(), - [](const auto& lhs, const auto& rhs) { return lhs.getTime() < rhs.getTime(); }); - - for (const auto& hit : sorted_hits) { - hits_out->push_back(hit); - } - } - -private: - double m_refInverseVelocity = 0.0034; // ns/mm -}; - -} // namespace eicrecon diff --git a/src/global/splitting/TrkTimeAlignment.h b/src/global/splitting/TrkTimeAlignment.h deleted file mode 100644 index fb1b889d1c..0000000000 --- a/src/global/splitting/TrkTimeAlignment.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov - -#pragma once - -#include -#include - -#include "RecHitTimeAlignment.h" - -namespace eicrecon { - -class TrkTimeAlignment - : public RecHitTimeAlignment { -public: - TrkTimeAlignment(std::string_view name) - : RecHitTimeAlignment{name, "inputTrackerHits", "outputTrackerHits", - "Align reconstructed tracker hit times."} {} -}; - -} // namespace eicrecon diff --git a/src/global/splitting/TrkTimeAlignmentFactory.h b/src/global/splitting/TrkTimeAlignmentFactory.h deleted file mode 100644 index b0a222e006..0000000000 --- a/src/global/splitting/TrkTimeAlignmentFactory.h +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov - -#pragma once - -#include -#include -#include - -#include -#include - -#include "TrkTimeAlignment.h" - -struct TrkTimeAlignmentFactory : public JOmniFactory { - using AlgoT = eicrecon::TrkTimeAlignment; - - JEventLevel m_factory_level; - - std::unique_ptr m_algo; - - std::vector m_trackerhit_collection_names = { - "TOFBarrelRecHits", "TOFEndcapRecHits", "MPGDBarrelRecHits", - "OuterMPGDBarrelRecHits", "BackwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits", - "SiBarrelVertexRecHits", "SiBarrelTrackerRecHits", "SiEndcapTrackerRecHits", - "B0TrackerRecHits", "TaggerTrackerRecHits", "ForwardRomanPotRecHits", - "ForwardOffMTrackerRecHits"}; - - // "DRICHRecHits" - // "DIRCBarRecHits", - // "RICHEndcapNRecHits_TK" // PFRICH - - std::vector m_trackerhit_collection_names_aligned = { - "TOFBarrelRecHits_aligned", "TOFEndcapRecHits_aligned", - "MPGDBarrelRecHits_aligned", "OuterMPGDBarrelRecHits_aligned", - "BackwardMPGDEndcapRecHits_aligned", "ForwardMPGDEndcapRecHits_aligned", - "SiBarrelVertexRecHits_aligned", "SiBarrelTrackerRecHits_aligned", - "SiEndcapTrackerRecHits_aligned", "B0TrackerRecHits_aligned", - "TaggerTrackerRecHits_aligned", "ForwardRomanPotRecHits_aligned", - "ForwardOffMTrackerRecHits_aligned"}; - - // "DRICHRecHits_aligned" - // "DIRCBarRecHits_aligned", - // "RICHEndcapNRecHits_TK_aligned" // PFRICH - - VariadicPodioInput m_trackerhits_in{this, - m_trackerhit_collection_names}; - - VariadicPodioOutput m_trackerhits_out{this, - m_trackerhit_collection_names_aligned}; - - void Configure() { - m_algo = std::make_unique(GetPrefix()); - m_algo->level(static_cast(logger()->level())); - m_algo->init(); - } - - void ChangeRun(int32_t /*run_nr*/) override {} - - void Process(int32_t /*run_number*/, uint64_t /*event_number*/) override { - for (size_t coll_index = 0; coll_index < m_trackerhits_in().size(); ++coll_index) { - const auto* coll_in = m_trackerhits_in().at(coll_index); - auto& coll_out = m_trackerhits_out().at(coll_index); - - if (coll_in != nullptr) { - m_algo->process({coll_in}, {coll_out.get()}); - } - } - } -}; diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index 32116c0fce..ef305f1c75 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -5,13 +5,14 @@ #include #include #include +#include +#include #include #include -#include "CalRecTimeAlignmentFactory.h" #include "TimeframeSplitter.h" -#include "TrkTimeAlignmentFactory.h" #include "extensions/jana/JOmniFactoryGeneratorT.h" +#include "factories/meta/RecHitTimeAlignment_factory.h" extern "C" { void InitPlugin(JApplication* app) { @@ -67,11 +68,13 @@ void InitPlugin(JApplication* app) { return; } - app->Add(new JOmniFactoryGeneratorT( + app->Add(new JOmniFactoryGeneratorT< + eicrecon::RecHitTimeAlignment_factory>( "timeAlignment", m_simtrackerhit_collection_names, m_simtrackerhit_collection_names_aligned, app, JEventLevel::Timeslice)); - app->Add(new JOmniFactoryGeneratorT( + app->Add(new JOmniFactoryGeneratorT< + eicrecon::RecHitTimeAlignment_factory>( "CalRecTimeAlignment", m_simcalorechit_collection_names, m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); From 610d2fa7dc2c26dae111bc86e29754aa18c8c07c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:06:05 +0000 Subject: [PATCH 15/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/algorithms/meta/RecHitTimeAlignment.h | 12 ++++++------ src/algorithms/meta/RecHitTimeAlignmentConfig.h | 3 ++- src/factories/meta/RecHitTimeAlignment_factory.h | 3 +-- src/global/splitting/splitting.cc | 11 +++++------ 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/algorithms/meta/RecHitTimeAlignment.h b/src/algorithms/meta/RecHitTimeAlignment.h index 259d631b32..8b49e49760 100644 --- a/src/algorithms/meta/RecHitTimeAlignment.h +++ b/src/algorithms/meta/RecHitTimeAlignment.h @@ -42,18 +42,18 @@ class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm, std::vector sorted_hits; sorted_hits.reserve(hits_in->size()); for (const auto& hit : *hits_in) { - auto copied_hit = hit.clone(); - const auto position = hit.getPosition(); - const auto radius = std::sqrt(position[0] * position[0] + position[1] * position[1] + - position[2] * position[2]); + auto copied_hit = hit.clone(); + const auto position = hit.getPosition(); + const auto radius = std::sqrt(position[0] * position[0] + position[1] * position[1] + + position[2] * position[2]); const auto average_time_of_flight = radius * this->m_cfg.reference_inverse_velocity; copied_hit.setTime(hit.getTime() - average_time_of_flight); sorted_hits.push_back(copied_hit); } std::stable_sort(sorted_hits.begin(), sorted_hits.end(), [](const auto& lhs, const auto& rhs) { - return lhs.getTime() < rhs.getTime(); - }); + return lhs.getTime() < rhs.getTime(); + }); for (const auto& hit : sorted_hits) { hits_out->push_back(hit); diff --git a/src/algorithms/meta/RecHitTimeAlignmentConfig.h b/src/algorithms/meta/RecHitTimeAlignmentConfig.h index b572e535ae..7bfc68cb29 100644 --- a/src/algorithms/meta/RecHitTimeAlignmentConfig.h +++ b/src/algorithms/meta/RecHitTimeAlignmentConfig.h @@ -6,7 +6,8 @@ namespace eicrecon { struct RecHitTimeAlignmentConfig { - double reference_inverse_velocity = 0.0034; // ns/mm estimated by MC average time of flight / distance from IP to calorimeter + double reference_inverse_velocity = + 0.0034; // ns/mm estimated by MC average time of flight / distance from IP to calorimeter }; } // namespace eicrecon diff --git a/src/factories/meta/RecHitTimeAlignment_factory.h b/src/factories/meta/RecHitTimeAlignment_factory.h index ec7b9c5e1c..9f16da6604 100644 --- a/src/factories/meta/RecHitTimeAlignment_factory.h +++ b/src/factories/meta/RecHitTimeAlignment_factory.h @@ -16,8 +16,7 @@ template class RecHitTimeAlignment_factory : public JOmniFactory, RecHitTimeAlignmentConfig> { public: - using FactoryT = - JOmniFactory, RecHitTimeAlignmentConfig>; + using FactoryT = JOmniFactory, RecHitTimeAlignmentConfig>; using AlgoT = RecHitTimeAlignment; private: diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index ef305f1c75..9f1a7a2c38 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -68,15 +68,14 @@ void InitPlugin(JApplication* app) { return; } - app->Add(new JOmniFactoryGeneratorT< - eicrecon::RecHitTimeAlignment_factory>( + app->Add(new JOmniFactoryGeneratorT>( "timeAlignment", m_simtrackerhit_collection_names, m_simtrackerhit_collection_names_aligned, app, JEventLevel::Timeslice)); - app->Add(new JOmniFactoryGeneratorT< - eicrecon::RecHitTimeAlignment_factory>( - "CalRecTimeAlignment", m_simcalorechit_collection_names, - m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); + app->Add( + new JOmniFactoryGeneratorT>( + "CalRecTimeAlignment", m_simcalorechit_collection_names, + m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); From c1f5fc75c9568acaa4178d00b91a5b4c5569615b Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Wed, 12 Aug 2026 13:13:15 -0500 Subject: [PATCH 16/31] fix: skip splitting plugin on JANA2 < 2026 Co-authored-by: Wouter Deconinck --- src/global/CMakeLists.txt | 4 +++- src/utilities/eicrecon/eicrecon.cc | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/global/CMakeLists.txt b/src/global/CMakeLists.txt index 4c75d68823..81dc003eca 100644 --- a/src/global/CMakeLists.txt +++ b/src/global/CMakeLists.txt @@ -4,4 +4,6 @@ add_subdirectory(particle_flow) add_subdirectory(pid) add_subdirectory(pid_lut) add_subdirectory(beam) -add_subdirectory(splitting) +if(JANA_VERSION VERSION_GREATER_EQUAL "2026.01.00") + add_subdirectory(splitting) +endif() diff --git a/src/utilities/eicrecon/eicrecon.cc b/src/utilities/eicrecon/eicrecon.cc index 3762a1e259..05320613de 100644 --- a/src/utilities/eicrecon/eicrecon.cc +++ b/src/utilities/eicrecon/eicrecon.cc @@ -50,7 +50,9 @@ std::vector EICRECON_DEFAULT_PLUGINS = { "ECTOF", "LOWQ2", "LUMISPECCAL", +#if defined(JANA_VERSION_MAJOR) && JANA_VERSION_MAJOR >= 2026 "splitting", +#endif "podio", "janatop", // clang-format on From a5fd2752a6fac79918bea2ff99c1f484fb2745b5 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Wed, 12 Aug 2026 13:44:09 -0500 Subject: [PATCH 17/31] fix(ci): change minq2 value 1000 => 100 --- .github/workflows/linux-eic-shell.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index f05f7aad2a..f6be77d9f6 100644 --- a/.github/workflows/linux-eic-shell.yml +++ b/.github/workflows/linux-eic-shell.yml @@ -1331,13 +1331,13 @@ jobs: include: - CXX: clang++ beam: 10x100 - minq2: 1000 + minq2: 100 detector_config: craterlake_tracking_only sanitizer: ASAN - CXX: clang++ beam: 10x100 - minq2: 1000 + minq2: 100 detector_config: craterlake_tracking_only sanitizer: TSAN nthreads: 4 From 4e373f9af086e3dbdb5c612b287d9fbc4f2589ed Mon Sep 17 00:00:00 2001 From: epic-capybara <139920704+epic-capybara@users.noreply.github.com> Date: Wed, 12 Aug 2026 15:26:51 -0400 Subject: [PATCH 18/31] Add timeframe splitting framework to EICrecon (fix: iwyu) (#2864) This PR applies the include-what-you-use fixes as suggested by https://github.com/eic/EICrecon/actions/runs/31629141021. Please merge this PR into the branch `timeframe_splitting_dev` to resolve failures in PR #2824. Auto-generated by [create-pull-request][1] [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/global/splitting/splitting.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index 9f1a7a2c38..d506328420 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -6,7 +6,10 @@ #include #include #include +#include +#include #include +#include #include #include From 8c5ca6ed8bd815e5cca8d184487ef76279b6f78c Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Wed, 12 Aug 2026 14:34:02 -0500 Subject: [PATCH 19/31] fix(ci): switch to 18x275 with full geometry (incl. calorimetry) --- .github/workflows/linux-eic-shell.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index f6be77d9f6..4bf38fabe4 100644 --- a/.github/workflows/linux-eic-shell.yml +++ b/.github/workflows/linux-eic-shell.yml @@ -1330,15 +1330,15 @@ jobs: matrix: include: - CXX: clang++ - beam: 10x100 + beam: 18x275 minq2: 100 - detector_config: craterlake_tracking_only + detector_config: craterlake_18x275 sanitizer: ASAN - CXX: clang++ - beam: 10x100 + beam: 18x275 minq2: 100 - detector_config: craterlake_tracking_only + detector_config: craterlake_18x275 sanitizer: TSAN nthreads: 4 From e2695c75067be58cd4dde63ceb3bbc55466dbcf4 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Wed, 12 Aug 2026 16:06:46 -0400 Subject: [PATCH 20/31] fix: update timeframe splitting CI and PODIO handling --- .github/workflows/linux-eic-shell.yml | 2 ++ src/global/splitting/splitting.cc | 3 ++- src/services/io/podio/JEventProcessorPODIO.cc | 12 +----------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index 4bf38fabe4..a5e645c72e 100644 --- a/.github/workflows/linux-eic-shell.yml +++ b/.github/workflows/linux-eic-shell.yml @@ -1326,6 +1326,7 @@ jobs: needs: - build - npsim-dis + - npsim-minbias strategy: matrix: include: @@ -1339,6 +1340,7 @@ jobs: beam: 18x275 minq2: 100 detector_config: craterlake_18x275 + sanitizer: TSAN nthreads: 4 diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index d506328420..b73f2c6364 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -1,3 +1,4 @@ + // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov @@ -83,4 +84,4 @@ void InitPlugin(JApplication* app) { // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); } -} // "C" +} // "C" \ No newline at end of file diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index 95f23142a2..ed7aa0acb2 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -526,17 +526,7 @@ JEventProcessorPODIO::JEventProcessorPODIO() { "EventHeader_BKG", }; - // TimeframeSplitter rebuilds these relation targets in each child PhysicsEvent. Persist - // them together with the default RawHit associations and links so no relation points back - // into the parent Timeslice frame. - if (japp->GetParameterValue("split_timeframes")) { - output_collections.insert( - output_collections.end(), - {"TOFBarrelRecHits", "TOFEndcapRecHits", "TOFBarrelRawHits", "TOFEndcapRawHits", - "B0ECalHits", "EcalBarrelImagingHits", "EcalBarrelScFiHits", "EcalEndcapNHits", - "EcalEndcapPHits", "EcalFarForwardZDCHits", "EcalLumiSpecHits", "HcalBarrelHits", - "HcalEndcapNHits", "HcalEndcapPInsertHits", "HcalFarForwardZDCHits", "LFHCALHits"}); - } + std::vector output_exclude_collections; // need to get as vector, then convert to set japp->SetDefaultParameter( From 72a824592686c7dbe5422736a2032aad8d392d51 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Thu, 13 Aug 2026 01:00:26 -0400 Subject: [PATCH 21/31] refactor: move hit time alignment to event building --- src/algorithms/CMakeLists.txt | 1 + src/algorithms/event_building/CMakeLists.txt | 8 ++++++++ .../HitTimeAlignment.h} | 14 +++++++------- .../event_building/HitTimeAlignmentConfig.h | 13 +++++++++++++ src/algorithms/meta/RecHitTimeAlignmentConfig.h | 13 ------------- src/factories/CMakeLists.txt | 1 + src/factories/event_building/CMakeLists.txt | 2 ++ .../HitTimeAlignment_factory.h} | 12 ++++++------ src/global/splitting/TimeframeSplitter.cc | 2 +- src/global/splitting/TimeframeSplitter.h | 2 +- src/global/splitting/splitting.cc | 8 ++++---- 11 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 src/algorithms/event_building/CMakeLists.txt rename src/algorithms/{meta/RecHitTimeAlignment.h => event_building/HitTimeAlignment.h} (80%) create mode 100644 src/algorithms/event_building/HitTimeAlignmentConfig.h delete mode 100644 src/algorithms/meta/RecHitTimeAlignmentConfig.h create mode 100644 src/factories/event_building/CMakeLists.txt rename src/factories/{meta/RecHitTimeAlignment_factory.h => event_building/HitTimeAlignment_factory.h} (74%) diff --git a/src/algorithms/CMakeLists.txt b/src/algorithms/CMakeLists.txt index 385bf4ff5c..50a1b4ca67 100644 --- a/src/algorithms/CMakeLists.txt +++ b/src/algorithms/CMakeLists.txt @@ -9,3 +9,4 @@ add_subdirectory(digi) add_subdirectory(reco) add_subdirectory(fardetectors) add_subdirectory(onnx) +add_subdirectory(event_building) diff --git a/src/algorithms/event_building/CMakeLists.txt b/src/algorithms/event_building/CMakeLists.txt new file mode 100644 index 0000000000..3b5ca91e53 --- /dev/null +++ b/src/algorithms/event_building/CMakeLists.txt @@ -0,0 +1,8 @@ +set(PLUGIN_NAME "algorithms_event_building") + +# Function creates ${PLUGIN_NAME}_plugin and ${PLUGIN_NAME}_library targets +# Setting default includes, libraries and installation paths +plugin_headers_only(${PLUGIN_NAME}) + +# Find dependencies +plugin_add_algorithms(${PLUGIN_NAME}) diff --git a/src/algorithms/meta/RecHitTimeAlignment.h b/src/algorithms/event_building/HitTimeAlignment.h similarity index 80% rename from src/algorithms/meta/RecHitTimeAlignment.h rename to src/algorithms/event_building/HitTimeAlignment.h index 8b49e49760..0d902a9f4d 100644 --- a/src/algorithms/meta/RecHitTimeAlignment.h +++ b/src/algorithms/event_building/HitTimeAlignment.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov +// Copyright (C) 2026 Takuya Kumaoka #pragma once @@ -11,22 +11,22 @@ #include #include "algorithms/interfaces/WithPodConfig.h" -#include "algorithms/meta/RecHitTimeAlignmentConfig.h" +#include "algorithms/event_building/HitTimeAlignmentConfig.h" namespace eicrecon { template -using RecHitTimeAlignmentAlgorithm = +using HitTimeAlignmentAlgorithm = algorithms::Algorithm, algorithms::Output>; template -class RecHitTimeAlignment : public RecHitTimeAlignmentAlgorithm, - public WithPodConfig { +class HitTimeAlignment : public HitTimeAlignmentAlgorithm, + public WithPodConfig { public: - using AlgorithmT = RecHitTimeAlignmentAlgorithm; + using AlgorithmT = HitTimeAlignmentAlgorithm; - explicit RecHitTimeAlignment(std::string_view name) + explicit HitTimeAlignment(std::string_view name) : AlgorithmT{name, {"inputHits"}, {"outputHits"}, diff --git a/src/algorithms/event_building/HitTimeAlignmentConfig.h b/src/algorithms/event_building/HitTimeAlignmentConfig.h new file mode 100644 index 0000000000..1651823edc --- /dev/null +++ b/src/algorithms/event_building/HitTimeAlignmentConfig.h @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2026 Takuya Kumaoka + +#pragma once + +namespace eicrecon { + +struct HitTimeAlignmentConfig { + double reference_inverse_velocity = + 0.0034; //< ns/mm estimated by MC average time of flight / distance from IP to calorimeter +}; + +} // namespace eicrecon diff --git a/src/algorithms/meta/RecHitTimeAlignmentConfig.h b/src/algorithms/meta/RecHitTimeAlignmentConfig.h deleted file mode 100644 index 7bfc68cb29..0000000000 --- a/src/algorithms/meta/RecHitTimeAlignmentConfig.h +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov - -#pragma once - -namespace eicrecon { - -struct RecHitTimeAlignmentConfig { - double reference_inverse_velocity = - 0.0034; // ns/mm estimated by MC average time of flight / distance from IP to calorimeter -}; - -} // namespace eicrecon diff --git a/src/factories/CMakeLists.txt b/src/factories/CMakeLists.txt index e040c9fc1b..735817816e 100644 --- a/src/factories/CMakeLists.txt +++ b/src/factories/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(pid) add_subdirectory(pid_lut) add_subdirectory(reco) add_subdirectory(tracking) +add_subdirectory(event_building) diff --git a/src/factories/event_building/CMakeLists.txt b/src/factories/event_building/CMakeLists.txt new file mode 100644 index 0000000000..c19f19b48a --- /dev/null +++ b/src/factories/event_building/CMakeLists.txt @@ -0,0 +1,2 @@ +set(PLUGIN_NAME "factories_event_building") +plugin_headers_only(${PLUGIN_NAME}) diff --git a/src/factories/meta/RecHitTimeAlignment_factory.h b/src/factories/event_building/HitTimeAlignment_factory.h similarity index 74% rename from src/factories/meta/RecHitTimeAlignment_factory.h rename to src/factories/event_building/HitTimeAlignment_factory.h index 9f16da6604..becde02d93 100644 --- a/src/factories/meta/RecHitTimeAlignment_factory.h +++ b/src/factories/event_building/HitTimeAlignment_factory.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov +// codCopyright (C) 2026 Takuya Kumaoka #pragma once @@ -7,17 +7,17 @@ #include #include -#include "algorithms/meta/RecHitTimeAlignment.h" +#include "algorithms/event_building/HitTimeAlignment.h" #include "extensions/jana/JOmniFactory.h" namespace eicrecon { template -class RecHitTimeAlignment_factory - : public JOmniFactory, RecHitTimeAlignmentConfig> { +class HitTimeAlignment_factory + : public JOmniFactory, HitTimeAlignmentConfig> { public: - using FactoryT = JOmniFactory, RecHitTimeAlignmentConfig>; - using AlgoT = RecHitTimeAlignment; + using FactoryT = JOmniFactory, HitTimeAlignmentConfig>; + using AlgoT = HitTimeAlignment; private: std::unique_ptr m_algo; diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index be66ac6c69..51280828ad 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov +// Copyright (C) 2026 Takuya Kumaoka #include "TimeframeSplitter.h" diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index a23ed98bc3..a8cfb9b1a9 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov +// Copyright (C) 2026 Takuya Kumaoka #pragma once diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index b73f2c6364..fc6111964e 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -1,6 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 - 2024 Whitney Armstrong, Wouter Deconinck, Dmitry Romanov +// Copyright (C) 2026 Takuya Kumaoka #include #include @@ -16,7 +16,7 @@ #include "TimeframeSplitter.h" #include "extensions/jana/JOmniFactoryGeneratorT.h" -#include "factories/meta/RecHitTimeAlignment_factory.h" +#include "factories/event_building/HitTimeAlignment_factory.h" extern "C" { void InitPlugin(JApplication* app) { @@ -72,12 +72,12 @@ void InitPlugin(JApplication* app) { return; } - app->Add(new JOmniFactoryGeneratorT>( + app->Add(new JOmniFactoryGeneratorT>( "timeAlignment", m_simtrackerhit_collection_names, m_simtrackerhit_collection_names_aligned, app, JEventLevel::Timeslice)); app->Add( - new JOmniFactoryGeneratorT>( + new JOmniFactoryGeneratorT>( "CalRecTimeAlignment", m_simcalorechit_collection_names, m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); From a8ecb29b17b8466c116666318c9bba2072976ffd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 20:09:34 +0000 Subject: [PATCH 22/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/global/splitting/splitting.cc | 2 +- src/services/io/podio/JEventProcessorPODIO.cc | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index fc6111964e..b64e8901f8 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -84,4 +84,4 @@ void InitPlugin(JApplication* app) { // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); } -} // "C" \ No newline at end of file +} // "C" diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index c0239c373c..42507b81e7 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -523,8 +523,6 @@ JEventProcessorPODIO::JEventProcessorPODIO() { "EventHeader_BKG", }; - - std::vector output_exclude_collections; // need to get as vector, then convert to set japp->SetDefaultParameter( "podio:output_collections", output_collections, From 04428f00a78e10d496d1be478a6712be563ee0b2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 13 Aug 2026 05:03:17 +0000 Subject: [PATCH 23/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/algorithms/event_building/HitTimeAlignment.h | 2 +- src/global/splitting/splitting.cc | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/algorithms/event_building/HitTimeAlignment.h b/src/algorithms/event_building/HitTimeAlignment.h index 0d902a9f4d..191544e03d 100644 --- a/src/algorithms/event_building/HitTimeAlignment.h +++ b/src/algorithms/event_building/HitTimeAlignment.h @@ -22,7 +22,7 @@ using HitTimeAlignmentAlgorithm = template class HitTimeAlignment : public HitTimeAlignmentAlgorithm, - public WithPodConfig { + public WithPodConfig { public: using AlgorithmT = HitTimeAlignmentAlgorithm; diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index b64e8901f8..085e028f19 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -76,10 +76,9 @@ void InitPlugin(JApplication* app) { "timeAlignment", m_simtrackerhit_collection_names, m_simtrackerhit_collection_names_aligned, app, JEventLevel::Timeslice)); - app->Add( - new JOmniFactoryGeneratorT>( - "CalRecTimeAlignment", m_simcalorechit_collection_names, - m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); + app->Add(new JOmniFactoryGeneratorT>( + "CalRecTimeAlignment", m_simcalorechit_collection_names, + m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); From 67292c39f96e6772f6efd9f6738356c97a188cdf Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Thu, 13 Aug 2026 01:55:18 -0400 Subject: [PATCH 24/31] Clarify timeframe scan loop termination --- src/global/splitting/TimeframeSplitter.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 51280828ad..fede8885e2 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -249,9 +249,22 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent Bool_t bMutipliTriggers[6] = {false, false, false, false, false, false}; Double_t multipliTrigTime[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - Double_t tsTimeS = iTimeSlice * m_timesplit_width; - Double_t tsTimeE = (iTimeSlice + 1) * m_timesplit_width; - while (1) { + if (m_timesplit_width <= 0.0F) { + throw std::runtime_error("TimeframeSplitter: timesplit_width must be greater than zero"); + } + if (m_timeframe_width <= 0.0F) { + throw std::runtime_error("TimeframeSplitter: timeframe_width must be greater than zero"); + } + const size_t nTimeSlices = \ + static_cast(std::floor(m_timeframe_width / m_timesplit_width)); + + + Double_t tsTimeS = 0.0; + Double_t tsTimeE = 0.0; + // Scan the timeframe one time slice at a time. + // The scan stops early when a physics trigger fires; otherwise it terminates + // after all time slices in the timeframe have been processed. + while (iTimeSlice < nTimeSlices) { tsTimeS = iTimeSlice * m_timesplit_width; tsTimeE = (iTimeSlice + 1) * m_timesplit_width; if (tsTimeE > m_timeframe_width) @@ -625,7 +638,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><>> } - if (tsTimeE > m_timeframe_width) + if (iTimeSlice >= nTimeSlices) m_bScanedAllTimeWindows = true; if (m_bScanedAllTimeWindows) { bInitialLoop = true; From 9bdd943802e49e76201ba67d671837a8147c954d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 13 Aug 2026 05:56:08 +0000 Subject: [PATCH 25/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/global/splitting/TimeframeSplitter.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index fede8885e2..17b9357267 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -255,10 +255,8 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent if (m_timeframe_width <= 0.0F) { throw std::runtime_error("TimeframeSplitter: timeframe_width must be greater than zero"); } - const size_t nTimeSlices = \ - static_cast(std::floor(m_timeframe_width / m_timesplit_width)); + const size_t nTimeSlices = static_cast(std::floor(m_timeframe_width / m_timesplit_width)); - Double_t tsTimeS = 0.0; Double_t tsTimeE = 0.0; // Scan the timeframe one time slice at a time. From 9d381523152329042318eb91e71f7ca016d458d0 Mon Sep 17 00:00:00 2001 From: epic-capybara <139920704+epic-capybara@users.noreply.github.com> Date: Thu, 13 Aug 2026 15:08:30 -0400 Subject: [PATCH 26/31] Add timeframe splitting framework to EICrecon (fix: iwyu) (#2868) This PR applies the include-what-you-use fixes as suggested by https://github.com/eic/EICrecon/actions/runs/31672030046. Please merge this PR into the branch `timeframe_splitting_dev` to resolve failures in PR #2824. Auto-generated by [create-pull-request][1] [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/global/splitting/TimeframeSplitter.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 17b9357267..1af4d387b5 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -9,6 +9,7 @@ #include #include #include +#include TimeframeSplitter::TimeframeSplitter() { SetTypeName(NAME_OF_THIS); From 9427b86a71c45b8859f1c345ad854cb9c0faf4c5 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Fri, 14 Aug 2026 00:36:31 -0400 Subject: [PATCH 27/31] Refactor based on PR comments --- .../event_building/HitTimeAlignment.h | 16 +- .../event_building/HitTimeAlignmentConfig.h | 2 +- .../event_building/HitTimeAlignment_factory.h | 23 +- src/global/splitting/TimeframeSplitter.cc | 412 +++++----- src/global/splitting/TimeframeSplitter.h | 735 ++++++++++-------- src/global/splitting/splitting.cc | 95 +-- 6 files changed, 655 insertions(+), 628 deletions(-) diff --git a/src/algorithms/event_building/HitTimeAlignment.h b/src/algorithms/event_building/HitTimeAlignment.h index 191544e03d..9f292eb346 100644 --- a/src/algorithms/event_building/HitTimeAlignment.h +++ b/src/algorithms/event_building/HitTimeAlignment.h @@ -39,23 +39,23 @@ class HitTimeAlignment : public HitTimeAlignmentAlgorithm, const auto [hits_in] = input; auto [hits_out] = output; - std::vector sorted_hits; - sorted_hits.reserve(hits_in->size()); + std::vector sortedHits; + sortedHits.reserve(hits_in->size()); for (const auto& hit : *hits_in) { - auto copied_hit = hit.clone(); + auto copiedHit = hit.clone(); const auto position = hit.getPosition(); const auto radius = std::sqrt(position[0] * position[0] + position[1] * position[1] + position[2] * position[2]); - const auto average_time_of_flight = radius * this->m_cfg.reference_inverse_velocity; - copied_hit.setTime(hit.getTime() - average_time_of_flight); - sorted_hits.push_back(copied_hit); + const auto aveTimeOfFlight = radius * this->m_cfg.refInverseVelocity; + copiedHit.setTime(hit.getTime() - aveTimeOfFlight); + sortedHits.push_back(copiedHit); } - std::stable_sort(sorted_hits.begin(), sorted_hits.end(), [](const auto& lhs, const auto& rhs) { + std::stable_sort(sortedHits.begin(), sortedHits.end(), [](const auto& lhs, const auto& rhs) { return lhs.getTime() < rhs.getTime(); }); - for (const auto& hit : sorted_hits) { + for (const auto& hit : sortedHits) { hits_out->push_back(hit); } } diff --git a/src/algorithms/event_building/HitTimeAlignmentConfig.h b/src/algorithms/event_building/HitTimeAlignmentConfig.h index 1651823edc..8fa85e9bde 100644 --- a/src/algorithms/event_building/HitTimeAlignmentConfig.h +++ b/src/algorithms/event_building/HitTimeAlignmentConfig.h @@ -6,7 +6,7 @@ namespace eicrecon { struct HitTimeAlignmentConfig { - double reference_inverse_velocity = + double refInverseVelocity = 0.0034; //< ns/mm estimated by MC average time of flight / distance from IP to calorimeter }; diff --git a/src/factories/event_building/HitTimeAlignment_factory.h b/src/factories/event_building/HitTimeAlignment_factory.h index becde02d93..06aadba312 100644 --- a/src/factories/event_building/HitTimeAlignment_factory.h +++ b/src/factories/event_building/HitTimeAlignment_factory.h @@ -1,10 +1,8 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -// codCopyright (C) 2026 Takuya Kumaoka +// Copyright (C) 2026 Takuya Kumaoka #pragma once -#include -#include #include #include "algorithms/event_building/HitTimeAlignment.h" @@ -22,11 +20,11 @@ class HitTimeAlignment_factory private: std::unique_ptr m_algo; - typename FactoryT::template VariadicPodioInput m_hits_in{this}; - typename FactoryT::template VariadicPodioOutput m_hits_out{this}; + typename FactoryT::template PodioInput m_hits_in{this}; + typename FactoryT::template PodioOutput m_hits_out{this}; - typename FactoryT::template ParameterRef m_reference_inverse_velocity{ - this, "referenceInverseVelocity", this->config().reference_inverse_velocity}; + typename FactoryT::template ParameterRef m_refInverseVelocity{ + this, "referenceInverseVelocity", this->config().refInverseVelocity}; public: void Configure() { @@ -37,13 +35,12 @@ class HitTimeAlignment_factory } void Process(int32_t /* run_number */, uint64_t /* event_number */) { - for (std::size_t index = 0; index < m_hits_in().size(); ++index) { - const auto* hits_in = m_hits_in().at(index); - if (hits_in != nullptr) { - m_algo->process({hits_in}, {m_hits_out().at(index).get()}); - } + const auto* hits_in = m_hits_in(); + + if (hits_in != nullptr) { + m_algo->process({hits_in}, {m_hits_out().get()}); } } }; -} // namespace eicrecon +} // namespace eicrecon \ No newline at end of file diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 1af4d387b5..7415f5ec99 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -6,10 +6,11 @@ #include #include #include -#include #include + #include #include +#include TimeframeSplitter::TimeframeSplitter() { SetTypeName(NAME_OF_THIS); @@ -17,12 +18,12 @@ TimeframeSplitter::TimeframeSplitter() { SetChildLevel(JEventLevel::PhysicsEvent); } -std::uint64_t TimeframeSplitter::object_id_key(const podio::ObjectID& object_id) { - const auto collection_id = - static_cast(static_cast(object_id.collectionID)); - const auto index = static_cast(static_cast(object_id.index)); +std::uint64_t TimeframeSplitter::objIdKey(const podio::ObjectID& objectID) { + const auto collectionID = + static_cast(static_cast(objectID.collectionID)); + const auto index = static_cast(static_cast(objectID.index)); - return (collection_id << 32U) | index; + return (collectionID << 32U) | index; } TimeframeSplitter::TrackerAssociationIndex TimeframeSplitter::buildTrkAssoId( @@ -35,10 +36,10 @@ TimeframeSplitter::TrackerAssociationIndex TimeframeSplitter::buildTrkAssoId( for (size_t assoId = 0; assoId < associations->size(); ++assoId) { const auto association = associations->at(assoId); - const auto raw_hit = association.getRawHit(); - if (!raw_hit.isAvailable()) + const auto rawHit = association.getRawHit(); + if (!rawHit.isAvailable()) continue; - index[object_id_key(raw_hit.getObjectID())].push_back(assoId); + index[objIdKey(rawHit.getObjectID())].push_back(assoId); } return index; @@ -54,57 +55,57 @@ TimeframeSplitter::CalorimeterAssociationIndex TimeframeSplitter::buildCalAssoId for (size_t assoId = 0; assoId < associations->size(); ++assoId) { const auto association = associations->at(assoId); - const auto raw_hit = association.getRawHit(); - if (!raw_hit.isAvailable()) + const auto rawHit = association.getRawHit(); + if (!rawHit.isAvailable()) continue; - index[object_id_key(raw_hit.getObjectID())].push_back(assoId); + index[objIdKey(rawHit.getObjectID())].push_back(assoId); } return index; } -bool TimeframeSplitter::overlaps_time_window(Double_t hitTime, Double_t resolution, - Double_t window_start, Double_t window_end) { +bool TimeframeSplitter::overlapsTimeWindow(double hitTime, double resolution, + double window_start, double window_end) { return hitTime + resolution > window_start && hitTime - resolution < window_end; } -bool TimeframeSplitter::is_after_time_window(Double_t hitTime, Double_t resolution, - Double_t window_end) { +bool TimeframeSplitter::judgeOverTimeWindow(double hitTime, double resolution, + double window_end) { return hitTime - resolution >= window_end; } -bool TimeframeSplitter::isValidEtaPhiBin(Int_t etaBin, Int_t phiBin) { +bool TimeframeSplitter::isValidEtaPhiBin(int etaBin, int phiBin) { return 0 <= etaBin && etaBin < kEtaPhiBins && 0 <= phiBin && phiBin < kEtaPhiBins; } -bool TimeframeSplitter::is_hit_in_time_slice(Double_t hitTime, Double_t time_resolution, - Double_t time_slice_start, Double_t time_slice_end) { - return !(hitTime + time_resolution < time_slice_start || - hitTime - time_resolution > time_slice_end); +bool TimeframeSplitter::judgeHitInTimeSlice(double hitTime, double timeResolution, + double timeslice_start, double timeslice_end) { + return !(hitTime + timeResolution < timeslice_start || + hitTime - timeResolution > timeslice_end); } -std::pair TimeframeSplitter::etaPhiBins(Double_t hitEta, Double_t hitPhi, - Double_t etaMin, Double_t etaMax, - Int_t bShift) { - const Double_t etaBinWidth = (etaMax - etaMin) / kEtaPhiBins; - const Double_t phiMin = -TMath::Pi(); - const Double_t phiMax = TMath::Pi(); - const Double_t phiBinWidth = (phiMax - phiMin) / kEtaPhiBins; - - const Double_t halfEtaBin = 0.5 * etaBinWidth * bShift; - const Double_t halfPhiBin = 0.5 * phiBinWidth * bShift; - const Double_t shiftedEtaMin = etaMin + halfEtaBin; - const Double_t shiftedEtaMax = etaMax + halfEtaBin; - const Double_t shiftedPhiMin = phiMin + halfPhiBin; - const Double_t shiftedPhiMax = phiMax + halfPhiBin; +std::pair TimeframeSplitter::etaPhiBins(double hitEta, double hitPhi, + double etaMin, double etaMax, + int bShift) { + const double etaBinWidth = (etaMax - etaMin) / kEtaPhiBins; + const double phiMin = -std::numbers::pi; + const double phiMax = std::numbers::pi; + const double phiBinWidth = (phiMax - phiMin) / kEtaPhiBins; + + const double halfEtaBin = 0.5 * etaBinWidth * bShift; + const double halfPhiBin = 0.5 * phiBinWidth * bShift; + const double shiftedEtaMin = etaMin + halfEtaBin; + const double shiftedEtaMax = etaMax + halfEtaBin; + const double shiftedPhiMin = phiMin + halfPhiBin; + const double shiftedPhiMax = phiMax + halfPhiBin; if (hitEta < shiftedEtaMin || hitEta >= shiftedEtaMax || hitPhi < shiftedPhiMin || hitPhi >= shiftedPhiMax) { return {kInvalidEtaPhiBin, kInvalidEtaPhiBin}; } - const Int_t etaBin = static_cast(std::floor((hitEta - shiftedEtaMin) / etaBinWidth)); - const Int_t phiBin = static_cast(std::floor((hitPhi - shiftedPhiMin) / phiBinWidth)); + const int etaBin = static_cast(std::floor((hitEta - shiftedEtaMin) / etaBinWidth)); + const int phiBin = static_cast(std::floor((hitPhi - shiftedPhiMin) / phiBinWidth)); return {etaBin, phiBin}; } @@ -112,9 +113,9 @@ size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0 const EtaPhiGrid& gridShifted, const EtaPhiTimeGrid& gridTime0, const EtaPhiTimeGrid& gridShiftedTime, - Int_t threshold, Double_t& averageTime) { + unsigned int threshold, double& averageTime) { size_t count = 0; - Double_t timeSum = 0.0; + double timeSum = 0.0; for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { if (grid0[iEta][iPhi] >= threshold || gridShifted[iEta][iPhi] >= threshold) { @@ -131,12 +132,12 @@ size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0 return count; } -Double_t TimeframeSplitter::averageSelectedTriggerTime(const std::array& values, - const std::array& times, +double TimeframeSplitter::averageSelectedTriggerTime(const std::array& values, + const std::array& times, std::initializer_list indices, - Double_t fallbackTime) { + double fallbackTime) { size_t count = 0; - Double_t timeSum = 0.0; + double timeSum = 0.0; for (const size_t index : indices) { if (values[index] <= 0.0) continue; @@ -146,63 +147,63 @@ Double_t TimeframeSplitter::averageSelectedTriggerTime(const std::array 0 ? timeSum / count : fallbackTime; } -Double_t TimeframeSplitter::tracker_time_resolution(size_t detector_id) { - if (detector_id < 3) +double TimeframeSplitter::trkTimeResolution(size_t detectorID) { + if (detectorID < 3) return timeResolution_ACLGad(); - if (detector_id < 7) + if (detectorID < 7) return timeResolution_MPGD(); return timeResolution_SiMaps(); } -std::pair TimeframeSplitter::backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, - Int_t bShift) { +std::pair TimeframeSplitter::backEndEtaPhiBins(double hitEta, double hitPhi, + int bShift) { // MPGD backward Endcap range -3.6 < eta < -1.72, +5%: -3.78 < eta < -1.634 - const Double_t etaMin = -3.78; - const Double_t etaMax = -1.634; + const double etaMin = -3.78; + const double etaMax = -1.634; return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); } -std::pair TimeframeSplitter::barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, - Int_t bShift) { +std::pair TimeframeSplitter::barrelEtaPhiBins(double hitEta, double hitPhi, + int bShift) { // MPGD barrel In range -1.49 < eta < 1.722, +5%: -1.56 < eta < 1.81 // MPGD barrel Out range -1.56 < eta < 1.61, +5%: -1.64 < eta < 1.70 // TOF barrel range -1.39 < eta < 1.39, +5%: -1.46 < eta < 1.46 // ECal barrel range -1.71 < eta < 1.31, +5%: -1.80 < eta < 1.38 - const Double_t etaMin = -1.80; - const Double_t etaMax = 1.81; + const double etaMin = -1.80; + const double etaMax = 1.81; return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); } -std::pair TimeframeSplitter::forwardEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, - Int_t bShift) { +std::pair TimeframeSplitter::forwardEndEtaPhiBins(double hitEta, double hitPhi, + int bShift) { // MPGD forward Endcap range 2.0 < eta < 3.35, +5%: 1.90 < eta < 3.52 // TOF forward Endcap range 1.86 < eta < 3.85, +5%: 1.77 < eta < 4.04 // ECal forward Endcap range 1.4 < eta < 3.5, +5%: 1.33 < eta < 3.68 - const Double_t etaMin = 1.77; - const Double_t etaMax = 4.04; + const double etaMin = 1.77; + const double etaMax = 4.04; return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); } TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent& child, int child_idx) { - const float m_timeframe_width = timeframe_width(); - const float m_timesplit_width = timesplit_width(); - const Double_t time_resolution_mpgd = timeResolution_MPGD(); - const Double_t time_resolution_tof = timeResolution_ACLGad(); - const Double_t time_resolution_emcal = timeResolution_EMCal(); + const float m_timeframeWidth = timeframeWidth(); + const float m_timesplitWidth = timesplitWidth(); + const double timeResolution_mpgd = timeResolution_MPGD(); + const double timeResolution_tof = timeResolution_ACLGad(); + const double timeResolution_emcal = timeResolution_EMCal(); - Bool_t m_bTrigger = false; + bool m_bTrigger = false; // Materialize these output collections even when no timeslice triggers, // so the output schema is available from the first event. - (void)m_event_header_out(); - (void)m_event_header_phy_out(); - (void)m_event_header_bkg_out(); + (void)m_eventHeader_outCol(); + (void)m_eventHeaderPhy_outCols(); + (void)m_eventHeaderBkg_outCols(); - const auto trackerHitCollsIn = m_trackerhits_in(); - const auto caloRecHitCollsIn = m_calorechit_in(); - const auto trkAssoCollsIn = m_trackerhitsAsso_in(); - const auto calrecAssoCollsIn = m_calorechitassociation_in(); + const auto trackerHitCollsIn = m_trackerHits_inCols(); + const auto caloRecHitCollsIn = m_calorimeterHit_inCols(); + const auto trkAssoCollsIn = m_trackerHitsAsso_inCols(); + const auto calrecAssoCollsIn = m_mcRecoCalorimeterHitAssociation_inCols(); // == s == Register hits of TOF and MPGD detectors in the time slice ================== if (child_idx == 0) { @@ -211,28 +212,28 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent // Association collections belong to the parent Timeslice and remain valid for all // of its children. Build each lookup once per parent instead of rebuilding the full // index for every triggered PhysicsEvent. - m_tracker_association_indices.clear(); - m_tracker_association_indices.reserve(trkAssoCollsIn.size()); + m_trkAssoIds.clear(); + m_trkAssoIds.reserve(trkAssoCollsIn.size()); for (const auto* associations : trkAssoCollsIn) { - m_tracker_association_indices.push_back(buildTrkAssoId(associations)); + m_trkAssoIds.push_back(buildTrkAssoId(associations)); } - m_calorimeter_association_indices.clear(); - m_calorimeter_association_indices.reserve(calrecAssoCollsIn.size()); + m_calAssoIds.clear(); + m_calAssoIds.reserve(calrecAssoCollsIn.size()); for (const auto* associations : calrecAssoCollsIn) { - m_calorimeter_association_indices.push_back(buildCalAssoId(associations)); + m_calAssoIds.push_back(buildCalAssoId(associations)); } // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ m_vPhysCooTimes.clear(); - Double_t prevMCTime = -9999.0; // temp check mc particle times - for (const auto& mcparticle : *m_mcparticles_in()) { + double prevMCTime = -9999.0; // temp check mc particle times + for (const auto& mcparticle : *m_mcParticles_inCol()) { if (mcparticle.getGeneratorStatus() != 1) continue; if (std::abs(prevMCTime - mcparticle.getTime()) < 50.) continue; - Double_t mcCollTime = mcparticle.getTime(); + double mcCollTime = mcparticle.getTime(); m_vPhysCooTimes.push_back(mcCollTime); prevMCTime = mcCollTime; } @@ -244,37 +245,38 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent // == e == Register hits of TOF and MPGD detectors in the time slice ================== // == s == Time frame scan loop ========================================================== - Double_t timesliceT0 = -999.0; - Bool_t bTimesliceTrigger = false; + double timesliceT0 = -999.0; + bool bTimesliceTrigger = false; - Bool_t bMutipliTriggers[6] = {false, false, false, false, false, false}; - Double_t multipliTrigTime[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + bool bMutipliTriggers[6] = {false, false, false, false, false, false}; + double multipliTrigTime[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - if (m_timesplit_width <= 0.0F) { - throw std::runtime_error("TimeframeSplitter: timesplit_width must be greater than zero"); + if (m_timesplitWidth <= 0.0F) { + throw std::runtime_error("TimeframeSplitter: timesplitWidth must be greater than zero"); } - if (m_timeframe_width <= 0.0F) { - throw std::runtime_error("TimeframeSplitter: timeframe_width must be greater than zero"); + if (m_timeframeWidth <= 0.0F) { + throw std::runtime_error("TimeframeSplitter: timeframeWidth must be greater than zero"); } - const size_t nTimeSlices = static_cast(std::floor(m_timeframe_width / m_timesplit_width)); - Double_t tsTimeS = 0.0; - Double_t tsTimeE = 0.0; + const size_t nTimeSlices = static_cast(std::floor(m_timeframeWidth / m_timesplitWidth)); + double tsTimeS = 0.0; + double tsTimeE = 0.0; + // Scan the timeframe one time slice at a time. // The scan stops early when a physics trigger fires; otherwise it terminates // after all time slices in the timeframe have been processed. while (iTimeSlice < nTimeSlices) { - tsTimeS = iTimeSlice * m_timesplit_width; - tsTimeE = (iTimeSlice + 1) * m_timesplit_width; - if (tsTimeE > m_timeframe_width) + tsTimeS = iTimeSlice * m_timesplitWidth; + tsTimeE = (iTimeSlice + 1) * m_timesplitWidth; + if (tsTimeE > m_timeframeWidth) break; iTimeSlice++; // == s == Multiplisity threshold Triggers ======================================= // == s == Multiplisity Single Triggers ======================================= - std::array singleTrig{}; - std::array singleTrigTime{}; + std::array singleTrig{}; + std::array singleTrigTime{}; // s // EndCap Cal Trigger EtaPhiGrid backEndCalGrid{}; @@ -282,7 +284,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid backEndIntTimesEtaPhi = {}; EtaPhiTimeGrid backEndIntTimesEtaPhiShifted = {}; fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapN), iniCalHitPoint[kCalEndcapN], - time_resolution_emcal, tsTimeS, tsTimeE, backEndCalGrid, backEndCalGridShifted, + timeResolution_emcal, tsTimeS, tsTimeE, backEndCalGrid, backEndCalGridShifted, backEndIntTimesEtaPhi, backEndIntTimesEtaPhiShifted, backEndEtaPhiBins); singleTrig[0] = countGridCellsWithMultiplicity(backEndCalGrid, backEndCalGridShifted, backEndIntTimesEtaPhi, @@ -294,7 +296,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid backEndIntTimesEtaPhiMatched = {}; EtaPhiTimeGrid backEndIntTimesEtaPhiMatchedShifted = {}; fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkBackwardMPGD), iniTrkHitPoint[kTrkBackwardMPGD], - time_resolution_mpgd, tsTimeS, tsTimeE, backEndCalGrid, + timeResolution_mpgd, tsTimeS, tsTimeE, backEndCalGrid, backEndCalGridShifted, backEndTrkGrid, backEndTrkGridShifted, 10, backEndIntTimesEtaPhiMatched, backEndIntTimesEtaPhiMatchedShifted, backEndEtaPhiBins); @@ -307,7 +309,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid barrelIntTimesEtaPhi = {}; EtaPhiTimeGrid barrelIntTimesEtaPhiShifted = {}; fillEtaPhiGrids(caloRecHitCollsIn.at(kCalBarrelScifi), iniCalHitPoint[kCalBarrelScifi], - time_resolution_emcal, tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, + timeResolution_emcal, tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelIntTimesEtaPhi, barrelIntTimesEtaPhiShifted, barrelEtaPhiBins); singleTrig[2] = countGridCellsWithMultiplicity(barrelCalGrid, barrelCalGridShifted, barrelIntTimesEtaPhi, @@ -318,16 +320,16 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid barrelIntTimesEtaPhiMatched = {}; EtaPhiTimeGrid barrelIntTimesEtaPhiMatchedShifted = {}; fillEtaPhiGridsMatched( - trackerHitCollsIn.at(kTrkMPGDBarrel), iniTrkHitPoint[kTrkMPGDBarrel], time_resolution_mpgd, + trackerHitCollsIn.at(kTrkMPGDBarrel), iniTrkHitPoint[kTrkMPGDBarrel], timeResolution_mpgd, tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkOuterMPGDBarrel), - iniTrkHitPoint[kTrkOuterMPGDBarrel], time_resolution_mpgd, tsTimeS, + iniTrkHitPoint[kTrkOuterMPGDBarrel], timeResolution_mpgd, tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); fillEtaPhiGridsMatched( - trackerHitCollsIn.at(kTrkTOFBarrel), iniTrkHitPoint[kTrkTOFBarrel], time_resolution_tof, + trackerHitCollsIn.at(kTrkTOFBarrel), iniTrkHitPoint[kTrkTOFBarrel], timeResolution_tof, tsTimeS, tsTimeE, barrelCalGrid, barrelCalGridShifted, barrelTrkGrid, barrelTrkGridShifted, 5, barrelIntTimesEtaPhiMatched, barrelIntTimesEtaPhiMatchedShifted, barrelEtaPhiBins); singleTrig[3] = countGridCellsWithMultiplicity( @@ -339,7 +341,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid frontEndIntTimesEtaPhi = {}; EtaPhiTimeGrid frontEndIntTimesEtaPhiShifted = {}; fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapP), iniCalHitPoint[kCalEndcapP], - time_resolution_emcal, tsTimeS, tsTimeE, frontEndCalGrid, + timeResolution_emcal, tsTimeS, tsTimeE, frontEndCalGrid, frontEndCalGridShifted, frontEndIntTimesEtaPhi, frontEndIntTimesEtaPhiShifted, forwardEndEtaPhiBins); singleTrig[4] = countGridCellsWithMultiplicity( @@ -351,12 +353,12 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid frontEndIntTimesEtaPhiMatched = {}; EtaPhiTimeGrid frontEndIntTimesEtaPhiMatchedShifted = {}; fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkForwardMPGD), iniTrkHitPoint[kTrkForwardMPGD], - time_resolution_mpgd, tsTimeS, tsTimeE, frontEndCalGrid, + timeResolution_mpgd, tsTimeS, tsTimeE, frontEndCalGrid, frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, forwardEndEtaPhiBins); fillEtaPhiGridsMatched(trackerHitCollsIn.at(kTrkTOFEndcap), iniTrkHitPoint[kTrkTOFEndcap], - time_resolution_tof, tsTimeS, tsTimeE, frontEndCalGrid, + timeResolution_tof, tsTimeS, tsTimeE, frontEndCalGrid, frontEndCalGridShifted, frontEndTrkGrid, frontEndTrkGridShifted, 5, frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, forwardEndEtaPhiBins); @@ -364,22 +366,22 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent frontEndTrkGrid, frontEndTrkGridShifted, frontEndIntTimesEtaPhiMatched, frontEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[5]); - const auto hitsB0 = count_hits_in_window(trackerHitCollsIn.at(kTrkB0), iniTrkHitPoint[kTrkB0], - time_resolution_tof, tsTimeS, tsTimeE); - iniTrkHitPoint[kTrkB0] = hitsB0.next_start_index; + const auto hitsB0 = countHitsInTimeWindow(trackerHitCollsIn.at(kTrkB0), iniTrkHitPoint[kTrkB0], + timeResolution_tof, tsTimeS, tsTimeE); + iniTrkHitPoint[kTrkB0] = hitsB0.nextStartID; singleTrig[6] = hitsB0.count; singleTrigTime[6] = hitsB0.average_time(); - Double_t totalZDCEnergy = 0.0; - Double_t totalZDCEnergyTime = 0.0; + double totalZDCEnergy = 0.0; + double totalZDCEnergyTime = 0.0; const auto* recHitsZDCECal = caloRecHitCollsIn.at(kCalZDC); if (recHitsZDCECal != nullptr) { for (size_t iHit = iniCalHitPoint[kCalZDC]; iHit < recHitsZDCECal->size(); ++iHit) { const auto& hit = recHitsZDCECal->at(iHit); - const Double_t hitTime = hit.getTime(); - if (hitTime - time_resolution_emcal > tsTimeE) + const double hitTime = hit.getTime(); + if (hitTime - timeResolution_emcal > tsTimeE) break; - if (is_hit_in_time_slice(hitTime, time_resolution_emcal, tsTimeS, tsTimeE)) { + if (judgeHitInTimeSlice(hitTime, timeResolution_emcal, tsTimeS, tsTimeE)) { totalZDCEnergy += hit.getEnergy(); totalZDCEnergyTime += hit.getEnergy() * hitTime; iniCalHitPoint[kCalZDC] = iHit; @@ -389,8 +391,8 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent singleTrig[7] = totalZDCEnergy; singleTrigTime[7] = totalZDCEnergy > 0.0 ? totalZDCEnergyTime / totalZDCEnergy : 0.0; - const Double_t etaPhiCalTriggerSum = singleTrig[0] + singleTrig[2] + singleTrig[4]; - const Double_t etaPhiCalTrkTriggerSum = singleTrig[1] + singleTrig[3] + singleTrig[5]; + const double etaPhiCalTriggerSum = singleTrig[0] + singleTrig[2] + singleTrig[4]; + const double etaPhiCalTrkTriggerSum = singleTrig[1] + singleTrig[3] + singleTrig[5]; bMutipliTriggers[0] = etaPhiCalTrkTriggerSum > 0 && singleTrig[6] > 4; bMutipliTriggers[1] = etaPhiCalTrkTriggerSum > 0 && singleTrig[7] > 50; bMutipliTriggers[2] = etaPhiCalTriggerSum > 0 && singleTrig[6] > 4; @@ -402,7 +404,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent !bMutipliTriggers[3] && !bMutipliTriggers[4] && !bMutipliTriggers[5]) continue; - const Double_t fallbackTriggerTime = 0.5 * (tsTimeS + tsTimeE); + const double fallbackTriggerTime = 0.5 * (tsTimeS + tsTimeE); if (bMutipliTriggers[0]) multipliTrigTime[0] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {1, 3, 5, 6}, fallbackTriggerTime); @@ -421,8 +423,8 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent if (bMutipliTriggers[5]) multipliTrigTime[5] = averageSelectedTriggerTime(singleTrig, singleTrigTime, {0, 2, 4}, fallbackTriggerTime); - Double_t multiTrigCount = 0; - Double_t totalTrigTime = 0.0; + double multiTrigCount = 0; + double totalTrigTime = 0.0; for (size_t iTrig = 0; iTrig < 6; ++iTrig) { if (bMutipliTriggers[iTrig]) { totalTrigTime += multipliTrigTime[iTrig]; @@ -451,8 +453,8 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent m_NewEventCount++; // Clone truth particles before detector relations so every child SimTrackerHit can // point to an MCParticle owned by this PhysicsEvent rather than by the parent Timeslice. - for (const auto& mcparticle : *m_mcparticles_in()) { - m_mcparticles_out()->push_back(mcparticle.clone(false)); + for (const auto& mcparticle : *m_mcParticles_inCol()) { + m_mcParticles_outCol()->push_back(mcparticle.clone(false)); } // == s == Register Tracker Hits ======================================================= @@ -461,25 +463,25 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent if (trkCollIn == nullptr) continue; - auto& trkCollOut = m_trackerhits_out().at(trkDetID); - const Double_t detTimeReso = tracker_time_resolution(trkDetID); + auto& trkCollOut = m_trackerHits_outCols().at(trkDetID); + const double detTimeReso = trkTimeResolution(trkDetID); const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); - auto& rawCollOut = m_rawhit_out().at(trkDetID); - auto& trkAssoCollOut = m_trackerhitsAsso_out().at(trkDetID); + auto& rawCollOut = m_rawTrackerHit_outCols().at(trkDetID); + auto& trkAssoCollOut = m_trackerHitsAsso_outCols().at(trkDetID); for (size_t iHit = 0; iHit < trkCollIn->size(); ++iHit) { const auto& trkHit = trkCollIn->at(iHit); - const Double_t hitT = trkHit.getTime(); - if (!overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { + const double hitT = trkHit.getTime(); + if (!overlapsTimeWindow(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { continue; } iniTrkHitPoint[trkDetID] = iHit; - copy_tracker_hit_with_relations( - trkHit, trkAssoCollIn, m_tracker_association_indices.at(trkDetID), trkCollOut, - rawCollOut, trkAssoCollOut, m_simtrackerhits_out().at(trkDetID), - m_rawhitlinks_out().at(trkDetID), m_mcparticles_out()); + copyTrkHitWithRelations( + trkHit, trkAssoCollIn, m_trkAssoIds.at(trkDetID), trkCollOut, + rawCollOut, trkAssoCollOut, m_simTrackerHits_outCols().at(trkDetID), + m_recoTrackerHitLinks_outCols().at(trkDetID), m_mcParticles_outCol()); } } // == e == Register Tracker Hits ======================================================= @@ -489,7 +491,7 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent const auto* caloInColl = caloRecHitCollsIn.at(calDetID); if (caloInColl == nullptr) continue; - auto& caloOutColl = m_calorechit_out().at(calDetID); + auto& caloOutColl = m_calorimeterHit_outCols().at(calDetID); const auto* caloInCollAsso = calrecAssoCollsIn.at(calDetID); if (caloInCollAsso == nullptr) @@ -498,29 +500,29 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent for (size_t iCalHit = 0; iCalHit < caloInColl->size(); ++iCalHit) { const auto& caloHit = caloInColl->at(iCalHit); - Double_t detTimeReso = time_resolution_emcal; - Double_t hitT = caloHit.getTime(); + double detTimeReso = timeResolution_emcal; + double hitT = caloHit.getTime(); if (hitT - detTimeReso > timesliceT0 + 30.) continue; - if (overlaps_time_window(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { + if (overlapsTimeWindow(hitT, detTimeReso, timesliceT0 - 10., timesliceT0 + 30.)) { auto copiedCaloHit = caloHit.clone(); copiedCaloHit.setRawHit(edm4hep::RawCalorimeterHit()); const auto rawHitFromRec = caloHit.getRawHit(); if (rawHitFromRec.isAvailable()) { - auto& rawCollOut = m_calorawhit_out().at(calDetID); + auto& rawCollOut = m_rawCalorimeterHit_outCols().at(calDetID); auto copiedRawHit = rawHitFromRec.clone(); rawCollOut->push_back(copiedRawHit); copiedCaloHit.setRawHit(copiedRawHit); - auto& assocCollOut = m_calorechitassociation_out().at(calDetID); - auto& linkCollOut = m_calorawhitlinks_out().at(calDetID); - auto& simCollOut = m_simcalorimeterhits_out().at(calDetID); + auto& assocCollOut = m_mcRecoCalorimeterHitAssociation_outCols().at(calDetID); + auto& linkCollOut = m_mcRecoCalorimeterHitLink_outCols().at(calDetID); + auto& simCollOut = m_simCalorimeterHit_outCols().at(calDetID); const auto rawHitID = rawHitFromRec.getObjectID(); - const auto& association_index = m_calorimeter_association_indices.at(calDetID); - const auto assocIterCal = association_index.find(object_id_key(rawHitID)); + const auto& association_index = m_calAssoIds.at(calDetID); + const auto assocIterCal = association_index.find(objIdKey(rawHitID)); if (assocIterCal != association_index.end()) { for (const size_t association_position : assocIterCal->second) { @@ -554,9 +556,9 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><><>> // == s == For MC Trigger Efficiency Estimation ~~~~~~~~ - Int_t physEventWeight = 2; + unsigned int physEventWeight = 2; for (auto it = m_vPhysCooTimes.begin(); it != m_vPhysCooTimes.end(); ++it) { - const Double_t physCollTime = *it; + const double physCollTime = *it; if ((physCollTime + 20 > timesliceT0 - 10) && (physCollTime - 10 < timesliceT0 + 30)) { physEventWeight = 1; m_vPhysCooTimes.erase(it); @@ -565,73 +567,73 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent } if (physEventWeight == 1) { - edm4hep::MutableEventHeader event_header_bkg; - event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_bkg.setEventNumber(m_event_number_ts); - event_header_bkg.setTimeStamp(iTimeSlice); - event_header_bkg.setWeight(1); - m_event_header_bkg_out()->push_back(event_header_bkg); - - edm4hep::MutableEventHeader event_header_phy; - event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_phy.setEventNumber(m_event_number_ts); - event_header_phy.setTimeStamp(iTimeSlice); - event_header_phy.setWeight(2); - m_event_header_phy_out()->push_back(event_header_phy); + edm4hep::MutableEventHeader eventHeader_bkg; + eventHeader_bkg.setRunNumber(m_eventNumber_TS * 10000 + child_idx); + eventHeader_bkg.setEventNumber(m_eventNumber_TS); + eventHeader_bkg.setTimeStamp(iTimeSlice); + eventHeader_bkg.setWeight(1); + m_eventHeaderBkg_outCols()->push_back(eventHeader_bkg); + + edm4hep::MutableEventHeader eventHeader_phy; + eventHeader_phy.setRunNumber(m_eventNumber_TS * 10000 + child_idx); + eventHeader_phy.setEventNumber(m_eventNumber_TS); + eventHeader_phy.setTimeStamp(iTimeSlice); + eventHeader_phy.setWeight(2); + m_eventHeaderPhy_outCols()->push_back(eventHeader_phy); for (size_t iTrig = 0; iTrig < 6; ++iTrig) { if (bMutipliTriggers[iTrig]) { - edm4hep::MutableEventHeader event_header_phy; - event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_phy.setEventNumber(m_event_number_ts); - event_header_phy.setTimeStamp(iTimeSlice); - event_header_phy.setWeight(iTrig + 3); - m_event_header_phy_out()->push_back(event_header_phy); + edm4hep::MutableEventHeader eventHeader_phy; + eventHeader_phy.setRunNumber(m_eventNumber_TS * 10000 + child_idx); + eventHeader_phy.setEventNumber(m_eventNumber_TS); + eventHeader_phy.setTimeStamp(iTimeSlice); + eventHeader_phy.setWeight(iTrig + 3); + m_eventHeaderPhy_outCols()->push_back(eventHeader_phy); } } m_PhysCount++; } else if (physEventWeight == 2) { - edm4hep::MutableEventHeader event_header_phy; - event_header_phy.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_phy.setEventNumber(m_event_number_ts); - event_header_phy.setTimeStamp(iTimeSlice); - event_header_phy.setWeight(1); - m_event_header_phy_out()->push_back(event_header_phy); - - edm4hep::MutableEventHeader event_header_bkg; - event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_bkg.setEventNumber(m_event_number_ts); - event_header_bkg.setTimeStamp(iTimeSlice); - event_header_bkg.setWeight(2); - m_event_header_bkg_out()->push_back(event_header_bkg); + edm4hep::MutableEventHeader eventHeader_phy; + eventHeader_phy.setRunNumber(m_eventNumber_TS * 10000 + child_idx); + eventHeader_phy.setEventNumber(m_eventNumber_TS); + eventHeader_phy.setTimeStamp(iTimeSlice); + eventHeader_phy.setWeight(1); + m_eventHeaderPhy_outCols()->push_back(eventHeader_phy); + + edm4hep::MutableEventHeader eventHeader_bkg; + eventHeader_bkg.setRunNumber(m_eventNumber_TS * 10000 + child_idx); + eventHeader_bkg.setEventNumber(m_eventNumber_TS); + eventHeader_bkg.setTimeStamp(iTimeSlice); + eventHeader_bkg.setWeight(2); + m_eventHeaderBkg_outCols()->push_back(eventHeader_bkg); for (size_t iTrig = 0; iTrig < 6; ++iTrig) { if (bMutipliTriggers[iTrig]) { - edm4hep::MutableEventHeader event_header_bkg; - event_header_bkg.setRunNumber(m_event_number_ts * 10000 + child_idx); - event_header_bkg.setEventNumber(m_event_number_ts); - event_header_bkg.setTimeStamp(iTimeSlice); - event_header_bkg.setWeight(iTrig + 3); - m_event_header_bkg_out()->push_back(event_header_bkg); + edm4hep::MutableEventHeader eventHeader_bkg; + eventHeader_bkg.setRunNumber(m_eventNumber_TS * 10000 + child_idx); + eventHeader_bkg.setEventNumber(m_eventNumber_TS); + eventHeader_bkg.setTimeStamp(iTimeSlice); + eventHeader_bkg.setWeight(iTrig + 3); + m_eventHeaderBkg_outCols()->push_back(eventHeader_bkg); } } } - m_event_number_ts++; + m_eventNumber_TS++; // Insert an independent EventHeader object into the physics event. // A subset header would keep a reference to the parent frame collection. - edm4hep::MutableEventHeader event_header; - if (m_event_header_in() != nullptr && !m_event_header_in()->empty()) { - const auto& event_header_in = m_event_header_in()->at(0); - event_header.setRunNumber(event_header_in.getRunNumber()); - event_header.setEventNumber(event_header_in.getEventNumber()); - event_header.setTimeStamp(event_header_in.getTimeStamp()); - event_header.setWeight(event_header_in.getWeight()); + edm4hep::MutableEventHeader eventHeader; + if (m_eventHeader_inCol() != nullptr && !m_eventHeader_inCol()->empty()) { + const auto& eventHeader_in = m_eventHeader_inCol()->at(0); + eventHeader.setRunNumber(eventHeader_in.getRunNumber()); + eventHeader.setEventNumber(eventHeader_in.getEventNumber()); + eventHeader.setTimeStamp(eventHeader_in.getTimeStamp()); + eventHeader.setWeight(eventHeader_in.getWeight()); } else { - event_header.setRunNumber(child.GetRunNumber()); - event_header.setEventNumber(child.GetEventNumber()); - event_header.setTimeStamp(iTimeSlice); - event_header.setWeight(physEventWeight); + eventHeader.setRunNumber(child.GetRunNumber()); + eventHeader.setEventNumber(child.GetEventNumber()); + eventHeader.setTimeStamp(iTimeSlice); + eventHeader.setWeight(physEventWeight); } - m_event_header_out()->push_back(event_header); + m_eventHeader_outCol()->push_back(eventHeader); // == e == For MC Trigger Efficiency Estimation ~~~~~~~~ // == s == For QA relation valuables QA<><><><><><><><><><><><><><><><><>> @@ -664,28 +666,4 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent return Result::KeepChildNextParent; } -void TimeframeSplitter::thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, - Int_t& thetaID2, Int_t& phiID2) { - Double_t hitX = hit.getPosition()[0]; - Double_t hitY = hit.getPosition()[1]; - Double_t hitZ = hit.getPosition()[2]; - const Double_t hitR = TMath::Sqrt(hitX * hitX + hitY * hitY + hitZ * hitZ); - if (hitR <= 0.0) { - thetaID1 = 0; - thetaID2 = 0; - phiID1 = 0; - phiID2 = 0; - return; - } - const Double_t cosTheta = std::clamp(hitZ / hitR, -1.0, 1.0); - const Double_t hitTheta = TMath::ACos(cosTheta); - - Double_t hitPhi = TMath::ATan2(hitY, hitX) + 2 * TMath::Pi(); - if (hitPhi < 0) - hitPhi += 2 * TMath::Pi(); - thetaID1 = hitTheta / (TMath::Pi() / 12.); - thetaID2 = (hitTheta + TMath::Pi() / 24.) / (TMath::Pi() / 12.); - phiID1 = hitPhi / (TMath::Pi() / 8.); - phiID2 = (hitPhi + TMath::Pi() / 16.) / (TMath::Pi() / 8.); -} diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index a8cfb9b1a9..573ec0278b 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -37,14 +37,15 @@ #include #include #include +#include +#include -#include "TMath.h" struct TimeframeSplitter : public JEventUnfolder { - Parameter timeframe_width{this, "timeframe_width", 2000.0, + Parameter timeframeWidth{this, "timeframe_width", 2000.0, "Width of each timeframe in ns"}; - Parameter timesplit_width{this, "timesplit_width", 20.0, "Width of each timeslice in ns"}; + Parameter timesplitWidth{this, "timesplit_width", 20.0, "Width of each timeslice in ns"}; Parameter timeResolution_SiMaps{this, "timeResolution_Silicon", 2000.0, "time resolution of Silicon detector in ns"}; Parameter timeResolution_MPGD{this, "timeResolution_MPGD", 30.0, @@ -55,21 +56,43 @@ struct TimeframeSplitter : public JEventUnfolder { "time resolution of EMCal detector in ns"}; bool m_use_timeframe = false; // Use timeframes to split events, or use timeslices - Int_t m_OrigTFCount = 0; //QA - Int_t m_NewEventCount = 0; //QA - Int_t m_PhysCount = 0; //QA + unsigned int m_OrigTFCount = 0; //QA + unsigned int m_NewEventCount = 0; //QA + unsigned int m_PhysCount = 0; //QA + + size_t m_eventNumber_TS = 0; // Event number for the current timeslice + std::vector m_vTargetEvent; // List of original event numbers for each timeslice + + static constexpr double kPi = 3.14159265358979323846; - size_t m_event_number_ts = 0; // Event number for the current timeslice - size_t m_event_number_orig = 0; // Event number for the current timeslice - std::vector m_vTargetEvent; // List of original event numbers for each timeslice + static constexpr int kEtaPhiBins = 10; + static constexpr int kInvalidEtaPhiBin = -1; - static constexpr Int_t kEtaPhiBins = 10; - static constexpr Int_t kInvalidEtaPhiBin = -1; + using EtaPhiGrid = std::array, kEtaPhiBins>; + using EtaPhiTimeGrid = std::array, kEtaPhiBins>; + using EtaPhiEnergyGrid = std::array, kEtaPhiBins>; - using EtaPhiGrid = std::array, kEtaPhiBins>; - using EtaPhiTimeGrid = std::array, kEtaPhiBins>; - using EtaPhiEnergyGrid = std::array, kEtaPhiBins>; + enum TrkCollectionType : size_t { + kTrackerHitAligned = 0, + kTrackerHit, + kTrackerHitAssociation, + kTrackerHitLink, + kSimTrackerHit, + kRawTrackerHit, + kTrkCollectionTypeSize + }; + +enum CalCollectionType : size_t { + kCalorimeterHitAligned = 0, + kCalorimeterHit, + kCalorimeterHitAssociation, + kCalorimeterHitLink, + kSimCalorimeterHit, + kRawCalorimeterHit, + kCalCollectionTypeSize +}; + enum TrkCollectionIndex : size_t { kTrkB0 = 0, kTrkTOFBarrel = 1, @@ -96,256 +119,294 @@ struct TimeframeSplitter : public JEventUnfolder { kCalLumi = 6 }; - std::vector m_trackerhit_collection_names = { - "B0TrackerRecHits_aligned", "TOFBarrelRecHits_aligned", - "TOFEndcapRecHits_aligned", "MPGDBarrelRecHits_aligned", - "OuterMPGDBarrelRecHits_aligned", "BackwardMPGDEndcapRecHits_aligned", - "ForwardMPGDEndcapRecHits_aligned", "SiBarrelVertexRecHits_aligned", - "SiBarrelTrackerRecHits_aligned", "SiEndcapTrackerRecHits_aligned", - "TaggerTrackerRecHits_aligned", "ForwardRomanPotRecHits_aligned", - "ForwardOffMTrackerRecHits_aligned"}; - + using trkCollNames = std::array; + std::array m_trkCollNames = {{ + { + "B0TrackerRecHits_aligned", + "B0TrackerRecHits", + "B0TrackerRawHitAssociations", + "B0TrackerRawHitLinks", + "B0TrackerHits", + "B0TrackerRawHits", + }, + { + "TOFBarrelRecHits_aligned", + "TOFBarrelRecHits", + "TOFBarrelRawHitAssociations", + "TOFBarrelRawHitLinks", + "TOFBarrelHits", + "TOFBarrelRawHits", + }, + { + "TOFEndcapRecHits_aligned", + "TOFEndcapRecHits", + "TOFEndcapRawHitAssociations", + "TOFEndcapRawHitLinks", + "TOFEndcapHits", + "TOFEndcapRawHits", + }, + { + "MPGDBarrelRecHits_aligned", + "MPGDBarrelRecHits", + "MPGDBarrelRawHitAssociations", + "MPGDBarrelRawHitLinks", + "MPGDBarrelHits", + "MPGDBarrelRawHits", + }, + { + "OuterMPGDBarrelRecHits_aligned", + "OuterMPGDBarrelRecHits", + "OuterMPGDBarrelRawHitAssociations", + "OuterMPGDBarrelRawHitLinks", + "OuterMPGDBarrelHits", + "OuterMPGDBarrelRawHits", + }, + { + "BackwardMPGDEndcapRecHits_aligned", + "BackwardMPGDEndcapRecHits", + "BackwardMPGDEndcapRawHitAssociations", + "BackwardMPGDEndcapRawHitLinks", + "BackwardMPGDEndcapHits", + "BackwardMPGDEndcapRawHits", + }, + { + "ForwardMPGDEndcapRecHits_aligned", + "ForwardMPGDEndcapRecHits", + "ForwardMPGDEndcapRawHitAssociations", + "ForwardMPGDEndcapRawHitLinks", + "ForwardMPGDEndcapHits", + "ForwardMPGDEndcapRawHits", + }, + { + "SiBarrelVertexRecHits_aligned", + "SiBarrelVertexRecHits", + "SiBarrelVertexRawHitAssociations", + "SiBarrelVertexRawHitLinks", + "VertexBarrelHits", + "SiBarrelVertexRawHits", + }, + { + "SiBarrelTrackerRecHits_aligned", + "SiBarrelTrackerRecHits", + "SiBarrelRawHitAssociations", + "SiBarrelRawHitLinks", + "SiBarrelHits", + "SiBarrelRawHits", + }, + { + "SiEndcapTrackerRecHits_aligned", + "SiEndcapTrackerRecHits", + "SiEndcapTrackerRawHitAssociations", + "SiEndcapTrackerRawHitLinks", + "TrackerEndcapHits", + "SiEndcapTrackerRawHits", + }, + { + "TaggerTrackerRecHits_aligned", + "TaggerTrackerRecHits", + "TaggerTrackerRawHitAssociations", + "TaggerTrackerRawHitLinks", + "TaggerTrackerHits", + "TaggerTrackerRawHits", + }, + { + "ForwardRomanPotRecHits_aligned", + "ForwardRomanPotRecHits", + "ForwardRomanPotRawHitAssociations", + "ForwardRomanPotRawHitLinks", + "ForwardRomanPotHits", + "ForwardRomanPotRawHits", + }, + { + "ForwardOffMTrackerRecHits_aligned", + "ForwardOffMTrackerRecHits", + "ForwardOffMTrackerRawHitAssociations", + "ForwardOffMTrackerRawHitLinks", + "ForwardOffMTrackerHits", + "ForwardOffMTrackerRawHits", + }, + }}; // "RICHEndcapNRecHits_aligned" // "DIRCBarRecHits_aligned", // "DRICHRecHits_aligned", - std::vector m_trackerhit_collection_names_out = { - "B0TrackerRecHits", "TOFBarrelRecHits", "TOFEndcapRecHits", - "MPGDBarrelRecHits", "OuterMPGDBarrelRecHits", "BackwardMPGDEndcapRecHits", - "ForwardMPGDEndcapRecHits", "SiBarrelVertexRecHits", "SiBarrelTrackerRecHits", - "SiEndcapTrackerRecHits", "TaggerTrackerRecHits", "ForwardRomanPotRecHits", - "ForwardOffMTrackerRecHits"}; - - // "RICHEndcapNRecHits" - // "DIRCBarRecHits", - // "DRICHRecHits", - - std::vector m_simtrackerhitAsso_collection_names = { - "B0TrackerRawHitAssociations", "TOFBarrelRawHitAssociations", - "TOFEndcapRawHitAssociations", "MPGDBarrelRawHitAssociations", - "OuterMPGDBarrelRawHitAssociations", "BackwardMPGDEndcapRawHitAssociations", - "ForwardMPGDEndcapRawHitAssociations", "SiBarrelVertexRawHitAssociations", - "SiBarrelRawHitAssociations", "SiEndcapTrackerRawHitAssociations", - "TaggerTrackerRawHitAssociations", "ForwardRomanPotRawHitAssociations", - "ForwardOffMTrackerRawHitAssociations"}; - - // "RICHEndcapNRawHitAssociations" - // "DIRCBarRawHitsAssociations", - // "DRICHRawHitAssociations", - - std::vector m_simtrackerhitAsso_collection_names_out = { - "B0TrackerRawHitAssociations", "TOFBarrelRawHitAssociations", - "TOFEndcapRawHitAssociations", "MPGDBarrelRawHitAssociations", - "OuterMPGDBarrelRawHitAssociations", "BackwardMPGDEndcapRawHitAssociations", - "ForwardMPGDEndcapRawHitAssociations", "SiBarrelVertexRawHitAssociations", - "SiBarrelRawHitAssociations", "SiEndcapTrackerRawHitAssociations", - "TaggerTrackerRawHitAssociations", "ForwardRomanPotRawHitAssociations", - "ForwardOffMTrackerRawHitAssociations"}; - // "RICHEndcapNRawHitsAssociations" - // "DIRCBarRawHitAssociations", - // "DRICHRawHitsAssociations", - - std::vector m_rawhitlink_collection_names = { - "B0TrackerRawHitLinks", "TOFBarrelRawHitLinks", "TOFEndcapRawHitLinks", - "MPGDBarrelRawHitLinks", "OuterMPGDBarrelRawHitLinks", "BackwardMPGDEndcapRawHitLinks", - "ForwardMPGDEndcapRawHitLinks", "SiBarrelVertexRawHitLinks", "SiBarrelRawHitLinks", - "SiEndcapTrackerRawHitLinks", "TaggerTrackerRawHitLinks", "ForwardRomanPotRawHitLinks", - "ForwardOffMTrackerRawHitLinks"}; - // "RICHEndcapNRawHitsLinks" - // "DIRCBarRawHitLinks", - // "DRICHRawHitLinks", - - std::vector m_rawhitlink_collection_names_out = { - "B0TrackerRawHitLinks", "TOFBarrelRawHitLinks", "TOFEndcapRawHitLinks", - "MPGDBarrelRawHitLinks", "OuterMPGDBarrelRawHitLinks", "BackwardMPGDEndcapRawHitLinks", - "ForwardMPGDEndcapRawHitLinks", "SiBarrelVertexRawHitLinks", "SiBarrelRawHitLinks", - "SiEndcapTrackerRawHitLinks", "TaggerTrackerRawHitLinks", "ForwardRomanPotRawHitLinks", - "ForwardOffMTrackerRawHitLinks"}; - // "RICHEndcapNRawHitsLinks" - // "DIRCBarRawHitLinks", - // "DRICHRawHitsLinks", - - std::vector m_simtrackerhit_collection_names_out = { - "B0TrackerHits", "TOFBarrelHits", "TOFEndcapHits", - "MPGDBarrelHits", "OuterMPGDBarrelHits", "BackwardMPGDEndcapHits", - "ForwardMPGDEndcapHits", "VertexBarrelHits", "SiBarrelHits", - "TrackerEndcapHits", "TaggerTrackerHits", "ForwardRomanPotHits", - "ForwardOffMTrackerHits"}; - - std::vector m_rawhit_collection_names = { - "B0TrackerRawHits", "TOFBarrelRawHits", "TOFEndcapRawHits", - "MPGDBarrelRawHits", "OuterMPGDBarrelRawHits", "BackwardMPGDEndcapRawHits", - "ForwardMPGDEndcapRawHits", "SiBarrelVertexRawHits", "SiBarrelRawHits", - "SiEndcapTrackerRawHits", "TaggerTrackerRawHits", "ForwardRomanPotRawHits", - "ForwardOffMTrackerRawHits"}; - // "RICHEndcapNRawHits" - // "DIRCBarRawHits", - // "DRICHRawHits", - - std::vector m_rawhit_collection_names_out = { - "B0TrackerRawHits", "TOFBarrelRawHits", "TOFEndcapRawHits", - "MPGDBarrelRawHits", "OuterMPGDBarrelRawHits", "BackwardMPGDEndcapRawHits", - "ForwardMPGDEndcapRawHits", "SiBarrelVertexRawHits", "SiBarrelRawHits", - "SiEndcapTrackerRawHits", "TaggerTrackerRawHits", "ForwardRomanPotRawHits", - "ForwardOffMTrackerRawHits"}; - // "ForwardOffMTrackerRawHits", - // "RICHEndcapNRawHits" - // "DIRCBarRawHits", - // "DRICHRawHits", - - std::vector m_calorawhit_collection_names_in = {"B0ECalRawHits", - "EcalBarrelImagingRawHits", - "EcalBarrelScFiRawHits", - "EcalEndcapNRawHits", - "EcalEndcapPRawHits", - "EcalFarForwardZDCRawHits", - "EcalLumiSpecRawHits", - "HcalBarrelRawHits", - "HcalEndcapNRawHits", - "HcalEndcapPInsertRawHits", - "HcalFarForwardZDCRawHits", - "LFHCALRawHits"}; - - std::vector m_calorawhit_collection_names_out = {"B0ECalRawHits", - "EcalBarrelImagingRawHits", - "EcalBarrelScFiRawHits", - "EcalEndcapNRawHits", - "EcalEndcapPRawHits", - "EcalFarForwardZDCRawHits", - "EcalLumiSpecRawHits", - "HcalBarrelRawHits", - "HcalEndcapNRawHits", - "HcalEndcapPInsertRawHits", - "HcalFarForwardZDCRawHits", - "LFHCALRawHits"}; - - std::vector m_calorawhitlink_collection_names = {"B0ECalRawHitLinks", - "EcalBarrelImagingRawHitLinks", - "EcalBarrelScFiRawHitLinks", - "EcalEndcapNRawHitLinks", - "EcalEndcapPRawHitLinks", - "EcalFarForwardZDCRawHitLinks", - "EcalLumiSpecRawHitLinks", - "HcalBarrelRawHitLinks", - "HcalEndcapNRawHitLinks", - "HcalEndcapPInsertRawHitLinks", - "HcalFarForwardZDCRawHitLinks", - "LFHCALRawHitLinks"}; - - std::vector m_simcalorimeterhit_collection_names_out = { - "B0ECalHits", "EcalBarrelImagingHits", "EcalBarrelScFiHits", "EcalEndcapNHits", - "EcalEndcapPHits", "EcalFarForwardZDCHits", "EcalLumiSpecHits", "HcalBarrelHits", - "HcalEndcapNHits", "HcalEndcapPInsertHits", "HcalFarForwardZDCHits", "LFHCALHits"}; - - std::vector m_calorechit_collection_names_in = {"B0ECalRecHits_aligned", - "EcalBarrelImagingRecHits_aligned", - "EcalBarrelScFiRecHits_aligned", - "EcalEndcapNRecHits_aligned", - "EcalEndcapPRecHits_aligned", - "EcalFarForwardZDCRecHits_aligned", - "EcalLumiSpecRecHits_aligned", - "HcalBarrelRecHits_aligned", - "HcalEndcapNRecHits_aligned", - "HcalEndcapPInsertRecHits_aligned", - "HcalFarForwardZDCRecHits_aligned", - "LFHCALRecHits_aligned"}; - - std::vector m_calorechit_collection_names_out = {"B0ECalRecHits", - "EcalBarrelImagingRecHits", - "EcalBarrelScFiRecHits", - "EcalEndcapNRecHits", - "EcalEndcapPRecHits", - "EcalFarForwardZDCRecHits", - "EcalLumiSpecRecHits", - "HcalBarrelRecHits", - "HcalEndcapNRecHits", - "HcalEndcapPInsertRecHits", - "HcalFarForwardZDCRecHits", - "LFHCALRecHits"}; - - std::vector m_calorechitassociation_collection_names_in = { - "B0ECalRawHitAssociations", - "EcalBarrelImagingRawHitAssociations", - "EcalBarrelScFiRawHitAssociations", - "EcalEndcapNRawHitAssociations", - "EcalEndcapPRawHitAssociations", - "EcalFarForwardZDCRawHitAssociations", - "EcalLumiSpecRawHitAssociations", - "HcalBarrelRawHitAssociations", - "HcalEndcapNRawHitAssociations", - "HcalEndcapPInsertRawHitAssociations", - "HcalFarForwardZDCRawHitAssociations", - "LFHCALRawHitAssociations"}; - - std::vector m_calorechitassociation_collection_names_out = { - "B0ECalRawHitAssociations", - "EcalBarrelImagingRawHitAssociations", - "EcalBarrelScFiRawHitAssociations", - "EcalEndcapNRawHitAssociations", - "EcalEndcapPRawHitAssociations", - "EcalFarForwardZDCRawHitAssociations", - "EcalLumiSpecRawHitAssociations", - "HcalBarrelRawHitAssociations", - "HcalEndcapNRawHitAssociations", - "HcalEndcapPInsertRawHitAssociations", - "HcalFarForwardZDCRawHitAssociations", - "LFHCALRawHitAssociations"}; - - PodioInput m_event_header_in{this, - {.name = "EventHeader", .is_optional = true}}; - PodioOutput m_event_header_out{this, "EventHeader"}; - - PodioInput m_mcparticles_in{this, {.name = "MCParticles"}}; - PodioOutput m_mcparticles_out{this, "MCParticles"}; - - VariadicPodioInput m_trackerhits_in{ - this, {.names = m_trackerhit_collection_names, .is_optional = true}}; - VariadicPodioOutput m_trackerhits_out{this, - m_trackerhit_collection_names_out}; - - VariadicPodioInput m_trackerhitsAsso_in{ - this, {.names = m_simtrackerhitAsso_collection_names, .is_optional = true}}; - VariadicPodioOutput m_trackerhitsAsso_out{ - this, m_simtrackerhitAsso_collection_names_out}; - - VariadicPodioOutput m_rawhitlinks_out{ - this, m_rawhitlink_collection_names_out}; - VariadicPodioOutput m_simtrackerhits_out{ - this, m_simtrackerhit_collection_names_out}; - - VariadicPodioInput m_rawhit_in{ - this, {.names = m_rawhit_collection_names, .is_optional = true}}; - VariadicPodioOutput m_rawhit_out{this, m_rawhit_collection_names_out}; - - VariadicPodioInput m_calorawhit_in{ - this, {.names = m_calorawhit_collection_names_in, .is_optional = true}}; - VariadicPodioOutput m_calorawhit_out{ - this, m_calorawhit_collection_names_out}; - - VariadicPodioOutput m_calorawhitlinks_out{ - this, m_calorawhitlink_collection_names}; - VariadicPodioOutput m_simcalorimeterhits_out{ - this, m_simcalorimeterhit_collection_names_out}; - - VariadicPodioInput m_calorechit_in{ - this, {.names = m_calorechit_collection_names_in, .is_optional = true}}; - VariadicPodioOutput m_calorechit_out{this, - m_calorechit_collection_names_out}; - - VariadicPodioInput m_calorechitassociation_in{ - this, {.names = m_calorechitassociation_collection_names_in, .is_optional = true}}; - VariadicPodioOutput m_calorechitassociation_out{ - this, m_calorechitassociation_collection_names_out}; + using calCollNames = std::array; + std::array m_calCollNames = {{ + { + "B0ECalRecHits_aligned", + "B0ECalRecHits", + "B0ECalRawHitAssociations", + "B0ECalRawHitLinks", + "B0ECalHits", + "B0ECalRawHits", + }, + { + "EcalBarrelImagingRecHits_aligned", + "EcalBarrelImagingRecHits", + "EcalBarrelImagingRawHitAssociations", + "EcalBarrelImagingRawHitLinks", + "EcalBarrelImagingHits", + "EcalBarrelImagingRawHits", + }, + { + "EcalBarrelScFiRecHits_aligned", + "EcalBarrelScFiRecHits", + "EcalBarrelScFiRawHitAssociations", + "EcalBarrelScFiRawHitLinks", + "EcalBarrelScFiHits", + "EcalBarrelScFiRawHits", + }, + { + "EcalEndcapNRecHits_aligned", + "EcalEndcapNRecHits", + "EcalEndcapNRawHitAssociations", + "EcalEndcapNRawHitLinks", + "EcalEndcapNHits", + "EcalEndcapNRawHits", + }, + { + "EcalEndcapPRecHits_aligned", + "EcalEndcapPRecHits", + "EcalEndcapPRawHitAssociations", + "EcalEndcapPRawHitLinks", + "EcalEndcapPHits", + "EcalEndcapPRawHits", + }, + { + "EcalFarForwardZDCRecHits_aligned", + "EcalFarForwardZDCRecHits", + "EcalFarForwardZDCRawHitAssociations", + "EcalFarForwardZDCRawHitLinks", + "EcalFarForwardZDCHits", + "EcalFarForwardZDCRawHits", + }, + { + "EcalLumiSpecRecHits_aligned", + "EcalLumiSpecRecHits", + "EcalLumiSpecRawHitAssociations", + "EcalLumiSpecRawHitLinks", + "EcalLumiSpecHits", + "EcalLumiSpecRawHits", + }, + { + "HcalBarrelRecHits_aligned", + "HcalBarrelRecHits", + "HcalBarrelRawHitAssociations", + "HcalBarrelRawHitLinks", + "HcalBarrelHits", + "HcalBarrelRawHits", + }, + { + "HcalEndcapNRecHits_aligned", + "HcalEndcapNRecHits", + "HcalEndcapNRawHitAssociations", + "HcalEndcapNRawHitLinks", + "HcalEndcapNHits", + "HcalEndcapNRawHits", + }, + { + "HcalEndcapPInsertRecHits_aligned", + "HcalEndcapPInsertRecHits", + "HcalEndcapPInsertRawHitAssociations", + "HcalEndcapPInsertRawHitLinks", + "HcalEndcapPInsertHits", + "HcalEndcapPInsertRawHits", + }, + { + "HcalFarForwardZDCRecHits_aligned", + "HcalFarForwardZDCRecHits", + "HcalFarForwardZDCRawHitAssociations", + "HcalFarForwardZDCRawHitLinks", + "HcalFarForwardZDCHits", + "HcalFarForwardZDCRawHits", + }, + { + "LFHCALRecHits_aligned", + "LFHCALRecHits", + "LFHCALRawHitAssociations", + "LFHCALRawHitLinks", + "LFHCALHits", + "LFHCALRawHits", + }, + }}; + + + std::vector getTrkCollectionNames(TrkCollectionType type) const { + std::vector names; + names.reserve(m_trkCollNames.size()); + for (const auto& collections : m_trkCollNames) { + names.push_back(collections[type]); + } + return names; + } - PodioOutput m_event_header_phy_out{this, "EventHeader_PHY"}; - PodioOutput m_event_header_bkg_out{this, "EventHeader_BKG"}; + std::vector getCalCollectionNames(CalCollectionType type) const { + std::vector names; + names.reserve(m_calCollNames.size()); + for (const auto& collections : m_calCollNames) { + names.push_back(collections[type]); + } + return names; + } - // For QA - PodioOutput m_ecalhitsintower_phy_out{this, "ECalHitsInTower_PHY"}; - PodioOutput m_ecalhitsintower_bkg_out{this, "ECalHitsInTower_BKG"}; + + PodioInput m_eventHeader_inCol{this, + {.name = "EventHeader", .is_optional = true}}; + PodioOutput m_eventHeader_outCol{this, "EventHeader"}; + + PodioInput m_mcParticles_inCol{this, {.name = "MCParticles"}}; + PodioOutput m_mcParticles_outCol{this, "MCParticles"}; + + // tracker collections + VariadicPodioInput m_trackerHits_inCols{ + this,{.names = getTrkCollectionNames(kTrackerHitAligned), .is_optional = true}}; + VariadicPodioOutput m_trackerHits_outCols{ + this, getTrkCollectionNames(kTrackerHit)}; + + VariadicPodioInput m_trackerHitsAsso_inCols{ + this, {.names = getTrkCollectionNames(kTrackerHitAssociation), .is_optional = true}}; + VariadicPodioOutput m_trackerHitsAsso_outCols{ + this, getTrkCollectionNames(kTrackerHitAssociation)}; + + // VariadicPodioOutput m_recoTrackerHitLinks_inCols{ + // this, getTrkCollectionNames(kTrackerHitLink)}; + VariadicPodioOutput m_recoTrackerHitLinks_outCols{ + this, getTrkCollectionNames(kTrackerHitLink)}; + + VariadicPodioOutput m_simTrackerHits_outCols{ + this, getTrkCollectionNames(kSimTrackerHit)}; + + VariadicPodioInput m_rawTrackerHit_inCols{ + this, {.names = getTrkCollectionNames(kRawTrackerHit), .is_optional = true}}; + VariadicPodioOutput m_rawTrackerHit_outCols{ + this, getTrkCollectionNames(kRawTrackerHit)}; + + // calorimeter collections + VariadicPodioInput m_rawCalorimeterHit_inCols{ + this, {.names = getCalCollectionNames(kRawCalorimeterHit), .is_optional = true}}; + VariadicPodioOutput m_rawCalorimeterHit_outCols{ + this, getCalCollectionNames(kRawCalorimeterHit)}; + + VariadicPodioOutput + m_mcRecoCalorimeterHitLink_outCols{this, getCalCollectionNames(kCalorimeterHitLink)}; + VariadicPodioOutput m_simCalorimeterHit_outCols{ + this, getCalCollectionNames(kSimCalorimeterHit)}; + + VariadicPodioInput m_calorimeterHit_inCols{ + this, {.names = getCalCollectionNames(kCalorimeterHitAligned), .is_optional = true}}; + VariadicPodioOutput m_calorimeterHit_outCols{ + this, getCalCollectionNames(kCalorimeterHit)}; + + VariadicPodioInput + m_mcRecoCalorimeterHitAssociation_inCols{ + this, {.names = getCalCollectionNames(kCalorimeterHitAssociation), .is_optional = true}}; + VariadicPodioOutput + m_mcRecoCalorimeterHitAssociation_outCols{ + this, getCalCollectionNames(kCalorimeterHitAssociation)}; + + PodioOutput m_eventHeaderPhy_outCols{this, "EventHeader_PHY"}; + PodioOutput m_eventHeaderBkg_outCols{this, "EventHeader_BKG"}; - PodioOutput m_ecaltowers_phy_out{this, "ECalTowers_PHY"}; - PodioOutput m_ecaltowers_bkg_out{this, "ECalTowers_BKG"}; TimeframeSplitter(); @@ -357,7 +418,7 @@ struct TimeframeSplitter : public JEventUnfolder { // == Global Variables ======================= bool bInitialLoop = true; - Int_t m_multiTriggerThreshold[4] = {1, 4, 20, 20}; + unsigned int m_multiTriggerThreshold[4] = {1, 4, 20, 20}; size_t iniTrkHitPoint[15] = {0}; // B0Trk, size_t iniCalHitPoint[15] = {0}; // B0Trk, bool m_bDetLastHits[10] = {false, false, false, false, false, false, false, false, false, false}; @@ -365,26 +426,26 @@ struct TimeframeSplitter : public JEventUnfolder { bool m_bOnceTriggered = false; bool m_bScanedAllTimeWindows = false; - Int_t targetDetId = 0; + unsigned int targetDetId = 0; size_t iTimeSlice = 0; - std::vector m_vPhysCooTimes = {}; + std::vector m_vPhysCooTimes = {}; // == Global Variables ======================= struct TimeWindowSummary { size_t count = 0; - Double_t time_sum = 0.0; - size_t next_start_index = 0; + double timeSum = 0.0; + size_t nextStartID = 0; - Double_t average_time() const { return count == 0 ? 0.0 : time_sum / count; } + double average_time() const { return count == 0 ? 0.0 : timeSum / count; } }; using TrackerAssociationIndex = std::unordered_map>; using CalorimeterAssociationIndex = std::unordered_map>; - std::vector m_tracker_association_indices; - std::vector m_calorimeter_association_indices; + std::vector m_trkAssoIds; + std::vector m_calAssoIds; - static std::uint64_t object_id_key(const podio::ObjectID& object_id); + static std::uint64_t objIdKey(const podio::ObjectID& object_id); static TrackerAssociationIndex buildTrkAssoId(const edm4eic::MCRecoTrackerHitAssociationCollection* associations); @@ -392,38 +453,40 @@ struct TimeframeSplitter : public JEventUnfolder { static CalorimeterAssociationIndex buildCalAssoId(const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations); - static bool overlaps_time_window(Double_t hitTime, Double_t resolution, Double_t window_start, - Double_t window_end); - static bool is_after_time_window(Double_t hitTime, Double_t resolution, Double_t window_end); + static bool overlapsTimeWindow(double hitTime, double resolution, double window_start, + double window_end); + static bool judgeOverTimeWindow(double hitTime, double resolution, double window_end); - static bool isValidEtaPhiBin(Int_t etaBin, Int_t phiBin); + static bool isValidEtaPhiBin(int etaBin, int phiBin); - static bool is_hit_in_time_slice(Double_t hitTime, Double_t time_resolution, - Double_t time_slice_start, Double_t time_slice_end); + static bool judgeHitInTimeSlice(double hitTime, double timeResolution, + double timeslice_start, double timeslice_end); template - inline void etaPhiCalc(const HitT& hit, Double_t& hitEta, Double_t& hitPhi) { - const Double_t hitX = hit.getPosition()[0]; - const Double_t hitY = hit.getPosition()[1]; - const Double_t hitZ = hit.getPosition()[2]; - const Double_t hitR = TMath::Sqrt(hitX * hitX + hitY * hitY + hitZ * hitZ); + inline void etaPhiCalc(const HitT& hit, double& hitEta, double& hitPhi) { + const double hitX = hit.getPosition()[0]; + const double hitY = hit.getPosition()[1]; + const double hitZ = hit.getPosition()[2]; + const double hitR = std::sqrt(hitX * hitX + hitY * hitY + hitZ * hitZ); if (hitR <= 0.0) { hitEta = 0.0; hitPhi = 0.0; return; } - const Double_t cosTheta = std::clamp(hitZ / hitR, -1.0, 1.0); - const Double_t hitTheta = TMath::ACos(cosTheta); - hitEta = -TMath::Log(TMath::Tan(hitTheta / 2.0)); - hitPhi = TMath::ATan2(hitY, hitX); + + const double cosTheta = std::clamp(hitZ / hitR, -1.0, 1.0); + const double hitTheta = std::acos(cosTheta); + + hitEta = -std::log(std::tan(hitTheta / 2.0)); + hitPhi = std::atan2(hitY, hitX); } - static std::pair etaPhiBins(Double_t hitEta, Double_t hitPhi, Double_t etaMin, - Double_t etaMax, Int_t bShift); + static std::pair etaPhiBins(double hitEta, double hitPhi, double etaMin, + double etaMax, int bShift); template - void fillEtaPhiGrids(const CollectionT* hits, size_t& iniHitID, Double_t timeResolution, - Double_t timeSliceStart, Double_t timeSliceEnd, EtaPhiGrid& grid, + void fillEtaPhiGrids(const CollectionT* hits, size_t& iniHitID, double timeResolution, + double timeSliceStart, double timeSliceEnd, EtaPhiGrid& grid, EtaPhiGrid& gridShifted, EtaPhiTimeGrid& gridTime, EtaPhiTimeGrid& gridShiftedTime, BinFunc binFunc) { if (hits == nullptr) @@ -432,16 +495,16 @@ struct TimeframeSplitter : public JEventUnfolder { const size_t hitCount = hits->size(); for (size_t iHit = iniHitID; iHit < hitCount; ++iHit) { const auto& hit = hits->at(iHit); - const Double_t hitT = hit.getTime(); + const double hitT = hit.getTime(); if (hitT - timeResolution > timeSliceEnd) { iniHitID = iHit; break; } - if (!is_hit_in_time_slice(hitT, timeResolution, timeSliceStart, timeSliceEnd)) + if (!judgeHitInTimeSlice(hitT, timeResolution, timeSliceStart, timeSliceEnd)) continue; - Double_t hitEta = 0.0; - Double_t hitPhi = 0.0; + double hitEta = 0.0; + double hitPhi = 0.0; etaPhiCalc(hit, hitEta, hitPhi); const auto [eta0, phi0] = binFunc(hitEta, hitPhi, 0); @@ -459,10 +522,10 @@ struct TimeframeSplitter : public JEventUnfolder { template void fillEtaPhiGridsMatched(const CollectionT* collection, size_t& iniHitID, - Double_t timeResolution, Double_t timeSliceStart, - Double_t timeSliceEnd, const EtaPhiGrid& baseGrid, + double timeResolution, double timeSliceStart, + double timeSliceEnd, const EtaPhiGrid& baseGrid, const EtaPhiGrid& baseGridShifted, EtaPhiGrid& compGrid, - EtaPhiGrid& compGridShifted, Int_t baseThreshold, + EtaPhiGrid& compGridShifted, unsigned int baseThreshold, EtaPhiTimeGrid& compGridTime, EtaPhiTimeGrid& compGridShiftedTime, BinFunc binFunc) { if (collection == nullptr) @@ -470,16 +533,16 @@ struct TimeframeSplitter : public JEventUnfolder { const size_t hitCount = collection->size(); for (size_t iHit = iniHitID; iHit < hitCount; ++iHit) { - const Double_t hitT = collection->at(iHit).getTime(); + const double hitT = collection->at(iHit).getTime(); if (hitT - timeResolution > timeSliceEnd) { iniHitID = iHit; break; } - if (!is_hit_in_time_slice(hitT, timeResolution, timeSliceStart, timeSliceEnd)) + if (!judgeHitInTimeSlice(hitT, timeResolution, timeSliceStart, timeSliceEnd)) continue; - Double_t hitEta = 0.0; - Double_t hitPhi = 0.0; + double hitEta = 0.0; + double hitPhi = 0.0; etaPhiCalc(collection->at(iHit), hitEta, hitPhi); const auto [eta0, phi0] = binFunc(hitEta, hitPhi, 0); @@ -499,68 +562,68 @@ struct TimeframeSplitter : public JEventUnfolder { const EtaPhiGrid& gridShifted, const EtaPhiTimeGrid& gridTime0, const EtaPhiTimeGrid& gridShiftedTime, - Int_t threshold, Double_t& averageTime); + unsigned int threshold, double& averageTime); - static Double_t averageSelectedTriggerTime(const std::array& values, - const std::array& times, + static double averageSelectedTriggerTime(const std::array& values, + const std::array& times, std::initializer_list indices, - Double_t fallbackTime); + double fallbackTime); - Double_t tracker_time_resolution(size_t detector_id); + double trkTimeResolution(size_t detectorID); template - TimeWindowSummary count_hits_in_window(const CollectionT* collection, size_t start_index, - Double_t resolution, Double_t window_start, - Double_t window_end) const { + TimeWindowSummary countHitsInTimeWindow(const CollectionT* collection, size_t startHitID, + double resolution, double window_start, + double window_end) const { TimeWindowSummary summary; - summary.next_start_index = start_index; + summary.nextStartID = startHitID; if (collection == nullptr) return summary; - for (size_t i = start_index; i < collection->size(); ++i) { + for (size_t i = startHitID; i < collection->size(); ++i) { const auto& hit = collection->at(i); - const Double_t hitTime = hit.getTime(); - if (is_after_time_window(hitTime, resolution, window_end)) + const double hitTime = hit.getTime(); + if (judgeOverTimeWindow(hitTime, resolution, window_end)) break; // Drop hits which cannot overlap the next window (which begins at window_end) if (hitTime + resolution < window_end) { - summary.next_start_index = i + 1; + summary.nextStartID = i + 1; } - if (overlaps_time_window(hitTime, resolution, window_start, window_end)) { + if (overlapsTimeWindow(hitTime, resolution, window_start, window_end)) { ++summary.count; - summary.time_sum += hitTime; + summary.timeSum += hitTime; } } return summary; } template - static void copy_tracker_hit_with_relations( - const edm4eic::TrackerHit& tracker_hit, + static void copyTrkHitWithRelations( + const edm4eic::TrackerHit& trackerHit, const edm4eic::MCRecoTrackerHitAssociationCollection* associations, - const TrackerAssociationIndex& association_index, TrackerHitOutputT& tracker_hits_out, - RawHitOutputT& raw_hits_out, AssociationOutputT& associations_out, + const TrackerAssociationIndex& association_index, TrackerHitOutputT& trackerHits_out, + RawHitOutputT& rawHits_out, AssociationOutputT& associations_out, std::unique_ptr& simHits_out, std::unique_ptr& links_out, std::unique_ptr& mc_particles_out) { - auto trackerHitCopied = tracker_hit.clone(); + auto trackerHitCopied = trackerHit.clone(); trackerHitCopied.setRawHit(edm4eic::RawTrackerHit()); - if (associations == nullptr || !tracker_hit.getRawHit().isAvailable()) { - tracker_hits_out->push_back(trackerHitCopied); + if (associations == nullptr || !trackerHit.getRawHit().isAvailable()) { + trackerHits_out->push_back(trackerHitCopied); return; } - const auto rawHitId = tracker_hit.getRawHit().getObjectID(); + const auto rawHitId = trackerHit.getRawHit().getObjectID(); - auto rawHitCopied = tracker_hit.getRawHit().clone(); - raw_hits_out->push_back(rawHitCopied); + auto rawHitCopied = trackerHit.getRawHit().clone(); + rawHits_out->push_back(rawHitCopied); trackerHitCopied.setRawHit(rawHitCopied); - const auto assocIterCal = association_index.find(object_id_key(rawHitId)); + const auto assocIterCal = association_index.find(objIdKey(rawHitId)); if (assocIterCal != association_index.end()) { for (const size_t index : assocIterCal->second) { @@ -583,30 +646,28 @@ struct TimeframeSplitter : public JEventUnfolder { simHits_out->push_back(simHitCopied); - auto copied_association = associations_out->create(); - copied_association.setWeight(association.getWeight()); - copied_association.setRawHit(rawHitCopied); - copied_association.setSimHit(simHitCopied); + auto copiedAsso = associations_out->create(); + copiedAsso.setWeight(association.getWeight()); + copiedAsso.setRawHit(rawHitCopied); + copiedAsso.setSimHit(simHitCopied); - auto copied_link = links_out->create(); - copied_link.setWeight(association.getWeight()); - copied_link.setFrom(rawHitCopied); - copied_link.setTo(simHitCopied); + auto copiedLink = links_out->create(); + copiedLink.setWeight(association.getWeight()); + copiedLink.setFrom(rawHitCopied); + copiedLink.setTo(simHitCopied); } } - tracker_hits_out->push_back(trackerHitCopied); + trackerHits_out->push_back(trackerHitCopied); } - static std::pair backEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift); + static std::pair backEndEtaPhiBins(double hitEta, double hitPhi, int bShift); - static std::pair barrelEtaPhiBins(Double_t hitEta, Double_t hitPhi, Int_t bShift); + static std::pair barrelEtaPhiBins(double hitEta, double hitPhi, int bShift); - static std::pair forwardEndEtaPhiBins(Double_t hitEta, Double_t hitPhi, - Int_t bShift); + static std::pair forwardEndEtaPhiBins(double hitEta, double hitPhi, + int bShift); Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override; - void thetaPhiBinCalc(edm4eic::TrackerHit hit, Int_t& thetaID1, Int_t& phiID1, Int_t& thetaID2, - Int_t& phiID2); }; diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index 085e028f19..c0e4506e4a 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -1,4 +1,3 @@ - // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2026 Takuya Kumaoka @@ -7,10 +6,7 @@ #include #include #include -#include -#include #include -#include #include #include @@ -21,64 +17,59 @@ extern "C" { void InitPlugin(JApplication* app) { - std::vector m_simtrackerhit_collection_names_aligned = { - "TOFBarrelRecHits_aligned", "TOFEndcapRecHits_aligned", - "MPGDBarrelRecHits_aligned", "OuterMPGDBarrelRecHits_aligned", - "BackwardMPGDEndcapRecHits_aligned", "ForwardMPGDEndcapRecHits_aligned", - "SiBarrelVertexRecHits_aligned", "SiBarrelTrackerRecHits_aligned", - "SiEndcapTrackerRecHits_aligned", "B0TrackerRecHits_aligned", - "TaggerTrackerRecHits_aligned", "ForwardRomanPotRecHits_aligned", - "ForwardOffMTrackerRecHits_aligned"}; - - std::vector m_simtrackerhit_collection_names = { - "TOFBarrelRecHits", "TOFEndcapRecHits", "MPGDBarrelRecHits", - "OuterMPGDBarrelRecHits", "BackwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits", - "SiBarrelVertexRecHits", "SiBarrelTrackerRecHits", "SiEndcapTrackerRecHits", - "B0TrackerRecHits", "TaggerTrackerRecHits", "ForwardRomanPotRecHits", - "ForwardOffMTrackerRecHits"}; + const std::vector> trkHitTimeCollectionNames = { + {"TOFBarrelRecHits", "TOFBarrelRecHits_aligned"}, + {"TOFEndcapRecHits", "TOFEndcapRecHits_aligned"}, + {"MPGDBarrelRecHits", "MPGDBarrelRecHits_aligned"}, + {"OuterMPGDBarrelRecHits", "OuterMPGDBarrelRecHits_aligned"}, + {"BackwardMPGDEndcapRecHits", "BackwardMPGDEndcapRecHits_aligned"}, + {"ForwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits_aligned"}, + {"SiBarrelVertexRecHits", "SiBarrelVertexRecHits_aligned"}, + {"SiBarrelTrackerRecHits", "SiBarrelTrackerRecHits_aligned"}, + {"SiEndcapTrackerRecHits", "SiEndcapTrackerRecHits_aligned"}, + {"B0TrackerRecHits", "B0TrackerRecHits_aligned"}, + {"TaggerTrackerRecHits", "TaggerTrackerRecHits_aligned"}, + {"ForwardRomanPotRecHits", "ForwardRomanPotRecHits_aligned"}, + {"ForwardOffMTrackerRecHits", "ForwardOffMTrackerRecHits_aligned"}, + }; - std::vector m_simcalorechit_collection_names = {"B0ECalRecHits", - "EcalBarrelImagingRecHits", - "EcalBarrelScFiRecHits", - "EcalEndcapNRecHits", - "EcalEndcapPRecHits", - "EcalFarForwardZDCRecHits", - "EcalLumiSpecRecHits", - "HcalBarrelRecHits", - "HcalEndcapNRecHits", - "HcalEndcapPInsertRecHits", - "HcalFarForwardZDCRecHits", - "LFHCALRecHits"}; + const std::vector> calHitTimeCollectionNames = { + {"B0ECalRecHits", "B0ECalRecHits_aligned"}, + {"EcalBarrelImagingRecHits", "EcalBarrelImagingRecHits_aligned"}, + {"EcalBarrelScFiRecHits", "EcalBarrelScFiRecHits_aligned"}, + {"EcalEndcapNRecHits", "EcalEndcapNRecHits_aligned"}, + {"EcalEndcapPRecHits", "EcalEndcapPRecHits_aligned"}, + {"EcalFarForwardZDCRecHits", "EcalFarForwardZDCRecHits_aligned"}, + {"EcalLumiSpecRecHits", "EcalLumiSpecRecHits_aligned"}, + {"HcalBarrelRecHits", "HcalBarrelRecHits_aligned"}, + {"HcalEndcapNRecHits", "HcalEndcapNRecHits_aligned"}, + {"HcalEndcapPInsertRecHits", "HcalEndcapPInsertRecHits_aligned"}, + {"HcalFarForwardZDCRecHits", "HcalFarForwardZDCRecHits_aligned"}, + {"LFHCALRecHits", "LFHCALRecHits_aligned"}, + }; - std::vector m_simcalorechit_collection_names_aligned = { - "B0ECalRecHits_aligned", - "EcalBarrelImagingRecHits_aligned", - "EcalBarrelScFiRecHits_aligned", - "EcalEndcapNRecHits_aligned", - "EcalEndcapPRecHits_aligned", - "EcalFarForwardZDCRecHits_aligned", - "EcalLumiSpecRecHits_aligned", - "HcalBarrelRecHits_aligned", - "HcalEndcapNRecHits_aligned", - "HcalEndcapPInsertRecHits_aligned", - "HcalFarForwardZDCRecHits_aligned", - "LFHCALRecHits_aligned"}; InitJANAPlugin(app); - const bool split_timeframes = + const bool splitTimeframes = app->RegisterParameter("split_timeframes", false, "Enable timeframe splitting"); - if (!split_timeframes) { + if (!splitTimeframes) { return; } - app->Add(new JOmniFactoryGeneratorT>( - "timeAlignment", m_simtrackerhit_collection_names, m_simtrackerhit_collection_names_aligned, - app, JEventLevel::Timeslice)); + for (const auto& [inName, outName] : trkHitTimeCollectionNames) { + app->Add( + new JOmniFactoryGeneratorT>( + outName, {inName}, {outName}, app, + JEventLevel::Timeslice)); + } - app->Add(new JOmniFactoryGeneratorT>( - "CalRecTimeAlignment", m_simcalorechit_collection_names, - m_simcalorechit_collection_names_aligned, app, JEventLevel::Timeslice)); + for (const auto& [inName, outName] : calHitTimeCollectionNames) { + app->Add( + new JOmniFactoryGeneratorT>( + outName, {inName}, {outName}, app, + JEventLevel::Timeslice)); + } // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); From 47582e6debcdda3fb468b31c34e38e3ce8ad3824 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 04:44:50 +0000 Subject: [PATCH 28/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../event_building/HitTimeAlignment.h | 8 +- .../event_building/HitTimeAlignment_factory.h | 2 +- src/global/splitting/TimeframeSplitter.cc | 102 ++++++-------- src/global/splitting/TimeframeSplitter.h | 131 ++++++++---------- src/global/splitting/splitting.cc | 80 +++++------ 5 files changed, 150 insertions(+), 173 deletions(-) diff --git a/src/algorithms/event_building/HitTimeAlignment.h b/src/algorithms/event_building/HitTimeAlignment.h index 9f292eb346..24f79e1f3a 100644 --- a/src/algorithms/event_building/HitTimeAlignment.h +++ b/src/algorithms/event_building/HitTimeAlignment.h @@ -42,10 +42,10 @@ class HitTimeAlignment : public HitTimeAlignmentAlgorithm, std::vector sortedHits; sortedHits.reserve(hits_in->size()); for (const auto& hit : *hits_in) { - auto copiedHit = hit.clone(); - const auto position = hit.getPosition(); - const auto radius = std::sqrt(position[0] * position[0] + position[1] * position[1] + - position[2] * position[2]); + auto copiedHit = hit.clone(); + const auto position = hit.getPosition(); + const auto radius = std::sqrt(position[0] * position[0] + position[1] * position[1] + + position[2] * position[2]); const auto aveTimeOfFlight = radius * this->m_cfg.refInverseVelocity; copiedHit.setTime(hit.getTime() - aveTimeOfFlight); sortedHits.push_back(copiedHit); diff --git a/src/factories/event_building/HitTimeAlignment_factory.h b/src/factories/event_building/HitTimeAlignment_factory.h index 06aadba312..17b55e0f8c 100644 --- a/src/factories/event_building/HitTimeAlignment_factory.h +++ b/src/factories/event_building/HitTimeAlignment_factory.h @@ -43,4 +43,4 @@ class HitTimeAlignment_factory } }; -} // namespace eicrecon \ No newline at end of file +} // namespace eicrecon diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 7415f5ec99..10b40cf14e 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -36,7 +36,7 @@ TimeframeSplitter::TrackerAssociationIndex TimeframeSplitter::buildTrkAssoId( for (size_t assoId = 0; assoId < associations->size(); ++assoId) { const auto association = associations->at(assoId); - const auto rawHit = association.getRawHit(); + const auto rawHit = association.getRawHit(); if (!rawHit.isAvailable()) continue; index[objIdKey(rawHit.getObjectID())].push_back(assoId); @@ -55,7 +55,7 @@ TimeframeSplitter::CalorimeterAssociationIndex TimeframeSplitter::buildCalAssoId for (size_t assoId = 0; assoId < associations->size(); ++assoId) { const auto association = associations->at(assoId); - const auto rawHit = association.getRawHit(); + const auto rawHit = association.getRawHit(); if (!rawHit.isAvailable()) continue; index[objIdKey(rawHit.getObjectID())].push_back(assoId); @@ -64,13 +64,12 @@ TimeframeSplitter::CalorimeterAssociationIndex TimeframeSplitter::buildCalAssoId return index; } -bool TimeframeSplitter::overlapsTimeWindow(double hitTime, double resolution, - double window_start, double window_end) { +bool TimeframeSplitter::overlapsTimeWindow(double hitTime, double resolution, double window_start, + double window_end) { return hitTime + resolution > window_start && hitTime - resolution < window_end; } -bool TimeframeSplitter::judgeOverTimeWindow(double hitTime, double resolution, - double window_end) { +bool TimeframeSplitter::judgeOverTimeWindow(double hitTime, double resolution, double window_end) { return hitTime - resolution >= window_end; } @@ -79,14 +78,12 @@ bool TimeframeSplitter::isValidEtaPhiBin(int etaBin, int phiBin) { } bool TimeframeSplitter::judgeHitInTimeSlice(double hitTime, double timeResolution, - double timeslice_start, double timeslice_end) { - return !(hitTime + timeResolution < timeslice_start || - hitTime - timeResolution > timeslice_end); + double timeslice_start, double timeslice_end) { + return !(hitTime + timeResolution < timeslice_start || hitTime - timeResolution > timeslice_end); } -std::pair TimeframeSplitter::etaPhiBins(double hitEta, double hitPhi, - double etaMin, double etaMax, - int bShift) { +std::pair TimeframeSplitter::etaPhiBins(double hitEta, double hitPhi, double etaMin, + double etaMax, int bShift) { const double etaBinWidth = (etaMax - etaMin) / kEtaPhiBins; const double phiMin = -std::numbers::pi; const double phiMax = std::numbers::pi; @@ -109,12 +106,10 @@ std::pair TimeframeSplitter::etaPhiBins(double hitEta, double hitPhi, return {etaBin, phiBin}; } -size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0, - const EtaPhiGrid& gridShifted, - const EtaPhiTimeGrid& gridTime0, - const EtaPhiTimeGrid& gridShiftedTime, - unsigned int threshold, double& averageTime) { - size_t count = 0; +size_t TimeframeSplitter::countGridCellsWithMultiplicity( + const EtaPhiGrid& grid0, const EtaPhiGrid& gridShifted, const EtaPhiTimeGrid& gridTime0, + const EtaPhiTimeGrid& gridShiftedTime, unsigned int threshold, double& averageTime) { + size_t count = 0; double timeSum = 0.0; for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { @@ -133,10 +128,10 @@ size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0 } double TimeframeSplitter::averageSelectedTriggerTime(const std::array& values, - const std::array& times, - std::initializer_list indices, - double fallbackTime) { - size_t count = 0; + const std::array& times, + std::initializer_list indices, + double fallbackTime) { + size_t count = 0; double timeSum = 0.0; for (const size_t index : indices) { if (values[index] <= 0.0) @@ -155,16 +150,14 @@ double TimeframeSplitter::trkTimeResolution(size_t detectorID) { return timeResolution_SiMaps(); } -std::pair TimeframeSplitter::backEndEtaPhiBins(double hitEta, double hitPhi, - int bShift) { +std::pair TimeframeSplitter::backEndEtaPhiBins(double hitEta, double hitPhi, int bShift) { // MPGD backward Endcap range -3.6 < eta < -1.72, +5%: -3.78 < eta < -1.634 const double etaMin = -3.78; const double etaMax = -1.634; return etaPhiBins(hitEta, hitPhi, etaMin, etaMax, bShift); } -std::pair TimeframeSplitter::barrelEtaPhiBins(double hitEta, double hitPhi, - int bShift) { +std::pair TimeframeSplitter::barrelEtaPhiBins(double hitEta, double hitPhi, int bShift) { // MPGD barrel In range -1.49 < eta < 1.722, +5%: -1.56 < eta < 1.81 // MPGD barrel Out range -1.56 < eta < 1.61, +5%: -1.64 < eta < 1.70 // TOF barrel range -1.39 < eta < 1.39, +5%: -1.46 < eta < 1.46 @@ -175,7 +168,7 @@ std::pair TimeframeSplitter::barrelEtaPhiBins(double hitEta, double hi } std::pair TimeframeSplitter::forwardEndEtaPhiBins(double hitEta, double hitPhi, - int bShift) { + int bShift) { // MPGD forward Endcap range 2.0 < eta < 3.35, +5%: 1.90 < eta < 3.52 // TOF forward Endcap range 1.86 < eta < 3.85, +5%: 1.77 < eta < 4.04 // ECal forward Endcap range 1.4 < eta < 3.5, +5%: 1.33 < eta < 3.68 @@ -186,8 +179,8 @@ std::pair TimeframeSplitter::forwardEndEtaPhiBins(double hitEta, doubl TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent& child, int child_idx) { - const float m_timeframeWidth = timeframeWidth(); - const float m_timesplitWidth = timesplitWidth(); + const float m_timeframeWidth = timeframeWidth(); + const float m_timesplitWidth = timesplitWidth(); const double timeResolution_mpgd = timeResolution_MPGD(); const double timeResolution_tof = timeResolution_ACLGad(); const double timeResolution_emcal = timeResolution_EMCal(); @@ -259,8 +252,8 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent } const size_t nTimeSlices = static_cast(std::floor(m_timeframeWidth / m_timesplitWidth)); - double tsTimeS = 0.0; - double tsTimeE = 0.0; + double tsTimeS = 0.0; + double tsTimeE = 0.0; // Scan the timeframe one time slice at a time. // The scan stops early when a physics trigger fires; otherwise it terminates @@ -341,9 +334,8 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent EtaPhiTimeGrid frontEndIntTimesEtaPhi = {}; EtaPhiTimeGrid frontEndIntTimesEtaPhiShifted = {}; fillEtaPhiGrids(caloRecHitCollsIn.at(kCalEndcapP), iniCalHitPoint[kCalEndcapP], - timeResolution_emcal, tsTimeS, tsTimeE, frontEndCalGrid, - frontEndCalGridShifted, frontEndIntTimesEtaPhi, frontEndIntTimesEtaPhiShifted, - forwardEndEtaPhiBins); + timeResolution_emcal, tsTimeS, tsTimeE, frontEndCalGrid, frontEndCalGridShifted, + frontEndIntTimesEtaPhi, frontEndIntTimesEtaPhiShifted, forwardEndEtaPhiBins); singleTrig[4] = countGridCellsWithMultiplicity( frontEndCalGrid, frontEndCalGridShifted, frontEndIntTimesEtaPhi, frontEndIntTimesEtaPhiShifted, 10, singleTrigTime[4]); @@ -367,17 +359,17 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent frontEndIntTimesEtaPhiMatchedShifted, 1, singleTrigTime[5]); const auto hitsB0 = countHitsInTimeWindow(trackerHitCollsIn.at(kTrkB0), iniTrkHitPoint[kTrkB0], - timeResolution_tof, tsTimeS, tsTimeE); + timeResolution_tof, tsTimeS, tsTimeE); iniTrkHitPoint[kTrkB0] = hitsB0.nextStartID; singleTrig[6] = hitsB0.count; singleTrigTime[6] = hitsB0.average_time(); - double totalZDCEnergy = 0.0; - double totalZDCEnergyTime = 0.0; - const auto* recHitsZDCECal = caloRecHitCollsIn.at(kCalZDC); + double totalZDCEnergy = 0.0; + double totalZDCEnergyTime = 0.0; + const auto* recHitsZDCECal = caloRecHitCollsIn.at(kCalZDC); if (recHitsZDCECal != nullptr) { for (size_t iHit = iniCalHitPoint[kCalZDC]; iHit < recHitsZDCECal->size(); ++iHit) { - const auto& hit = recHitsZDCECal->at(iHit); + const auto& hit = recHitsZDCECal->at(iHit); const double hitTime = hit.getTime(); if (hitTime - timeResolution_emcal > tsTimeE) break; @@ -393,12 +385,12 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent const double etaPhiCalTriggerSum = singleTrig[0] + singleTrig[2] + singleTrig[4]; const double etaPhiCalTrkTriggerSum = singleTrig[1] + singleTrig[3] + singleTrig[5]; - bMutipliTriggers[0] = etaPhiCalTrkTriggerSum > 0 && singleTrig[6] > 4; - bMutipliTriggers[1] = etaPhiCalTrkTriggerSum > 0 && singleTrig[7] > 50; - bMutipliTriggers[2] = etaPhiCalTriggerSum > 0 && singleTrig[6] > 4; - bMutipliTriggers[3] = etaPhiCalTriggerSum > 0 && singleTrig[7] > 0.005; - bMutipliTriggers[4] = etaPhiCalTrkTriggerSum > 1; - bMutipliTriggers[5] = etaPhiCalTriggerSum > 2; + bMutipliTriggers[0] = etaPhiCalTrkTriggerSum > 0 && singleTrig[6] > 4; + bMutipliTriggers[1] = etaPhiCalTrkTriggerSum > 0 && singleTrig[7] > 50; + bMutipliTriggers[2] = etaPhiCalTriggerSum > 0 && singleTrig[6] > 4; + bMutipliTriggers[3] = etaPhiCalTriggerSum > 0 && singleTrig[7] > 0.005; + bMutipliTriggers[4] = etaPhiCalTrkTriggerSum > 1; + bMutipliTriggers[5] = etaPhiCalTriggerSum > 2; if (!bMutipliTriggers[0] && !bMutipliTriggers[1] && !bMutipliTriggers[2] && !bMutipliTriggers[3] && !bMutipliTriggers[4] && !bMutipliTriggers[5]) @@ -463,11 +455,11 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent if (trkCollIn == nullptr) continue; - auto& trkCollOut = m_trackerHits_outCols().at(trkDetID); - const double detTimeReso = trkTimeResolution(trkDetID); - const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); - auto& rawCollOut = m_rawTrackerHit_outCols().at(trkDetID); - auto& trkAssoCollOut = m_trackerHitsAsso_outCols().at(trkDetID); + auto& trkCollOut = m_trackerHits_outCols().at(trkDetID); + const double detTimeReso = trkTimeResolution(trkDetID); + const auto* trkAssoCollIn = trkAssoCollsIn.at(trkDetID); + auto& rawCollOut = m_rawTrackerHit_outCols().at(trkDetID); + auto& trkAssoCollOut = m_trackerHitsAsso_outCols().at(trkDetID); for (size_t iHit = 0; iHit < trkCollIn->size(); ++iHit) { const auto& trkHit = trkCollIn->at(iHit); @@ -478,10 +470,10 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent } iniTrkHitPoint[trkDetID] = iHit; - copyTrkHitWithRelations( - trkHit, trkAssoCollIn, m_trkAssoIds.at(trkDetID), trkCollOut, - rawCollOut, trkAssoCollOut, m_simTrackerHits_outCols().at(trkDetID), - m_recoTrackerHitLinks_outCols().at(trkDetID), m_mcParticles_outCol()); + copyTrkHitWithRelations(trkHit, trkAssoCollIn, m_trkAssoIds.at(trkDetID), trkCollOut, + rawCollOut, trkAssoCollOut, m_simTrackerHits_outCols().at(trkDetID), + m_recoTrackerHitLinks_outCols().at(trkDetID), + m_mcParticles_outCol()); } } // == e == Register Tracker Hits ======================================================= @@ -665,5 +657,3 @@ TimeframeSplitter::Result TimeframeSplitter::Unfold(const JEvent& parent, JEvent } return Result::KeepChildNextParent; } - - diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 573ec0278b..4e9a10f150 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -40,11 +40,9 @@ #include #include - struct TimeframeSplitter : public JEventUnfolder { - Parameter timeframeWidth{this, "timeframe_width", 2000.0, - "Width of each timeframe in ns"}; + Parameter timeframeWidth{this, "timeframe_width", 2000.0, "Width of each timeframe in ns"}; Parameter timesplitWidth{this, "timesplit_width", 20.0, "Width of each timeslice in ns"}; Parameter timeResolution_SiMaps{this, "timeResolution_Silicon", 2000.0, "time resolution of Silicon detector in ns"}; @@ -60,7 +58,7 @@ struct TimeframeSplitter : public JEventUnfolder { unsigned int m_NewEventCount = 0; //QA unsigned int m_PhysCount = 0; //QA - size_t m_eventNumber_TS = 0; // Event number for the current timeslice + size_t m_eventNumber_TS = 0; // Event number for the current timeslice std::vector m_vTargetEvent; // List of original event numbers for each timeslice static constexpr double kPi = 3.14159265358979323846; @@ -73,26 +71,25 @@ struct TimeframeSplitter : public JEventUnfolder { using EtaPhiEnergyGrid = std::array, kEtaPhiBins>; enum TrkCollectionType : size_t { - kTrackerHitAligned = 0, - kTrackerHit, - kTrackerHitAssociation, - kTrackerHitLink, - kSimTrackerHit, - kRawTrackerHit, - kTrkCollectionTypeSize + kTrackerHitAligned = 0, + kTrackerHit, + kTrackerHitAssociation, + kTrackerHitLink, + kSimTrackerHit, + kRawTrackerHit, + kTrkCollectionTypeSize }; -enum CalCollectionType : size_t { - kCalorimeterHitAligned = 0, - kCalorimeterHit, - kCalorimeterHitAssociation, - kCalorimeterHitLink, - kSimCalorimeterHit, - kRawCalorimeterHit, - kCalCollectionTypeSize -}; + enum CalCollectionType : size_t { + kCalorimeterHitAligned = 0, + kCalorimeterHit, + kCalorimeterHitAssociation, + kCalorimeterHitLink, + kSimCalorimeterHit, + kRawCalorimeterHit, + kCalCollectionTypeSize + }; - enum TrkCollectionIndex : size_t { kTrkB0 = 0, kTrkTOFBarrel = 1, @@ -119,7 +116,7 @@ enum CalCollectionType : size_t { kCalLumi = 6 }; - using trkCollNames = std::array; + using trkCollNames = std::array; std::array m_trkCollNames = {{ { "B0TrackerRecHits_aligned", @@ -230,7 +227,7 @@ enum CalCollectionType : size_t { // "DIRCBarRecHits_aligned", // "DRICHRecHits_aligned", - using calCollNames = std::array; + using calCollNames = std::array; std::array m_calCollNames = {{ { "B0ECalRecHits_aligned", @@ -330,7 +327,6 @@ enum CalCollectionType : size_t { }, }}; - std::vector getTrkCollectionNames(TrkCollectionType type) const { std::vector names; names.reserve(m_trkCollNames.size()); @@ -349,9 +345,8 @@ enum CalCollectionType : size_t { return names; } - - PodioInput m_eventHeader_inCol{this, - {.name = "EventHeader", .is_optional = true}}; + PodioInput m_eventHeader_inCol{ + this, {.name = "EventHeader", .is_optional = true}}; PodioOutput m_eventHeader_outCol{this, "EventHeader"}; PodioInput m_mcParticles_inCol{this, {.name = "MCParticles"}}; @@ -359,7 +354,7 @@ enum CalCollectionType : size_t { // tracker collections VariadicPodioInput m_trackerHits_inCols{ - this,{.names = getTrkCollectionNames(kTrackerHitAligned), .is_optional = true}}; + this, {.names = getTrkCollectionNames(kTrackerHitAligned), .is_optional = true}}; VariadicPodioOutput m_trackerHits_outCols{ this, getTrkCollectionNames(kTrackerHit)}; @@ -387,8 +382,8 @@ enum CalCollectionType : size_t { VariadicPodioOutput m_rawCalorimeterHit_outCols{ this, getCalCollectionNames(kRawCalorimeterHit)}; - VariadicPodioOutput - m_mcRecoCalorimeterHitLink_outCols{this, getCalCollectionNames(kCalorimeterHitLink)}; + VariadicPodioOutput m_mcRecoCalorimeterHitLink_outCols{ + this, getCalCollectionNames(kCalorimeterHitLink)}; VariadicPodioOutput m_simCalorimeterHit_outCols{ this, getCalCollectionNames(kSimCalorimeterHit)}; @@ -401,13 +396,12 @@ enum CalCollectionType : size_t { m_mcRecoCalorimeterHitAssociation_inCols{ this, {.names = getCalCollectionNames(kCalorimeterHitAssociation), .is_optional = true}}; VariadicPodioOutput - m_mcRecoCalorimeterHitAssociation_outCols{ - this, getCalCollectionNames(kCalorimeterHitAssociation)}; + m_mcRecoCalorimeterHitAssociation_outCols{this, + getCalCollectionNames(kCalorimeterHitAssociation)}; PodioOutput m_eventHeaderPhy_outCols{this, "EventHeader_PHY"}; PodioOutput m_eventHeaderBkg_outCols{this, "EventHeader_BKG"}; - TimeframeSplitter(); std::vector> @@ -419,21 +413,21 @@ enum CalCollectionType : size_t { bool bInitialLoop = true; unsigned int m_multiTriggerThreshold[4] = {1, 4, 20, 20}; - size_t iniTrkHitPoint[15] = {0}; // B0Trk, - size_t iniCalHitPoint[15] = {0}; // B0Trk, + size_t iniTrkHitPoint[15] = {0}; // B0Trk, + size_t iniCalHitPoint[15] = {0}; // B0Trk, bool m_bDetLastHits[10] = {false, false, false, false, false, false, false, false, false, false}; bool m_bOnceTriggered = false; bool m_bScanedAllTimeWindows = false; - unsigned int targetDetId = 0; - size_t iTimeSlice = 0; + unsigned int targetDetId = 0; + size_t iTimeSlice = 0; std::vector m_vPhysCooTimes = {}; // == Global Variables ======================= struct TimeWindowSummary { - size_t count = 0; - double timeSum = 0.0; + size_t count = 0; + double timeSum = 0.0; size_t nextStartID = 0; double average_time() const { return count == 0 ? 0.0 : timeSum / count; } @@ -454,16 +448,15 @@ enum CalCollectionType : size_t { buildCalAssoId(const edm4eic::MCRecoCalorimeterHitAssociationCollection* associations); static bool overlapsTimeWindow(double hitTime, double resolution, double window_start, - double window_end); + double window_end); static bool judgeOverTimeWindow(double hitTime, double resolution, double window_end); static bool isValidEtaPhiBin(int etaBin, int phiBin); - static bool judgeHitInTimeSlice(double hitTime, double timeResolution, - double timeslice_start, double timeslice_end); + static bool judgeHitInTimeSlice(double hitTime, double timeResolution, double timeslice_start, + double timeslice_end); - template - inline void etaPhiCalc(const HitT& hit, double& hitEta, double& hitPhi) { + template inline void etaPhiCalc(const HitT& hit, double& hitEta, double& hitPhi) { const double hitX = hit.getPosition()[0]; const double hitY = hit.getPosition()[1]; const double hitZ = hit.getPosition()[2]; @@ -481,8 +474,8 @@ enum CalCollectionType : size_t { hitPhi = std::atan2(hitY, hitX); } - static std::pair etaPhiBins(double hitEta, double hitPhi, double etaMin, - double etaMax, int bShift); + static std::pair etaPhiBins(double hitEta, double hitPhi, double etaMin, double etaMax, + int bShift); template void fillEtaPhiGrids(const CollectionT* hits, size_t& iniHitID, double timeResolution, @@ -494,7 +487,7 @@ enum CalCollectionType : size_t { const size_t hitCount = hits->size(); for (size_t iHit = iniHitID; iHit < hitCount; ++iHit) { - const auto& hit = hits->at(iHit); + const auto& hit = hits->at(iHit); const double hitT = hit.getTime(); if (hitT - timeResolution > timeSliceEnd) { iniHitID = iHit; @@ -522,12 +515,11 @@ enum CalCollectionType : size_t { template void fillEtaPhiGridsMatched(const CollectionT* collection, size_t& iniHitID, - double timeResolution, double timeSliceStart, - double timeSliceEnd, const EtaPhiGrid& baseGrid, - const EtaPhiGrid& baseGridShifted, EtaPhiGrid& compGrid, - EtaPhiGrid& compGridShifted, unsigned int baseThreshold, - EtaPhiTimeGrid& compGridTime, EtaPhiTimeGrid& compGridShiftedTime, - BinFunc binFunc) { + double timeResolution, double timeSliceStart, double timeSliceEnd, + const EtaPhiGrid& baseGrid, const EtaPhiGrid& baseGridShifted, + EtaPhiGrid& compGrid, EtaPhiGrid& compGridShifted, + unsigned int baseThreshold, EtaPhiTimeGrid& compGridTime, + EtaPhiTimeGrid& compGridShiftedTime, BinFunc binFunc) { if (collection == nullptr) return; @@ -565,23 +557,23 @@ enum CalCollectionType : size_t { unsigned int threshold, double& averageTime); static double averageSelectedTriggerTime(const std::array& values, - const std::array& times, - std::initializer_list indices, - double fallbackTime); + const std::array& times, + std::initializer_list indices, + double fallbackTime); double trkTimeResolution(size_t detectorID); template TimeWindowSummary countHitsInTimeWindow(const CollectionT* collection, size_t startHitID, - double resolution, double window_start, - double window_end) const { + double resolution, double window_start, + double window_end) const { TimeWindowSummary summary; summary.nextStartID = startHitID; if (collection == nullptr) return summary; for (size_t i = startHitID; i < collection->size(); ++i) { - const auto& hit = collection->at(i); + const auto& hit = collection->at(i); const double hitTime = hit.getTime(); if (judgeOverTimeWindow(hitTime, resolution, window_end)) break; @@ -600,14 +592,15 @@ enum CalCollectionType : size_t { } template - static void copyTrkHitWithRelations( - const edm4eic::TrackerHit& trackerHit, - const edm4eic::MCRecoTrackerHitAssociationCollection* associations, - const TrackerAssociationIndex& association_index, TrackerHitOutputT& trackerHits_out, - RawHitOutputT& rawHits_out, AssociationOutputT& associations_out, - std::unique_ptr& simHits_out, - std::unique_ptr& links_out, - std::unique_ptr& mc_particles_out) { + static void + copyTrkHitWithRelations(const edm4eic::TrackerHit& trackerHit, + const edm4eic::MCRecoTrackerHitAssociationCollection* associations, + const TrackerAssociationIndex& association_index, + TrackerHitOutputT& trackerHits_out, RawHitOutputT& rawHits_out, + AssociationOutputT& associations_out, + std::unique_ptr& simHits_out, + std::unique_ptr& links_out, + std::unique_ptr& mc_particles_out) { auto trackerHitCopied = trackerHit.clone(); trackerHitCopied.setRawHit(edm4eic::RawTrackerHit()); @@ -665,9 +658,7 @@ enum CalCollectionType : size_t { static std::pair barrelEtaPhiBins(double hitEta, double hitPhi, int bShift); - static std::pair forwardEndEtaPhiBins(double hitEta, double hitPhi, - int bShift); + static std::pair forwardEndEtaPhiBins(double hitEta, double hitPhi, int bShift); Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override; - }; diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index c0e4506e4a..4e6209538e 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -17,37 +17,36 @@ extern "C" { void InitPlugin(JApplication* app) { - const std::vector> trkHitTimeCollectionNames = { - {"TOFBarrelRecHits", "TOFBarrelRecHits_aligned"}, - {"TOFEndcapRecHits", "TOFEndcapRecHits_aligned"}, - {"MPGDBarrelRecHits", "MPGDBarrelRecHits_aligned"}, - {"OuterMPGDBarrelRecHits", "OuterMPGDBarrelRecHits_aligned"}, - {"BackwardMPGDEndcapRecHits", "BackwardMPGDEndcapRecHits_aligned"}, - {"ForwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits_aligned"}, - {"SiBarrelVertexRecHits", "SiBarrelVertexRecHits_aligned"}, - {"SiBarrelTrackerRecHits", "SiBarrelTrackerRecHits_aligned"}, - {"SiEndcapTrackerRecHits", "SiEndcapTrackerRecHits_aligned"}, - {"B0TrackerRecHits", "B0TrackerRecHits_aligned"}, - {"TaggerTrackerRecHits", "TaggerTrackerRecHits_aligned"}, - {"ForwardRomanPotRecHits", "ForwardRomanPotRecHits_aligned"}, - {"ForwardOffMTrackerRecHits", "ForwardOffMTrackerRecHits_aligned"}, - }; - - const std::vector> calHitTimeCollectionNames = { - {"B0ECalRecHits", "B0ECalRecHits_aligned"}, - {"EcalBarrelImagingRecHits", "EcalBarrelImagingRecHits_aligned"}, - {"EcalBarrelScFiRecHits", "EcalBarrelScFiRecHits_aligned"}, - {"EcalEndcapNRecHits", "EcalEndcapNRecHits_aligned"}, - {"EcalEndcapPRecHits", "EcalEndcapPRecHits_aligned"}, - {"EcalFarForwardZDCRecHits", "EcalFarForwardZDCRecHits_aligned"}, - {"EcalLumiSpecRecHits", "EcalLumiSpecRecHits_aligned"}, - {"HcalBarrelRecHits", "HcalBarrelRecHits_aligned"}, - {"HcalEndcapNRecHits", "HcalEndcapNRecHits_aligned"}, - {"HcalEndcapPInsertRecHits", "HcalEndcapPInsertRecHits_aligned"}, - {"HcalFarForwardZDCRecHits", "HcalFarForwardZDCRecHits_aligned"}, - {"LFHCALRecHits", "LFHCALRecHits_aligned"}, - }; + const std::vector> trkHitTimeCollectionNames = { + {"TOFBarrelRecHits", "TOFBarrelRecHits_aligned"}, + {"TOFEndcapRecHits", "TOFEndcapRecHits_aligned"}, + {"MPGDBarrelRecHits", "MPGDBarrelRecHits_aligned"}, + {"OuterMPGDBarrelRecHits", "OuterMPGDBarrelRecHits_aligned"}, + {"BackwardMPGDEndcapRecHits", "BackwardMPGDEndcapRecHits_aligned"}, + {"ForwardMPGDEndcapRecHits", "ForwardMPGDEndcapRecHits_aligned"}, + {"SiBarrelVertexRecHits", "SiBarrelVertexRecHits_aligned"}, + {"SiBarrelTrackerRecHits", "SiBarrelTrackerRecHits_aligned"}, + {"SiEndcapTrackerRecHits", "SiEndcapTrackerRecHits_aligned"}, + {"B0TrackerRecHits", "B0TrackerRecHits_aligned"}, + {"TaggerTrackerRecHits", "TaggerTrackerRecHits_aligned"}, + {"ForwardRomanPotRecHits", "ForwardRomanPotRecHits_aligned"}, + {"ForwardOffMTrackerRecHits", "ForwardOffMTrackerRecHits_aligned"}, + }; + const std::vector> calHitTimeCollectionNames = { + {"B0ECalRecHits", "B0ECalRecHits_aligned"}, + {"EcalBarrelImagingRecHits", "EcalBarrelImagingRecHits_aligned"}, + {"EcalBarrelScFiRecHits", "EcalBarrelScFiRecHits_aligned"}, + {"EcalEndcapNRecHits", "EcalEndcapNRecHits_aligned"}, + {"EcalEndcapPRecHits", "EcalEndcapPRecHits_aligned"}, + {"EcalFarForwardZDCRecHits", "EcalFarForwardZDCRecHits_aligned"}, + {"EcalLumiSpecRecHits", "EcalLumiSpecRecHits_aligned"}, + {"HcalBarrelRecHits", "HcalBarrelRecHits_aligned"}, + {"HcalEndcapNRecHits", "HcalEndcapNRecHits_aligned"}, + {"HcalEndcapPInsertRecHits", "HcalEndcapPInsertRecHits_aligned"}, + {"HcalFarForwardZDCRecHits", "HcalFarForwardZDCRecHits_aligned"}, + {"LFHCALRecHits", "LFHCALRecHits_aligned"}, + }; InitJANAPlugin(app); @@ -57,19 +56,16 @@ void InitPlugin(JApplication* app) { return; } - for (const auto& [inName, outName] : trkHitTimeCollectionNames) { - app->Add( - new JOmniFactoryGeneratorT>( - outName, {inName}, {outName}, app, - JEventLevel::Timeslice)); - } + for (const auto& [inName, outName] : trkHitTimeCollectionNames) { + app->Add(new JOmniFactoryGeneratorT>( + outName, {inName}, {outName}, app, JEventLevel::Timeslice)); + } - for (const auto& [inName, outName] : calHitTimeCollectionNames) { - app->Add( - new JOmniFactoryGeneratorT>( - outName, {inName}, {outName}, app, - JEventLevel::Timeslice)); - } + for (const auto& [inName, outName] : calHitTimeCollectionNames) { + app->Add( + new JOmniFactoryGeneratorT>( + outName, {inName}, {outName}, app, JEventLevel::Timeslice)); + } // Unfolder that takes timeframes and splits them into physics events. app->Add(new TimeframeSplitter()); From 16ca933e4be033ab8d29f21d2083f7663c5a9402 Mon Sep 17 00:00:00 2001 From: Takuya Kumaoka Date: Fri, 14 Aug 2026 11:45:13 -0400 Subject: [PATCH 29/31] Fix signedness of grid multiplicity thresholds --- src/global/splitting/TimeframeSplitter.cc | 10 ++++++---- src/global/splitting/TimeframeSplitter.h | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 10b40cf14e..81c853c59f 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -106,10 +106,12 @@ std::pair TimeframeSplitter::etaPhiBins(double hitEta, double hitPhi, return {etaBin, phiBin}; } -size_t TimeframeSplitter::countGridCellsWithMultiplicity( - const EtaPhiGrid& grid0, const EtaPhiGrid& gridShifted, const EtaPhiTimeGrid& gridTime0, - const EtaPhiTimeGrid& gridShiftedTime, unsigned int threshold, double& averageTime) { - size_t count = 0; +size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0, + const EtaPhiGrid& gridShifted, + const EtaPhiTimeGrid& gridTime0, + const EtaPhiTimeGrid& gridShiftedTime, + int threshold, double& averageTime) { + size_t count = 0; double timeSum = 0.0; for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 4e9a10f150..55ddae91a6 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -412,9 +412,9 @@ struct TimeframeSplitter : public JEventUnfolder { // == Global Variables ======================= bool bInitialLoop = true; - unsigned int m_multiTriggerThreshold[4] = {1, 4, 20, 20}; - size_t iniTrkHitPoint[15] = {0}; // B0Trk, - size_t iniCalHitPoint[15] = {0}; // B0Trk, + int m_multiTriggerThreshold[4] = {1, 4, 20, 20}; + size_t iniTrkHitPoint[15] = {0}; // B0Trk, + size_t iniCalHitPoint[15] = {0}; // B0Trk, bool m_bDetLastHits[10] = {false, false, false, false, false, false, false, false, false, false}; bool m_bOnceTriggered = false; @@ -515,11 +515,12 @@ struct TimeframeSplitter : public JEventUnfolder { template void fillEtaPhiGridsMatched(const CollectionT* collection, size_t& iniHitID, - double timeResolution, double timeSliceStart, double timeSliceEnd, - const EtaPhiGrid& baseGrid, const EtaPhiGrid& baseGridShifted, - EtaPhiGrid& compGrid, EtaPhiGrid& compGridShifted, - unsigned int baseThreshold, EtaPhiTimeGrid& compGridTime, - EtaPhiTimeGrid& compGridShiftedTime, BinFunc binFunc) { + double timeResolution, double timeSliceStart, + double timeSliceEnd, const EtaPhiGrid& baseGrid, + const EtaPhiGrid& baseGridShifted, EtaPhiGrid& compGrid, + EtaPhiGrid& compGridShifted, int baseThreshold, + EtaPhiTimeGrid& compGridTime, EtaPhiTimeGrid& compGridShiftedTime, + BinFunc binFunc) { if (collection == nullptr) return; @@ -554,7 +555,7 @@ struct TimeframeSplitter : public JEventUnfolder { const EtaPhiGrid& gridShifted, const EtaPhiTimeGrid& gridTime0, const EtaPhiTimeGrid& gridShiftedTime, - unsigned int threshold, double& averageTime); + int threshold, double& averageTime); static double averageSelectedTriggerTime(const std::array& values, const std::array& times, From 34e9d6967544c82b8d0b87f613e99966c0953779 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 15:54:07 +0000 Subject: [PATCH 30/31] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/global/splitting/TimeframeSplitter.cc | 2 +- src/global/splitting/TimeframeSplitter.h | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 81c853c59f..50bbdaa242 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -111,7 +111,7 @@ size_t TimeframeSplitter::countGridCellsWithMultiplicity(const EtaPhiGrid& grid0 const EtaPhiTimeGrid& gridTime0, const EtaPhiTimeGrid& gridShiftedTime, int threshold, double& averageTime) { - size_t count = 0; + size_t count = 0; double timeSum = 0.0; for (size_t iEta = 0; iEta < kEtaPhiBins; ++iEta) { for (size_t iPhi = 0; iPhi < kEtaPhiBins; ++iPhi) { diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 55ddae91a6..a1dd346152 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -413,8 +413,8 @@ struct TimeframeSplitter : public JEventUnfolder { bool bInitialLoop = true; int m_multiTriggerThreshold[4] = {1, 4, 20, 20}; - size_t iniTrkHitPoint[15] = {0}; // B0Trk, - size_t iniCalHitPoint[15] = {0}; // B0Trk, + size_t iniTrkHitPoint[15] = {0}; // B0Trk, + size_t iniCalHitPoint[15] = {0}; // B0Trk, bool m_bDetLastHits[10] = {false, false, false, false, false, false, false, false, false, false}; bool m_bOnceTriggered = false; @@ -515,10 +515,9 @@ struct TimeframeSplitter : public JEventUnfolder { template void fillEtaPhiGridsMatched(const CollectionT* collection, size_t& iniHitID, - double timeResolution, double timeSliceStart, - double timeSliceEnd, const EtaPhiGrid& baseGrid, - const EtaPhiGrid& baseGridShifted, EtaPhiGrid& compGrid, - EtaPhiGrid& compGridShifted, int baseThreshold, + double timeResolution, double timeSliceStart, double timeSliceEnd, + const EtaPhiGrid& baseGrid, const EtaPhiGrid& baseGridShifted, + EtaPhiGrid& compGrid, EtaPhiGrid& compGridShifted, int baseThreshold, EtaPhiTimeGrid& compGridTime, EtaPhiTimeGrid& compGridShiftedTime, BinFunc binFunc) { if (collection == nullptr) @@ -554,8 +553,8 @@ struct TimeframeSplitter : public JEventUnfolder { static size_t countGridCellsWithMultiplicity(const EtaPhiGrid& grid0, const EtaPhiGrid& gridShifted, const EtaPhiTimeGrid& gridTime0, - const EtaPhiTimeGrid& gridShiftedTime, - int threshold, double& averageTime); + const EtaPhiTimeGrid& gridShiftedTime, int threshold, + double& averageTime); static double averageSelectedTriggerTime(const std::array& values, const std::array& times, From d7c313d589283b4ee2b9b4e8d239ec6326b60c7b Mon Sep 17 00:00:00 2001 From: epic-capybara <139920704+epic-capybara@users.noreply.github.com> Date: Sat, 15 Aug 2026 18:55:50 -0400 Subject: [PATCH 31/31] Add timeframe splitting framework to EICrecon (fix: iwyu) (#2873) This PR applies the include-what-you-use fixes as suggested by https://github.com/eic/EICrecon/actions/runs/31816763274. Please merge this PR into the branch `timeframe_splitting_dev` to resolve failures in PR #2824. Auto-generated by [create-pull-request][1] [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/global/splitting/TimeframeSplitter.cc | 4 +--- src/global/splitting/TimeframeSplitter.h | 4 +--- src/global/splitting/splitting.cc | 4 ++++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/global/splitting/TimeframeSplitter.cc b/src/global/splitting/TimeframeSplitter.cc index 50bbdaa242..725a7422de 100644 --- a/src/global/splitting/TimeframeSplitter.cc +++ b/src/global/splitting/TimeframeSplitter.cc @@ -6,11 +6,9 @@ #include #include #include -#include - #include -#include #include +#include TimeframeSplitter::TimeframeSplitter() { SetTypeName(NAME_OF_THIS); diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index a1dd346152..83d32f8e76 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -37,8 +37,6 @@ #include #include #include -#include -#include struct TimeframeSplitter : public JEventUnfolder { diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index 4e6209538e..d8a194fdf0 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -6,8 +6,12 @@ #include #include #include +#include +#include #include +#include #include +#include #include #include "TimeframeSplitter.h"