Belle II Software development
TrepsInputModule.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 <generators/modules/trepsinput/TrepsInputModule.h>
10#include <framework/geometry/B2Vector3.h>
11#include <string.h>
12#include <string>
13#include <boost/filesystem.hpp>
14#include <TFile.h>
15#include <TRandom.h>
16
17#include <map>
18
19using namespace Belle2;
20
21//-----------------------------------------------------------------
22// Register the Module
23//-----------------------------------------------------------------
24REG_MODULE(TrepsInput);
25
26//-----------------------------------------------------------------
27// Implementation
28//-----------------------------------------------------------------
29
31{
32 // Set module properties
33 setDescription("Input from TREPS generator (No-tag), Input from TREPS generator for ee->ee hadrons");
34
35 // Parameter definitions
36 addParam("ParameterFile", m_parameterFile,
37 "parameter file for TREPS input", std::string("treps_par.dat"));
38 addParam("DifferentialCrossSectionFile", m_differentialCrossSectionFile,
39 "file name for differential cross section table input. If UseDiscreteAndSortedW is true, the file is used",
40 std::string("pipidcs.dat"));
41 addParam("WListTableFile", m_wListTableFile,
42 "file name for W-List table input. If UseDiscreteAndSortedW is false (default), the file is used", std::string("wlist_table.dat"));
43 addParam("UseDiscreteAndSortedW", m_useDiscreteAndSortedW,
44 "if true, use WListTable for discrete and sorted W. if false (default), use DifferentialCrossSection", false);
45
46 addParam("MaximalQ2", m_maximalQ2,
47 "Maximal :math:`Q^2 = -q^2`, where q is the difference between the initial "
48 "and final electron or positron momenta. Negative means no cut.",
49 -1.0);
50 addParam("MaximalAbsCosTheta", m_maximalAbsCosTheta,
51 "Maximal :math:`|\\cos(\\theta)|`, where :math:`\\theta` is the final-state particle "
52 "polar angle.", 1.01);
53 addParam("ApplyCosThetaCutCharged", m_applyCosThetaCutCharged,
54 "Whether to apply cut on :math:`|cos(theta)|` for charged particles only.",
55 true);
56 addParam("MinimalTransverseMomentum", m_minimalTransverseMomentum,
57 "Minimal transverse momentum of the final-state particles.", 0.0);
58 addParam("ApplyTransverseMomentumCutCharged",
60 "Whether to apply cut on the minimal transverse momentum for "
61 "charged particles only.", true);
62
63}
64
66{
69}
70
72{
73 /*
74 * Check if the BeamParameters have changed (if they do, abort the job;
75 * otherwise cross section calculation will be a nightmare).
76 */
77 if (m_beamParams.hasChanged()) {
78 if (!m_initialized) {
80 B2INFO("Initialized the TREPS generator!");
81 } else {
82 B2FATAL("TrepsInputModule::event(): BeamParameters have changed within "
83 "a job, this is not supported for TREPS!");
84 }
85 }
86
87 /* Generation of the initial particle from beam parameters. */
88 const MCInitialParticles& initial = m_initial.generate();
89 ROOT::Math::XYZVector vertex = initial.getVertex();
90
92 if (m_generator.inmode != 0) return;
93
94 m_generator.wtcount++;
95 m_generator.wf = (float)(m_generator.wtable(1));
96
97 if (abs((double)m_generator.wf - m_generator.w) >= 0.001 && m_generator.wf > 0.01) {
98 B2INFO(" W value changed. " << m_generator.w << " to " << m_generator.wf);
99 m_generator.w = (double)m_generator.wf;
100 m_generator.updateW();
101 }
102 } else {
104 m_generator.updateW();
105 }
106
107 int idummy = 0;
108 int iret = m_generator.event_gen(idummy);
109 m_mpg.clear();
110
111 // fill data of the initial electron and positron
114 electron.setPDG(11);
115 electron.setMomentum(ROOT::Math::XYZVector(m_generator.getElectronMomentum()));
116 electron.setMass(m_generator.me);
117 electron.setEnergy(sqrt(m_generator.me * m_generator.me + m_generator.getElectronMomentum().Mag2()));
118
121 positron.setPDG(-11);
122 positron.setMomentum(ROOT::Math::XYZVector(m_generator.getPositronMomentum()));
123 positron.setMass(m_generator.me);
124 positron.setEnergy(sqrt(m_generator.me * m_generator.me + m_generator.getPositronMomentum().Mag2()));
125
126 if (iret >= 1) {
127
128 const Part_gen* part = m_generator.partgen;
129
130 // fill data of the final-state particles
131 for (int i = 0; i < m_generator.npart ; i++) {
132 auto& p = m_mpg.addParticle();
133 p.setPDG(part[i].part_prop.icode);
134 p.set4Vector(ROOT::Math::PxPyPzEVector(part[i].p.Px(), part[i].p.Py(), part[i].p.Pz(), part[i].p.E()));
135 p.setMass(part[i].part_prop.pmass);
137 p.setProductionVertex(vertex);
138 p.setValidVertex(true);
139 }
140 // fill data of the recoil electron and positron
141 auto& p1 = m_mpg.addParticle();
142 p1.setPDG(11);
143 p1.set4Vector(ROOT::Math::PxPyPzEVector(m_generator.pe.Px(), m_generator.pe.Py(), m_generator.pe.Pz(), m_generator.pe.E()));
144 p1.setMass(m_generator.me);
146 p1.setProductionVertex(vertex);
147 p1.setValidVertex(true);
148
149 auto& p2 = m_mpg.addParticle();
150 p2.setPDG(-11);
151 p2.set4Vector(ROOT::Math::PxPyPzEVector(m_generator.pp.Px(), m_generator.pp.Py(), m_generator.pp.Pz(), m_generator.pp.E()));
152 p2.setMass(m_generator.me);
154 p2.setProductionVertex(vertex);
155 p2.setValidVertex(true);
156
157 }
158 //Fill MCParticle List
160
161}
162
164{
165}
166
168{
169 if (m_generator.diffCrossSectionOfW.size() == 0) {
170 B2FATAL("Cross Section Table is empty !!!");
171 return 0.;
172 }
173
174 // lower_bound returns first iterator which meets >=W condition. --> upper side
175 auto it_upper = m_generator.diffCrossSectionOfW.lower_bound(W);
176 auto it_lower = it_upper;
177 it_lower--;
178
179 return (it_upper->second - it_lower->second) / (it_upper->first - it_lower->first) * (W - it_lower->first) + it_lower->second;
180}
181
183{
184
185 while (1) {
186 double crossSectionForMC = gRandom->Uniform(0.0, m_generator.totalCrossSectionForMC);
187
188 auto it_upper = m_generator.WOfCrossSectionForMC.lower_bound(crossSectionForMC);
189 auto it_lower = it_upper;
190 it_lower--;
191
192 double diffCrossSectionAtUpper = m_generator.diffCrossSectionOfW.at(it_upper->second);
193 double diffCrossSectionAtLower = m_generator.diffCrossSectionOfW.at(it_lower->second);
194 double limit = (diffCrossSectionAtUpper > diffCrossSectionAtLower) ? diffCrossSectionAtUpper * 1.01 : diffCrossSectionAtLower *
195 1.01;
196 // Higher diffCrossSection * 1.01 is set as limit. Same definition of limit is used in TrepsB::wtable().
197
198 double W = (crossSectionForMC - it_lower->first) / limit + it_lower->second ;
199 if (W < m_generator.diffCrossSectionOfW.begin()->first or W > m_generator.diffCrossSectionOfW.rbegin()->first)
200 B2FATAL("W has to be in [" << m_generator.diffCrossSectionOfW.begin()->first << ", "
201 << m_generator.diffCrossSectionOfW.rbegin()->first
202 << "] !!! W = " << W << ", crossSectionForMC = " << crossSectionForMC);
203
204 double trial = gRandom->Uniform(0.0, limit);
205 double crossSection = getCrossSection(W);
206
207 if (trial < crossSection)
208 return W;
209
210 }
211
212 return 0;
213}
214
215
217{
218 // Set parameter files
219 m_generator.setParameterFile(m_parameterFile);
220 m_generator.setDiffcrosssectionFile(m_differentialCrossSectionFile);
221 m_generator.setWlistFile(m_wListTableFile);
222
223 // Set cut parameters
224 m_generator.setMaximalQ2(m_maximalQ2);
225 m_generator.setMaximalAbsCosTheta(m_maximalAbsCosTheta);
226 m_generator.applyCosThetaCutCharged(m_applyCosThetaCutCharged);
227 m_generator.setMinimalTransverseMomentum(m_minimalTransverseMomentum);
228 m_generator.applyTransverseMomentumCutCharged(m_applyTransverseMomentumCutCharged);
229
230 // Initialize the initial particle information
231 const BeamParameters& nominalBeam = m_initial.getBeamParameters();
232 m_generator.setBeamEnergy(nominalBeam.getMass() / 2.);
233 B2Vector3D p3 = nominalBeam.getHER().Vect();
234 m_generator.setElectronMomentum(p3);
235 p3 = B2Vector3D(nominalBeam.getLER().Vect());
236 m_generator.setPositronMomentum(p3);
237
238 // Initialize generator;
239 m_generator.initp();
240
241 m_generator.create_hist();
242 m_generator.initg();
243
245 // Initialize wtable with WListTable
246 B2INFO("Discrete W-list is used !!!");
247
248 m_generator.wtcount = 0;
249 m_generator.wtable(0);
250
251 m_generator.w = (double)m_generator.wf;
252
253 m_generator.updateW();
254 } else {
255 // Initialize wtable with DifferentialCrossSection
256 m_generator.wtable();
257 }
258
259 m_initialized = true;
260}
This class contains the nominal beam parameters and the parameters used for smearing of the primary v...
The base module for generator modules, which sets the generator information as EventExtraInfo.
const BeamParameters & getBeamParameters() const
Return reference to nominal beam parameters.
This class contains the initial state for the given event.
const ROOT::Math::PxPyPzEVector & getHER() const
Get 4vector of the high energy beam.
const ROOT::Math::PxPyPzEVector & getLER() const
Get 4vector of the low energy beam.
const ROOT::Math::XYZVector & getVertex() const
Get the position of the collision.
double getMass() const
Get the invariant mass of the collision (= energy in CMS)
Class to represent Particle data in graph.
@ c_setDecayInfo
Set decay time and vertex.
void generateList(const std::string &name="", int options=c_setNothing)
Generates the MCParticle list and stores it in the StoreArray with the given name.
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
Definition: MCParticle.h:57
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition: MCParticle.h:49
void setMass(float mass)
Set particle mass.
Definition: MCParticle.h:366
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
Definition: MCParticle.h:353
void setEnergy(float energy)
Set energy.
Definition: MCParticle.h:372
void setPDG(int pdg)
Set PDG code of the particle.
Definition: MCParticle.h:335
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
Definition: MCParticle.h:417
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
std::string m_parameterFile
Parameter file which configures the setting of beam, production particle etc.
UtrepsB m_generator
Treps generator.
std::string m_differentialCrossSectionFile
Differential cross section table file.
double m_maximalQ2
Maximal Q^2 = -q^2, where q is the difference between the initial and final electron or positron mome...
DBObjPtr< BeamParameters > m_beamParams
BeamParameter.
bool m_initialized
True if generator has been initialized.
double getCrossSection(double W)
Returns the differential cross section for given W [GeV].
bool m_useDiscreteAndSortedW
if it is true, W-list table is used for discrete and sorted W
double m_minimalTransverseMomentum
Minimal transverse momentum of the final-state particles.
StoreArray< MCParticle > m_mcparticles
MCParticle collection.
virtual void terminate() override
initialization for trepsinput
bool m_applyCosThetaCutCharged
Whether to apply cut on |cos(theta)| for charged particles only.
virtual void generatorInitialize() override
initialization for trepsinput
double simulateW()
Simulate W distribution according to given input file of cross section table.
TrepsInputModule()
Constructor: Sets the description, the properties and the parameters of the module.
double m_maximalAbsCosTheta
Maximal |cos(theta)|, where theta is the final-state particle polar angle.
InitialParticleGeneration m_initial
initial particle used by BeamParameter class
MCParticleGraph m_mpg
An instance of the MCParticle graph.
std::string m_wListTableFile
W-List table file.
void initializeGenerator()
Initialize the TREPS generator
bool m_applyTransverseMomentumCutCharged
Whether to apply cut on the minimal transverse momentum for charged particles only.
virtual void generatorEvent() override
input event from TREPS
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
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
void initialize()
function to be executed on initialize()
MCInitialParticles & generate()
Generate a new event.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
void clear()
Reset particles and decay information to make the class reusable.
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.