File indexing completed on 2026-08-01 09:04:34
0001
0002
0003
0004 #pragma once
0005
0006 #include <algorithms/geo.h>
0007
0008 namespace eicrecon {
0009
0010
0011
0012
0013
0014 template <auto... MemberFunctionPtrs> struct Chain {};
0015
0016
0017
0018
0019 template <auto... MemberFunctionPtrs> struct ChainInvoker;
0020
0021
0022 template <auto MemberFunctionPtr> struct ChainInvoker<MemberFunctionPtr> {
0023 template <typename T> static auto invoke(T& instance) { return (instance.*MemberFunctionPtr)(); }
0024 };
0025
0026
0027 template <auto FirstMemberFunctionPtr, auto... RestMemberFunctionPtrs>
0028 struct ChainInvoker<FirstMemberFunctionPtr, RestMemberFunctionPtrs...> {
0029 template <typename T> static auto invoke(T& instance) {
0030 auto nested = (instance.*FirstMemberFunctionPtr)();
0031 return ChainInvoker<RestMemberFunctionPtrs...>::invoke(nested);
0032 }
0033 };
0034
0035
0036
0037
0038 template <typename... Chains> class RangeSplit;
0039
0040
0041 template <auto... MemberFunctionPtrs> class RangeSplit<Chain<MemberFunctionPtrs...>> {
0042 public:
0043 RangeSplit(std::vector<std::pair<double, double>> ranges) : m_ranges(ranges) {};
0044
0045 template <typename T> std::vector<int> operator()(T& instance) const {
0046 std::vector<int> ids;
0047 auto value = ChainInvoker<MemberFunctionPtrs...>::invoke(instance);
0048
0049 for (std::size_t i = 0; i < m_ranges.size(); i++) {
0050 if (value > m_ranges[i].first && value < m_ranges[i].second) {
0051 ids.push_back(i);
0052 }
0053 }
0054 return ids;
0055 }
0056
0057 private:
0058 std::vector<std::pair<double, double>> m_ranges;
0059 };
0060
0061
0062
0063
0064 class GeometrySplit {
0065 public:
0066 GeometrySplit(std::vector<std::vector<long int>> ids, std::string readout,
0067 std::vector<std::string> divisions)
0068 : m_ids(ids)
0069 , m_divisions(divisions)
0070 , m_readout(readout)
0071 , is_init(std::make_shared<std::once_flag>())
0072 , m_id_dec(std::make_shared<dd4hep::DDSegmentation::BitFieldCoder*>())
0073 , m_div_ids(std::make_shared<std::vector<std::size_t>>()) {};
0074
0075 template <typename T> std::vector<int> operator()(T& instance) const {
0076
0077
0078 std::call_once(*is_init, &GeometrySplit::init, this);
0079
0080
0081 auto cellID = instance.getCellID();
0082 std::vector<long int> det_ids;
0083 for (auto d : *m_div_ids) {
0084 det_ids.push_back((*m_id_dec)->get(cellID, d));
0085 }
0086
0087 auto index = std::find(m_ids.begin(), m_ids.end(), det_ids);
0088
0089 std::vector<int> ids;
0090 if (index != m_ids.end()) {
0091 ids.push_back(std::distance(m_ids.begin(), index));
0092 }
0093 return ids;
0094 }
0095
0096 private:
0097 void init() const {
0098 *m_id_dec = algorithms::GeoSvc::instance().detector()->readout(m_readout).idSpec().decoder();
0099 for (auto d : m_divisions) {
0100 m_div_ids->push_back((*m_id_dec)->index(d));
0101 }
0102 }
0103
0104 std::vector<std::vector<long int>> m_ids;
0105 std::vector<std::string> m_divisions;
0106 std::string m_readout;
0107
0108 std::shared_ptr<std::once_flag> is_init;
0109 std::shared_ptr<dd4hep::DDSegmentation::BitFieldCoder*> m_id_dec;
0110 std::shared_ptr<std::vector<std::size_t>> m_div_ids;
0111 };
0112
0113
0114
0115
0116 template <auto... MemberFunctionPtrs> class ValueSplit {
0117 public:
0118 ValueSplit(std::vector<std::vector<int>> ids) : m_ids(ids) {};
0119
0120 template <typename T> std::vector<int> operator()(T& instance) const {
0121 std::vector<int> ids;
0122
0123 std::vector<int> values;
0124 (values.push_back((instance.*MemberFunctionPtrs)()), ...);
0125 auto index = std::find(m_ids.begin(), m_ids.end(), values);
0126 if (index != m_ids.end()) {
0127 ids.push_back(std::distance(m_ids.begin(), index));
0128 }
0129 return ids;
0130 }
0131
0132 private:
0133 std::vector<std::vector<int>> m_ids;
0134 };
0135
0136 }