File indexing completed on 2026-07-16 08:11:19
0001 #ifndef V0_DUPLICATE_READER_H
0002 #define V0_DUPLICATE_READER_H
0003
0004 #include <TTree.h>
0005
0006 #include <cmath>
0007 #include <set>
0008 #include <stdexcept>
0009 #include <string>
0010 #include <vector>
0011
0012 class V0DuplicateReader
0013 {
0014 public:
0015 enum class ParticleType
0016 {
0017 K0s,
0018 Lambda
0019 };
0020
0021 V0DuplicateReader(TTree* tree, ParticleType particleType)
0022 : m_tree(tree)
0023 , m_particleType(particleType)
0024 {
0025 if (!m_tree)
0026 {
0027 throw std::runtime_error("V0DuplicateReader: input tree is null");
0028 }
0029
0030 prefix = (m_particleType == ParticleType::K0s) ? "K_S0" : "Lambda0";
0031
0032 setupBranches();
0033
0034
0035
0036 }
0037
0038 void enableDeltaBCOCut(long long minDeltaBCO, long long maxDeltaBCO)
0039 {
0040 m_useDeltaBCOCut = true;
0041 m_minDeltaBCO = minDeltaBCO;
0042 m_maxDeltaBCO = maxDeltaBCO;
0043 }
0044
0045 void disableDeltaBCOCut()
0046 {
0047 m_useDeltaBCOCut = false;
0048 }
0049
0050 bool loadEntry(Long64_t entry)
0051 {
0052 if (!m_tree) return false;
0053
0054 m_tree->GetEntry(entry);
0055
0056 Long64_t m_bco = get<Long64_t>("Collision_BCO");
0057 Long64_t m_eventBCO = get<Long64_t>("GL1_BCO");
0058 int m_runNumber = get<int>("runNumber");
0059
0060 m_deltaBCO = (m_bco >= 0 && m_eventBCO >= 0) ? (m_bco - m_eventBCO) : -1;
0061
0062 if (m_useDeltaBCOCut)
0063 {
0064 m_passesDeltaBCO = (m_deltaBCO >= m_minDeltaBCO && m_deltaBCO < m_maxDeltaBCO);
0065 }
0066 else
0067 {
0068 m_passesDeltaBCO = true;
0069 }
0070
0071 if (!m_passesDeltaBCO)
0072 {
0073 m_currentEntryIsUnique = false;
0074 return true;
0075 }
0076
0077 std::vector<std::string> candidateBranches = {
0078 "mass",
0079 "pT",
0080 "pseudorapidity",
0081 "phi",
0082 "decayLength",
0083 "DIRA",
0084 "IP",
0085 "x",
0086 "y",
0087 "z",
0088 "chi2"
0089 };
0090
0091 std::vector<float> candidateVariables;
0092
0093 for(std::string name : candidateBranches)
0094 {
0095 candidateVariables.push_back(get<float>(prefix+"_"+name));
0096 }
0097
0098 const std::string eventKey =
0099 std::to_string(m_runNumber) + "_" + std::to_string(m_bco);
0100
0101 const std::string candidateKey = buildCandidateKey(candidateVariables);
0102 const std::string fullKey = eventKey + "__" + candidateKey;
0103
0104 const auto [it, inserted] = m_seenCandidateKeys.insert(fullKey);
0105
0106 if (inserted)
0107 {
0108 ++m_numberOfUniqueCandidates;
0109 m_currentEntryIsUnique = true;
0110 }
0111 else
0112 {
0113 ++m_numberOfDuplicateCandidates;
0114 m_currentEntryIsUnique = false;
0115 }
0116
0117 return true;
0118 }
0119
0120 bool isCurrentEntryUnique() const
0121 {
0122 return m_currentEntryIsUnique;
0123 }
0124
0125 bool passesDeltaBCOCut() const
0126 {
0127 return m_passesDeltaBCO;
0128 }
0129
0130 long long deltaBCO() const
0131 {
0132 return m_deltaBCO;
0133 }
0134
0135 void reset()
0136 {
0137 m_seenCandidateKeys.clear();
0138 m_numberOfUniqueCandidates = 0;
0139 m_numberOfDuplicateCandidates = 0;
0140 m_currentEntryIsUnique = false;
0141 m_deltaBCO = -1;
0142 m_passesDeltaBCO = true;
0143 }
0144
0145 Long64_t entries() const
0146 {
0147 return m_tree ? m_tree->GetEntries() : 0;
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 long long numberOfUniqueCandidates() const
0169 {
0170 return m_numberOfUniqueCandidates;
0171 }
0172
0173 long long numberOfDuplicateCandidates() const
0174 {
0175 return m_numberOfDuplicateCandidates;
0176 }
0177
0178 template<typename T>
0179 T get(const std::string& name)
0180 {
0181 T val = *(T*)leafmap[name.c_str()];
0182 return val;
0183 }
0184
0185 private:
0186 void setupBranches()
0187 {
0188 TObjArray* branches = m_tree->GetListOfBranches();
0189 size_t nbranches = m_tree->GetNbranches();
0190 for(size_t i=0;i<nbranches;i++)
0191 {
0192 std::string branchname = branches->At(i)->GetName();
0193 leafmap[branchname] = m_tree->GetLeaf(branchname.c_str())->GetValuePointer();
0194 }
0195 }
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 static std::string buildCandidateKey(const std::vector<float>& candidateVariables)
0225 {
0226 std::string key;
0227 key.reserve(candidateVariables.size() * 16);
0228
0229 for (float value : candidateVariables)
0230 {
0231 const long long roundedValue = llround(value * 1e6);
0232 key += std::to_string(roundedValue);
0233 key += "_";
0234 }
0235
0236 return key;
0237 }
0238
0239 private:
0240 TTree* m_tree = nullptr;
0241 ParticleType m_particleType;
0242
0243 std::string prefix;
0244
0245 std::map<std::string,void*> leafmap;
0246
0247 std::set<std::string> m_seenCandidateKeys;
0248
0249 long long m_numberOfUniqueCandidates = 0;
0250 long long m_numberOfDuplicateCandidates = 0;
0251 bool m_currentEntryIsUnique = false;
0252
0253 bool m_useDeltaBCOCut = false;
0254 long long m_minDeltaBCO = 0;
0255 long long m_maxDeltaBCO = 350;
0256 long long m_deltaBCO = -1;
0257 bool m_passesDeltaBCO = true;
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 };
0278
0279 #endif