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/VariableManager/Manager.h>
12#include <analysis/utility/DetectorSurface.h>
13
14#include <cmath>
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");
28
29 // Parameter definitions
30 addParam("decayString",
32 "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.");
33 addParam("particleListReference",
35 "The name of the input ParticleList of reference tracks. Must be a charged stable particle as defined in Const::chargedStableSet.");
36 addParam("detectorNames",
38 "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}.",
39 std::vector<std::string>());
40 addParam("useHighestProbMassForExt",
42 "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.",
43 bool(false));
44 addParam("payloadName",
46 "The name of the database payload object with the PID detector weights.",
47 std::string("PIDDetectorWeights"));
48 addParam("excludePIDDetWeights",
50 "If set to true, will not use the PID detector weights for the score definition.",
51 bool(false));
52}
53
55{
56}
57
59{
60 m_event_metadata.isRequired();
61
63 m_DBWeights = std::make_unique<DBObjPtr<PIDDetectorWeights>>(m_payloadName);
64 }
65
67 if (!valid) {
68 B2ERROR("Decay string " << m_decayString << " is invalid.");
69 }
70
72
73 m_pListTarget.isRequired(mother->getFullName());
75
76 if (m_nSelectedDaughters > 1) {
77 B2ERROR("More than one daughter is selected in the decay string " << m_decayString << ".");
78 }
79
81
82 B2INFO("Calculating track-based isolation variables for the decay string: "
84 << " using the reference ParticleList: "
86 << ".");
87
89 B2ERROR("Selected ParticleList in decay string:"
91 << " and/or reference ParticleList: "
93 << " is not that of a valid particle in Const::chargedStableSet!");
94 }
95
97 B2INFO("Will use track fit result for the most probable mass hypothesis in helix extrapolation.");
98 }
99
100 std::string detNamesConcat("");
101
102 for (auto& detName : m_detNames) {
103
104 // Ensure we use uppercase detector labels.
105 boost::to_upper(detName);
106
107 detNamesConcat += "_" + detName;
108
109 // Define the name(s) of the variables for this detector to be stored as extraInfo.
110 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
111
112
113 auto iDetLayer = detName + std::to_string(iLayer);
114
115 auto distVarName = "distToClosestTrkAt" + iDetLayer + "_VS_" + m_pListReferenceName;
117 distVarName += "__useHighestProbMassForExt";
118 }
119 auto refPartIdxVarName = "idxOfClosestPartAt" + iDetLayer + "In_" + m_pListReferenceName;
120
121 m_detLayerToDistVariable.insert(std::make_pair(iDetLayer, distVarName));
122 m_detLayerToRefPartIdxVariable.insert(std::make_pair(iDetLayer, refPartIdxVarName));
123
124 }
125
126 // Isolation score variable.
127 m_isoScoreVariable = "trkIsoScore" + detNamesConcat + "_VS_" + m_pListReferenceName;
128 m_isoScoreVariableAsWeightedAvg = "trkIsoScoreAsWeightedAvg" + detNamesConcat + "_VS_" + m_pListReferenceName;
130 m_isoScoreVariable += "__useHighestProbMassForExt";
131 m_isoScoreVariableAsWeightedAvg += "__useHighestProbMassForExt";
132 }
133 }
134
135}
136
138{
139 B2DEBUG(11, "Start processing EVENT: " << m_event_metadata->getEvent());
140
141 const auto nMotherParticles = m_pListTarget->getListSize();
142
143 // Fill transient container of all selected charged particles in the decay
144 // for which the distance to nearest neighbour is to be calculated.
145 // If the input ParticleList is that of standard charged particles, just copy
146 // the whole list over, otherwise loop over the selected charged daughters.
147 std::unordered_map<int, const Particle*> targetParticles;
148 targetParticles.reserve(nMotherParticles);
149
150 for (unsigned int iPart(0); iPart < nMotherParticles; ++iPart) {
151
152 auto iParticle = m_pListTarget->getParticle(iPart);
153
154 // Loop over the input detectors.
155 for (const auto& detName : m_detNames) {
156
157 // Loop over the layer of the input detector.
158 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
159
160 auto iDetLayer = detName + std::to_string(iLayer);
161
163 for (auto* iDaughter : m_decaydescriptor.getSelectionParticles(iParticle)) {
164 // Check if the distance for this target particle has been set already,
165 // e.g. by a previous instance of this module.
166 if (iDaughter->hasExtraInfo(m_detLayerToDistVariable[iDetLayer])) {
167 continue;
168 }
169 targetParticles.insert({iDaughter->getMdstSource(), iDaughter});
170 }
171 } else {
172 if (iParticle->hasExtraInfo(m_detLayerToDistVariable[iDetLayer])) {
173 continue;
174 }
175 targetParticles.insert({iParticle->getMdstSource(), iParticle});
176 }
177
178 }
179 }
180 }
181
182 const auto nParticlesTarget = targetParticles.size();
183 const auto nParticlesReference = m_pListReference->getListSize();
184
185 // Loop over the input detectors.
186 for (const auto& detName : m_detNames) {
187
188 // Loop over the layer of the input detector.
189 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
190
191 auto iDetLayer = detName + std::to_string(iLayer);
192
193 B2DEBUG(11, "\n"
194 << "Detector surface: " << iDetLayer << "\n"
195 << "nMotherParticles: " << nMotherParticles << "\n"
196 << "nParticlesTarget: " << nParticlesTarget << "\n"
197 << "nParticlesReference: " << nParticlesReference);
198
199 double dummyDist(-1.0);
200
201 // Store the pair-wise distances in a map,
202 // where the keys are pairs of mdst indexes.
203 std::map<std::pair<int, int>, double> particleMdstSourcePairsToDist;
204
205 // Loop over input particle list
206 for (const auto& targetParticle : targetParticles) {
207
208 auto iMdstSource = targetParticle.first;
209 auto iParticle = targetParticle.second;
210
211 for (unsigned int jPart(0); jPart < nParticlesReference; ++jPart) {
212
213 auto jParticle = m_pListReference->getParticle(jPart);
214 auto jMdstSource = jParticle->getMdstSource();
215
216 auto partMdstSourcePair = std::make_pair(iMdstSource, jMdstSource);
217
218 // Set dummy distance if same particle.
219 if (iMdstSource == jMdstSource) {
220 particleMdstSourcePairsToDist[partMdstSourcePair] = dummyDist;
221 continue;
222 }
223 // If:
224 //
225 // - the mass hypothesis of the best fit is used, OR
226 // - the mass hypothesis of the 'default' fit of the two particles is the same,
227 //
228 // avoid re-doing the calculation if a pair with the flipped mdst indexes in the map already exists.
229 if (m_useHighestProbMassForExt || (iParticle->getPDGCodeUsedForFit() == jParticle->getPDGCodeUsedForFit())) {
230 if (particleMdstSourcePairsToDist.count({jMdstSource, iMdstSource})) {
231 particleMdstSourcePairsToDist[partMdstSourcePair] = particleMdstSourcePairsToDist[ {jMdstSource, iMdstSource}];
232 continue;
233 }
234 }
235 // Calculate the pair-wise distance.
236 particleMdstSourcePairsToDist[partMdstSourcePair] = this->getDistAtDetSurface(iParticle, jParticle, iDetLayer);
237 }
238
239 }
240
241 // For each particle in the input list, find the minimum among all distances to the reference particles.
242 for (const auto& targetParticle : targetParticles) {
243
244 auto iMdstSource = targetParticle.first;
245 auto iParticle = targetParticle.second;
246
247 // Save the distances and the mdst indexes of the reference particles.
248 std::vector<std::pair<double, int>> iDistancesAndRefMdstSources;
249 for (const auto& [mdstIdxs, dist] : particleMdstSourcePairsToDist) {
250 if (mdstIdxs.first == iMdstSource) {
251 if (!std::isnan(dist) && dist >= 0) {
252 iDistancesAndRefMdstSources.push_back(std::make_pair(dist, mdstIdxs.second));
253 }
254 }
255 }
256
257 if (!iDistancesAndRefMdstSources.size()) {
258 B2DEBUG(12, "The container of distances is empty. Perhaps the target and reference lists contain the same exact particles?");
259 continue;
260 }
261
262 const auto minDist = *std::min_element(std::begin(iDistancesAndRefMdstSources), std::end(iDistancesAndRefMdstSources),
263 [](const auto & l, const auto & r) {return l.first < r.first;});
264
265 auto jParticle = m_pListReference->getParticleWithMdstSource(minDist.second);
266
267 B2DEBUG(11, "\n"
268 << "Particle w/ mdstSource[" << iMdstSource << "] (PDG = "
269 << iParticle->getPDGCode() << "). Closest charged particle w/ mdstSource["
270 << minDist.second
271 << "] (PDG = " << jParticle->getPDGCode()
272 << ") at " << iDetLayer
273 << " surface is found at D = " << minDist.first
274 << " [cm]\n"
275 << "Storing extraInfo variables:\n"
276 << m_detLayerToDistVariable[iDetLayer]
277 << "\n"
278 << m_detLayerToRefPartIdxVariable[iDetLayer]);
279
280 if (!iParticle->hasExtraInfo(m_detLayerToDistVariable[iDetLayer])) {
281 m_particles[iParticle->getArrayIndex()]->addExtraInfo(m_detLayerToDistVariable[iDetLayer], minDist.first);
282 }
283 m_particles[iParticle->getArrayIndex()]->writeExtraInfo(m_detLayerToRefPartIdxVariable[iDetLayer], minDist.second);
284
285 } // end loop over input particle list.
286
287 } // end loop over detector layers.
288
289 } // end loop over input detectors.
290
291 // Now calculate the isolation score for each target particle.
292 for (const auto& targetParticle : targetParticles) {
293
294 auto iMdstSource = targetParticle.first;
295 auto iParticle = targetParticle.second;
296
297 // Initialise isolation score.
298 double isoScore(0.0);
299 double isoScoreAsWeightedAvg(0.0);
300 double sumWeights(0.0);
301
302 B2DEBUG(11, "Particle w/ mdstSource[" << iMdstSource << "] (PDG = " << iParticle->getPDGCode() << ").");
303
304 for (const auto& detName : m_detNames) {
305
306 auto detWeight = this->getDetectorWeight(iParticle, detName);
307
308 auto weightedSumNonIsoLayers = this->getWeightedSumNonIsoLayers(iParticle, detName, detWeight);
309 auto weightedSumInvDists = this->getWeightedSumInvDists(iParticle, detName, detWeight);
310
311 isoScore += weightedSumNonIsoLayers;
312 isoScoreAsWeightedAvg += weightedSumInvDists;
313 sumWeights += detWeight;
314
315 }
316
317 // Normalise the isolation score to lie in [0, 1].
318 auto minScore = 0.;
319 auto maxScore = m_detNames.size();
320 isoScore = (isoScore - minScore) / (maxScore - minScore);
321
322 isoScoreAsWeightedAvg /= sumWeights;
323 // Normalise weighted average between [0, 1].
324 // But first, clip values that are too large.
325 // Finally, ensure a larger score is assigned for well-isolated tracks.
326 isoScoreAsWeightedAvg = 1. - ((std::min(isoScoreAsWeightedAvg, 1e2) - minScore) / (1e2 - minScore));
327
328 B2DEBUG(11, "\n"
329 << "Isolation score: " << isoScore
330 << "\n"
331 << "Isolation score (as weighted avg): " << isoScoreAsWeightedAvg
332 << "\n"
333 << "Storing extraInfo variable:\n"
335 << "\n"
337
338 m_particles[iParticle->getArrayIndex()]->writeExtraInfo(m_isoScoreVariable, isoScore);
339 m_particles[iParticle->getArrayIndex()]->writeExtraInfo(m_isoScoreVariableAsWeightedAvg, isoScoreAsWeightedAvg);
340
341 }
342
343 B2DEBUG(11, "Finished processing EVENT: " << m_event_metadata->getEvent());
344
345}
346
347
348double TrackIsoCalculatorModule::getDetectorWeight(const Particle* iParticle, const std::string& detName) const
349{
350
352 return -1.;
353 }
354
355 auto hypo = Const::ChargedStable(std::abs(iParticle->getPDGCode()));
356 auto p = iParticle->getP();
357 auto theta = iParticle->getMomentum().Theta();
358 auto det = this->getDetEnum(detName);
359
360 auto detWeight = (*m_DBWeights.get())->getWeight(hypo, det, p, theta);
361 // If w > 0, the detector has detrimental impact on PID:
362 // the value is reset to zero to prevent the detector from contributing to the score.
363 // NB: NaN should stay NaN.
364 detWeight = (detWeight < 0 || std::isnan(detWeight)) ? detWeight : 0.0;
365
366 return detWeight;
367
368}
369
370
371double TrackIsoCalculatorModule::getWeightedSumNonIsoLayers(const Particle* iParticle, const std::string& detName,
372 const float detWeight) const
373{
374
375 auto det = this->getDetEnum(detName);
376 auto nLayers = DetectorSurface::detToLayers.at(detName).size();
377
378 unsigned int n(0);
379 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
380 auto iDetLayer = detName + std::to_string(iLayer);
381 auto distVar = m_detLayerToDistVariable.at(iDetLayer);
382 auto threshDist = this->getDistThreshold(det, iLayer);
383
384 if (iParticle->hasExtraInfo(distVar)) {
385 if (iParticle->getExtraInfo(distVar) < threshDist) {
386 n++;
387 }
388 }
389
390 }
391
392 if (!n) {
393 B2DEBUG(12, "\nNo close-enough neighbours to this particle in the " << detName << " were found.");
394 }
395
396 if (n > nLayers) {
397 B2FATAL("\nTotal layers in " << detName << ": N=" << nLayers
398 << "\n"
399 << "Layers w/ a close-enough particle: n=" << n
400 << "\n"
401 << "n > N ?? Abort...");
402 }
403
404 return 1. - (-detWeight * (n / nLayers));
405
406}
407
408
409double TrackIsoCalculatorModule::getWeightedSumInvDists(const Particle* iParticle, const std::string& detName,
410 const float detWeight) const
411{
412
413 auto det = this->getDetEnum(detName);
414
415 double sumInvDists(0.);
416 for (const auto& iLayer : DetectorSurface::detToLayers.at(detName)) {
417
418 auto iDetLayer = detName + std::to_string(iLayer);
419 auto distVar = m_detLayerToDistVariable.at(iDetLayer);
420 auto threshDist = this->getDistThreshold(det, iLayer);
421
422 if (iParticle->hasExtraInfo(distVar)) {
423 sumInvDists += threshDist / iParticle->getExtraInfo(distVar);
424 }
425
426 }
427
428 return detWeight * sumInvDists;
429
430}
431
432
434 const Particle* jParticle,
435 const std::string& detLayerName) const
436{
437
438 // Radius and z boundaries of the cylinder describing this detector's surface.
439 const auto rho = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_rho;
440 const auto zfwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_zfwd;
441 const auto zbwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_zbwd;
442 // Polar angle boundaries between barrel and endcaps.
443 const auto th_fwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_fwd;
444 const auto th_fwd_brl = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_fwd_brl;
445 const auto th_bwd_brl = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_bwd_brl;
446 const auto th_bwd = DetectorSurface::detLayerToSurfBoundaries.at(detLayerName).m_th_bwd;
447
448 std::string nameExtTheta = "helixExtTheta(" + std::to_string(rho) + "," + std::to_string(zfwd) + "," + std::to_string(zbwd) + ")";
450 nameExtTheta.replace(nameExtTheta.size() - 1, 1, ", 1)");
451 }
452 const auto iExtTheta = std::get<double>(Variable::Manager::Instance().getVariable(nameExtTheta)->function(iParticle));
453 const auto jExtTheta = std::get<double>(Variable::Manager::Instance().getVariable(nameExtTheta)->function(jParticle));
454
455 std::string nameExtPhi = "helixExtPhi(" + std::to_string(rho) + "," + std::to_string(zfwd) + "," + std::to_string(zbwd) + ")";
457 nameExtPhi.replace(nameExtPhi.size() - 1, 1, ", 1)");
458 }
459 const auto iExtPhi = std::get<double>(Variable::Manager::Instance().getVariable(nameExtPhi)->function(iParticle));
460 const auto jExtPhi = std::get<double>(Variable::Manager::Instance().getVariable(nameExtPhi)->function(jParticle));
461
462 const auto iExtInBarrel = (iExtTheta >= th_fwd_brl && iExtTheta < th_bwd_brl);
463 const auto jExtInBarrel = (jExtTheta >= th_fwd_brl && jExtTheta < th_bwd_brl);
464
465 const auto iExtInFWDEndcap = (iExtTheta >= th_fwd && iExtTheta < th_fwd_brl);
466 const auto jExtInFWDEndcap = (jExtTheta >= th_fwd && jExtTheta < th_fwd_brl);
467
468 const auto iExtInBWDEndcap = (iExtTheta >= th_bwd_brl && iExtTheta < th_bwd);
469 const auto jExtInBWDEndcap = (jExtTheta >= th_bwd_brl && jExtTheta < th_bwd);
470
471 if (boost::contains(detLayerName, "CDC") || boost::contains(detLayerName, "TOP")) {
472
473 // If any of the two extrapolated tracks is not in the barrel region of the CDC/TOP, the distance is undefined.
474 if (!iExtInBarrel || !jExtInBarrel) {
475 return std::numeric_limits<double>::quiet_NaN();
476 }
477
478 // For CDC and TOP, we calculate the distance between the points where the two input
479 // extrapolated track helices cross the input detector's cylindrical surface
480 // on the (rho, phi) plane. Namely, this is the cord length of the arc
481 // that subtends deltaPhi.
482 auto diffPhi = jExtPhi - iExtPhi;
483 if (std::abs(diffPhi) > M_PI) {
484 diffPhi = (diffPhi > M_PI) ? diffPhi - 2 * M_PI : 2 * M_PI + diffPhi;
485 }
486
487 return 2.0 * rho * sin(std::abs(diffPhi) / 2.0);
488
489 } else {
490
491 if (boost::contains(detLayerName, "ARICH")) {
492 // If any of the two tracks is not in the ARICH theta acceptance, the distance is undefined.
493 if (!iExtInFWDEndcap || !jExtInFWDEndcap) {
494 return std::numeric_limits<double>::quiet_NaN();
495 }
496 }
497 if (boost::contains(detLayerName, "ECL") || boost::contains(detLayerName, "KLM")) {
498
499 // For ECL and KLM, we require track pairs to be both in the barrel,
500 // both in the FWD endcap, or both in the FWD endcap. Otherwise, the distance is undefined.
501 if (
502 !(iExtInBarrel && jExtInBarrel) &&
503 !(iExtInFWDEndcap && jExtInFWDEndcap) &&
504 !(iExtInBWDEndcap && jExtInBWDEndcap)
505 ) {
506 return std::numeric_limits<double>::quiet_NaN();
507 }
508 }
509
510 // Ok, we know theta and phi.
511 // Let's extract (spherical) R by using the transformation:
512 //
513 // 1. rho = r * sin(theta)
514 // 2. phi = phi
515 // 3. z = r * cos(theta)
516 //
517 // The formula to be inverted depends on where each extrapolated track's theta is found:
518 // if in barrel, use 1. (rho is known), if in fwd/bwd endcap, use 3. (zfwd/zbwd is known).
519
520 const auto iExtR = (iExtTheta >= th_fwd_brl && iExtTheta < th_bwd_brl) ? rho / sin(iExtTheta) : ((iExtTheta >= th_fwd
521 && iExtTheta < th_fwd_brl) ? zfwd / cos(iExtTheta) : zbwd / cos(iExtTheta));
522 const auto jExtR = (jExtTheta >= th_fwd_brl && jExtTheta < th_bwd_brl) ? rho / sin(jExtTheta) : ((jExtTheta >= th_fwd
523 && jExtTheta < th_fwd_brl) ? zfwd / cos(jExtTheta) : zbwd / cos(jExtTheta));
524
525 return sqrt((iExtR * iExtR) + (jExtR * jExtR) - 2 * iExtR * jExtR * (sin(iExtTheta) * sin(jExtTheta) * cos(iExtPhi - jExtPhi)
526 + cos(iExtTheta) * cos(jExtTheta)));
527
528 }
529
530 return std::numeric_limits<double>::quiet_NaN();
531
532}
533
535{
536
537 bool checkPList = false;
538
541 } else {
542 for (int pdgcode : m_decaydescriptor.getSelectionPDGCodes()) {
543 checkPList = Const::chargedStableSet.find(abs(pdgcode)) != Const::invalidParticle;
544 if (!checkPList) {
545 break;
546 }
547 }
548 }
549
551 bool checkPListReference = false;
552 if (dd.init(m_pListReferenceName)) {
553 checkPListReference = Const::chargedStableSet.find(abs(dd.getMother()->getPDGCode())) != Const::invalidParticle;
554 }
555
556 return (checkPList and checkPListReference);
557
558};
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
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
Class to store reconstructed particles.
Definition: Particle.h:76
bool hasExtraInfo(const std::string &name) const
Return whether the extra info with the given name is set.
Definition: Particle.cc:1351
int getPDGCode(void) const
Returns PDG code.
Definition: Particle.h:465
ROOT::Math::XYZVector getMomentum() const
Returns momentum vector.
Definition: Particle.h:580
double getP() const
Returns momentum magnitude (same as getMomentumMagnitude but with shorter name)
Definition: Particle.h:598
double getExtraInfo(const std::string &name) const
Return given value if set.
Definition: Particle.cc:1374
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:26
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
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.