Belle II Software development
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 <mdst/dataobjects/PIDLikelihood.h>
25#include <framework/gearbox/Gearbox.h>
26
27using namespace std;
28using namespace Belle2;
29using namespace Belle2::Variable;
30using namespace ROOT::Math;
31
32namespace {
33 class ROETest : public ::testing::Test {
34 protected:
36 void SetUp() override
37 {
38
40 StoreArray<ECLCluster> myECLClusters;
41 StoreArray<KLMCluster> myKLMClusters;
42 StoreArray<TrackFitResult> myTFRs;
43 StoreArray<Track> myTracks;
44 StoreArray<Particle> myParticles;
45 StoreArray<RestOfEvent> myROEs;
46 StoreArray<PIDLikelihood> myPIDLikelihoods;
47 myECLClusters.registerInDataStore();
48 myKLMClusters.registerInDataStore();
49 myTFRs.registerInDataStore();
50 myTracks.registerInDataStore();
51 myParticles.registerInDataStore();
52 myROEs.registerInDataStore();
53 myPIDLikelihoods.registerInDataStore();
54 myParticles.registerRelationTo(myROEs);
55 myTracks.registerRelationTo(myPIDLikelihoods);
57
58 TestUtilities::TestParticleFactory factory;
59 ROOT::Math::XYZVector ipposition(0, 0, 0);
60 PxPyPzEVector ksmomentum(1, 0, 0, 3);
61 ROOT::Math::XYZVector ksposition(1.0, 0, 0);
62 //Creation of test particles:
63 //All daughters and mother particles have the same momenta within a decay
64 //In principle, this concept can be better developed if needed
65 auto* ksParticle = factory.produceParticle(string("^K_S0 -> ^pi+ ^pi-"), ksmomentum, ksposition);
66 PxPyPzEVector d0momentum(-2, 0, 0, 4);
67 auto* d0Particle = factory.produceParticle(string("^D0 -> ^K+ ^pi-"), d0momentum, ipposition);
68 PxPyPzEVector pi0momentum(-0.2, 0, 0, 1);
69 auto* pi0Particle = factory.produceParticle(string("^pi0 -> ^gamma ^gamma"), pi0momentum, ipposition);
70 PxPyPzEVector b0momentum(3, 0, 0, 5);
71 factory.produceParticle(string("^B0 -> [^K_S0 -> ^pi+ ^pi-] [^pi0 -> ^gamma ^gamma] ^gamma"), b0momentum, ipposition);
72
73 RestOfEvent roe;
74 vector<const Particle*> roeParticles;
75 roeParticles.push_back(ksParticle->getDaughter(0));
76 roeParticles.push_back(ksParticle->getDaughter(1));
77 roeParticles.push_back(d0Particle->getDaughter(0));
78 roeParticles.push_back(d0Particle->getDaughter(1));
79 roeParticles.push_back(pi0Particle->getDaughter(0));
80 roeParticles.push_back(pi0Particle->getDaughter(1));
81 roe.addParticles(roeParticles);
82 roe.initializeMask("cutMask", "TestModule");
83 //Exclude K_S0 pions
84 std::shared_ptr<Variable::Cut> trackSelection = std::shared_ptr<Variable::Cut>(Variable::Cut::compile("p > 1.5"));
85 //Exclude pi0 gammas
86 std::shared_ptr<Variable::Cut> eclSelection = std::shared_ptr<Variable::Cut>(Variable::Cut::compile("p > 1"));
87 roe.updateMaskWithCuts("cutMask", trackSelection, eclSelection);
88 roe.initializeMask("excludeMask", "TestModule");
89 vector<const Particle*> excludeParticles = {ksParticle->getDaughter(1), d0Particle->getDaughter(0)};
90 roe.excludeParticlesFromMask("excludeMask", excludeParticles, Particle::EParticleSourceObject::c_Track, true);
91 roe.initializeMask("keepMask", "TestModule");
92 roe.excludeParticlesFromMask("keepMask", excludeParticles, Particle::EParticleSourceObject::c_Track, false);
93 roe.initializeMask("V0Mask", "TestModule");
94 roe.updateMaskWithCuts("V0Mask"); // No selection
95 //Add V0 to ROE mask:
96 roe.updateMaskWithV0("V0Mask", ksParticle);
97 myROEs.appendNew(roe);
98 roe.print();
99 }
100
102 void TearDown() override
103 {
105 }
106 };
107
108 TEST_F(ROETest, hasParticle)
109 {
110 Gearbox& gearbox = Gearbox::getInstance();
111 gearbox.setBackends({std::string("file:")});
112 gearbox.close();
113 gearbox.open("geometry/Belle2.xml", false);
114 StoreArray<Particle> myParticles;
116 const RestOfEvent* roe = myROEs[0];
117 EXPECT_TRUE(roe->hasParticle(myParticles[0])); // K_S0_pi0
118 EXPECT_TRUE(roe->hasParticle(myParticles[1])); // K_S0_pi1
119 EXPECT_FALSE(roe->hasParticle(myParticles[2])); // K_S0
120 EXPECT_TRUE(roe->hasParticle(myParticles[3])); // D0_K
121 EXPECT_TRUE(roe->hasParticle(myParticles[4])); // D0_pi
122 EXPECT_FALSE(roe->hasParticle(myParticles[5])); // D0
123 EXPECT_TRUE(roe->hasParticle(myParticles[6])); // pi0_gamma0
124 EXPECT_TRUE(roe->hasParticle(myParticles[7])); // pi0_gamma1
125 EXPECT_FALSE(roe->hasParticle(myParticles[8])); // pi0
126 EXPECT_FALSE(roe->hasParticle(myParticles[9])); // B0_K_S0_pi0
127 EXPECT_FALSE(roe->hasParticle(myParticles[10])); // B0_K_S0_pi1
128 EXPECT_FALSE(roe->hasParticle(myParticles[11])); // B0_pi0_gamma0
129 }
130
131 TEST_F(ROETest, useROERecoilFrame)
132 {
133 Gearbox& gearbox = Gearbox::getInstance();
134 gearbox.setBackends({std::string("file:")});
135 gearbox.close();
136 gearbox.open("geometry/Belle2.xml", false);
137
138 StoreArray<Particle> myParticles;
140 StoreObjPtr<RestOfEvent> myROEObject;
144 myParticles[14]->addRelationTo(myROEs[0]); // Add relation to B0
145 myROEObject.assign(myROEs[0]);
146
148 // Recoil vector against all ROE particles
149 PxPyPzEVector pRecoil = T.getBeamFourMomentum() - myROEs[0]->get4Vector();
150 Particle tmp(pRecoil, 0);
151 RestFrame frame(&tmp);
152 //std::cout << "HER: " << T.getBeamParams().getHER()[0] << " LER: " << T.getBeamParams().getLER()[0] << std::endl;
153
154 const Manager::Var* var = Manager::Instance().getVariable("useROERecoilFrame(p)");
155 ASSERT_NE(var, nullptr);
156 EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[5])),
157 frame.getMomentum(myParticles[5]->get4Vector()).P()); // test on D0 in ROE
158 EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[14])),
159 frame.getMomentum(myParticles[14]->get4Vector()).P()); // test on B0 on signal side
160 var = Manager::Instance().getVariable("useROERecoilFrame(E)");
161 ASSERT_NE(var, nullptr);
162 EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[5])),
163 frame.getMomentum(myParticles[5]->get4Vector()).E()); // test on D0 in ROE
164 EXPECT_FLOAT_EQ(std::get<double>(var->function(myParticles[14])),
165 frame.getMomentum(myParticles[14]->get4Vector()).E()); // test on B0 on signal side
166
168 DataStore::Instance().getEntry(myROEObject)->object = nullptr;
170 }
171
172 TEST_F(ROETest, getParticles)
173 {
175 const RestOfEvent* roe = myROEs[0];
176
177 EXPECT_TRUE(roe->getParticles().size() == 6);
178 EXPECT_TRUE(roe->getPhotons().size() == 2);
179 EXPECT_TRUE(roe->getHadrons().size() == 0);
180 EXPECT_TRUE(roe->getChargedParticles().size() == 4);
181 EXPECT_TRUE(roe->getChargedParticles("all", 321).size() == 1);
182 EXPECT_TRUE(roe->getChargedParticles("all", 211).size() == 3);
183 }
184
185 TEST_F(ROETest, updateMaskWithCuts)
186 {
187 StoreArray<Particle> myParticles;
189 const RestOfEvent* roe = myROEs[0];
190
191 EXPECT_FALSE(roe->hasParticle(myParticles[0], "cutMask")); // K_S0_pi0
192 EXPECT_FALSE(roe->hasParticle(myParticles[1], "cutMask")); // K_S0_pi0
193 EXPECT_TRUE(roe->hasParticle(myParticles[3], "cutMask")); // D0_K
194 EXPECT_TRUE(roe->hasParticle(myParticles[4], "cutMask")); // D0_pi
195 EXPECT_FALSE(roe->hasParticle(myParticles[6], "cutMask")); // pi0_gamma0
196 EXPECT_FALSE(roe->hasParticle(myParticles[7], "cutMask")); // pi0_gamma1
197 }
198 TEST_F(ROETest, excludeParticlesFromMask)
199 {
200 StoreArray<Particle> myParticles;
202 const RestOfEvent* roe = myROEs[0];
203
204 EXPECT_TRUE(roe->hasParticle(myParticles[0], "excludeMask")); // K_S0_pi0
205 EXPECT_FALSE(roe->hasParticle(myParticles[1], "excludeMask")); // K_S0_pi0
206 EXPECT_FALSE(roe->hasParticle(myParticles[3], "excludeMask")); // D0_K
207 EXPECT_TRUE(roe->hasParticle(myParticles[4], "excludeMask")); // D0_pi
208 EXPECT_TRUE(roe->hasParticle(myParticles[6], "excludeMask")); // pi0_gamma0
209 EXPECT_TRUE(roe->hasParticle(myParticles[7], "excludeMask")); // pi0_gamma1
210 // Inverted result with "!"
211 EXPECT_TRUE(!roe->hasParticle(myParticles[0], "keepMask")); // K_S0_pi0
212 EXPECT_FALSE(!roe->hasParticle(myParticles[1], "keepMask")); // K_S0_pi0
213 EXPECT_FALSE(!roe->hasParticle(myParticles[3], "keepMask")); // D0_K
214 EXPECT_TRUE(!roe->hasParticle(myParticles[4], "keepMask")); // D0_pi
215 // Photons not touched:
216 EXPECT_TRUE(roe->hasParticle(myParticles[6], "keepMask")); // pi0_gamma0
217 EXPECT_TRUE(roe->hasParticle(myParticles[7], "keepMask")); // pi0_gamma1
218 }
219 TEST_F(ROETest, updateMaskWithV0)
220 {
221 StoreArray<Particle> myParticles;
223 const RestOfEvent* roe = myROEs[0];
224 // Has particle checks for daughters
225 EXPECT_TRUE(roe->hasParticle(myParticles[0], "V0Mask")); // K_S0_pi0
226 EXPECT_TRUE(roe->hasParticle(myParticles[1], "V0Mask")); // K_S0_pi0
227 EXPECT_TRUE(roe->hasParticle(myParticles[3], "V0Mask")); // D0_K
228 EXPECT_TRUE(roe->hasParticle(myParticles[4], "V0Mask")); // D0_pi
229 EXPECT_TRUE(roe->hasParticle(myParticles[6], "V0Mask")); // pi0_gamma0
230 EXPECT_TRUE(roe->hasParticle(myParticles[7], "V0Mask")); // pi0_gamma1
231 //Get all particles, including the K_S0 in the mask:
232 auto v0maskParticles = roe->getParticles("V0Mask", false);
233 //Get all particles, but substitute K_S0 FS daughters:
234 auto v0maskParticlesUnpacked = roe->getParticles("V0Mask", true);
235 B2INFO("packed size is " << v0maskParticles.size());
236 for (auto* particle : v0maskParticles) {
237 B2INFO("My pdg: " << particle->getPDGCode());
238 }
239 B2INFO("unpacked size is " << v0maskParticlesUnpacked.size());
240 for (auto* particle : v0maskParticlesUnpacked) {
241 B2INFO("My pdg: " << particle->getPDGCode());
242 }
243 EXPECT_FLOAT_EQ(v0maskParticles.size(), 5);
244 EXPECT_FLOAT_EQ(v0maskParticlesUnpacked.size(), 6);
245 }
246
247 TEST_F(ROETest, maskNamingConventions)
248 {
249 RestOfEvent roe;
250
251 EXPECT_B2FATAL(roe.initializeMask("clean-mask", "maskNamingConventionTest"));
252 EXPECT_B2FATAL(roe.initializeMask("1mask", "maskNamingConventionTest"));
253 EXPECT_B2FATAL(roe.initializeMask("", "maskNamingConventionTest"));
254 EXPECT_B2FATAL(roe.initializeMask("all", "maskNamingConventionTest"));
255
256 roe.initializeMask("Clean_mask", "maskNamingConventionTest");
257 EXPECT_TRUE(roe.hasMask("Clean_mask"));
258
259 roe.initializeMask("cl3an_mask", "maskNamingConventionTest");
260 EXPECT_TRUE(roe.hasMask("cl3an_mask"));
261 }
262
263} //
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition DataStore.h:71
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition DataStore.cc:93
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition DataStore.cc:85
StoreEntry * getEntry(const StoreAccessorBase &accessor)
Check whether an entry with the correct type is registered in the DataStore map and return it.
Definition DataStore.cc:293
Singleton class responsible for loading detector parameters from an XML file.
Definition Gearbox.h:34
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Definition GeneralCut.h:84
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:76
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:55
std::vector< const Particle * > getParticles(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get all Particles from ROE mask.
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.
void print(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Prints the contents of a RestOfEvent object to screen.
void initializeMask(const std::string &name, const std::string &origin="unknown")
Initialize new mask.
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.
bool hasMask(const std::string &name) const
True if this ROE object has mask.
std::vector< const Particle * > getPhotons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get photons from ROE mask.
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.
void addParticles(const std::vector< const Particle * > &particle)
Add StoreArray indices of given Particles to the list of unused particles in the event.
void updateMaskWithV0(const std::string &name, const Particle *particleV0)
Update mask with composite particle.
std::vector< const Particle * > getHadrons(const std::string &maskName=c_defaultMaskName, bool unpackComposite=true) const
Get hadrons from ROE mask.
void excludeParticlesFromMask(const std::string &maskName, const std::vector< const Particle * > &particles, Particle::EParticleSourceObject listType, bool discard)
Update mask by keeping or excluding particles.
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
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
Definition Manager.cc:58
static Manager & Instance()
get singleton instance.
Definition Manager.cc:26
const Belle2::Particle * produceParticle(const std::string &decayString, const ROOT::Math::PxPyPzEVector &momentum, const ROOT::Math::XYZVector &vertex)
Main method to produce particles.
static Gearbox & getInstance()
Return reference to the Gearbox instance.
Definition Gearbox.cc:81
Abstract base class for different kinds of events.
STL namespace.
TObject * object
The pointer to the actual object.
Definition StoreEntry.h:48
A variable returning a floating-point value for a given Particle.
Definition Manager.h:145