Belle II Software  release-06-02-00
ParticleDaughterVariables.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 include
10 #include <analysis/variables/ParticleDaughterVariables.h>
11 
12 #include <analysis/VariableManager/Manager.h>
13 #include <analysis/variables/MCTruthVariables.h>
14 
15 // dataobjects
16 #include <analysis/dataobjects/Particle.h>
17 #include <mdst/dataobjects/MCParticle.h>
18 
19 // framework aux
20 #include <framework/logging/Logger.h>
21 #include <framework/gearbox/Const.h>
22 
23 #include <iostream>
24 #include <cmath>
25 
26 using namespace std;
27 
28 namespace Belle2 {
33  namespace Variable {
34 
35  double hasCharmedDaughter(const Particle* particle, const std::vector<double>& transition)
36  {
37  double Status = 0.0;
38 
39  // Check if correct arguments
40  if (abs(transition[0]) != 1) {
41  B2ERROR("The parameter variable hasCharmedDaughter() only accepts 1 or -1 as an argument.");
42  return std::numeric_limits<float>::quiet_NaN();
43  }
44 
45  // Check if particle exists
46  if (!particle) {
47  B2ERROR("This particle does not exist!");
48  return std::numeric_limits<float>::quiet_NaN();
49  }
50 
51  // Check if MC particle exists
52  const MCParticle* mcp = particle->getMCParticle();
53  if (!mcp)
54  return std::numeric_limits<float>::quiet_NaN();
55 
56  // MCParticle should be related to a B meson
57  if (abs(mcp->getPDG()) != 511 and abs(mcp->getPDG()) != 521)
58  return std::numeric_limits<float>::quiet_NaN();
59 
60  // Check if the particle has daughters
61  int nDaughters = int(mcp->getNDaughters());
62  if (nDaughters < 1) {
63  B2ERROR("This particle does not have any daughters!");
64  return std::numeric_limits<float>::quiet_NaN();
65  }
66 
67  // Get the PDG sign and load daughters
68  int motherPDGSign = (particle->getPDGCode()) / (abs(particle->getPDGCode()));
69  std::vector<MCParticle*> mcDaughters = mcp->getDaughters();
70 
71  for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
72  int daughterPDG = mcDaughters[iDaughter]->getPDG();
73  int daughterPDGSign = daughterPDG / (abs(daughterPDG));
74 
75  if (transition[0] == 1) {
76  if (((abs(daughterPDG) / 100) % 10 == 4 || (abs(daughterPDG) / 1000) % 10 == 4)
77  && motherPDGSign == daughterPDGSign) // charmed meson or baryon and b->anti-c transition
78  Status = 1.0;
79  } else if (transition[0] == -1) {
80  if (((abs(daughterPDG) / 100) % 10 == 4 || (abs(daughterPDG) / 1000) % 10 == 4)
81  && motherPDGSign == -daughterPDGSign) // charmed meson or baryon and b->c transition
82  Status = 1.0;
83  }
84  }
85 
86  return Status;
87  }
88 
89  double hasCharmoniumDaughter(const Particle* particle)
90  {
91  double Status = 0.0;
92 
93  // Check if particle exists
94  if (!particle) {
95  B2ERROR("This particle does not exist!");
96  return std::numeric_limits<float>::quiet_NaN();
97  }
98 
99  // Check if MC particle exists
100  const MCParticle* mcp = particle->getMCParticle();
101  if (!mcp)
102  return std::numeric_limits<float>::quiet_NaN();
103 
104  // MCParticle should be related to a B meson
105  if (abs(mcp->getPDG()) != 511 and abs(mcp->getPDG()) != 521)
106  return std::numeric_limits<float>::quiet_NaN();
107 
108  // Check if the particle has daughters
109  int nDaughters = int(mcp->getNDaughters());
110  if (nDaughters < 1) {
111  B2ERROR("This particle does not have any daughters!");
112  return std::numeric_limits<float>::quiet_NaN();
113  }
114 
115  // Load daughters
116  std::vector<MCParticle*> mcDaughters = mcp->getDaughters();
117 
118  for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
119  int daughterPDG = mcDaughters[iDaughter]->getPDG();
120  if ((abs(daughterPDG) / 10) % 10 == 4 && (abs(daughterPDG) / 100) % 10 == 4) // charmonium state: b->c anti-c q transition
121  Status = 1.0;
122  }
123 
124  return Status;
125  }
126 
127  double hasRealPhotonDaughter(const Particle* particle)
128  {
129  double Status = 0.0;
130 
131  // Check if particle exists
132  if (!particle) {
133  B2ERROR("This particle does not exist!");
134  return std::numeric_limits<float>::quiet_NaN();
135  }
136 
137  // Check if the particle has daughters
138  int nDaughters = int(particle->getNDaughters());
139  if (nDaughters < 1) {
140  B2ERROR("This particle does not have any daughters!");
141  return std::numeric_limits<float>::quiet_NaN();
142  }
143 
144  // Load daughters
145  const std::vector<Particle*> daughters = particle->getDaughters();
146 
147  for (int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
148  double photosFlag = particleMCPhotosParticle(daughters[iDaughter]);
149  int PDGcode = daughters[iDaughter]->getPDGCode();
150 
151  // Is it a real photon?
152  if (PDGcode == Const::photon.getPDGCode() && photosFlag > -0.5 && photosFlag < 0.5) { // must not be from PHOTOS
153  Status = 1.0;
154  }
155  }
156 
157  return Status;
158  }
159 
160  VARIABLE_GROUP("DirectDaughterInfo");
161  REGISTER_VARIABLE("hasCharmedDaughter(i)", hasCharmedDaughter,
162  "Returns information regarding the charm quark presence in the decay.");
163  REGISTER_VARIABLE("hasCharmoniumDaughter", hasCharmoniumDaughter,
164  "Returns information regarding the charmonium state presence in the decay.");
165  REGISTER_VARIABLE("hasRealPhotonDaughter", hasRealPhotonDaughter,
166  "Returns information regarding photon daughter origin for a particle.");
167  }
169 }
Abstract base class for different kinds of events.