Belle II Software  release-08-01-10
restofevent.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 #include <gtest/gtest.h>
9 #include <framework/utilities/TestHelpers.h>
10 #include "utilities/TestParticleFactory.h"
11 #include <analysis/dataobjects/Particle.h>
12 #include <analysis/VariableManager/Manager.h>
13 #include <analysis/dataobjects/RestOfEvent.h>
14 
15 #include <analysis/VariableManager/Utility.h>
16 #include <analysis/utility/PCmsLabTransform.h>
17 #include <analysis/utility/ReferenceFrame.h>
18 
19 #include <framework/datastore/StoreArray.h>
20 #include <framework/logging/Logger.h>
21 #include <mdst/dataobjects/Track.h>
22 #include <mdst/dataobjects/ECLCluster.h>
23 #include <mdst/dataobjects/KLMCluster.h>
24 #include <framework/gearbox/Gearbox.h>
25 
26 using namespace std;
27 using namespace Belle2;
28 using namespace Belle2::Variable;
29 using namespace ROOT::Math;
30 
31 namespace {
32  class ROETest : public ::testing::Test {
33  protected:
35  void SetUp() override
36  {
37 
38  DataStore::Instance().setInitializeActive(true);
39  StoreArray<ECLCluster> myECLClusters;
40  StoreArray<KLMCluster> myKLMClusters;
42  StoreArray<Track> myTracks;
43  StoreArray<Particle> myParticles;
45  StoreArray<PIDLikelihood> myPIDLikelihoods;
46  myECLClusters.registerInDataStore();
47  myKLMClusters.registerInDataStore();
48  myTFRs.registerInDataStore();
49  myTracks.registerInDataStore();
50  myParticles.registerInDataStore();
51  myROEs.registerInDataStore();
52  myPIDLikelihoods.registerInDataStore();
53  myParticles.registerRelationTo(myROEs);
54  myTracks.registerRelationTo(myPIDLikelihoods);
55  DataStore::Instance().setInitializeActive(false);
56 
58  ROOT::Math::XYZVector ipposition(0, 0, 0);
59  PxPyPzEVector ksmomentum(1, 0, 0, 3);
60  ROOT::Math::XYZVector ksposition(1.0, 0, 0);
61  //Creation of test particles:
62  //All daughters and mother particles have the same momenta within a decay
63  //In principle, this concept can be better developed if needed
64  auto* ksParticle = factory.produceParticle(string("^K_S0 -> ^pi+ ^pi-"), ksmomentum, ksposition);
65  PxPyPzEVector d0momentum(-2, 0, 0, 4);
66  auto* d0Particle = factory.produceParticle(string("^D0 -> ^K+ ^pi-"), d0momentum, ipposition);
67  PxPyPzEVector pi0momentum(-0.2, 0, 0, 1);
68  auto* pi0Particle = factory.produceParticle(string("^pi0 -> ^gamma ^gamma"), pi0momentum, ipposition);
69  PxPyPzEVector b0momentum(3, 0, 0, 5);
70  factory.produceParticle(string("^B0 -> [^K_S0 -> ^pi+ ^pi-] [^pi0 -> ^gamma ^gamma] ^gamma"), b0momentum, ipposition);
71 
72  RestOfEvent roe;
73  vector<const Particle*> roeParticles;
74  roeParticles.push_back(ksParticle->getDaughter(0));
75  roeParticles.push_back(ksParticle->getDaughter(1));
76  roeParticles.push_back(d0Particle->getDaughter(0));
77  roeParticles.push_back(d0Particle->getDaughter(1));
78  roeParticles.push_back(pi0Particle->getDaughter(0));
79  roeParticles.push_back(pi0Particle->getDaughter(1));
80  roe.addParticles(roeParticles);
81  roe.initializeMask("cutMask", "TestModule");
82  //Exclude K_S0 pions
83  std::shared_ptr<Variable::Cut> trackSelection = std::shared_ptr<Variable::Cut>(Variable::Cut::compile("p > 1.5"));
84  //Exclude pi0 gammas
85  std::shared_ptr<Variable::Cut> eclSelection = std::shared_ptr<Variable::Cut>(Variable::Cut::compile("p > 1"));
86  roe.updateMaskWithCuts("cutMask", trackSelection, eclSelection);
87  roe.initializeMask("excludeMask", "TestModule");
88  vector<const Particle*> excludeParticles = {ksParticle->getDaughter(1), d0Particle->getDaughter(0)};
89  roe.excludeParticlesFromMask("excludeMask", excludeParticles, Particle::EParticleSourceObject::c_Track, true);
90  roe.initializeMask("keepMask", "TestModule");
91  roe.excludeParticlesFromMask("keepMask", excludeParticles, Particle::EParticleSourceObject::c_Track, false);
92  roe.initializeMask("V0Mask", "TestModule");
93  roe.updateMaskWithCuts("V0Mask"); // No selection
94  //Add V0 to ROE mask:
95  roe.updateMaskWithV0("V0Mask", ksParticle);
96  myROEs.appendNew(roe);
97  roe.print();
98  }
99 
101  void TearDown() override
102  {
103  DataStore::Instance().reset();
104  }
105  };
106 
107  TEST_F(ROETest, hasParticle)
108  {
109  Gearbox& gearbox = Gearbox::getInstance();
110  gearbox.setBackends({std::string("file:")});
111  gearbox.close();
112  gearbox.open("geometry/Belle2.xml", false);
113  StoreArray<Particle> myParticles;
114  StoreArray<RestOfEvent> myROEs{};
115  const RestOfEvent* roe = myROEs[0];
116  EXPECT_TRUE(roe->hasParticle(myParticles[0])); // K_S0_pi0
117  EXPECT_TRUE(roe->hasParticle(myParticles[1])); // K_S0_pi1
118  EXPECT_FALSE(roe->hasParticle(myParticles[2])); // K_S0
119  EXPECT_TRUE(roe->hasParticle(myParticles[3])); // D0_K
120  EXPECT_TRUE(roe->hasParticle(myParticles[4])); // D0_pi
121  EXPECT_FALSE(roe->hasParticle(myParticles[5])); // D0
122  EXPECT_TRUE(roe->hasParticle(myParticles[6])); // pi0_gamma0
123  EXPECT_TRUE(roe->hasParticle(myParticles[7])); // pi0_gamma1
124  EXPECT_FALSE(roe->hasParticle(myParticles[8])); // pi0
125  EXPECT_FALSE(roe->hasParticle(myParticles[9])); // B0_K_S0_pi0
126  EXPECT_FALSE(roe->hasParticle(myParticles[10])); // B0_K_S0_pi1
127  EXPECT_FALSE(roe->hasParticle(myParticles[11])); // B0_pi0_gamma0
128  }
129 
130  TEST_F(ROETest, useROERecoilFrame)
131  {
132  Gearbox& gearbox = Gearbox::getInstance();
133  gearbox.setBackends({std::string("file:")});
134  gearbox.close();
135  gearbox.open("geometry/Belle2.xml", false);
136 
137  StoreArray<Particle> myParticles;
139  StoreObjPtr<RestOfEvent> myROEObject;
140  DataStore::Instance().setInitializeActive(true);
141  myROEObject.registerInDataStore(DataStore::c_DontWriteOut);
142  DataStore::Instance().setInitializeActive(false);
143  myParticles[14]->addRelationTo(myROEs[0]); // Add relation to B0
144  myROEObject.assign(myROEs[0]);
145 
147  // Recoil vector against all ROE particles
148  PxPyPzEVector pRecoil = T.getBeamFourMomentum() - myROEs[0]->get4Vector();
149  Particle tmp(pRecoil, 0);
150  RestFrame frame(&tmp);
151  //std::cout << "HER: " << T.getBeamParams().getHER()[0] << " LER: " << T.getBeamParams().getLER()[0] << std::endl;
152 
153  const Manager::Var* var = Manager::Instance().getVariable("useROERecoilFrame(p)");
154  ASSERT_NE(var, nullptr);
155  EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[5])),
156  frame.getMomentum(myParticles[5]->get4Vector()).P()); // test on D0 in ROE
157  EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[14])),
158  frame.getMomentum(myParticles[14]->get4Vector()).P()); // test on B0 on signal side
159  var = Manager::Instance().getVariable("useROERecoilFrame(E)");
160  ASSERT_NE(var, nullptr);
161  EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[5])),
162  frame.getMomentum(myParticles[5]->get4Vector()).E()); // test on D0 in ROE
163  EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[14])),
164  frame.getMomentum(myParticles[14]->get4Vector()).E()); // test on B0 on signal side
165 
166  DataStore::Instance().setInitializeActive(true);
167  DataStore::Instance().getEntry(myROEObject)->object = nullptr;
168  DataStore::Instance().setInitializeActive(false);
169  }
170 
171  TEST_F(ROETest, getParticles)
172  {
173  StoreArray<RestOfEvent> myROEs{};
174  const RestOfEvent* roe = myROEs[0];
175 
176  EXPECT_TRUE(roe->getParticles().size() == 6);
177  EXPECT_TRUE(roe->getPhotons().size() == 2);
178  EXPECT_TRUE(roe->getHadrons().size() == 0);
179  EXPECT_TRUE(roe->getChargedParticles().size() == 4);
180  EXPECT_TRUE(roe->getChargedParticles("all", 321).size() == 1);
181  EXPECT_TRUE(roe->getChargedParticles("all", 211).size() == 3);
182  }
183 
184  TEST_F(ROETest, updateMaskWithCuts)
185  {
186  StoreArray<Particle> myParticles;
187  StoreArray<RestOfEvent> myROEs{};
188  const RestOfEvent* roe = myROEs[0];
189 
190  EXPECT_FALSE(roe->hasParticle(myParticles[0], "cutMask")); // K_S0_pi0
191  EXPECT_FALSE(roe->hasParticle(myParticles[1], "cutMask")); // K_S0_pi0
192  EXPECT_TRUE(roe->hasParticle(myParticles[3], "cutMask")); // D0_K
193  EXPECT_TRUE(roe->hasParticle(myParticles[4], "cutMask")); // D0_pi
194  EXPECT_FALSE(roe->hasParticle(myParticles[6], "cutMask")); // pi0_gamma0
195  EXPECT_FALSE(roe->hasParticle(myParticles[7], "cutMask")); // pi0_gamma1
196  }
197  TEST_F(ROETest, excludeParticlesFromMask)
198  {
199  StoreArray<Particle> myParticles;
200  StoreArray<RestOfEvent> myROEs{};
201  const RestOfEvent* roe = myROEs[0];
202 
203  EXPECT_TRUE(roe->hasParticle(myParticles[0], "excludeMask")); // K_S0_pi0
204  EXPECT_FALSE(roe->hasParticle(myParticles[1], "excludeMask")); // K_S0_pi0
205  EXPECT_FALSE(roe->hasParticle(myParticles[3], "excludeMask")); // D0_K
206  EXPECT_TRUE(roe->hasParticle(myParticles[4], "excludeMask")); // D0_pi
207  EXPECT_TRUE(roe->hasParticle(myParticles[6], "excludeMask")); // pi0_gamma0
208  EXPECT_TRUE(roe->hasParticle(myParticles[7], "excludeMask")); // pi0_gamma1
209  // Inverted result with "!"
210  EXPECT_TRUE(!roe->hasParticle(myParticles[0], "keepMask")); // K_S0_pi0
211  EXPECT_FALSE(!roe->hasParticle(myParticles[1], "keepMask")); // K_S0_pi0
212  EXPECT_FALSE(!roe->hasParticle(myParticles[3], "keepMask")); // D0_K
213  EXPECT_TRUE(!roe->hasParticle(myParticles[4], "keepMask")); // D0_pi
214  // Photons not touched:
215  EXPECT_TRUE(roe->hasParticle(myParticles[6], "keepMask")); // pi0_gamma0
216  EXPECT_TRUE(roe->hasParticle(myParticles[7], "keepMask")); // pi0_gamma1
217  }
218  TEST_F(ROETest, updateMaskWithV0)
219  {
220  StoreArray<Particle> myParticles;
221  StoreArray<RestOfEvent> myROEs{};
222  const RestOfEvent* roe = myROEs[0];
223  // Has particle checks for daughters
224  EXPECT_TRUE(roe->hasParticle(myParticles[0], "V0Mask")); // K_S0_pi0
225  EXPECT_TRUE(roe->hasParticle(myParticles[1], "V0Mask")); // K_S0_pi0
226  EXPECT_TRUE(roe->hasParticle(myParticles[3], "V0Mask")); // D0_K
227  EXPECT_TRUE(roe->hasParticle(myParticles[4], "V0Mask")); // D0_pi
228  EXPECT_TRUE(roe->hasParticle(myParticles[6], "V0Mask")); // pi0_gamma0
229  EXPECT_TRUE(roe->hasParticle(myParticles[7], "V0Mask")); // pi0_gamma1
230  //Get all particles, including the K_S0 in the mask:
231  auto v0maskParticles = roe->getParticles("V0Mask", false);
232  //Get all particles, but substitute K_S0 FS daughters:
233  auto v0maskParticlesUnpacked = roe->getParticles("V0Mask", true);
234  B2INFO("packed size is " << v0maskParticles.size());
235  for (auto* particle : v0maskParticles) {
236  B2INFO("My pdg: " << particle->getPDGCode());
237  }
238  B2INFO("unpacked size is " << v0maskParticlesUnpacked.size());
239  for (auto* particle : v0maskParticlesUnpacked) {
240  B2INFO("My pdg: " << particle->getPDGCode());
241  }
242  EXPECT_FLOAT_EQ(v0maskParticles.size(), 5);
243  EXPECT_FLOAT_EQ(v0maskParticlesUnpacked.size(), 6);
244  }
245 
246  TEST_F(ROETest, maskNamingConventions)
247  {
248  RestOfEvent roe;
249 
250  EXPECT_B2FATAL(roe.initializeMask("clean-mask", "maskNamingConventionTest"));
251  EXPECT_B2FATAL(roe.initializeMask("1mask", "maskNamingConventionTest"));
252  EXPECT_B2FATAL(roe.initializeMask("", "maskNamingConventionTest"));
253  EXPECT_B2FATAL(roe.initializeMask("all", "maskNamingConventionTest"));
254 
255  roe.initializeMask("Clean_mask", "maskNamingConventionTest");
256  EXPECT_TRUE(roe.hasMask("Clean_mask"));
257 
258  roe.initializeMask("cl3an_mask", "maskNamingConventionTest");
259  EXPECT_TRUE(roe.hasMask("cl3an_mask"));
260  }
261 
262 } //
Singleton class responsible for loading detector parameters from an XML file.
Definition: Gearbox.h:34
Class to hold Lorentz transformations from/to CMS and boost vector.
ROOT::Math::PxPyPzEVector getBeamFourMomentum() const
Returns LAB four-momentum of e+e-, i.e.
Class to store reconstructed particles.
Definition: Particle.h:75
Rest frame of a particle.
This is a general purpose class for collecting reconstructed MDST data objects that are not used in r...
Definition: RestOfEvent.h:57
std::vector< const Particle * > getParticles(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get all Particles from ROE mask.
Definition: RestOfEvent.cc:45
std::vector< const Particle * > getChargedParticles(const std::string &maskName=c_defaultMaskName, unsigned int pdg=0, bool unpackComposite=true) const
Get charged particles from ROE mask.
Definition: RestOfEvent.cc:108
void print(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Prints the contents of a RestOfEvent object to screen.
Definition: RestOfEvent.cc:391
void initializeMask(const std::string &name, const std::string &origin="unknown")
Initialize new mask.
Definition: RestOfEvent.cc:134
void updateMaskWithCuts(const std::string &name, const std::shared_ptr< Variable::Cut > &trackCut=nullptr, const std::shared_ptr< Variable::Cut > &eclCut=nullptr, const std::shared_ptr< Variable::Cut > &klmCut=nullptr, bool updateExisting=false)
Update mask with cuts.
Definition: RestOfEvent.cc:191
bool hasMask(const std::string &name) const
True if this ROE object has mask.
Definition: RestOfEvent.cc:297
std::vector< const Particle * > getPhotons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get photons from ROE mask.
Definition: RestOfEvent.cc:84
bool hasParticle(const Particle *particle, const std::string &maskName=c_defaultMaskName) const
Check if ROE has StoreArray index of given to the list of unused tracks in the event.
Definition: RestOfEvent.cc:124
void addParticles(const std::vector< const Particle * > &particle)
Add StoreArray indices of given Particles to the list of unused particles in the event.
Definition: RestOfEvent.cc:24
void updateMaskWithV0(const std::string &name, const Particle *particleV0)
Update mask with composite particle.
Definition: RestOfEvent.cc:231
std::vector< const Particle * > getHadrons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get hadrons from ROE mask.
Definition: RestOfEvent.cc:96
void excludeParticlesFromMask(const std::string &maskName, const std::vector< const Particle * > &particles, Particle::EParticleSourceObject listType, bool discard)
Update mask by keeping or excluding particles.
Definition: RestOfEvent.cc:154
bool assign(TObject *object, bool replace=false)
Assign 'object' to this accessor.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
This is a class, which generates DataStore particles, according to the provided decay string e....
const Belle2::Particle * produceParticle(const std::string &decayString, const ROOT::Math::PxPyPzEVector &momentum, const ROOT::Math::XYZVector &vertex)
Main method to produce particles.
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
Abstract base class for different kinds of events.
A variable returning a floating-point value for a given Particle.
Definition: Manager.h:146