ATLAS Offline Software
BeamHaloParticleBuffer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 #include "CLHEP/Random/RandFlat.h"
8 #include <iostream>
9 
10 //------------------------------------------------------------------------------
11 
12 BinnedInterval::BinnedInterval(double upperBinEdge,
13  const std::vector<double>& intervalUpperBinEdges): m_upperBinEdge(upperBinEdge) {
14  m_intervalUpperBinEdges = new std::vector<double>(intervalUpperBinEdges);
15 }
16 
17 //------------------------------------------------------------------------------
18 
20  m_upperBinEdge = binnedInterval.m_upperBinEdge;
21  m_intervalUpperBinEdges = new std::vector<double>(*(binnedInterval.m_intervalUpperBinEdges));
22 }
23 
24 //------------------------------------------------------------------------------
25 
28 }
29 
30 //------------------------------------------------------------------------------
31 
33  : m_fileName(fileName)
34  , m_ofstream()
35  , m_ifstream()
36  , m_numberOfParticles(0)
37  , m_binnedIntervals()
38  , m_upperBinEdge(0.)
39  , m_intervalUpperBinEdges()
40  , m_intervalUpperBinEdge(0)
41  , m_writeFlag(false) {
42  m_recordSize = sizeof(long) + sizeof(double)*8;
44 }
45 
46 //------------------------------------------------------------------------------
47 
49  m_writeFlag = true;
51  m_binnedIntervals.clear();
53 
54  m_ofstream.open(m_fileName.c_str(), std::ios::out | std::ios::binary);
55  if(!m_ofstream) {
56  std::cerr << "Error: could not open output file" << m_fileName << std::endl;
57  return 1;
58  }
59 
60  return 0;
61 }
62 
63 //------------------------------------------------------------------------------
64 
66  if(m_numberOfParticles <= 0) {
67  std::cerr << "Error: the number of particles in the input file is not known." << std::endl;
68  return 1;
69  }
70 
71  m_writeFlag = false;
72 
73  m_ifstream.open(m_fileName.c_str(), std::ios::in | std::ios::binary);
74  if(!m_ifstream) {
75  std::cerr << "Error: could not open input file" << m_fileName << std::endl;
76  return 1;
77  }
78 
79  return 0;
80 }
81 
82 //------------------------------------------------------------------------------
83 
85  if(m_writeFlag) {
86  if(m_ofstream.is_open()) {
87  m_ofstream.close();
88 
89  // Store the remaining bin edge vector.
90  if(m_intervalUpperBinEdges.size() > 0) {
92  m_binnedIntervals.push_back(binnedInterval);
95  }
96  }
97  }
98  else {
99  if(m_ifstream.is_open()) {
100  m_ifstream.close();
101  }
102  }
103 
104  return 0;
105 }
106 
107 //------------------------------------------------------------------------------
108 
110  if(!m_writeFlag) {
111  std::cerr << "Error: the file " << m_fileName << " is currently open for reading." << std::endl;
112  return 0;
113  }
114 
115  long pdgId = 0;
116  double px = 0., py = 0., pz = 0., e = 0., x = 0., y = 0., z = 0., t = 0., weight = 0.;
117 
118  pdgId = particle->pdgId();
119  px = particle->fourVector().px();
120  py = particle->fourVector().py();
121  pz = particle->fourVector().pz();
122  e = particle->fourVector().e();
123  x = particle->positionAtScoringPlane().x();
124  y = particle->positionAtScoringPlane().y();
125  z = particle->positionAtScoringPlane().z();
126  t = particle->positionAtScoringPlane().t();
127  weight = particle->weight();
128 
129  m_ofstream.write((char*)(&pdgId), sizeof(long)); if(m_ifstream.bad()) return 0;
130  m_ofstream.write((char*)(&px), sizeof(double)); if(m_ifstream.bad()) return 0;
131  m_ofstream.write((char*)(&py), sizeof(double)); if(m_ifstream.bad()) return 0;
132  m_ofstream.write((char*)(&pz), sizeof(double)); if(m_ifstream.bad()) return 0;
133  m_ofstream.write((char*)(&e), sizeof(double)); if(m_ifstream.bad()) return 0;
134  m_ofstream.write((char*)(&x), sizeof(double)); if(m_ifstream.bad()) return 0;
135  m_ofstream.write((char*)(&y), sizeof(double)); if(m_ifstream.bad()) return 0;
136  m_ofstream.write((char*)(&z), sizeof(double)); if(m_ifstream.bad()) return 0;
137  m_ofstream.write((char*)(&t), sizeof(double)); if(m_ifstream.bad()) return 0;
138  m_ofstream.write((char*)(&weight), sizeof(double)); if(m_ifstream.bad()) return 0;
139 
141 
142  // If 'm_particlesPerInterval' particles have been collected into
143  // this interval then push the interval into the map and clear the
144  // interval read for more particles.
147  m_binnedIntervals.push_back(binnedInterval);
148  m_intervalUpperBinEdges.clear();
150  }
151 
152  // Append the weight to give the current upper bin edge. Then push
153  // the bin edge back.
156 
157  // Increment the upper bin edge. This is a separate number to avoid
158  // problems relating to floating point precision which can cause
159  // (total weight) - (weight of particle) = (total weight)
160  // when the "total weight" is large and the "weight" is small. The
161  // solution is to factorise the problem into two steps:
162  // (1) "total weight", "weight of bin"
163  // (2) "total weight of bin", "weight of particle"
165 
166  return 0;
167 }
168 
169 //------------------------------------------------------------------------------
170 
172  double generatedWeightSum;
173  bool found;
174  BeamHaloParticle *beamHaloParticle;
175 
176  if(m_writeFlag) {
177  std::cerr << "Error: the file " << m_fileName << " is currently open for writing." << std::endl;
178  return 0;
179  }
180 
181  if (!engine) {
182  std::cerr << "Error: the RandomEngine pointer is null." << std::endl;
183  return 0;
184  }
185 
186  long particleIndex = 0;
187 
188  // Generate a number between 0 and the total weight sum.
189  generatedWeightSum = CLHEP::RandFlat::shoot(engine)*m_upperBinEdge;
190 
191  //std::cout << "Total weight sum = " << m_upperBinEdge << ", generated weight sum = " << generatedWeightSum << std::endl;
192 
193  // Find the interval which corresponds to this weight sum.
196  found = false;
197  while(superBinItr!=superBinItr_end && !found) {
198  //std::cout << "Upper bin edge = " << (*superBinItr).upperBinEdge() << std::endl;
199 
200  // This works assuming the elements are correctly ordered.
201  if(generatedWeightSum <= (*superBinItr).upperBinEdge()) {
202  found = true;
203  }
204  else {
205  ++superBinItr;
206  particleIndex += (*superBinItr).intervalUpperBinEdges()->size();
207  }
208  }
209 
210  // This should never happen.
211  if(!found) {
212  std::cerr << "Could not find an interval for the weight sum " << generatedWeightSum << std::endl;
213  return 0;
214  }
215 
216  const std::vector<double> *intervalUpperBinEdges = (*superBinItr).intervalUpperBinEdges();
217 
218  double intervalWeightSum = intervalUpperBinEdges->back();
219 
220 
221  // Generate a number between 0 and the total weight in this interval
222  generatedWeightSum = CLHEP::RandFlat::shoot(engine)*intervalWeightSum;
223 
224  //std::cout << "Interval weight sum = " << intervalWeightSum << ", generated weight sum = " << generatedWeightSum << std::endl;
225 
226  // Find the particle within this interval.
227  std::vector<double>::const_iterator intervalItr = intervalUpperBinEdges->begin();
228  std::vector<double>::const_iterator intervalItr_end = intervalUpperBinEdges->end();
229  found = false;
230  while(intervalItr!=intervalItr_end && !found) {
231  //std::cout << "Particle bin edge = " << (*intervalItr) << std::endl;
232 
233  // This works assuming the elements are correctly ordered.
234  if(generatedWeightSum <= (*intervalItr)) {
235  found = true;
236  }
237  else {
238  ++intervalItr;
239  ++particleIndex;
240  }
241  }
242 
243  // This should never happen.
244  if(!found) {
245  std::cerr << "Could not find a particle for the weight sum " << generatedWeightSum << std::endl;
246  return 0;
247  }
248 
249  if(particleIndex >= m_numberOfParticles) {
250  std::cerr << "Particle index " << particleIndex << " is out of range." << std::endl;
251  return 0;
252  }
253 
254  // Read this particle from the binary file.
255  m_ifstream.seekg(particleIndex*m_recordSize);
256  beamHaloParticle = readParticle();
257  if(!beamHaloParticle) return 0;
258 
259  return beamHaloParticle;
260 }
261 
262 //------------------------------------------------------------------------------
263 
265  if(m_writeFlag) {
266  std::cerr << "Error: the file " << m_fileName << " is current open for writing." << std::endl;
267  return 0;
268  }
269 
270  long pdgId = 0;
271  double px = 0., py = 0., pz = 0., e = 0., x = 0., y = 0., z = 0., t = 0., weight = 0.;
272 
273  m_ifstream.read((char*)(&pdgId), sizeof(pdgId)); if(m_ifstream.bad()) return 0;
274  m_ifstream.read((char*)(&px), sizeof(px)); if(m_ifstream.bad()) return 0;
275  m_ifstream.read((char*)(&py), sizeof(py)); if(m_ifstream.bad()) return 0;
276  m_ifstream.read((char*)(&pz), sizeof(pz)); if(m_ifstream.bad()) return 0;
277  m_ifstream.read((char*)(&e), sizeof(e)); if(m_ifstream.bad()) return 0;
278  m_ifstream.read((char*)(&x), sizeof(x)); if(m_ifstream.bad()) return 0;
279  m_ifstream.read((char*)(&y), sizeof(y)); if(m_ifstream.bad()) return 0;
280  m_ifstream.read((char*)(&z), sizeof(z)); if(m_ifstream.bad()) return 0;
281  m_ifstream.read((char*)(&t), sizeof(t)); if(m_ifstream.bad()) return 0;
282  m_ifstream.read((char*)(&weight), sizeof(weight)); if(m_ifstream.bad()) return 0;
283 
284  HepMC::FourVector fourVector(px,py,pz,e);
285  HepMC::FourVector positionAtScoringPlane(x,y,z,t);
286  BeamHaloParticle *beamHaloParticle = new BeamHaloParticle(pdgId, fourVector, positionAtScoringPlane, weight);
287 
288  return beamHaloParticle;
289 }
290 
291 //------------------------------------------------------------------------------
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
BeamHaloParticle
A class to describe a generic beam halo particle.
Definition: BeamHaloParticle.h:22
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
test_pyathena.px
px
Definition: test_pyathena.py:18
BeamHaloParticleBuffer::m_particlesPerInterval
unsigned int m_particlesPerInterval
The number of particles per interval.
Definition: BeamHaloParticleBuffer.h:78
BeamHaloParticleBuffer::m_numberOfParticles
long m_numberOfParticles
The number of particles present within the output or input file.
Definition: BeamHaloParticleBuffer.h:81
BeamHaloParticleBuffer.h
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
BinnedInterval::m_upperBinEdge
double m_upperBinEdge
Definition: BeamHaloParticleBuffer.h:41
BeamHaloParticleBuffer::openForReading
int openForReading()
Definition: BeamHaloParticleBuffer.cxx:65
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
BeamHaloParticleBuffer::writeParticle
int writeParticle(BeamHaloParticle *particle)
A member function to append a particle to the binary file.
Definition: BeamHaloParticleBuffer.cxx:109
x
#define x
BinnedInterval::~BinnedInterval
~BinnedInterval()
Definition: BeamHaloParticleBuffer.cxx:26
BeamHaloParticleBuffer::m_recordSize
int m_recordSize
The size of 1 binary data record.
Definition: BeamHaloParticleBuffer.h:75
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
BinnedInterval::m_intervalUpperBinEdges
std::vector< double > * m_intervalUpperBinEdges
Definition: BeamHaloParticleBuffer.h:42
BeamHaloParticleBuffer::BeamHaloParticleBuffer
BeamHaloParticleBuffer(const std::string &fileName)
Definition: BeamHaloParticleBuffer.cxx:32
BeamHaloParticle.h
BeamHaloParticleBuffer::m_fileName
std::string m_fileName
File name.
Definition: BeamHaloParticleBuffer.h:66
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
BeamHaloParticleBuffer::close
int close()
Definition: BeamHaloParticleBuffer.cxx:84
z
#define z
BeamHaloParticleBuffer::readParticle
BeamHaloParticle * readParticle(void)
A member function to read a particle from the current position in the binary file.
Definition: BeamHaloParticleBuffer.cxx:264
Amg::pz
@ pz
Definition: GeoPrimitives.h:40
BeamHaloParticleBuffer::readRandomParticle
BeamHaloParticle * readRandomParticle(CLHEP::HepRandomEngine *engine)
A member function to read a random particle from the binary file.
Definition: BeamHaloParticleBuffer.cxx:171
Amg::py
@ py
Definition: GeoPrimitives.h:39
BeamHaloParticleBuffer::m_binnedIntervals
std::vector< BinnedInterval > m_binnedIntervals
A map of the upper bin limits and an vector of bin limits within the given interval.
Definition: BeamHaloParticleBuffer.h:88
BeamHaloParticleBuffer::m_ofstream
std::ofstream m_ofstream
A data member to store the output file stream.
Definition: BeamHaloParticleBuffer.h:69
BeamHaloParticleBuffer::m_intervalUpperBinEdge
double m_intervalUpperBinEdge
The upper bin edge of a bin within a given interval.
Definition: BeamHaloParticleBuffer.h:97
BeamHaloParticleBuffer::m_ifstream
std::ifstream m_ifstream
A data member to store the input file stream.
Definition: BeamHaloParticleBuffer.h:72
y
#define y
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
BinnedInterval::BinnedInterval
BinnedInterval(double upperBinEdge, const std::vector< double > &intervalUpperBinEdges)
Definition: BeamHaloParticleBuffer.cxx:12
BinnedInterval
Definition: BeamHaloParticleBuffer.h:17
BeamHaloParticleBuffer::openForWriting
int openForWriting()
Definition: BeamHaloParticleBuffer.cxx:48
BeamHaloParticleBuffer::m_upperBinEdge
double m_upperBinEdge
The upper edge of the bin.
Definition: BeamHaloParticleBuffer.h:91
BinnedInterval::intervalUpperBinEdges
const std::vector< double > * intervalUpperBinEdges() const
Definition: BeamHaloParticleBuffer.h:38
BeamHaloParticleBuffer::m_intervalUpperBinEdges
std::vector< double > m_intervalUpperBinEdges
A vector of bin limits for a given interval.
Definition: BeamHaloParticleBuffer.h:94
BeamHaloParticleBuffer::m_writeFlag
bool m_writeFlag
A flag to select read or write.
Definition: BeamHaloParticleBuffer.h:100