Skip to content

Commit c1ceef8

Browse files
committed
Introducing non-uniform mu InteractionSampler
Provides a novel InteractionSampler for collision structure which is able to sample (orbit,bc) values according to an externally given hNBcVTX distribution (obtained from FIT, EventSelection) A unit test which shows and tests the new feature. Fixes https://its.cern.ch/jira/browse/O2-6450
1 parent b5582b6 commit c1ceef8

File tree

5 files changed

+202
-1
lines changed

5 files changed

+202
-1
lines changed

DataFormats/simulation/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ o2_target_root_dictionary(
5555
# * src/SimulationDataLinkDef.h
5656
# * and not src/SimulationDataFormatLinkDef.h
5757

58+
o2_add_test(InteractionSampler
59+
SOURCES test/testInteractionSampler.cxx
60+
COMPONENT_NAME SimulationDataFormat
61+
PUBLIC_LINK_LIBRARIES O2::SimulationDataFormat)
62+
5863
o2_add_test(BasicHits
5964
SOURCES test/testBasicHits.cxx
6065
COMPONENT_NAME SimulationDataFormat

DataFormats/simulation/include/SimulationDataFormat/InteractionSampler.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "CommonDataFormat/BunchFilling.h"
2323
#include "CommonConstants/LHCConstants.h"
2424
#include "MathUtils/RandomRing.h"
25+
#include <TH1F.h>
2526

2627
namespace o2
2728
{
@@ -130,6 +131,30 @@ class FixedSkipBC_InteractionSampler : public InteractionSampler
130131
ClassDef(FixedSkipBC_InteractionSampler, 1);
131132
};
132133

134+
// A version of the interaction sampler which can sample according to non-uniform mu(bc) as
135+
// observed during data taking.
136+
class NonUniformMuInteractionSampler : public InteractionSampler
137+
{
138+
public:
139+
NonUniformMuInteractionSampler() : InteractionSampler() { mBCIntensityScales.resize(o2::constants::lhc::LHCMaxBunches, 1); }
140+
bool setBCIntensityScales(const std::vector<float>& scales_from_vector);
141+
bool setBCIntensityScales(const TH1F& scales_from_histo); // initialize scales
142+
143+
// helper function to determine the scales from a histogram (count from event selection analysis)
144+
std::vector<float> determineBCIntensityScalesFromHistogram(const TH1F& scales_from_histo);
145+
146+
const std::vector<float>& getBCIntensityScales() const { return mBCIntensityScales; }
147+
148+
protected:
149+
int simulateInteractingBC() override;
150+
int getBCJump() const;
151+
152+
private:
153+
// non-uniformity
154+
std::vector<float> mBCIntensityScales;
155+
ClassDef(NonUniformMuInteractionSampler, 1);
156+
};
157+
133158
} // namespace steer
134159
} // namespace o2
135160

DataFormats/simulation/src/InteractionSampler.cxx

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ const o2::InteractionTimeRecord& InteractionSampler::generateCollisionTime()
115115
int InteractionSampler::simulateInteractingBC()
116116
{
117117
// Returns number of collisions assigned to selected BC
118-
119118
nextCollidingBC(mBCJumpGenerator.getNextValue());
119+
120120
// once BC is decided, enforce at least one interaction
121121
int ncoll = mNCollBCGenerator.getNextValue();
122122

@@ -162,3 +162,97 @@ void InteractionSampler::setBunchFilling(const std::string& bcFillingFile)
162162
mBCFilling = *bc;
163163
delete bc;
164164
}
165+
166+
// ________________________________________________
167+
bool NonUniformMuInteractionSampler::setBCIntensityScales(const std::vector<float>& scales_from_vector)
168+
{
169+
// Sets the intensity scales per bunch crossing index
170+
// The length of this vector needs to be compatible with the bunch filling chosen
171+
mBCIntensityScales = scales_from_vector;
172+
173+
if (scales_from_vector.size() != mInteractingBCs.size()) {
174+
LOG(error) << "Scaling factors and bunch filling scheme are not compatible. Not doing anything";
175+
return false;
176+
}
177+
178+
// since this is a scaling factor, we need to normalize the max to 1
179+
float max_val = 0.;
180+
for (auto v : mBCIntensityScales) {
181+
max_val = std::max(max_val, v);
182+
}
183+
// normalize
184+
for (auto& v : mBCIntensityScales) {
185+
if (v < 0.) {
186+
v = std::abs(v);
187+
} else {
188+
v /= max_val;
189+
}
190+
}
191+
return true;
192+
}
193+
194+
// ________________________________________________
195+
196+
bool NonUniformMuInteractionSampler::setBCIntensityScales(const TH1F& hist)
197+
{
198+
return setBCIntensityScales(determineBCIntensityScalesFromHistogram(hist));
199+
}
200+
201+
std::vector<float> NonUniformMuInteractionSampler::determineBCIntensityScalesFromHistogram(const TH1F& hist)
202+
{
203+
std::vector<float> scales;
204+
// we go through the BCs and query the count from histogram
205+
for (auto bc : mInteractingBCs) {
206+
scales.push_back(hist.GetBinContent(bc + 1));
207+
}
208+
return scales;
209+
}
210+
211+
int NonUniformMuInteractionSampler::getBCJump() const
212+
{
213+
auto muFunc = [this](int bc_position) {
214+
return mBCIntensityScales[bc_position % mInteractingBCs.size()] * mMuBC;
215+
};
216+
217+
double U = gRandom->Rndm(); // uniform (0,1)
218+
double T = -std::log(1.0 - U); // threshold
219+
double sumMu = 0.0;
220+
int offset = 0;
221+
auto bcStart = mCurrBCIdx; // the current bc
222+
int maxSearch = o2::constants::lhc::LHCMaxBunches;
223+
224+
while (offset < maxSearch) {
225+
auto mu_here = muFunc(bcStart + offset); // mu at next BC
226+
sumMu += mu_here;
227+
if (sumMu >= T) {
228+
break; // found BC with at least one collision
229+
}
230+
++offset;
231+
}
232+
return offset;
233+
}
234+
235+
int NonUniformMuInteractionSampler::simulateInteractingBC()
236+
{
237+
nextCollidingBC(getBCJump());
238+
239+
auto muFunc = [this](int bc_position) {
240+
return mBCIntensityScales[bc_position % mInteractingBCs.size()] * mMuBC;
241+
};
242+
243+
// now sample number of collisions in chosenBC, conditioned >=1:
244+
double mu_chosen = muFunc(mCurrBCIdx); // or does it need to be mCurrBCIdx
245+
int ncoll = 0;
246+
do {
247+
ncoll = gRandom->Poisson(mu_chosen);
248+
} while (ncoll == 0);
249+
250+
// assign random time withing a bunch
251+
for (int i = ncoll; i--;) {
252+
mTimeInBC.push_back(mCollTimeGenerator.getNextValue());
253+
}
254+
if (ncoll > 1) { // sort in DECREASING time order (we are reading vector from the end)
255+
std::sort(mTimeInBC.begin(), mTimeInBC.end(), [](const float a, const float b) { return a > b; });
256+
}
257+
return ncoll;
258+
}

