diff --git a/src/algorithms/meta/SubDivideFunctors.h b/src/algorithms/meta/SubDivideFunctors.h index 090b54ad89..8d3bad845a 100644 --- a/src/algorithms/meta/SubDivideFunctors.h +++ b/src/algorithms/meta/SubDivideFunctors.h @@ -4,6 +4,9 @@ #pragma once #include +#include +#include +#include namespace eicrecon { @@ -13,16 +16,30 @@ namespace eicrecon { template class RangeSplit { public: + RangeSplit(std::vector> ranges, bool inside = true) + : m_ranges(ranges), m_inside(ranges.size(), inside) {} - RangeSplit(std::vector> ranges) : m_ranges(ranges) {}; + RangeSplit(const std::vector>& ranges, const std::vector& inside) + : m_ranges(ranges) { + if (inside.size() != ranges.size()) { + throw std::invalid_argument("Size of inside must match the size of ranges"); + } + m_inside = inside; + } template std::vector operator()(T& instance) const { std::vector ids; //Check if requested value is within the ranges for(size_t i = 0; i < m_ranges.size(); i++){ - if((instance.*MemberFunctionPtr)() > m_ranges[i].first && (instance.*MemberFunctionPtr)() < m_ranges[i].second){ - ids.push_back(i); + if(m_inside[i]){ + if((instance.*MemberFunctionPtr)() >= m_ranges[i].first && (instance.*MemberFunctionPtr)() <= m_ranges[i].second){ + ids.push_back(i); + } + } else { + if((instance.*MemberFunctionPtr)() < m_ranges[i].first || (instance.*MemberFunctionPtr)() > m_ranges[i].second){ + ids.push_back(i); + } } } return ids; @@ -30,6 +47,7 @@ class RangeSplit { private: std::vector> m_ranges; + std::vector m_inside; }; @@ -39,7 +57,7 @@ class RangeSplit { class GeometrySplit { public: - GeometrySplit(std::vector> ids, std::string readout, std::vector divisions) + GeometrySplit(std::vector> ids, const std::string& readout, const std::vector& divisions) : m_ids(ids), m_readout(readout), m_divisions(divisions){}; template @@ -90,7 +108,8 @@ template class ValueSplit { public: - ValueSplit(std::vector> ids) : m_ids(ids) {}; + ValueSplit( std::vector> ids, bool matching = true) + : m_ids(ids), m_matching(matching) {}; template std::vector operator()(T& instance) const { @@ -107,6 +126,60 @@ class ValueSplit { private: std::vector> m_ids; + bool m_matching = true; + +}; + +// ---------------------------------------------------------------------------- +// Functor to split collection based on any number of collection values +// ---------------------------------------------------------------------------- +template +class BooleanSplit { +public: + using ComparisonFunction = std::function; + + BooleanSplit( std::vector> ids, ComparisonFunction comparison) + : m_ids(ids), m_comparisons(ids.size(), comparison) {}; + + BooleanSplit( std::vector ids, ComparisonFunction comparison) + : m_ids(1,ids), m_comparisons(ids.size(), comparison) {}; + + + BooleanSplit( std::vector> ids, std::vector comparisons) + : m_ids(ids) { + if (ids.size() != comparisons.size()) { + throw std::invalid_argument("Size of values to compare must match the size of boolean functions"); + } + m_comparisons = comparisons; + } + + template + std::vector operator()(T& instance) const { + std::vector ids; + // Check if requested value matches any configuration combinations + std::vector values; + (values.push_back((instance.*MemberFunctionPtrs)()), ...); + for (size_t i = 0; i < m_ids.size(); ++i){ + if(compareVectors(m_ids[i], values, m_comparisons)){ + ids.push_back(i); + } + } + return ids; + } + +private: + std::vector> m_ids; + std::vector m_comparisons; + + static bool compareVectors(const std::vector& vec1, const std::vector& vec2, const std::vector& comparisons) { + for (size_t i = 0; i < vec1.size(); ++i) { + if (!comparisons[i](vec1[i], vec2[i])) { + return false; + } + } + return true; + } + }; diff --git a/src/algorithms/reco/ChargedMCParticleSelector.h b/src/algorithms/reco/ChargedMCParticleSelector.h deleted file mode 100644 index f004d83cef..0000000000 --- a/src/algorithms/reco/ChargedMCParticleSelector.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2024 Dmitry Kalinkin, Derek Anderson - -#pragma once - -#include -#include - -#include -#include - -#include "algorithms/interfaces/WithPodConfig.h" - -namespace eicrecon { - - class ChargedMCParticleSelector : public WithPodConfig { - - private: - - std::shared_ptr m_log; - - public: - - // algorithm initialization - void init(std::shared_ptr& logger) { - m_log = logger; - } - - // primary algorithm call - std::unique_ptr process(const edm4hep::MCParticleCollection* inputs) { - auto outputs = std::make_unique(); - outputs->setSubsetCollection(); - - for (const auto &particle : *inputs) { - if (particle.getCharge() != 0.) { - outputs->push_back(particle); - } - } - - return std::move(outputs); - } - - }; - -} diff --git a/src/algorithms/reco/ChargedReconstructedParticleSelector.h b/src/algorithms/reco/ChargedReconstructedParticleSelector.h deleted file mode 100644 index 93381738e4..0000000000 --- a/src/algorithms/reco/ChargedReconstructedParticleSelector.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2024 Dmitry Kalinkin, Derek Anderson - -#pragma once - -#include -#include - -#include -#include - -#include "algorithms/interfaces/WithPodConfig.h" - -namespace eicrecon { - - class ChargedReconstructedParticleSelector : public WithPodConfig { - - private: - - std::shared_ptr m_log; - - public: - - // algorithm initialization - void init(std::shared_ptr& logger) { - m_log = logger; - } - - // primary algorithm call - std::unique_ptr process(const edm4eic::ReconstructedParticleCollection* inputs) { - auto outputs = std::make_unique(); - outputs->setSubsetCollection(); - - for (const auto &particle : *inputs) { - if (particle.getCharge() != 0.) { - outputs->push_back(particle); - } - } - - return std::move(outputs); - } - - }; - -} diff --git a/src/global/reco/ChargedMCParticleSelector_factory.h b/src/global/reco/ChargedMCParticleSelector_factory.h deleted file mode 100644 index 8bfbd8c531..0000000000 --- a/src/global/reco/ChargedMCParticleSelector_factory.h +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2024 Wouter Deconinck, Dmitry Kalinkin, Derek Anderson - -#pragma once - -#include "extensions/jana/JOmniFactory.h" -#include "algorithms/reco/ChargedMCParticleSelector.h" - -namespace eicrecon { - - class ChargedMCParticleSelector_factory : public JOmniFactory { - - private: - - // algorithm - std::unique_ptr m_algo; - - // input collection - PodioInput m_pars_in {this, "GeneratedParticles"}; - - // output collection - PodioOutput m_pars_out {this}; - - public: - - void Configure() { - m_algo = std::make_unique(); - m_algo->init(logger()); - } - - void ChangeRun(int64_t run_number) { - /* nothing to do */ - } - - void Process(int64_t run_number, int64_t event_number) { - m_pars_out() = m_algo->process(m_pars_in()); - } - - }; - -} // end eicrecon namespace diff --git a/src/global/reco/ChargedReconstructedParticleSelector_factory.h b/src/global/reco/ChargedReconstructedParticleSelector_factory.h deleted file mode 100644 index 249f306e51..0000000000 --- a/src/global/reco/ChargedReconstructedParticleSelector_factory.h +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2024, Derek Anderson - -#pragma once - -#include "extensions/jana/JOmniFactory.h" -#include "algorithms/reco/ChargedReconstructedParticleSelector.h" - -namespace eicrecon { - - class ChargedReconstructedParticleSelector_factory : public JOmniFactory { - - private: - - // algorithm - std::unique_ptr m_algo; - - // input collection - PodioInput m_pars_in {this, "GeneratedParticles"}; - - // output collection - PodioOutput m_pars_out {this}; - - public: - - void Configure() { - m_algo = std::make_unique(); - m_algo->init(logger()); - } - - void ChangeRun(int64_t run_number) { - /* nothing to do */ - } - - void Process(int64_t run_number, int64_t event_number) { - m_pars_out() = m_algo->process(m_pars_in()); - } - - }; - -} // end eicrecon namespace diff --git a/src/global/reco/reco.cc b/src/global/reco/reco.cc index 9813baac82..7c9b070e68 100644 --- a/src/global/reco/reco.cc +++ b/src/global/reco/reco.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include "algorithms/interfaces/WithPodConfig.h" @@ -27,6 +28,8 @@ #include "extensions/jana/JOmniFactoryGeneratorT.h" #include "factories/meta/CollectionCollector_factory.h" #include "factories/meta/FilterMatching_factory.h" +#include "factories/meta/SubDivideCollection_factory.h" +#include "algorithms/meta/SubDivideFunctors.h" #include "factories/reco/FarForwardNeutronReconstruction_factory.h" #ifdef USE_ONNX #include "factories/reco/InclusiveKinematicsML_factory.h" @@ -41,13 +44,13 @@ #include "factories/reco/HadronicFinalState_factory.h" #endif #include "factories/reco/UndoAfterBurnerMCParticles_factory.h" -#include "global/reco/ChargedReconstructedParticleSelector_factory.h" #include "global/reco/MC2SmearedParticle_factory.h" #include "global/reco/MatchClusters_factory.h" #include "global/reco/ReconstructedElectrons_factory.h" #include "global/reco/ScatteredElectronsEMinusPz_factory.h" #include "global/reco/ScatteredElectronsTruth_factory.h" + extern "C" { void InitPlugin(JApplication *app) { InitJANAPlugin(app); @@ -248,10 +251,11 @@ void InitPlugin(JApplication *app) { app )); - app->Add(new JOmniFactoryGeneratorT( + app->Add(new JOmniFactoryGeneratorT>( "GeneratedChargedParticles", {"GeneratedParticles"}, {"GeneratedChargedParticles"}, + {.function = BooleanSplit<&edm4eic::ReconstructedParticle::getCharge>{std::vector{0.0},std::not_equal_to{}}}, app ));