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].");
82 B2ERROR(
"ringName can only be LER or HER");
85 B2ERROR(
"realTime must be positive");
97 B2ERROR(
m_treeName <<
": no such TTree in the SAD file");
118 m_tree->SetBranchAddress(
"dp_over_p0", &
m_sad.dp_over_p0);
121 int numEntries =
m_tree->GetEntries();
122 if (numEntries <= 0) {
123 B2ERROR(
"SAD tree is empty");
130 for (
int i = 0; i < numEntries; i++) {
141 GearDir ring(
"/Detector/SuperKEKB/LER/");
145 GearDir ring(
"/Detector/SuperKEKB/HER/");
150 m_sectionOrdering.insert(
m_sectionOrdering.end(), {1, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2});
152 B2RESULT(
"BG rate: " <<
m_rates.back() / 1e6 <<
" MHz, events to generate: "
168 eventMetaData->setEndOfData();
180 int ring_section = -1;
181 double ssraw =
m_sad.ss;
182 if (
m_sad.ss < 0) ssraw += 3016.;
183 int section = (int)(ssraw * 12 / 3016.);
201 ROOT::Math::XYZVector momentum(
m_sad.px, -
m_sad.py, pz);
230 double particlePosGeant4[] = {0.0, 0.0, 0.0};
231 double particleMomGeant4[] = {0.0, 0.0, 0.0};
234 TGeoHMatrix transMatrix;
242 transMatrix.LocalToMaster(particlePosSADfar, particlePosGeant4);
243 transMatrix.LocalToMasterVect(particleMomSADfar, particleMomGeant4);
245 part->
setMomentum(ROOT::Math::XYZVector(particleMomGeant4[0], particleMomGeant4[1], particleMomGeant4[2]));
246 part->
setProductionVertex(ROOT::Math::XYZVector(particlePosGeant4[0], particlePosGeant4[1], particlePosGeant4[2]));
259 B2RESULT(
"BG rate: " <<
m_rates.back() / 1e6 <<
" MHz, equivalent time: "
263 B2ERROR(
"Number of generated events does not match the equivalent running time: "
269 for (
unsigned i = 0; i <
m_counters.size(); i++) {
274 B2RESULT(
"SAD particle usage: on average " << average <<
" times, max "
275 <<
m_counters[imax] <<
" times (entry " << imax <<
")");
282 double rate = gRandom->Uniform(
m_rates.back());
285 while (i2 - i1 > 1) {
286 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 ~BeamBkgGeneratorModule()
Destructor.
virtual void event() override
Event processor.
virtual void endRun() override
End-of-run action.
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]
virtual void beginRun() override
Called when entering a new run.
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.