10#include <background/modules/BeamBkgGenerator/BeamBkgGeneratorModule.h>
13#include <framework/datastore/StoreArray.h>
14#include <framework/datastore/StoreObjPtr.h>
17#include <framework/gearbox/Unit.h>
18#include <framework/gearbox/Const.h>
19#include <framework/logging/Logger.h>
20#include <framework/gearbox/GearDir.h>
23#include <framework/dataobjects/EventMetaData.h>
24#include <mdst/dataobjects/MCParticle.h>
25#include <generators/SAD/dataobjects/SADMetaHit.h>
31#include <TGeoMatrix.h>
32#include <generators/SAD/ReaderSAD.h>
51 "The generator picks up particles from the SAD file randomly "
52 "according to their rates. "
53 "Number of events is determined from 'realTime' and overall rate, and "
54 "the generator terminates the execution when this number is reached.");
61 "equivalent superKEKB running time to generate sample [ns].");
77 B2ERROR(
"ringName can only be LER or HER");
80 B2ERROR(
"realTime must be positive");
92 B2ERROR(
m_treeName <<
": no such TTree in the SAD file");
113 m_tree->SetBranchAddress(
"dp_over_p0", &
m_sad.dp_over_p0);
116 int numEntries =
m_tree->GetEntries();
117 if (numEntries <= 0) {
118 B2ERROR(
"SAD tree is empty");
125 for (
int i = 0; i < numEntries; i++) {
136 GearDir ring(
"/Detector/SuperKEKB/LER/");
140 GearDir ring(
"/Detector/SuperKEKB/HER/");
145 m_sectionOrdering.insert(
m_sectionOrdering.end(), {1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2});
147 B2RESULT(
"BG rate: " <<
m_rates.back() / 1e6 <<
" MHz, events to generate: "
159 eventMetaData->setEndOfData();
171 int ring_section = -1;
172 double ssraw =
m_sad.ss;
173 if (
m_sad.ss < 0) ssraw += 3016.;
174 int section = (int)(ssraw * 12 / 3016.);
192 ROOT::Math::XYZVector momentum(
m_sad.px, -
m_sad.py, pz);
205 part->setPDG(pdgCode);
207 part->setProductionVertex(position);
208 part->setProductionTime(0);
209 part->setMomentum(momentum);
210 part->setEnergy(
sqrt(momentum.Mag2() + mass * mass));
211 part->setValidVertex(
true);
221 double particlePosGeant4[] = {0.0, 0.0, 0.0};
222 double particleMomGeant4[] = {0.0, 0.0, 0.0};
225 TGeoHMatrix transMatrix;
233 transMatrix.LocalToMaster(particlePosSADfar, particlePosGeant4);
234 transMatrix.LocalToMasterVect(particleMomSADfar, particleMomGeant4);
236 part->setMomentum(ROOT::Math::XYZVector(particleMomGeant4[0], particleMomGeant4[1], particleMomGeant4[2]));
237 part->setProductionVertex(ROOT::Math::XYZVector(particlePosGeant4[0], particlePosGeant4[1], particlePosGeant4[2]));
246 B2RESULT(
"BG rate: " <<
m_rates.back() / 1e6 <<
" MHz, equivalent time: "
250 B2ERROR(
"Number of generated events does not match the equivalent running time: "
256 for (
unsigned i = 0; i <
m_counters.size(); i++) {
261 B2RESULT(
"SAD particle usage: on average " << average <<
" times, max "
262 <<
m_counters[imax] <<
" times (entry " << imax <<
")");
269 double rate = gRandom->Uniform(
m_rates.back());
272 while (i2 - i1 > 1) {
273 int i = (i1 + i2) / 2;
SADTree m_sad
TTree entry data.
TTree * m_tree
root tree pointer
std::vector< int > m_counters
counters: how many times SAD particles are used
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
ReaderSAD m_readerSAD
the transformation from SAD to Belle II system for the far beamline
std::vector< double > m_rates
cumulative rates of SAD particles [Hz]
virtual void terminate() override
Termination action.
BeamBkgGeneratorModule()
Constructor.
ROOT::Math::RotationY m_rotation
rotation from SAD to Belle II frame
std::string m_fileName
name of the SAD file converted to root
int generateEntry() const
Pick up particle randomly from the SAD file according to its rate.
int m_ring
ring number, 1-HER, 2-LER
int m_numEvents
number of events to generate
double m_realTime
equivalent SuperKEKB running time in [ns]
std::vector< int > m_sectionOrdering
superKEKB section ordering
TFile * m_file
root file pointer
int m_eventCounter
event counter
std::string m_ringName
name of the superKEKB ring (LER or HER)
std::string m_treeName
name of the TTree in the SAD file
static const ChargedStable electron
electron particle
GearDir is the basic class used for accessing the parameter store.
A Class to store the Monte Carlo particle information.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
void setDescription(const std::string &description)
Sets the description of the module.
@ c_HER
High Energy Ring (electrons)
@ c_LER
Low Energy Ring (positrons)
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
Type-safe access to single objects in the data store.
static const double us
[microsecond]
static const double m
[meters]
static const double s
[second]
static const double GeV
Standard of [energy, momentum, mass].
double getAngle(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard angle unit.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.