Skip to content

Commit 56bfdbe

Browse files
committed
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 b911f95 commit 56bfdbe

File tree

4 files changed

+63
-10
lines changed

4 files changed

+63
-10
lines changed

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)