Belle II Software  release-08-01-10
EventT0GeneratorModule.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 // Own header.
10 #include <generators/modules/EventT0GeneratorModule.h>
11 
12 // framework aux
13 #include <framework/gearbox/Unit.h>
14 #include <framework/logging/Logger.h>
15 
16 // root
17 #include <TRandom.h>
18 
19 using namespace std;
20 using namespace Belle2;
21 
22 //-----------------------------------------------------------------
23 // Register module
24 //-----------------------------------------------------------------
25 
26 REG_MODULE(EventT0Generator);
27 
28 //-----------------------------------------------------------------
29 // Implementation
30 //-----------------------------------------------------------------
31 
32 EventT0GeneratorModule::EventT0GeneratorModule() : Module()
33 
34 {
35  // set module description
36  setDescription("Module generates discrete event t0 in ~4ns steps (bunch spacing) "
37  "according to double gaussian distribution and adds it to the "
38  "production and decay times of MCParticles. This means that after "
39  "this module the time origin (t = 0) is set to what L1 trigger "
40  "would give as the collision time. In case of cosmics, the L1 trigger"
41  "jitter is generated according to a continuos double gaussian distribution");
42 
44 
45  // Add parameters
46  addParam("coreGaussWidth", m_coreGaussWidth, "sigma of core gaussian [ns]", double(5.6));
47  addParam("tailGaussWidth", m_tailGaussWidth, "sigma of tail gaussian [ns]", double(14.5));
48  addParam("tailGaussFraction", m_tailGaussFraction,
49  "fraction (by area) of tail gaussian", double(0.08));
50  addParam("fixedT0", m_fixedT0,
51  "If set, a fixed event t0 is used instead of simulating the bunch timing.", m_fixedT0);
52  addParam("maximumT0", m_maximumT0,
53  "If set, randomize between -maximum and maximum.",
54  m_maximumT0);
55  addParam("isCosmics", m_isCosmics,
56  "if True simulate L1 jitter for cosmics", bool(false));
57  addParam("coreGaussWidthCosmics", m_coreGaussWidthCosmics, "sigma of core gaussian for cosmics [ns]", double(13));
58  addParam("tailGaussMeanCosmics", m_tailGaussMeanCosmics, "mean of tail gaussian for cosmics [ns]", double(28));
59  addParam("tailGaussWidthCosmics", m_tailGaussWidthCosmics, "sigma of tail gaussian for cosmics [ns]", double(15));
60  addParam("tailGaussFractionCosmics", m_tailGaussFractionCosmics,
61  "fraction (by area) of tail gaussian for cosmics", double(0.09));
62 
63 }
64 
65 
67 {
69  m_initialParticles.registerInDataStore();
70  m_simClockState.registerInDataStore();
71 
72  if (not std::isnan(m_maximumT0) and not std::isnan(m_fixedT0)) {
73  B2ERROR("You can not set both the maximum T0 and the fixed T0 option.");
74  }
75 }
76 
77 
79 {
80 
81 
82  double eventTime = 0;
83  int bucket = 0;
84  int beamRevo9Cycle = 0;
85  int relBucketNo = 0;
86  //if m_isCosmics we need to randomize revo9count,
87  //at least for the SVD trigger bin
88  //if !m_isCosmics the revo9Count value is overwritten
89  unsigned revo9range = (m_bunchStructure->getRFBucketsPerRevolution() / 4) * 9;
90  int revo9count = gRandom->Integer(revo9range);
91 
92  if (!m_isCosmics) {
93  // generate bucket number w.r.t revo9 marker
94 
95  bucket = m_bunchStructure->generateBucketNumber(); // [RF clock]
96  beamRevo9Cycle = gRandom->Integer(9); // number of beam revolutions w.r.t revo9 marker
97  int bucketRevo9 = bucket + beamRevo9Cycle * m_bunchStructure->getRFBucketsPerRevolution(); // [RF clock]
98 
99  // generate L1 time jitter
100 
101  double timeJitter = 0;
102  if (not std::isnan(m_maximumT0)) {
103  timeJitter = -m_maximumT0 + (2 * m_maximumT0) * gRandom->Rndm();
104  } else if (not std::isnan(m_fixedT0)) {
105  timeJitter = m_fixedT0;
106  } else {
107  double sigma = m_coreGaussWidth;
108  if (gRandom->Rndm() < m_tailGaussFraction) sigma = m_tailGaussWidth;
109  timeJitter = gRandom->Gaus(0., sigma);
110  }
111 
112  // calculate revo9count (system clock ticks since revo9 marker as determined by L1 trigger)
113 
114  double bucketTimeSep = 1 / m_clockSettings->getAcceleratorRF();
115  relBucketNo = round(timeJitter / bucketTimeSep); // RF clock
116  revo9count = (bucketRevo9 + relBucketNo) / 4; // system clock
117 
118  // calculate collision time w.r.t L1 trigger
119 
120  eventTime = (bucketRevo9 - revo9count * 4) * bucketTimeSep;
121 
122  } else {
123 
124  //compute jitter for cosmics, .i.e. no filling pattern
125  double sigma = m_coreGaussWidthCosmics;
126  if (gRandom->Rndm() < m_tailGaussFractionCosmics) sigma = m_tailGaussWidthCosmics;
127  eventTime = gRandom->Gaus(0., sigma);
128  }
129 
130  // correct MC particle times according to generated collision time
131 
132  for (auto& particle : m_mcParticles) {
133  particle.setProductionTime(particle.getProductionTime() + eventTime);
134  particle.setDecayTime(particle.getDecayTime() + eventTime);
135  }
136 
137  // store collision time to MC initial particles (e.g. beam particles)
138 
139  if (not m_initialParticles.isValid()) m_initialParticles.create();
140  m_initialParticles->setTime(eventTime);
141 
142  // store revo9count (modulo range) in order to be distibuted to sub-detectors
143  revo9count %= revo9range;
144  if (revo9count < 0) revo9count += revo9range;
145 
146  m_simClockState.create();
147  m_simClockState->setRevo9Count(revo9count);
148  m_simClockState->setBucketNumber(bucket);
149  m_simClockState->setBeamCycleNumber(beamRevo9Cycle);
150  m_simClockState->setRelativeBucketNo(relBucketNo);
151 }
double m_tailGaussMeanCosmics
mean of tail gaussian [ns] for cosmics
double m_maximumT0
if set, randomize between -maximum and maximum
bool m_isCosmics
if true L1 jitter for cosmics is simulated
virtual void initialize() override
Initialize the Module.
double m_fixedT0
if set, a fixed t0 value is used instead of a gaussian distribution
DBObjPtr< HardwareClockSettings > m_clockSettings
hardware clock settings
virtual void event() override
Event processor.
double m_tailGaussFractionCosmics
area fraction of core gaussian for cosmics
double m_coreGaussWidth
sigma of core gaussian [ns]
double m_tailGaussWidthCosmics
sigma of tail gaussian [ns] for cosmics
DBObjPtr< BunchStructure > m_bunchStructure
bunch structure (fill pattern)
double m_tailGaussFraction
area fraction of core gaussian
double m_tailGaussWidth
sigma of tail gaussian [ns]
StoreArray< MCParticle > m_mcParticles
MC particles.
double m_coreGaussWidthCosmics
sigma of core gaussian [ns] for cosmics
StoreObjPtr< SimClockState > m_simClockState
generated hardware clock state
StoreObjPtr< MCInitialParticles > m_initialParticles
beam particles
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.