Belle II Software development
TrackIsoCalculatorModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <analysis/modules/TrackIsoCalculator/TrackIsoCalculatorModule.h>
10#include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
11#include <analysis/utility/DetectorSurface.h>
12
13#include <cmath>
14#include <iomanip>
15#include <boost/algorithm/string.hpp>
16
17
18using namespace Belle2;
19
20REG_MODULE(TrackIsoCalculator);
21
23{
24 // Set module properties
26 R"DOC(Calculate track isolation variables on the charged stable particles, or selected charged daughters, of the input ParticleList.)DOC");
27
28 // Parameter definitions
29 addParam("decayString",
31 "The name of the input charged stable particle list, e.g. ``mu+:all``, or a composite particle w/ charged stable daughters for which distances are to be calculated, e.g. ``D0 -> ^K- pi+``. Note that in the latter case we allow only one daughter to be selected in the decay string per module instance.");
32 addParam("particleListReference",
34 "The name of the input ParticleList of reference tracks. Must be a charged stable particle as defined in Const::chargedStableSet.");
35 addParam("detectorNames",
37 "The list of names of the detectors at whose (cylindrical) surface(s) we extrapolate each helix's polar and azimuthal angle. Allowed values: {CDC, TOP, ARICH, ECL, KLM}.",
38 std::vector<std::string>());
39 addParam("useHighestProbMassForExt",
41 "If this option is set, the helix extrapolation for the target and reference particles will use the track fit result for the most probable mass hypothesis, namely, the one that gives the highest chi2Prob of the fit.",
42 bool(false));
43 addParam("payloadName",
45 "The name of the database payload object with the PID detector weights.",
46 std::string("PIDDetectorWeights"));
47 addParam("excludePIDDetWeights",
49 "If set to true, will not use the PID detector weights for the score definition.",
50 bool(false));
51}
52
54{
55}
56
58{
59 m_event_metadata.isRequired();
60
62 m_DBWeights = std::make_unique<DBObjPtr<PIDDetectorWeights>>(m_payloadName);
63 }
64
66 if (!valid) {
67 B2ERROR("Decay string " << m_decayString << " is invalid.");
68 }
69
71
72 m_pListTarget.isRequired(mother->getFullName());
74
75 if (m_nSelectedDaughters > 1) {
76 B2ERROR("More than one daughter is selected in the decay string " << m_decayString << ".");
77 }
78
80
81 B2INFO("Calculating track-based isolation variables for the decay string: "
83 << " using the reference ParticleList: "
85 << ".");
86
88 B2ERROR("Selected ParticleList in decay string:"
90 << " and/or reference ParticleList: "
92 << " is not that of a valid particle in Const::chargedStableSet!");
93 }
94
96 B2INFO("Will use track fit result for the most probable mass hypothesis in helix extrapolation.");
97 }
98
99 std::string detNamesConcat("");
100
101 for (auto& detName : m_detNames) {
102
103 // Ensure we use uppercase detector labels.
104 boost::to_upper(detName);
105
106 detNamesConcat += "_" + detName;
107
108 // Define the name(s) of the variables for this detector to be stored as extraInfo.
109 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
110
111
112 auto iDetLayer = detName + std::to_string(iLayer);
113
114 auto distVarName = "distToClosestTrkAt" + iDetLayer + "_VS_" + m_pListReferenceName;
116 distVarName += "__useHighestProbMassForExt";
117 }
118 auto refPartIdxVarName = "idxOfClosestPartAt" + iDetLayer + "In_" + m_pListReferenceName;
119
120 m_detLayerToDistVariable.insert(std::make_pair(iDetLayer, distVarName));
121 m_detLayerToRefPartIdxVariable.insert(std::make_pair(iDetLayer, refPartIdxVarName));
122
123 }
124
125 // Isolation score variable.
126 m_isoScoreVariable = "trkIsoScore" + detNamesConcat + "_VS_" + m_pListReferenceName;
127 m_isoScoreVariableAsWeightedAvg = "trkIsoScoreAsWeightedAvg" + detNamesConcat + "_VS_" + m_pListReferenceName;
129 m_isoScoreVariable += "__useHighestProbMassForExt";
130 m_isoScoreVariableAsWeightedAvg += "__useHighestProbMassForExt";
131 }
132 }
133
134}
135
137{
138 B2DEBUG(11, "Start processing EVENT: " << m_event_metadata->getEvent());
139
140 const auto nMotherParticles = m_pListTarget->getListSize();
141
142 // Fill transient container of all selected charged particles in the decay
143 // for which the distance to nearest neighbour is to be calculated.
144 // If the input ParticleList is that of standard charged particles, just copy
145 // the whole list over, otherwise loop over the selected charged daughters.
146 std::unordered_map<unsigned int, const Particle*> targetParticles;
147 targetParticles.reserve(nMotherParticles);
148
149 for (unsigned int iPart(0); iPart < nMotherParticles; ++iPart) {
150
151 auto iParticle = m_pListTarget->getParticle(iPart);
152
153 // Loop over the input detectors.
154 for (const auto& detName : m_detNames) {
155
156 // Loop over the layer of the input detector.
157 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
158
159 auto iDetLayer = detName + std::to_string(iLayer);
160
162 for (auto* iDaughter : m_decaydescriptor.getSelectionParticles(iParticle)) {
163 // Check if the distance for this target particle has been set already,
164 // e.g. by a previous instance of this module.
165 if (iDaughter->hasExtraInfo(m_detLayerToDistVariable[iDetLayer])) {
166 continue;
167 }
168 targetParticles.insert({iDaughter->getMdstArrayIndex(), iDaughter});
169 }
170 } else {
171 if (iParticle->hasExtraInfo(m_detLayerToDistVariable[iDetLayer])) {
172 continue;
173 }
174 targetParticles.insert({iParticle->getMdstArrayIndex(), iParticle});
175 }
176
177 }
178 }
179 }
180
181 const auto nParticlesTarget = targetParticles.size();
182 const auto nParticlesReference = m_pListReference->getListSize();
183
184 // Loop over the input detectors.
185 for (const auto& detName : m_detNames) {
186
187 // Loop over the layer of the input detector.
188 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
189
190 auto iDetLayer = detName + std::to_string(iLayer);
191
192 B2DEBUG(11, "\n"
193 << "Detector surface: " << iDetLayer << "\n"
194 << "nMotherParticles: " << nMotherParticles << "\n"
195 << "nParticlesTarget: " << nParticlesTarget << "\n"
196 << "nParticlesReference: " << nParticlesReference);
197
198 double dummyDist(-1.0);
199
200 // Store the pair-wise distances in a map,
201 // where the keys are pairs of mdst indexes.
202 std::map<std::pair<unsigned int, unsigned int>, double> particleMdstIdxPairsToDist;
203
204 // Loop over input particle list
205 for (const auto& targetParticle : targetParticles) {
206
207 auto iMdstIdx = targetParticle.first;
208 auto iParticle = targetParticle.second;
209
210 for (unsigned int jPart(0); jPart < nParticlesReference; ++jPart) {
211
212 auto jParticle = m_pListReference->getParticle(jPart);
213 auto jMdstIdx = jParticle->getMdstArrayIndex();
214
215 auto partMdstIdxPair = std::make_pair(iMdstIdx, jMdstIdx);
216
217 // Set dummy distance if same particle.
218 if (iMdstIdx == jMdstIdx) {
219 particleMdstIdxPairsToDist[partMdstIdxPair] = dummyDist;
220 continue;
221 }
222 // If:
223 //
224 // - the mass hypothesis of the best fit is used, OR
225 // - the mass hypothesis of the 'default' fit of the two particles is the same,
226 //
227 // avoid re-doing the calculation if a pair with the flipped mdst indexes in the map already exists.
228 if (m_useHighestProbMassForExt || (iParticle->getPDGCodeUsedForFit() == jParticle->getPDGCodeUsedForFit())) {
229 if (particleMdstIdxPairsToDist.count({jMdstIdx, iMdstIdx})) {
230 particleMdstIdxPairsToDist[partMdstIdxPair] = particleMdstIdxPairsToDist[ {jMdstIdx, iMdstIdx}];
231 continue;
232 }
233 }
234 // Calculate the pair-wise distance.
235 particleMdstIdxPairsToDist[partMdstIdxPair] = this->getDistAtDetSurface(iParticle, jParticle, iDetLayer);
236 }
237
238 }
239
240 // For each particle in the input list, find the minimum among all distances to the reference particles.
241 for (const auto& targetParticle : targetParticles) {
242
243 auto iMdstIdx = targetParticle.first;
244 auto iParticle = targetParticle.second;
245
246 // Save the distances and the mdst indexes of the reference particles.
247 std::vector<std::pair<double, unsigned int>> iDistancesAndRefMdstIdxs;
248 for (const auto& [mdstIdxs, dist] : particleMdstIdxPairsToDist) {
249 if (mdstIdxs.first == iMdstIdx) {
250 if (!std::isnan(dist) && dist >= 0) {
251 iDistancesAndRefMdstIdxs.push_back(std::make_pair(dist, mdstIdxs.second));
252 }
253 }
254 }
255
256 if (!iDistancesAndRefMdstIdxs.size()) {
257 B2DEBUG(12, "The container of distances is empty. Perhaps the target and reference lists contain the same exact particles?");
258 continue;
259 }
260
261 const auto minDist = *std::min_element(std::begin(iDistancesAndRefMdstIdxs), std::end(iDistancesAndRefMdstIdxs),
262 [](const auto & l, const auto & r) {return l.first < r.first;});
263
264 auto jParticle = m_pListReference->getParticleWithMdstIdx(minDist.second);
265
266 B2DEBUG(11, "\n"
267 << "Particle w/ mdstIndex[" << iMdstIdx << "] (PDG = "
268 << iParticle->getPDGCode() << "). Closest charged particle w/ mdstIndex["
269 << minDist.second
270 << "] (PDG = " << jParticle->getPDGCode()
271 << ") at " << iDetLayer
272 << " surface is found at D = " << minDist.first
273 << " [cm]\n"
274 << "Storing extraInfo variables:\n"
275 << m_detLayerToDistVariable[iDetLayer]
276 << "\n"
277 << m_detLayerToRefPartIdxVariable[iDetLayer]);
278
279 if (!iParticle->hasExtraInfo(m_detLayerToDistVariable[iDetLayer])) {
280 m_particles[iParticle->getArrayIndex()]->addExtraInfo(m_detLayerToDistVariable[iDetLayer], minDist.first);
281 }
282 m_particles[iParticle->getArrayIndex()]->writeExtraInfo(m_detLayerToRefPartIdxVariable[iDetLayer], minDist.second);
283
284 } // end loop over input particle list.
285
286 } // end loop over detector layers.
287
288 } // end loop over input detectors.
289
290 // Now calculate the isolation score for each target particle.
291 for (const auto& targetParticle : targetParticles) {
292
293 auto iMdstIdx = targetParticle.first;
294 auto iParticle = targetParticle.second;
295
296 // Initialise isolation score.
297 double isoScore(0.0);
298 double isoScoreAsWeightedAvg(0.0);
299 double sumWeights(0.0);
300
301 B2DEBUG(11, "Particle w/ mdstIndex[" << iMdstIdx << "] (PDG = " << iParticle->getPDGCode() << ").");
302
303 for (const auto& detName : m_detNames) {
304
305 auto detWeight = this->getDetectorWeight(iParticle, detName);
306
307 auto weightedSumNonIsoLayers = this->getWeightedSumNonIsoLayers(iParticle, detName, detWeight);
308 auto weightedSumInvDists = this->getWeightedSumInvDists(iParticle, detName, detWeight);
309
310 isoScore += weightedSumNonIsoLayers;
311 isoScoreAsWeightedAvg += weightedSumInvDists;
312 sumWeights += detWeight;
313
314 }
315
316 // Normalise the isolation score to lie in [0, 1].
317 auto minScore = 0.;
318 auto maxScore = m_detNames.size();
319 isoScore = (isoScore - minScore) / (maxScore - minScore);
320
321 isoScoreAsWeightedAvg /= sumWeights;
322 // Normalise weighted average between [0, 1].
323 // But first, clip values that are too large.
324 // Finally, ensure a larger score is assigned for well-isolated tracks.
325 isoScoreAsWeightedAvg = 1. - ((std::min(isoScoreAsWeightedAvg, 1e2) - minScore) / (1e2 - minScore));
326
327 B2DEBUG(11, "\n"
328 << "Isolation score: " << isoScore
329 << "\n"
330 << "Isolation score (as weighted avg): " << isoScoreAsWeightedAvg
331 << "\n"
332 << "Storing extraInfo variable:\n"
334 << "\n"
336
337 m_particles[iParticle->getArrayIndex()]->writeExtraInfo(m_isoScoreVariable, isoScore);
338 m_particles[iParticle->getArrayIndex()]->writeExtraInfo(m_isoScoreVariableAsWeightedAvg, isoScoreAsWeightedAvg);
339
340 }
341
342 B2DEBUG(11, "Finished processing EVENT: " << m_event_metadata->getEvent());
343
344}
345
346
347double TrackIsoCalculatorModule::getDetectorWeight(const Particle* iParticle, const std::string& detName) const
348{
349
351 return -1.;
352 }
353
354 auto hypo = Const::ChargedStable(std::abs(iParticle->getPDGCode()));
355 auto p = iParticle->getP();
356 auto theta = iParticle->getMomentum().Theta();
357 auto det = this->getDetEnum(detName);
358
359 auto detWeight = (*m_DBWeights.get())->getWeight(hypo, det, p, theta);
360 // If w > 0, the detector has detrimental impact on PID:
361 // the value is reset to zero to prevent the detector from contributing to the score.
362 // NB: NaN should stay NaN.
363 detWeight = (detWeight < 0 || std::isnan(detWeight)) ? detWeight : 0.0;
364
365 return detWeight;
366
367}
368
369
370double TrackIsoCalculatorModule::getWeightedSumNonIsoLayers(const Particle* iParticle, const std::string& detName,
371 const float detWeight) const
372{
373
374 auto det = this->getDetEnum(detName);
375 auto nLayers = DetectorSurface::detToLayers.at(detName).size();
376
377 unsigned int n(0);
378 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
379 auto iDetLayer = detName + std::to_string(iLayer);
380 auto distVar = m_detLayerToDistVariable.at(iDetLayer);
381 auto threshDist = this->getDistThreshold(det, iLayer);
382
383 if (iParticle->hasExtraInfo(distVar)) {
384 if (iParticle->getExtraInfo(distVar) < threshDist) {
385 n++;
386 }
387 }
388
389 }
390
391 if (!n) {
392 B2DEBUG(12, "\nNo close-enough neighbours to this particle in the " << detName << " were found.");
393 }
394
395 if (n > nLayers) {
396 B2FATAL("\nTotal layers in " << detName << ": N=" << nLayers
397 << "\n"
398 << "Layers w/ a close-enough particle: n=" << n
399 << "\n"
400 << "n > N ?? Abort...");
401 }
402
403 return 1. - (-detWeight * (n / nLayers));
404
405}
406
407
408double TrackIsoCalculatorModule::getWeightedSumInvDists(const Particle* iParticle, const std::string& detName,
409 const float detWeight) const
410{
411
412 auto det = this->getDetEnum(detName);
413
414 double sumInvDists(0.);
415 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
416
417 auto iDetLayer = detName + std::to_string(iLayer);
418 auto distVar = m_detLayerToDistVariable.at(iDetLayer);
419 auto threshDist = this->getDistThreshold(det, iLayer);
420
421 if (iParticle->hasExtraInfo(distVar)) {
422 sumInvDists += threshDist / iParticle->getExtraInfo(distVar);
423 }
424
425 }
426
427 return detWeight * sumInvDists;
428
429}
430
431
433 const Particle* jParticle,
434 const std::string& detLayerName) const
435{
436
437 // Radius and z boundaries of the cylinder describing this detector's surface.
438 const auto rho = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_rho;
439 const auto zfwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_zfwd;
440 const auto zbwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_zbwd;
441 // Polar angle boundaries between barrel and endcaps.
442 const auto th_fwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_fwd;
443 const auto th_fwd_brl = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_fwd_brl;
444 const auto th_bwd_brl = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_bwd_brl;
445 const auto th_bwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_bwd;
446
447 std::string nameExtTheta = "helixExtTheta(" + std::to_string(rho) + "," + std::to_string(zfwd) + "," + std::to_string(zbwd) + ")";
449 nameExtTheta.replace(nameExtTheta.size() - 1, 1, ", 1)");
450 }
451 const auto iExtTheta = std::get<double>(Variable::Manager::Instance().getVariable(nameExtTheta)->function(iParticle));
452 const auto jExtTheta = std::get<double>(Variable::Manager::Instance().getVariable(nameExtTheta)->function(jParticle));
453
454 std::string nameExtPhi = "helixExtPhi(" + std::to_string(rho) + "," + std::to_string(zfwd) + "," + std::to_string(zbwd) + ")";
456 nameExtPhi.replace(nameExtPhi.size() - 1, 1, ", 1)");
457 }
458 const auto iExtPhi = std::get<double>(Variable::Manager::Instance().getVariable(nameExtPhi)->function(iParticle));
459 const auto jExtPhi = std::get<double>(Variable::Manager::Instance().getVariable(nameExtPhi)->function(jParticle));
460
461 const auto iExtInBarrel = (iExtTheta >= th_fwd_brl && iExtTheta < th_bwd_brl);
462 const auto jExtInBarrel = (jExtTheta >= th_fwd_brl && jExtTheta < th_bwd_brl);
463
464 const auto iExtInFWDEndcap = (iExtTheta >= th_fwd && iExtTheta < th_fwd_brl);
465 const auto jExtInFWDEndcap = (jExtTheta >= th_fwd && jExtTheta < th_fwd_brl);
466
467 const auto iExtInBWDEndcap = (iExtTheta >= th_bwd_brl && iExtTheta < th_bwd);
468 const auto jExtInBWDEndcap = (jExtTheta >= th_bwd_brl && jExtTheta < th_bwd);
469
470 if (boost::contains(detLayerName, "CDC") || boost::contains(detLayerName, "TOP")) {
471
472 // If any of the two extrapolated tracks is not in the barrel region of the CDC/TOP, the distance is undefined.
473 if (!iExtInBarrel || !jExtInBarrel) {
474 return std::numeric_limits<double>::quiet_NaN();
475 }
476
477 // For CDC and TOP, we calculate the distance between the points where the two input
478 // extrapolated track helices cross the input detector's cylindrical surface
479 // on the (rho, phi) plane. Namely, this is the cord length of the arc
480 // that subtends deltaPhi.
481 auto diffPhi = jExtPhi - iExtPhi;
482 if (std::abs(diffPhi) > M_PI) {
483 diffPhi = (diffPhi > M_PI) ? diffPhi - 2 * M_PI : 2 * M_PI + diffPhi;
484 }
485
486 return 2.0 * rho * sin(std::abs(diffPhi) / 2.0);
487
488 } else {
489
490 if (boost::contains(detLayerName, "ARICH")) {
491 // If any of the two tracks is not in the ARICH theta acceptance, the distance is undefined.
492 if (!iExtInFWDEndcap || !jExtInFWDEndcap) {
493 return std::numeric_limits<double>::quiet_NaN();
494 }
495 }
496 if (boost::contains(detLayerName, "ECL") || boost::contains(detLayerName, "KLM")) {
497
498 // For ECL and KLM, we require track pairs to be both in the barrel,
499 // both in the FWD endcap, or both in the FWD endcap. Otherwise, the distance is undefined.
500 if (
501 !(iExtInBarrel && jExtInBarrel) &&
502 !(iExtInFWDEndcap && jExtInFWDEndcap) &&
503 !(iExtInBWDEndcap && jExtInBWDEndcap)
504 ) {
505 return std::numeric_limits<double>::quiet_NaN();
506 }
507 }
508
509 // Ok, we know theta and phi.
510 // Let's extract (spherical) R by using the transformation:
511 //
512 // 1. rho = r * sin(theta)
513 // 2. phi = phi
514 // 3. z = r * cos(theta)
515 //
516 // The formula to be inverted depends on where each extrapolated track's theta is found:
517 // if in barrel, use 1. (rho is known), if in fwd/bwd endcap, use 3. (zfwd/zbwd is known).
518
519 const auto iExtR = (iExtTheta >= th_fwd_brl && iExtTheta < th_bwd_brl) ? rho / sin(iExtTheta) : ((iExtTheta >= th_fwd
520 && iExtTheta < th_fwd_brl) ? zfwd / cos(iExtTheta) : zbwd / cos(iExtTheta));
521 const auto jExtR = (jExtTheta >= th_fwd_brl && jExtTheta < th_bwd_brl) ? rho / sin(jExtTheta) : ((jExtTheta >= th_fwd
522 && jExtTheta < th_fwd_brl) ? zfwd / cos(jExtTheta) : zbwd / cos(jExtTheta));
523
524 return sqrt((iExtR * iExtR) + (jExtR * jExtR) - 2 * iExtR * jExtR * (sin(iExtTheta) * sin(jExtTheta) * cos(iExtPhi - jExtPhi)
525 + cos(iExtTheta) * cos(jExtTheta)));
526
527 }
528
529 return std::numeric_limits<double>::quiet_NaN();
530
531}
532
534{
535
536 bool checkPList = false;
537
540 } else {
541 for (int pdgcode : m_decaydescriptor.getSelectionPDGCodes()) {
542 checkPList = Const::chargedStableSet.find(abs(pdgcode)) != Const::invalidParticle;
543 if (!checkPList) {
544 break;
545 }
546 }
547 }
548
550 bool checkPListReference = false;
551 if (dd.init(m_pListReferenceName)) {
552 checkPListReference = Const::chargedStableSet.find(abs(dd.getMother()->getPDGCode())) != Const::invalidParticle;
553 }
554
555 return (checkPList and checkPListReference);
556
557};
Provides a type-safe way to pass members of the chargedStableSet set.
Definition: Const.h:589
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
Definition: Const.h:571
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:618
static const ParticleType invalidParticle
Invalid particle, used internally.
Definition: Const.h:681
Represents a particle in the DecayDescriptor.
int getPDGCode() const
Return PDG code.
std::string getFullName() const
returns the full name of the particle full_name = name:label
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
std::vector< int > getSelectionPDGCodes()
Return list of PDG codes of selected particles.
std::vector< std::string > getSelectionNames()
Return list of human readable names of selected particles.
std::vector< const Particle * > getSelectionParticles(const Particle *particle)
Get a vector of pointers with selected daughters in the decay tree.
const DecayDescriptorParticle * getMother() const
return mother.
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Class to store reconstructed particles.
Definition: Particle.h:75
bool hasExtraInfo(const std::string &name) const
Return whether the extra info with the given name is set.
Definition: Particle.cc:1266
int getPDGCode(void) const
Returns PDG code.
Definition: Particle.h:454
ROOT::Math::XYZVector getMomentum() const
Returns momentum vector.
Definition: Particle.h:560
double getP() const
Returns momentum magnitude (same as getMomentumMagnitude but with shorter name)
Definition: Particle.h:578
double getExtraInfo(const std::string &name) const
Return given value if set.
Definition: Particle.cc:1289
StoreObjPtr< EventMetaData > m_event_metadata
The event information.
std::unique_ptr< DBObjPtr< PIDDetectorWeights > > m_DBWeights
Interface to get the database payload with the PID detector weights.
~TrackIsoCalculatorModule() override
Destructor, use this to clean up anything you created in the constructor.
void initialize() override
Use this to initialize resources or memory your module needs.
double getDistAtDetSurface(const Particle *iParticle, const Particle *jParticle, const std::string &detLayerName) const
Calculate the distance between the points where the two input extrapolated track helices cross the gi...
void event() override
Called once for each event.
std::unordered_map< std::string, std::string > m_detLayerToDistVariable
Map that associates to each detector layer (e.g., 'CDC6') the name of the variable representing the d...
std::string m_decayString
The name of the input charged stable particle list, or composite particle w/ charged stable daughters...
StoreObjPtr< ParticleList > m_pListTarget
The input ParticleList object for which distances are to be calculated.
std::string m_isoScoreVariable
The name of the variable representing the track isolation score.
double getWeightedSumInvDists(const Particle *iParticle, const std::string &detName, const float detWeight) const
Get the sum of the inverse (scaled) minimum distances over the given detector layers,...
StoreArray< Particle > m_particles
StoreArray of Particles.
std::string m_payloadName
The name of the database payload object with the MVA weights.
std::vector< std::string > m_detNames
The list of names of the detectors at whose inner (cylindrical) surface we extrapolate each track's p...
Const::EDetector getDetEnum(const std::string &detName) const
Get the enum type for this detector name.
std::string m_pListReferenceName
The name of the input ParticleList of reference tracks.
std::unordered_map< std::string, std::string > m_detLayerToRefPartIdxVariable
Map that associates to each detector layer (e.g, 'CDC6') the name of the variable representing the md...
double getDistThreshold(Const::EDetector det, int layer) const
Get the threshold value per detector layer for the distance to closest ext.
bool onlySelectedStdChargedInDecay()
Check whether input particle list and reference list are of a valid charged stable particle.
double getDetectorWeight(const Particle *iParticle, const std::string &detName) const
Get the PID weight, , for this particle and detector reading it from the payload, if selected.
bool m_excludePIDDetWeights
Exclude the PID detector weights for the isolation score definition.
DecayDescriptor m_decaydescriptor
< Decay descriptor of decays to look for.
TrackIsoCalculatorModule()
Constructor: Sets the description, the properties and the parameters of the module.
double getWeightedSumNonIsoLayers(const Particle *iParticle, const std::string &detName, const float detWeight) const
Get the sum of layers with a close-by track, divided by the total number of layers,...
unsigned short m_nSelectedDaughters
The number of selected daughters in the decay string.
StoreObjPtr< ParticleList > m_pListReference
The input ParticleList object of reference tracks.
std::string m_isoScoreVariableAsWeightedAvg
The name of the variable representing the track isolation score.
bool m_useHighestProbMassForExt
If this option is set, the helix extrapolation for the target and reference particles will use the tr...
static Manager & Instance()
get singleton instance.
Definition: Manager.cc:25
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
static const std::unordered_map< std::string, DetSurfCylBoundaries > detLayerToSurfBoundaries
Map that associates to each detector layer its valid cylindrical surface's boundaries.
static const std::unordered_map< std::string, std::vector< int > > detToLayers
Map that associates to each detector its list of valid layers.