Belle II Software  release-08-01-10
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 
18 using namespace Belle2;
19 
20 REG_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",
36  m_detNames,
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 
65  bool valid = m_decaydescriptor.init(m_decayString);
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: "
82  << m_decayString
83  << " using the reference ParticleList: "
85  << ".");
86 
88  B2ERROR("Selected ParticleList in decay string:"
89  << m_decayString
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 
161  if (m_nSelectedDaughters) {
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 
347 double 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 
370 double 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 
408 double 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 
538  if (!m_nSelectedDaughters) {
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 
549  DecayDescriptor dd;
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:580
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
Definition: Const.h:562
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:609
static const ParticleType invalidParticle
Invalid particle, used internally.
Definition: Const.h:672
Represents a particle in the DecayDescriptor.
int getPDGCode() const
Return PDG code.
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.
const DecayDescriptorParticle * getMother() const
return mother.
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.
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:1267
int getPDGCode(void) const
Returns PDG code.
Definition: Particle.h:426
ROOT::Math::XYZVector getMomentum() const
Returns momentum vector.
Definition: Particle.h:526
double getP() const
Returns momentum magnitude (same as getMomentumMagnitude but with shorter name)
Definition: Particle.h:544
double getExtraInfo(const std::string &name) const
Return given value if set.
Definition: Particle.cc:1290
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 detctor 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
REG_MODULE(arichBtest)
Register the Module.
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
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.