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);
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 setMass(float mass)
Set particle mass.
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
void setEnergy(float energy)
Set energy.
void setValidVertex(bool valid)
Set indication whether vertex and time information is valid or just default.
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
void setPDG(int pdg)
Set PDG code of the particle.
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
void setStatus(unsigned short int status)
Set Status code for the particle.
void setProductionTime(float time)
Set production time.
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.