EICrecon
JANA based reconstruction for the EPIC detector
Loading...
Searching...
No Matches
SubDivideFunctors.h
Go to the documentation of this file.
1// Copyright 2024, Simon Gardner
2// Subject to the terms in the LICENSE file found in the top-level directory.
3//
4#pragma once
5
6#include <algorithms/geo.h>
7
8namespace eicrecon {
9
10// ----------------------------------------------------------------------------
11// Chain wrapper type for explicit member function call chaining
12// Usage: Chain<&A::getB, &B::getC> chains A->getB()->getC()
13// ----------------------------------------------------------------------------
14template <auto... MemberFunctionPtrs> struct Chain {};
15
16// ----------------------------------------------------------------------------
17// Helper to invoke a chain of member function calls
18// ----------------------------------------------------------------------------
19template <auto... MemberFunctionPtrs> struct ChainInvoker;
20
21// Base case: single member function
22template <auto MemberFunctionPtr> struct ChainInvoker<MemberFunctionPtr> {
23 template <typename T> static auto invoke(T& instance) { return (instance.*MemberFunctionPtr)(); }
24};
25
26// Recursive case: chain multiple member functions
27template <auto FirstMemberFunctionPtr, auto... RestMemberFunctionPtrs>
28struct ChainInvoker<FirstMemberFunctionPtr, RestMemberFunctionPtrs...> {
29 template <typename T> static auto invoke(T& instance) {
30 auto nested = (instance.*FirstMemberFunctionPtr)();
32 }
33};
34
35// ----------------------------------------------------------------------------
36// Functor to split collection based on a range of values
37// ----------------------------------------------------------------------------
38template <typename... Chains> class RangeSplit;
39
40// Specialization: single Chain
41template <auto... MemberFunctionPtrs> class RangeSplit<Chain<MemberFunctionPtrs...>> {
42public:
43 RangeSplit(std::vector<std::pair<double, double>> ranges) : m_ranges(ranges) {};
44
45 template <typename T> std::vector<int> operator()(T& instance) const {
46 std::vector<int> ids;
48 // Check if requested value is within the ranges
49 for (std::size_t i = 0; i < m_ranges.size(); i++) {
50 if (value > m_ranges[i].first && value < m_ranges[i].second) {
51 ids.push_back(i);
52 }
53 }
54 return ids;
55 }
56
57private:
58 std::vector<std::pair<double, double>> m_ranges;
59};
60
61// ----------------------------------------------------------------------------
62// Functor to split collection based on geometry
63// ----------------------------------------------------------------------------
65public:
66 GeometrySplit(std::vector<std::vector<long int>> ids, std::string readout,
67 std::vector<std::string> divisions)
68 : m_ids(ids)
69 , m_divisions(divisions)
70 , m_readout(readout)
71 , is_init(std::make_shared<std::once_flag>())
72 , m_id_dec(std::make_shared<dd4hep::DDSegmentation::BitFieldCoder*>())
73 , m_div_ids(std::make_shared<std::vector<std::size_t>>()) {};
74
75 template <typename T> std::vector<int> operator()(T& instance) const {
76
77 // Initialize the decoder and division ids on the first function call
78 std::call_once(*is_init, &GeometrySplit::init, this);
79
80 //Check which detector division to put the hit into
81 auto cellID = instance.getCellID();
82 std::vector<long int> det_ids;
83 for (auto d : *m_div_ids) {
84 det_ids.push_back((*m_id_dec)->get(cellID, d));
85 }
86
87 auto index = std::find(m_ids.begin(), m_ids.end(), det_ids);
88
89 std::vector<int> ids;
90 if (index != m_ids.end()) {
91 ids.push_back(std::distance(m_ids.begin(), index));
92 }
93 return ids;
94 }
95
96private:
97 void init() const {
98 *m_id_dec = algorithms::GeoSvc::instance().detector()->readout(m_readout).idSpec().decoder();
99 for (auto d : m_divisions) {
100 m_div_ids->push_back((*m_id_dec)->index(d));
101 }
102 }
103
104 std::vector<std::vector<long int>> m_ids;
105 std::vector<std::string> m_divisions;
106 std::string m_readout;
107
108 std::shared_ptr<std::once_flag> is_init;
109 std::shared_ptr<dd4hep::DDSegmentation::BitFieldCoder*> m_id_dec;
110 std::shared_ptr<std::vector<std::size_t>> m_div_ids;
111};
112
113// ----------------------------------------------------------------------------
114// Functor to split collection based on any number of collection values
115// ----------------------------------------------------------------------------
116template <auto... MemberFunctionPtrs> class ValueSplit {
117public:
118 ValueSplit(std::vector<std::vector<int>> ids) : m_ids(ids) {};
119
120 template <typename T> std::vector<int> operator()(T& instance) const {
121 std::vector<int> ids;
122 // Check if requested value matches any configuration combinations
123 std::vector<int> values;
124 (values.push_back((instance.*MemberFunctionPtrs)()), ...);
125 auto index = std::find(m_ids.begin(), m_ids.end(), values);
126 if (index != m_ids.end()) {
127 ids.push_back(std::distance(m_ids.begin(), index));
128 }
129 return ids;
130 }
131
132private:
133 std::vector<std::vector<int>> m_ids;
134};
135
136} // namespace eicrecon
Definition SubDivideFunctors.h:64
GeometrySplit(std::vector< std::vector< long int > > ids, std::string readout, std::vector< std::string > divisions)
Definition SubDivideFunctors.h:66
std::vector< int > operator()(T &instance) const
Definition SubDivideFunctors.h:75
std::vector< int > operator()(T &instance) const
Definition SubDivideFunctors.h:45
RangeSplit(std::vector< std::pair< double, double > > ranges)
Definition SubDivideFunctors.h:43
Definition SubDivideFunctors.h:38
Definition SubDivideFunctors.h:116
std::vector< int > operator()(T &instance) const
Definition SubDivideFunctors.h:120
ValueSplit(std::vector< std::vector< int > > ids)
Definition SubDivideFunctors.h:118
Definition ActsGeometryProvider.h:28
-client
Definition CalorimeterClusterRecoCoG.cc:37
Definition SimCalorimeterHitProcessor.cc:35
static auto invoke(T &instance)
Definition SubDivideFunctors.h:29
static auto invoke(T &instance)
Definition SubDivideFunctors.h:23
Definition SubDivideFunctors.h:19
Definition SubDivideFunctors.h:14