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