Belle II Software  release-08-00-04
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...
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
Base class for Modules.
Definition: Module.h:72
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.
virtual void initialize() override
initialization for trepsinput
double getCrossSection(double W)
Returns the differential cross section for given W [GeV].
virtual void event() override
input event from TREPS
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.
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.
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.