Belle II Software  release-08-01-10
initialparticles.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 #include <framework/datastore/DataStore.h>
10 #include <framework/database/DBStore.h>
11 #include <framework/dbobjects/BeamParameters.h>
12 #include <framework/utilities/CalcMeanCov.h>
13 #include <generators/utilities/InitialParticleGeneration.h>
14 
15 #include <gtest/gtest.h>
16 
17 using namespace std;
18 using namespace Belle2;
19 
20 namespace {
21 
24  class InitialParticleGenerationTests : public ::testing::Test {
25  protected:
26 
28  virtual void SetUp()
29  {
30  DataStore::Instance().setInitializeActive(true);
31  generator.initialize();
32  DataStore::Instance().setInitializeActive(false);
33 
34  // have some useful defaults for the beam parameters
35  beamparams.setHER(7.004, 0.0415, 0, {2.63169e-05, 1e-5, 1e-5});
36  beamparams.setLER(4.002, -0.0415, 0, {5.64063e-06, 1e-5, 1e-5});
37  beamparams.setVertex({0, 1, 2}, {4.10916e-07, 0, -2.64802e-06, 0, 1.7405e-11, 0, -2.64802e-06, 0, 0.000237962});
38  }
39 
41  virtual void TearDown()
42  {
43  DataStore::Instance().reset();
44  DBStore::Instance().reset();
45  }
46 
47  InitialParticleGeneration generator{BeamParameters::c_smearALL};
48  BeamParameters beamparams;
49  };
50 
52  TEST_F(InitialParticleGenerationTests, TestCMSGeneration)
53  {
54  beamparams.setGenerationFlags(BeamParameters::c_generateCMS);
55  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
56  auto initialCMS = generator.generate();
57  // transformation should be identity
58  EXPECT_EQ(initialCMS.getLabToCMS(), ROOT::Math::LorentzRotation());
59  // her should be along z
60  EXPECT_NEAR(initialCMS.getHER().Theta(), 0, 1e-15);
61  // ler should be opposite z
62  EXPECT_NEAR(initialCMS.getLER().Theta(), M_PI, 1e-15);
63  // both should have the same energy
64  EXPECT_NEAR(initialCMS.getHER().E(), initialCMS.getLER().E(), 1e-15);
65  // and the invariant mass should of course be correct
66  EXPECT_EQ(initialCMS.getMass(), beamparams.getMass());
67 
68  // and now compare it to generation in Lab
69  beamparams.setGenerationFlags(0);
70  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
71  auto initialLAB = generator.generate();
72  // same invariant mass
73  EXPECT_EQ(initialLAB.getMass(), beamparams.getMass());
74  // no smearing so LER and HER need to be identical to beam parameters
75  EXPECT_EQ(initialLAB.getHER(), beamparams.getHER());
76  EXPECT_EQ(initialLAB.getLER(), beamparams.getLER());
77  // so check that the CMS beams are identical to the transformed lab ones
78  EXPECT_EQ(initialCMS.getHER(), initialLAB.getLabToCMS() * initialLAB.getHER());
79  EXPECT_EQ(initialCMS.getLER(), initialLAB.getLabToCMS() * initialLAB.getLER());
80  }
81 
83  TEST_F(InitialParticleGenerationTests, TestEnergySmear)
84  {
85  // two beams completely head on, one with energy uncertainty so invariant
86  // mass uncertainty should be exactly the same as single uncertainty. Here
87  // we give variance so we expect 0.1
88  beamparams.setHER(10, 0, 0, {0.01});
89  beamparams.setLER(10, M_PI, 0, {0});
90  beamparams.setGenerationFlags(BeamParameters::c_smearBeamEnergy);
91  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
92 
93  // so let's generate events with this and store all invariant masses
94  {
95  CalcMeanCov<1> mean;
96  for (int i = 0; i < 100000; ++i) {
97  auto& initial = generator.generate();
98  ASSERT_TRUE(initial.hasGenerationFlags(BeamParameters::c_smearBeamEnergy));
99  mean.add(initial.getMass());
100  }
101  // and compare with expectation
102  EXPECT_NEAR(mean.getStddev(), 0.1, 0.0005);
103  EXPECT_NEAR(mean.getMean(), 20, 0.001);
104  }
105 
106  // uncertainty on both so result should be sqrt(a^2 + b^2) = sqrt(2) * 0.1
107  beamparams.setLER(10, M_PI, 0, {0.01});
108  beamparams.setGenerationFlags(BeamParameters::c_smearBeamEnergy);
109  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
110  {
111  CalcMeanCov<1> mean;
112  for (int i = 0; i < 100000; ++i) {
113  auto& initial = generator.generate();
114  ASSERT_TRUE(initial.hasGenerationFlags(BeamParameters::c_smearBeamEnergy));
115  mean.add(initial.getMass());
116  }
117  EXPECT_NEAR(mean.getStddev(), std::sqrt(2) * 0.1, 0.0005);
118  EXPECT_NEAR(mean.getMean(), 20, 0.001);
119  }
120  }
121 
122 
126  TEST_F(InitialParticleGenerationTests, TestVertexSmear)
127  {
128  beamparams.setGenerationFlags(BeamParameters::c_smearVertex);
129  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
130 
131  CalcMeanCov<3> mean;
132  for (int i = 0; i < 100000; ++i) {
133  auto& initial = generator.generate();
134  mean.add(initial.getVertex().X(), initial.getVertex().Y(), initial.getVertex().Z());
135  }
136  auto cov = beamparams.getCovVertex();
137  auto pos = beamparams.getVertex();
138  EXPECT_NEAR(mean.getMean(0), pos.x(), 1e-4);
139  EXPECT_NEAR(mean.getMean(1), pos.y(), 1e-4);
140  EXPECT_NEAR(mean.getMean(2), pos.z(), 1e-4);
141  for (int i = 0; i < 3; ++i) {
142  for (int j = 0; j < 3; ++j) {
143  EXPECT_NEAR(mean.getCovariance(i, j), cov(i, j), 1e-6);
144  }
145  }
146  }
147 
156  TEST_F(InitialParticleGenerationTests, TestFlags)
157  {
158  // so loop over all flags
159  for (int flag = 0; flag <= BeamParameters::c_smearALL; ++flag) {
160  // set the flag and overwrite dbstore
161  beamparams.setGenerationFlags(flag);
162  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
163  // rememeber last event and set it to the settings for initialization
164  MCInitialParticles last = beamparams;
165  // no generate a few events and check everything
166  for (int i = 0; i < 5; ++i) {
167  auto& initial = generator.generate();
168  EXPECT_EQ(flag, initial.getGenerationFlags());
169  // create text representation of flags
170  const std::string flags = initial.getGenerationFlagString();
171  if (flag & BeamParameters::c_smearBeam) {
172  // smearing of beam is active, check that the beams are actually
173  // different to the settings and the previous event
174  EXPECT_NE(initial.getHER(), beamparams.getHER()) << flags << " " << i;
175  EXPECT_NE(initial.getLER(), beamparams.getLER()) << flags << " " << i;
176  EXPECT_NE(initial.getHER(), last.getHER()) << flags << " " << i;
177  EXPECT_NE(initial.getLER(), last.getLER()) << flags << " " << i;
178  } else if (!(flag & BeamParameters::c_generateCMS)) {
179  // no smearing no cms generation, so everything should stay fixed.
180  EXPECT_EQ(initial.getHER(), beamparams.getHER()) << flags << " " << i;
181  EXPECT_EQ(initial.getLER(), beamparams.getLER()) << flags << " " << i;
182  EXPECT_EQ(initial.getHER(), last.getHER()) << flags << " " << i;
183  EXPECT_EQ(initial.getLER(), last.getLER()) << flags << " " << i;
184  } else {
185  // we want to compare CMS initial particles to lab beam energies
186  // but transformation is identity if c_generateCMS is set. Reset
187  // it so that the can boost beams to CMS for comparison
188  beamparams.setGenerationFlags(0);
189  EXPECT_EQ(initial.getHER(), beamparams.getLabToCMS() * beamparams.getHER()) << flags << " " << i;
190  EXPECT_EQ(initial.getLER(), beamparams.getLabToCMS() * beamparams.getLER()) << flags << " " << i;
191  // comparison to beamparameters fails in generateCMS so we just
192  // skip the first round here
193  if (i > 0) {
194  EXPECT_EQ(initial.getHER(), last.getHER()) << flags << " " << i;
195  EXPECT_EQ(initial.getLER(), last.getLER()) << flags << " " << i;
196  }
197  }
198  if (flag & BeamParameters::c_smearVertex) {
199  //smearing of the vertex is enabled, make sure the vertex changes
200  EXPECT_NE(initial.getVertex(), beamparams.getVertex());
201  EXPECT_NE(initial.getVertex(), last.getVertex());
202  } else {
203  //otherwise make sure it doesn't change.
204  EXPECT_EQ(initial.getVertex(), beamparams.getVertex());
205  EXPECT_EQ(initial.getVertex(), last.getVertex());
206  }
207  last = initial;
208  }
209  }
210  }
211 
213  TEST_F(InitialParticleGenerationTests, TestValidFlag)
214  {
215  beamparams.setGenerationFlags(0);
216  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
217 
218  MCInitialParticles& initial = generator.generate();
219  ROOT::Math::PxPyPzEVector her = initial.getHER();
220  ROOT::Math::PxPyPzEVector ler = initial.getLER();
221  ROOT::Math::XYZVector vertex = initial.getVertex();
222  for (int i = 0; i < 10; ++i) {
223  initial = generator.generate();
224  EXPECT_EQ(her, initial.getHER());
225  EXPECT_EQ(ler, initial.getLER());
226  EXPECT_EQ(vertex, initial.getVertex());
227  }
228  beamparams.setGenerationFlags(BeamParameters::c_smearALL);
229  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
230  for (int i = 0; i < 10; ++i) {
231  initial = generator.generate();
232  EXPECT_NE(her, initial.getHER());
233  EXPECT_NE(ler, initial.getLER());
234  EXPECT_NE(vertex, initial.getVertex());
235  her = initial.getHER();
236  ler = initial.getLER();
237  vertex = initial.getVertex();
238  }
239  }
240 
241  TEST_F(InitialParticleGenerationTests, UpdateVertex)
242  {
243  beamparams.setGenerationFlags(BeamParameters::c_smearBeam);
244  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
245  // first run but no smearing allowed, should return the nominal vertex
246  ROOT::Math::XYZVector shift = generator.updateVertex();
247  EXPECT_EQ(shift, ROOT::Math::XYZVector(0, 1, 2));
248  // create a new initial particle. Particle exists now, no smearing allowed so no change in shift
249  const MCInitialParticles& initial = generator.generate();
250  auto nominal = initial.getVertex();
251  shift = generator.updateVertex();
252  EXPECT_EQ(shift, ROOT::Math::XYZVector(0, 0, 0));
253  // ok, allow smearing, now we expect shift
254  beamparams.setGenerationFlags(BeamParameters::c_smearALL);
255  DBStore::Instance().addConstantOverride("BeamParameters", new BeamParameters(beamparams));
256  shift = generator.updateVertex();
257  EXPECT_NE(shift, ROOT::Math::XYZVector(0, 0, 0));
258  EXPECT_EQ(nominal + shift, initial.getVertex());
259  // but running again should not shift again
260  shift = generator.updateVertex();
261  EXPECT_EQ(shift, ROOT::Math::XYZVector(0, 0, 0));
262  // unless we force regeneration
263  auto previous = initial.getVertex();
264  shift = generator.updateVertex(true);
265  EXPECT_NE(shift, ROOT::Math::XYZVector(0, 0, 0));
266  EXPECT_EQ(previous + shift, initial.getVertex());
267  }
268 }
This class contains the nominal beam parameters and the parameters used for smearing of the primary v...
Class to calculate mean and and covariance between a number of parameters on running data without sto...
Definition: CalcMeanCov.h:35
This class contains the initial state for the given event.
const ROOT::Math::PxPyPzEVector & getLER() const
Get 4vector of the low energy beam.
const ROOT::Math::PxPyPzEVector & getHER() const
Get 4vector of the high energy beam.
const ROOT::Math::XYZVector & getVertex() const
Get the position of the collision.
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.