Belle II Software  release-08-01-10
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 
19 using namespace Belle2;
20 
21 //-----------------------------------------------------------------
22 // Register the Module
23 //-----------------------------------------------------------------
24 REG_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 {
103  m_generator.w = simulateW();
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 & getLER() const
Get 4vector of the low energy beam.
const ROOT::Math::PxPyPzEVector & getHER() const
Get 4vector of the high 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
REG_MODULE(arichBtest)
Register the Module.
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
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
void initialize()
function to be executed on initialize()
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
MCInitialParticles & generate()
Generate a new event.
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.