Belle II Software  release-08-01-10
InclusiveVariables.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 // Own header.
10 #include <analysis/variables/InclusiveVariables.h>
11 
12 #include <analysis/dataobjects/Particle.h>
13 
14 #include <framework/gearbox/Const.h>
15 #include <framework/logging/Logger.h>
16 #include <framework/utilities/Conversion.h>
17 
18 using namespace std;
19 
20 namespace Belle2 {
25  namespace Variable {
26 
27  int nDaughterPhotons(const Particle* particle)
28  {
29  int result = 0;
30  auto fspDaughters = particle->getFinalStateDaughters();
31  for (auto* daughter : fspDaughters) {
32  if (abs(daughter->getPDGCode()) == Const::photon.getPDGCode()) {
33  result++;
34  }
35  }
36  return result;
37  }
38 
39  int nDaughterNeutralHadrons(const Particle* particle)
40  {
41  int result = 0;
42  auto fspDaughters = particle->getFinalStateDaughters();
43  for (auto* daughter : fspDaughters) {
44  if (abs(daughter->getPDGCode()) == Const::neutron.getPDGCode()
45  or abs(daughter->getPDGCode()) == Const::Klong.getPDGCode()) {
46  result++;
47  }
48  }
49  return result;
50  }
51 
52  int nDaughterCharged(const Particle* particle, const std::vector<double>& argument)
53  {
54  int absPDGCode = 0;
55  if (argument.size() == 1) {
56  absPDGCode = abs(std::lround(argument[0]));
57  }
58 
59  int result = 0;
60  auto fspDaughters = particle->getFinalStateDaughters();
61  for (auto* daughter : fspDaughters) {
62  if (absPDGCode != 0) {
63  if (abs(daughter->getPDGCode()) == absPDGCode) {
64  result++;
65  }
66  } else if (abs(daughter->getCharge()) > 0) {
67  result++;
68  }
69  }
70  return result;
71  }
72 
73  int nCompositeDaughters(const Particle* particle, const std::vector<double>& argument)
74  {
75  int absPDGCode = 0;
76  if (argument.size() == 1) {
77  absPDGCode = abs(std::lround(argument[0]));
78  }
79 
80  int result = 0;
81  auto primaryDaughters = particle->getDaughters();
82  for (auto* daughter : primaryDaughters) {
83  if (daughter->getParticleSource() == Particle::EParticleSourceObject::c_Composite or
84  daughter->getParticleSource() == Particle::EParticleSourceObject::c_V0) {
85  if (absPDGCode != 0) {
86  if (abs(daughter->getPDGCode()) == absPDGCode) {
87  result++;
88  }
89  } else {
90  result++;
91  }
92  }
93  }
94  return result;
95  }
96 
97  int nCompositeAllGenerationDaughters(const Particle* particle, const std::vector<double>& argument)
98  {
99  int absPDGCode = 0;
100  if (argument.size() == 1) {
101  absPDGCode = abs(std::lround(argument[0]));
102  }
103 
104  int result = 0;
105  auto allDaughters = particle->getAllDaughters();
106  for (auto* daughter : allDaughters) {
107  if (daughter->getParticleSource() == Particle::EParticleSourceObject::c_Composite or
108  daughter->getParticleSource() == Particle::EParticleSourceObject::c_V0) {
109  if (absPDGCode != 0) {
110  if (abs(daughter->getPDGCode()) == absPDGCode) {
111  result++;
112  }
113  } else {
114  result++;
115  }
116  }
117  }
118  return result;
119  }
120 
121  Manager::FunctionPtr daughterAverageOf(const std::vector<std::string>& arguments)
122  {
123  if (arguments.size() == 1) {
124  const Variable::Manager::Var* var = Manager::Instance().getVariable(arguments[0]);
125  auto func = [var](const Particle * particle) -> double {
126  double sum = 0.0;
127  if (particle->getNDaughters() == 0)
128  {
129  return Const::doubleNaN;
130  }
131  if (std::holds_alternative<double>(var->function(particle->getDaughter(0))))
132  {
133  for (unsigned j = 0; j < particle->getNDaughters(); ++j) {
134  sum += std::get<double>(var->function(particle->getDaughter(j)));
135  }
136  } else if (std::holds_alternative<int>(var->function(particle->getDaughter(0))))
137  {
138  for (unsigned j = 0; j < particle->getNDaughters(); ++j) {
139  sum += std::get<int>(var->function(particle->getDaughter(j)));
140  }
141  }
142  return sum / particle->getNDaughters();
143  };
144  return func;
145  } else {
146  B2FATAL("The meta variable daughterAverageOf requires only one argument!");
147  }
148  }
149 
150  // ---
151 
152  VARIABLE_GROUP("For fully-inclusive particles");
153 
154  REGISTER_VARIABLE("nDaughterPhotons", nDaughterPhotons,
155  "Returns the number of final state daughter photons.");
156  REGISTER_VARIABLE("nDaughterNeutralHadrons", nDaughterNeutralHadrons,
157  "Returns the number of K_L0 or neutrons among the final state daughters.");
158  REGISTER_VARIABLE("nDaughterCharged(pdg)", nDaughterCharged,
159  "Returns the number of charged daughters with the provided PDG code or the number "
160  "of all charged daughters if no argument has been provided. "
161  "The variable is flavor agnostic and it returns the sum of the number of particle and anti-particle.");
162  REGISTER_VARIABLE("nCompositeDaughters(pdg)", nCompositeDaughters,
163  "Returns the number of primary composite daughters with the provided PDG code or the number"
164  "of all primary composite daughters if no argument has been provided. "
165  "The variable is flavor agnostic and it returns the sum of the number of particle and anti-particle.");
166  REGISTER_VARIABLE("nCompositeAllGenerationDaughters(pdg)", nCompositeAllGenerationDaughters,
167  "Returns the number of all generations' composite daughters with the provided PDG code or the number"
168  "of all generations' composite daughters if no argument has been provided. "
169  "The variable is flavor agnostic and it returns the sum of the number of particle and anti-particle.");
170  REGISTER_METAVARIABLE("daughterAverageOf(variable)", daughterAverageOf,
171  "Returns the mean value of a variable over all daughters.", Manager::VariableDataType::c_double)
172  }
174 }
Abstract base class for different kinds of events.