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 <framework/gearbox/Gearbox.h>
25
26using namespace std;
27using namespace Belle2;
28using namespace Belle2::Variable;
29using namespace ROOT::Math;
30
31namespace {
32 class ROETest : public ::testing::Test {
33 protected:
35 void SetUp() override
36 {
37
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);
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 {
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;
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;
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
167 DataStore::Instance().getEntry(myROEObject)->object = nullptr;
169 }
170
171 TEST_F(ROETest, getParticles)
172 {
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;
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;
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;
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} //
@ 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:54
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition: DataStore.cc:86
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:294
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)
Creates an instance of a cut and returns a unique_ptr to it, if you need a copy-able object instead y...
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: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
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
Definition: Manager.cc:57
static Manager & Instance()
get singleton instance.
Definition: Manager.cc:25
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.
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:146