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