ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Generators
BeamHaloGenerator
src
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
5
#include "
BeamHaloGenerator/BeamHaloParticleBuffer.h
"
6
#include "
BeamHaloGenerator/BeamHaloParticle.h
"
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
27
BinnedInterval::BinnedInterval
(
const
BinnedInterval
& binnedInterval) {
28
m_upperBinEdge
= binnedInterval.
m_upperBinEdge
;
29
m_intervalUpperBinEdges
=
new
std::vector<double>(*(binnedInterval.
m_intervalUpperBinEdges
));
30
}
31
32
//------------------------------------------------------------------------------
33
34
BinnedInterval::~BinnedInterval
() {
35
if
(
m_intervalUpperBinEdges
)
delete
m_intervalUpperBinEdges
;
36
}
37
38
//------------------------------------------------------------------------------
39
40
BeamHaloParticleBuffer::BeamHaloParticleBuffer
(
const
std::string& fileName)
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;
51
m_particlesPerInterval
= 1000;
52
}
53
54
//------------------------------------------------------------------------------
55
56
int
BeamHaloParticleBuffer::openForWriting
() {
57
m_writeFlag
=
true
;
58
m_numberOfParticles
= 0;
59
m_binnedIntervals
.clear();
60
m_intervalUpperBinEdges
.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
73
int
BeamHaloParticleBuffer::openForReading
() {
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
92
int
BeamHaloParticleBuffer::close
() {
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) {
99
BinnedInterval
binnedInterval(
m_upperBinEdge
,
m_intervalUpperBinEdges
);
100
m_binnedIntervals
.push_back(binnedInterval);
101
m_intervalUpperBinEdges
.clear();
102
m_intervalUpperBinEdge
= 0.;
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
117
int
BeamHaloParticleBuffer::writeParticle
(
BeamHaloParticle
*particle) {
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
148
m_numberOfParticles
++;
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.
153
if
(
m_intervalUpperBinEdges
.size() >=
m_particlesPerInterval
) {
154
BinnedInterval
binnedInterval(
m_upperBinEdge
,
m_intervalUpperBinEdges
);
155
m_binnedIntervals
.push_back(binnedInterval);
156
m_intervalUpperBinEdges
.clear();
157
m_intervalUpperBinEdge
= 0.;
158
}
159
160
// Append the weight to give the current upper bin edge. Then push
161
// the bin edge back.
162
m_intervalUpperBinEdge
+= weight;
163
m_intervalUpperBinEdges
.push_back(
m_intervalUpperBinEdge
);
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"
172
m_upperBinEdge
+= weight;
173
174
return
0;
175
}
176
177
//------------------------------------------------------------------------------
178
179
BeamHaloParticle
*
BeamHaloParticleBuffer::readRandomParticle
(CLHEP::HepRandomEngine* engine) {
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.
202
std::vector<BinnedInterval>::iterator superBinItr =
m_binnedIntervals
.begin();
203
std::vector<BinnedInterval>::iterator superBinItr_end =
m_binnedIntervals
.end();
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
272
BeamHaloParticle
*
BeamHaloParticleBuffer::readParticle
(
void
) {
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
//------------------------------------------------------------------------------
BeamHaloParticleBuffer.h
BeamHaloParticle.h
y
#define y
x
#define x
z
#define z
BeamHaloParticleBuffer::m_intervalUpperBinEdge
double m_intervalUpperBinEdge
The upper bin edge of a bin within a given interval.
Definition
BeamHaloParticleBuffer.h:97
BeamHaloParticleBuffer::readRandomParticle
BeamHaloParticle * readRandomParticle(CLHEP::HepRandomEngine *engine)
A member function to read a random particle from the binary file.
Definition
BeamHaloParticleBuffer.cxx:179
BeamHaloParticleBuffer::m_writeFlag
bool m_writeFlag
A flag to select read or write.
Definition
BeamHaloParticleBuffer.h:100
BeamHaloParticleBuffer::m_particlesPerInterval
unsigned int m_particlesPerInterval
The number of particles per interval.
Definition
BeamHaloParticleBuffer.h:78
BeamHaloParticleBuffer::openForWriting
int openForWriting()
Definition
BeamHaloParticleBuffer.cxx:56
BeamHaloParticleBuffer::writeParticle
int writeParticle(BeamHaloParticle *particle)
A member function to append a particle to the binary file.
Definition
BeamHaloParticleBuffer.cxx:117
BeamHaloParticleBuffer::readParticle
BeamHaloParticle * readParticle(void)
A member function to read a particle from the current position in the binary file.
Definition
BeamHaloParticleBuffer.cxx:272
BeamHaloParticleBuffer::BeamHaloParticleBuffer
BeamHaloParticleBuffer(const std::string &fileName)
Definition
BeamHaloParticleBuffer.cxx:40
BeamHaloParticleBuffer::openForReading
int openForReading()
Definition
BeamHaloParticleBuffer.cxx:73
BeamHaloParticleBuffer::m_ofstream
std::ofstream m_ofstream
A data member to store the output file stream.
Definition
BeamHaloParticleBuffer.h:69
BeamHaloParticleBuffer::m_fileName
std::string m_fileName
File name.
Definition
BeamHaloParticleBuffer.h:66
BeamHaloParticleBuffer::m_upperBinEdge
double m_upperBinEdge
The upper edge of the bin.
Definition
BeamHaloParticleBuffer.h:91
BeamHaloParticleBuffer::m_intervalUpperBinEdges
std::vector< double > m_intervalUpperBinEdges
A vector of bin limits for a given interval.
Definition
BeamHaloParticleBuffer.h:94
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_recordSize
int m_recordSize
The size of 1 binary data record.
Definition
BeamHaloParticleBuffer.h:75
BeamHaloParticleBuffer::m_numberOfParticles
long m_numberOfParticles
The number of particles present within the output or input file.
Definition
BeamHaloParticleBuffer.h:81
BeamHaloParticleBuffer::close
int close()
Definition
BeamHaloParticleBuffer.cxx:92
BeamHaloParticleBuffer::m_ifstream
std::ifstream m_ifstream
A data member to store the input file stream.
Definition
BeamHaloParticleBuffer.h:72
BeamHaloParticle
A class to describe a generic beam halo particle.
Definition
BeamHaloParticle.h:21
BinnedInterval
Definition
BeamHaloParticleBuffer.h:17
BinnedInterval::~BinnedInterval
~BinnedInterval()
Definition
BeamHaloParticleBuffer.cxx:34
BinnedInterval::BinnedInterval
BinnedInterval(double upperBinEdge, const std::vector< double > &intervalUpperBinEdges)
Definition
BeamHaloParticleBuffer.cxx:20
BinnedInterval::intervalUpperBinEdges
const std::vector< double > * intervalUpperBinEdges() const
Definition
BeamHaloParticleBuffer.h:38
BinnedInterval::m_intervalUpperBinEdges
std::vector< double > * m_intervalUpperBinEdges
Definition
BeamHaloParticleBuffer.h:42
BinnedInterval::m_upperBinEdge
double m_upperBinEdge
Definition
BeamHaloParticleBuffer.h:41
BinnedInterval::upperBinEdge
double upperBinEdge() const
Definition
BeamHaloParticleBuffer.h:37
HepMC::FourVector
HepMC3::FourVector FourVector
Definition
SimpleVector.h:11
Pythia8_RapidityOrderMPI.val
val
Definition
Pythia8_RapidityOrderMPI.py:14
Generated on
for ATLAS Offline Software by
1.17.0