Skip to content

Commit 938075e

Browse files
Debug streamer: Add downsampling by tsalis (#12112)
* Debug streamer: Add downsampling by tsalis * Adding time series for vertex position - adding time series for DCA to vertex for ITS-TPC tracks * increase ClassDef for TimeSeriesITSTPC * fix typo
1 parent 030e396 commit 938075e

File tree

4 files changed

+319
-78
lines changed

4 files changed

+319
-78
lines changed

Common/Utils/include/CommonUtils/DebugStreamer.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ enum SamplingTypes {
5050
sampleID = 2, ///< sample every n IDs (per example track)
5151
sampleIDGlobal = 3, ///< in case different streamers have access to the same IDs use this gloabl ID
5252
sampleWeights = 4, ///< perform sampling on weights, defined where the streamer is called
53+
sampleTsalis = 5, ///< perform sampling on tsalis pdf
5354
};
5455

5556
#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
@@ -163,10 +164,34 @@ class DebugStreamer
163164
/// \return returns integer index for given streamer flag
164165
static int getIndex(const StreamFlags streamFlag);
165166

167+
/// Random downsampling trigger function using Tsalis/Hagedorn spectra fit (sqrt(s) = 62.4 GeV to 13 TeV) as in https://iopscience.iop.org/article/10.1088/2399-6528/aab00f/pdf
168+
/// \return flat q/pt trigger
169+
/// \param pt pat of particle
170+
/// \param factorPt defines the sampling
171+
/// \param sqrts centre of mass energy
172+
/// \param weight weight which is internally calculated
173+
/// \param rnd random value between (0->1) used to check for sampling
174+
/// \param mass particles mass (use pion if not known)
175+
static bool downsampleTsalisCharged(float pt, float factorPt, float sqrts, float& weight, float rnd, float mass = 0.13957);
176+
177+
/// get random value between min and max
178+
static float getRandom(float min = 0, float max = 1);
179+
166180
private:
167181
using StreamersPerFlag = tbb::concurrent_unordered_map<size_t, std::unique_ptr<o2::utils::TreeStreamRedirector>>;
168182
StreamersPerFlag mTreeStreamer; ///< streamer which is used for the debugging
169183

184+
/// Tsalis/Hagedorn function describing charged pt spectra (m s = 62.4 GeV to 13 TeV) as in https://iopscience.iop.org/article/10.1088/2399-6528/aab00f/pdf
185+
/// https://github.com/alisw/AliPhysics/blob/523f2dc8b45d913e9b7fda9b27e746819cbe5b09/PWGPP/AliAnalysisTaskFilteredTree.h#L145
186+
/// \param pt - transverse momentum
187+
/// \param mass - mass of particle
188+
/// \param sqrts - centre of mass energy
189+
/// \return - invariant yields of the charged particle *pt
190+
/// n(sqrts)= a + b/sqrt(s) - formula 6
191+
/// T(sqrts)= c + d/sqrt(s) - formula 7
192+
/// a = 6.81 ± 0.06 and b = 59.24 ± 3.53 GeV - for charged particles page 3
193+
/// c = 0.082 ± 0.002 GeV and d = 0.151 ± 0.048 (GeV) - for charged particles page 4
194+
static float tsalisCharged(float pt, float mass, float sqrts);
170195
#else
171196

172197
// empty implementation of the class for GPU or when the debug streamer is not build for CPU

Common/Utils/src/DebugStreamer.cxx

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,27 +65,22 @@ bool o2::utils::DebugStreamer::checkStream(const StreamFlags streamFlag, const s
6565
// check sampling frequency
6666
const auto sampling = getSamplingTypeFrequency(streamFlag);
6767
if (sampling.first != SamplingTypes::sampleAll) {
68-
// init random number generator for each thread
69-
static thread_local std::mt19937 generator(std::random_device{}());
70-
std::uniform_real_distribution<> distr(0, 1);
71-
7268
auto sampleTrack = [&]() {
7369
if (samplingID == -1) {
7470
LOGP(fatal, "Sampling type sampleID not supported for stream flag {}", streamFlag);
7571
}
76-
std::uniform_real_distribution<> distr(0, 1);
7772
// sample on samplingID (e.g. track level)
7873
static thread_local std::unordered_map<StreamFlags, std::pair<size_t, bool>> idMap;
7974
// in case of first call samplingID in idMap is 0 and always false and first ID rejected
8075
if (idMap[streamFlag].first != samplingID) {
81-
idMap[streamFlag] = std::pair<size_t, bool>{samplingID, (distr(generator) < sampling.second)};
76+
idMap[streamFlag] = std::pair<size_t, bool>{samplingID, (getRandom() < sampling.second)};
8277
}
8378
return idMap[streamFlag].second;
8479
};
8580

8681
if (sampling.first == SamplingTypes::sampleRandom) {
8782
// just sample randomly
88-
return (distr(generator) < sampling.second);
83+
return (getRandom() < sampling.second);
8984
} else if (sampling.first == SamplingTypes::sampleID) {
9085
return sampleTrack();
9186
} else if (sampling.first == SamplingTypes::sampleIDGlobal) {
@@ -106,12 +101,44 @@ bool o2::utils::DebugStreamer::checkStream(const StreamFlags streamFlag, const s
106101
}
107102
} else if (sampling.first == SamplingTypes::sampleWeights) {
108103
// sample with weight
109-
return (weight * distr(generator) < sampling.second);
104+
return (weight * getRandom() < sampling.second);
110105
}
111106
}
112107
return true;
113108
}
114109

110+
float o2::utils::DebugStreamer::tsalisCharged(float pt, float mass, float sqrts)
111+
{
112+
const float a = 6.81;
113+
const float b = 59.24;
114+
const float c = 0.082;
115+
const float d = 0.151;
116+
const float mt = std::sqrt(mass * mass + pt * pt);
117+
const float n = a + b / sqrts;
118+
const float T = c + d / sqrts;
119+
const float p0 = n * T;
120+
const float result = std::pow((1. + mt / p0), -n) * pt;
121+
return result;
122+
}
123+
124+
bool o2::utils::DebugStreamer::downsampleTsalisCharged(float pt, float factorPt, float sqrts, float& weight, float rnd, float mass)
125+
{
126+
const float prob = tsalisCharged(pt, mass, sqrts);
127+
const float probNorm = tsalisCharged(1., mass, sqrts);
128+
weight = prob / probNorm;
129+
const bool isSampled = (rnd * (weight * pt * pt)) < factorPt;
130+
return isSampled;
131+
}
132+
133+
float o2::utils::DebugStreamer::getRandom(float min, float max)
134+
{
135+
// init random number generator for each thread
136+
static thread_local std::mt19937 generator(std::random_device{}());
137+
std::uniform_real_distribution<> distr(min, max);
138+
const float rnd = distr(generator);
139+
return rnd;
140+
}
141+
115142
int o2::utils::DebugStreamer::getIndex(const StreamFlags streamFlag)
116143
{
117144
// see: https://stackoverflow.com/a/71539401

Detectors/Calibration/include/DetectorsCalibration/IntegratedClusterCalibrator.h

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,28 @@ struct ITSTPC_Matching {
362362
};
363363

364364
struct TimeSeriesITSTPC {
365-
TimeSeries mTSTPC; ///< TPC standalone DCAs
366-
TimeSeries mTSITSTPC; ///< ITS-TPC standalone DCAs
367-
ITSTPC_Matching mITSTPCAll; ///< ITS-TPC matching efficiency for ITS standalone + afterburner
368-
ITSTPC_Matching mITSTPCStandalone; ///< ITS-TPC matching efficiency for ITS standalone
369-
ITSTPC_Matching mITSTPCAfterburner; ///< ITS-TPC matchin efficiency fir ITS afterburner
365+
TimeSeries mTSTPC; ///< TPC standalone DCAs
366+
TimeSeries mTSITSTPC; ///< ITS-TPC standalone DCAs
367+
ITSTPC_Matching mITSTPCAll; ///< ITS-TPC matching efficiency for ITS standalone + afterburner
368+
ITSTPC_Matching mITSTPCStandalone; ///< ITS-TPC matching efficiency for ITS standalone
369+
ITSTPC_Matching mITSTPCAfterburner; ///< ITS-TPC matchin efficiency fir ITS afterburner
370+
std::vector<float> nPrimVertices; ///< number of primary vertices
371+
std::vector<float> nVertexContributors_Median; ///< number of primary vertices
372+
std::vector<float> nVertexContributors_RMS; ///< number of primary vertices
373+
std::vector<float> vertexX_Median; ///< vertex x position
374+
std::vector<float> vertexY_Median; ///< vertex y position
375+
std::vector<float> vertexZ_Median; ///< vertex z position
376+
std::vector<float> vertexX_RMS; ///< vertex x RMS
377+
std::vector<float> vertexY_RMS; ///< vertex y RMS
378+
std::vector<float> vertexZ_RMS; ///< vertex z RMS
379+
std::vector<float> mDCAr_comb_A_Median; ///< DCAr for ITS-TPC track - A-side
380+
std::vector<float> mDCAz_comb_A_Median; ///< DCAz for ITS-TPC track - A-side
381+
std::vector<float> mDCAr_comb_A_RMS; ///< DCAr RMS for ITS-TPC track - A-side
382+
std::vector<float> mDCAz_comb_A_RMS; ///< DCAz RMS for ITS-TPC track - A-side
383+
std::vector<float> mDCAr_comb_C_Median; ///< DCAr for ITS-TPC track - C-side
384+
std::vector<float> mDCAz_comb_C_Median; ///< DCAz for ITS-TPC track - C-side
385+
std::vector<float> mDCAr_comb_C_RMS; ///< DCAr RMS for ITS-TPC track - C-side
386+
std::vector<float> mDCAz_comb_C_RMS; ///< DCAz RMS for ITS-TPC track - C-side
370387

371388
// dump this object to a tree
372389
void dumpToTree(const char* outFileName, const int nHBFPerTF = 32);
@@ -390,6 +407,8 @@ struct TimeSeriesITSTPC {
390407
bool areSameSize() const { return (mTSTPC.areSameSize() && mTSITSTPC.areSameSize()); } ///< check if stored currents have same number of entries
391408
bool isEmpty() const { return mTSTPC.isEmpty(); } ///< check if values are empty
392409
size_t getEntries() const { return mTSTPC.getEntries(); } ///< \return returns number of values stored
410+
void fill(const std::vector<float>& vecFrom, std::vector<float>& vecTo, const unsigned int posIndex) { std::copy(vecFrom.begin(), vecFrom.end(), vecTo.begin() + posIndex); }
411+
void insert(std::vector<float>& vec, const std::vector<float>& vecTmp) { vec.insert(vec.begin(), vecTmp.begin(), vecTmp.end()); }
393412

394413
/// acummulate integrated currents at given index
395414
/// \param posIndex index where data will be copied to
@@ -401,6 +420,25 @@ struct TimeSeriesITSTPC {
401420
mITSTPCAll.fill(posIndex, data.mITSTPCAll);
402421
mITSTPCStandalone.fill(posIndex, data.mITSTPCStandalone);
403422
mITSTPCAfterburner.fill(posIndex, data.mITSTPCAfterburner);
423+
fill(data.mDCAr_comb_A_Median, mDCAr_comb_A_Median, posIndex);
424+
fill(data.mDCAz_comb_A_Median, mDCAz_comb_A_Median, posIndex);
425+
fill(data.mDCAr_comb_A_RMS, mDCAr_comb_A_RMS, posIndex);
426+
fill(data.mDCAz_comb_A_RMS, mDCAz_comb_A_RMS, posIndex);
427+
fill(data.mDCAr_comb_C_Median, mDCAr_comb_C_Median, posIndex);
428+
fill(data.mDCAz_comb_C_Median, mDCAz_comb_C_Median, posIndex);
429+
fill(data.mDCAr_comb_C_RMS, mDCAr_comb_C_RMS, posIndex);
430+
fill(data.mDCAz_comb_C_RMS, mDCAz_comb_C_RMS, posIndex);
431+
432+
const int iTF = posIndex / mTSTPC.getNBins();
433+
nPrimVertices[iTF] = data.nPrimVertices.front();
434+
nVertexContributors_Median[iTF] = data.nVertexContributors_Median.front();
435+
nVertexContributors_RMS[iTF] = data.nVertexContributors_RMS.front();
436+
vertexX_Median[iTF] = data.vertexX_Median.front();
437+
vertexY_Median[iTF] = data.vertexY_Median.front();
438+
vertexZ_Median[iTF] = data.vertexZ_Median.front();
439+
vertexX_RMS[iTF] = data.vertexX_RMS.front();
440+
vertexY_RMS[iTF] = data.vertexY_RMS.front();
441+
vertexZ_RMS[iTF] = data.vertexZ_RMS.front();
404442
}
405443

406444
/// \param nDummyValues number of empty values which are inserted at the beginning of the accumulated integrated currents
@@ -411,6 +449,27 @@ struct TimeSeriesITSTPC {
411449
mITSTPCAll.insert(nDummyValues);
412450
mITSTPCStandalone.insert(nDummyValues);
413451
mITSTPCAfterburner.insert(nDummyValues);
452+
std::vector<float> vecTmp(nDummyValues, 0);
453+
insert(mDCAr_comb_A_Median, vecTmp);
454+
insert(mDCAz_comb_A_Median, vecTmp);
455+
insert(mDCAr_comb_A_RMS, vecTmp);
456+
insert(mDCAz_comb_A_RMS, vecTmp);
457+
insert(mDCAr_comb_C_Median, vecTmp);
458+
insert(mDCAz_comb_C_Median, vecTmp);
459+
insert(mDCAr_comb_C_RMS, vecTmp);
460+
insert(mDCAz_comb_C_RMS, vecTmp);
461+
462+
const int nDummyValuesVtx = nDummyValues / mTSTPC.getNBins();
463+
std::vector<float> vecTmpVtx(nDummyValuesVtx, 0);
464+
insert(nPrimVertices, vecTmp);
465+
insert(nVertexContributors_Median, vecTmp);
466+
insert(nVertexContributors_RMS, vecTmp);
467+
insert(vertexX_Median, vecTmp);
468+
insert(vertexY_Median, vecTmp);
469+
insert(vertexZ_Median, vecTmp);
470+
insert(vertexX_RMS, vecTmp);
471+
insert(vertexY_RMS, vecTmp);
472+
insert(vertexZ_RMS, vecTmp);
414473
}
415474

416475
/// resize buffer for accumulated currents
@@ -421,9 +480,28 @@ struct TimeSeriesITSTPC {
421480
mITSTPCAll.resize(nTotal);
422481
mITSTPCStandalone.resize(nTotal);
423482
mITSTPCAfterburner.resize(nTotal);
424-
}
425-
426-
ClassDefNV(TimeSeriesITSTPC, 1);
483+
mDCAr_comb_A_Median.resize(nTotal);
484+
mDCAz_comb_A_Median.resize(nTotal);
485+
mDCAr_comb_A_RMS.resize(nTotal);
486+
mDCAz_comb_A_RMS.resize(nTotal);
487+
mDCAr_comb_C_Median.resize(nTotal);
488+
mDCAz_comb_C_Median.resize(nTotal);
489+
mDCAr_comb_C_RMS.resize(nTotal);
490+
mDCAz_comb_C_RMS.resize(nTotal);
491+
492+
const int nTotalVtx = nTotal / mTSTPC.getNBins();
493+
nPrimVertices.resize(nTotalVtx);
494+
nVertexContributors_Median.resize(nTotalVtx);
495+
nVertexContributors_RMS.resize(nTotalVtx);
496+
vertexX_Median.resize(nTotalVtx);
497+
vertexY_Median.resize(nTotalVtx);
498+
vertexZ_Median.resize(nTotalVtx);
499+
vertexX_RMS.resize(nTotalVtx);
500+
vertexY_RMS.resize(nTotalVtx);
501+
vertexZ_RMS.resize(nTotalVtx);
502+
}
503+
504+
ClassDefNV(TimeSeriesITSTPC, 2);
427505
};
428506

429507
} // end namespace tpc

0 commit comments

Comments
 (0)