Skip to content

Commit b955c59

Browse files
sawenzelmhemmer-cern
authored andcommitted
Optional InteractionSampler sampling overwrite
Allow to overwrite InteractionSampler by means of virtualizing sampling function. Used in CollisionContextTool do allow putting collisions at fixed N intervals (export mode) for the purpose of systematic studies / debugging. - To use this feature say `export ALICEO2_ENFORCE_TRIVIAL_BC_SAMPLER="2:5" to put 5 collisions into every 2nd bunch-crossing (within the bunch filling scheme)
1 parent 7939dda commit b955c59

4 files changed

Lines changed: 63 additions & 10 deletions

File tree

DataFormats/simulation/include/SimulationDataFormat/InteractionSampler.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class InteractionSampler
6767
void print() const;
6868

6969
protected:
70-
int simulateInteractingBC();
70+
virtual int simulateInteractingBC();
7171
void nextCollidingBC(int n);
7272

7373
o2::math_utils::RandomRing<10000> mBCJumpGenerator; // generator of random jumps in BC
@@ -89,7 +89,7 @@ class InteractionSampler
8989

9090
static constexpr float DefIntRate = 50e3; ///< default interaction rate
9191

92-
ClassDefNV(InteractionSampler, 1);
92+
ClassDef(InteractionSampler, 1);
9393
};
9494

9595
//_________________________________________________
@@ -113,6 +113,23 @@ inline void InteractionSampler::nextCollidingBC(int n)
113113
mIR.bc = mInteractingBCs[mCurrBCIdx];
114114
}
115115

116+
// Special case of InteractionSampler without actual sampling.
117+
// Engineers interaction sequence by putting one in each N-th BC with multiplicity mult.
118+
class FixedSkipBC_InteractionSampler : public InteractionSampler
119+
{
120+
121+
public:
122+
FixedSkipBC_InteractionSampler(int every_n, int mult) : mEveryN{every_n}, mMultiplicity{mult}, InteractionSampler() {}
123+
124+
protected:
125+
int simulateInteractingBC() override;
126+
127+
private:
128+
int mEveryN; // the skip number ---> fills every N-th BC in the bunch filling scheme
129+
int mMultiplicity; // how many events to put if bc is filled
130+
ClassDef(FixedSkipBC_InteractionSampler, 1);
131+
};
132+
116133
} // namespace steer
117134
} // namespace o2
118135

DataFormats/simulation/src/InteractionSampler.cxx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,24 @@ int InteractionSampler::simulateInteractingBC()
130130
return ncoll;
131131
}
132132

133+
//_________________________________________________
134+
int FixedSkipBC_InteractionSampler::simulateInteractingBC()
135+
{
136+
// Returns number of collisions assigned to selected BC
137+
138+
nextCollidingBC(mEveryN); // we jump regular intervals
139+
int ncoll = mMultiplicity; // well defined pileup
140+
141+
// assign random time withing a bunch
142+
for (int i = ncoll; i--;) {
143+
mTimeInBC.push_back(mCollTimeGenerator.getNextValue());
144+
}
145+
if (ncoll > 1) { // sort in DECREASING time order (we are reading vector from the end)
146+
std::sort(mTimeInBC.begin(), mTimeInBC.end(), [](const float a, const float b) { return a > b; });
147+
}
148+
return ncoll;
149+
}
150+
133151
//_________________________________________________
134152
void InteractionSampler::setBunchFilling(const std::string& bcFillingFile)
135153
{

DataFormats/simulation/src/SimulationDataLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#pragma link off all functions;
2525

2626
#pragma link C++ class o2::steer::InteractionSampler + ;
27+
#pragma link C++ class o2::steer::FixedSkipBC_InteractionSampler + ;
2728
#pragma link C++ class o2::sim::StackParam + ;
2829
#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::sim::StackParam> + ;
2930
#pragma link C++ class o2::MCTrackT < double> + ;

Steer/src/CollisionContextTool.cxx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,17 +302,34 @@ int main(int argc, char* argv[])
302302
for (int id = 0; id < ispecs.size(); ++id) {
303303
auto mode = ispecs[id].syncmode;
304304
if (mode == InteractionLockMode::NOLOCK) {
305-
o2::steer::InteractionSampler sampler;
306-
sampler.setInteractionRate(ispecs[id].interactionRate);
305+
auto sampler = std::make_unique<o2::steer::InteractionSampler>();
306+
307+
// for debug purposes: allows to instantiate trivial sampler
308+
if (const char* env = getenv("ALICEO2_ENFORCE_TRIVIAL_BC_SAMPLER")) {
309+
std::string spec(env);
310+
std::regex re(R"((\d+):(\d+))");
311+
std::smatch match;
312+
int every_n = 1, mult = 1;
313+
if (std::regex_match(spec, match, re)) {
314+
every_n = std::stoi(match[1]);
315+
mult = std::stoi(match[2]);
316+
} else {
317+
LOG(error) << "ALICEO2_ENFORCE_TRIVIAL_BC_SAMPLER format invalid, expected NUMBER_1:NUMBER_2";
318+
exit(1);
319+
}
320+
sampler.reset(new o2::steer::FixedSkipBC_InteractionSampler(every_n, mult));
321+
}
322+
323+
sampler->setInteractionRate(ispecs[id].interactionRate);
307324
if (!options.bcpatternfile.empty()) {
308-
setBCFillingHelper(sampler, options.bcpatternfile);
325+
setBCFillingHelper(*sampler, options.bcpatternfile);
309326
}
310327
o2::InteractionTimeRecord record;
311328
// this loop makes sure that the first collision is within the range of orbits asked (if noEmptyTF is enabled)
312329
do {
313-
sampler.setFirstIR(o2::InteractionRecord(options.firstBC, orbitstart));
314-
sampler.init();
315-
record = sampler.generateCollisionTime();
330+
sampler->setFirstIR(o2::InteractionRecord(options.firstBC, orbitstart));
331+
sampler->init();
332+
record = sampler->generateCollisionTime();
316333
} while (options.noEmptyTF && usetimeframelength && record.orbit >= orbitstart + orbits_total);
317334
int count = 0;
318335
do {
@@ -325,7 +342,7 @@ int main(int argc, char* argv[])
325342
std::pair<o2::InteractionTimeRecord, std::vector<o2::steer::EventPart>> insertvalue(record, parts);
326343
auto iter = std::lower_bound(collisions.begin(), collisions.end(), insertvalue, [](std::pair<o2::InteractionTimeRecord, std::vector<o2::steer::EventPart>> const& a, std::pair<o2::InteractionTimeRecord, std::vector<o2::steer::EventPart>> const& b) { return a.first < b.first; });
327344
collisions.insert(iter, insertvalue);
328-
record = sampler.generateCollisionTime();
345+
record = sampler->generateCollisionTime();
329346
count++;
330347
} while ((ispecs[id].mcnumberasked > 0 && count < ispecs[id].mcnumberasked)); // TODO: this loop should probably be replaced by a condition with usetimeframelength and number of orbits
331348

@@ -360,7 +377,7 @@ int main(int argc, char* argv[])
360377
}
361378

362379
// keep bunch filling information produced by these samplers
363-
bunchFillings.push_back(sampler.getBunchFilling());
380+
bunchFillings.push_back(sampler->getBunchFilling());
364381

365382
} else {
366383
// we are in some lock/sync mode and modify existing collisions

0 commit comments

Comments
 (0)