DataFormats/simulation/src/SimulationDataLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#pragma link C++ class o2::steer::InteractionSampler + ;
2727
#pragma link C++ class o2::steer::FixedSkipBC_InteractionSampler + ;
28+
#pragma link C++ class o2::steer::NonUniformMuInteractionSampler + ;
2829
#pragma link C++ class o2::sim::StackParam + ;
2930
#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::sim::StackParam> + ;
3031
#pragma link C++ class o2::MCTrackT < double> + ;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#define BOOST_TEST_MODULE Test InteractionSampler class
13+
#define BOOST_TEST_MAIN
14+
#define BOOST_TEST_DYN_LINK
15+
16+
#include <boost/test/unit_test.hpp>
17+
#include "SimulationDataFormat/InteractionSampler.h"
18+
#include "CCDB/BasicCCDBManager.h"
19+
#include "DataFormatsParameters/AggregatedRunInfo.h"
20+
#include "DataFormatsParameters/GRPLHCIFData.h"
21+
#include "TFile.h"
22+
#include "TGrid.h"
23+
#include <TH1F.h>
24+
25+
namespace o2
26+
{
27+
28+
BOOST_AUTO_TEST_CASE(NonUniformSampler)
29+
{
30+
auto run_number = 559827;
31+
auto runInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(o2::ccdb::BasicCCDBManager::instance(), run_number);
32+
33+
o2::steer::NonUniformMuInteractionSampler sampler;
34+
sampler.setBunchFilling(runInfo.grpLHC->getBunchFilling());
35+
36+
TGrid::Connect("alien");
37+
if (gGrid) {
38+
// the test distribution provided by Igor Altsybeev
39+
auto distr_file = TFile::Open("alien:///alice/cern.ch/user/s/swenzel/AliceO2_TestData/NBcVTX_559827/hBcTVX_data_PbPb_24ar_559827.root");
40+
41+
//
42+
if (distr_file && !distr_file->IsZombie()) {
43+
auto hist = distr_file->Get<TH1F>("hBcTVX");
44+
if (hist) {
45+
sampler.init();
46+
sampler.setBCIntensityScales(*hist);
47+
48+
// sample into a vector of a certain size
49+
std::vector<o2::InteractionTimeRecord> samples;
50+
51+
int N = 100000;
52+
samples.resize(N);
53+
54+
sampler.generateCollisionTimes(samples);
55+
56+
// fill an output histogram
57+
auto output_hist = (TH1F*)hist->Clone("h2"); // make a full copy
58+
output_hist->Reset();
59+
60+
for (const auto& sample : samples) {
61+
output_hist->Fill(sample.bc);
62+
}
63+
64+
// Write out
65+
auto fout = TFile::Open("NBCVTX_out.root", "RECREATE");
66+
fout->WriteObject(output_hist, "NBcVTX");
67+
fout->Close();
68+
69+
// compare mean values of original and newly sampled hist
70+
BOOST_CHECK_CLOSE(hist->GetMean(), output_hist->GetMean(), 0.5);
71+
}
72+
}
73+
}
74+
}
75+
76+
} // namespace o2

0 commit comments

Comments
 (0)