65 TPCTimeSeries(std::shared_ptr<o2::base::GRPGeomRequest> req,
const bool disableWriter,
const o2::base::Propagator::MatCorrType matType,
const bool enableUnbinnedWriter,
const bool tpcOnly, std::shared_ptr<o2::globaltracking::DataRequest> dr) : mCCDBRequest(req), mDisableWriter(disableWriter), mMatType(matType), mUnbinnedWriter(enableUnbinnedWriter), mTPCOnly(tpcOnly), mDataRequest(dr) {};
70 mNMaxTracks = ic.options().get<
int>(
"max-tracks");
71 mMinMom = ic.options().get<
float>(
"min-momentum");
72 mMinNCl = ic.options().get<
int>(
"min-cluster");
73 mMaxTgl = ic.options().get<
float>(
"max-tgl");
74 mMaxQPt = ic.options().get<
float>(
"max-qPt");
75 mCoarseStep = ic.options().get<
float>(
"coarse-step");
76 mFineStep = ic.options().get<
float>(
"fine-step");
77 mCutDCA = ic.options().get<
float>(
"cut-DCA-median");
78 mCutRMS = ic.options().get<
float>(
"cut-DCA-RMS");
79 mRefXSec = ic.options().get<
float>(
"refX-for-sector");
80 mTglBins = ic.options().get<
int>(
"tgl-bins");
81 mPhiBins = ic.options().get<
int>(
"phi-bins");
82 mQPtBins = ic.options().get<
int>(
"qPt-bins");
83 mNThreads = ic.options().get<
int>(
"threads");
84 maxITSTPCDCAr = ic.options().get<
float>(
"max-ITS-TPC-DCAr");
85 maxITSTPCDCAz = ic.options().get<
float>(
"max-ITS-TPC-DCAz");
86 maxITSTPCDCAr_comb = ic.options().get<
float>(
"max-ITS-TPC-DCAr_comb");
87 maxITSTPCDCAz_comb = ic.options().get<
float>(
"max-ITS-TPC-DCAz_comb");
88 mTimeWindowMUS = ic.options().get<
float>(
"time-window-mult-mus");
89 mMIPdEdx = ic.options().get<
float>(
"MIP-dedx");
90 mMaxSnp = ic.options().get<
float>(
"max-snp");
91 mXCoarse = ic.options().get<
float>(
"mX-coarse");
92 mSqrt = ic.options().get<
float>(
"sqrts");
93 mMultBins = ic.options().get<
int>(
"mult-bins");
94 mMultMax = ic.options().get<
int>(
"mult-max");
95 mMinTracksPerVertex = ic.options().get<
int>(
"min-tracks-per-vertex");
96 mMaxdEdxRatio = ic.options().get<
float>(
"max-dedx-ratio");
97 mMaxdEdxRegionRatio = ic.options().get<
float>(
"max-dedx-region-ratio");
98 mSamplingFactor = ic.options().get<
float>(
"sampling-factor");
99 mSampleTsallis = ic.options().get<
bool>(
"sample-unbinned-tsallis");
100 mXOuterMatching = ic.options().get<
float>(
"refX-for-outer-ITS");
101 mUseMinBiasTrigger = !ic.options().get<
bool>(
"disable-min-bias-trigger");
102 mMaxOccupancyHistBins = ic.options().get<
int>(
"max-occupancy-bins");
104 if (mUnbinnedWriter) {
105 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
106 mGenerator.emplace_back(std::mt19937(std::random_device{}()));
109 mBufferVals.resize(mNThreads);
110 mBufferDCA.
setBinning(mPhiBins, mTglBins, mQPtBins, mMultBins, mMaxTgl, mMaxQPt, mMultMax);
111 if (mUnbinnedWriter) {
112 std::string outfile = ic.options().get<std::string>(
"out-file-unbinned");
114 ROOT::EnableThreadSafety();
116 mStreamer.resize(mNThreads);
117 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
118 std::string outfileThr = outfile;
119 outfileThr.replace(outfileThr.length() - 5, outfileThr.length(), fmt::format(
"_{}.root", iThread));
120 LOGP(info,
"Writing unbinned data to: {}", outfileThr);
121 mStreamer[iThread] = std::make_unique<o2::utils::TreeStreamRedirector>(outfileThr.data(),
"recreate");
133 LOGP(info,
"Updated reference drift velocity to: {}", mVDrift);
136 const int nBins = getNBins();
142 if (mAvgADCAr.size() != nBins) {
144 mAvgADCAr.resize(nBins);
145 mAvgCDCAr.resize(nBins);
146 mAvgADCAz.resize(nBins);
147 mAvgCDCAz.resize(nBins);
148 mAvgMeffA.resize(nBins);
149 mAvgMeffC.resize(nBins);
150 mAvgChi2MatchA.resize(nBins);
151 mAvgChi2MatchC.resize(nBins);
152 mMIPdEdxRatioQMaxA.resize(nBins);
153 mMIPdEdxRatioQMaxC.resize(nBins);
154 mMIPdEdxRatioQTotA.resize(nBins);
155 mMIPdEdxRatioQTotC.resize(nBins);
156 mTPCChi2A.resize(nBins);
157 mTPCChi2C.resize(nBins);
158 mTPCNClA.resize(nBins);
159 mTPCNClC.resize(nBins);
160 mLogdEdxQTotA.resize(nBins);
161 mLogdEdxQTotC.resize(nBins);
162 mLogdEdxQMaxA.resize(nBins);
163 mLogdEdxQMaxC.resize(nBins);
164 mITSPropertiesA.resize(nBins);
165 mITSPropertiesC.resize(nBins);
166 mITSTPCDeltaPA.resize(nBins);
167 mITSTPCDeltaPC.resize(nBins);
168 mSigmaYZA.resize(nBins);
169 mSigmaYZC.resize(nBins);
177 auto tracksITSTPC = mTPCOnly ? gsl::span<o2::dataformats::TrackTPCITS>() : recoData.
getTPCITSTracks();
178 auto tracksITS = mTPCOnly ? gsl::span<o2::its::TrackITS>() : recoData.
getITSTracks();
181 auto vertices = mTPCOnly ? gsl::span<o2::dataformats::PrimaryVertex>() : recoData.
getPrimaryVertices();
192 const auto& tofClusters = mTPCOnly ? gsl::span<o2::tof::Cluster>() : recoData.
getTOFClusters();
194 LOGP(info,
"Processing {} vertices, {} primary matched vertices, {} TPC tracks, {} ITS tracks, {} ITS-TPC tracks, {} TOF clusters", vertices.size(), primMatchedTracks.size(), tracksTPC.size(), tracksITS.size(), tracksITSTPC.size(), tofClusters.size());
197 auto indicesITSTPC_vtx = processVertices(vertices, primMatchedTracks, primMatchedTracksRef, recoData);
200 std::unordered_map<unsigned int, std::array<int, 2>> indicesITSTPC;
202 for (
int i = 0;
i < tracksITSTPC.size(); ++
i) {
203 auto it = indicesITSTPC_vtx.find(
i);
205 const auto idxVtx = (it != indicesITSTPC_vtx.end()) ? (it->second) : -1;
207 indicesITSTPC[tracksITSTPC[
i].getRefTPC().getIndex()] = {
i, idxVtx};
210 std::vector<std::tuple<int, float, float, o2::track::TrackLTIntegral, double, float, unsigned int>> idxTPCTrackToTOFCluster;
213 if (mUnbinnedWriter) {
217 idxTPCTrackToTOFCluster = std::vector<std::tuple<int, float, float, o2::track::TrackLTIntegral, double, float, unsigned int>>(tracksTPC.size(), {-1, -999, -999, defLT, 0, 0, 0});
222 std::map<ULong64_t, short> t0array;
223 for (
const auto&
t0 : ft0rec) {
224 if (!(
t0.isValidTime(1) &&
t0.isValidTime(2))) {
228 auto bclong =
t0.mIntRecord.differenceInBC(recoData.
startIR);
229 if (t0array.find(bclong) == t0array.end()) {
230 t0array.emplace(std::make_pair(bclong,
t0.getCollisionTime(0)));
237 for (
const auto& tofMatch : tofMatches) {
238 for (
const auto& tpctofmatch : tofMatch) {
240 if (refTPC.isIndexSet()) {
242 ULong64_t bclongtof = (tpctofmatch.getSignal() - 10000) * BC_TIME_INPS_INV;
244 unsigned int mask = 0;
245 if (!(t0array.find(bclongtof) == t0array.end())) {
246 t0 += t0array.find(bclongtof)->second;
250 double signal = tpctofmatch.getSignal() -
t0;
251 float deltaT = tpctofmatch.getDeltaT();
253 float dy = tpctofmatch.getDYatTOF();
254 bool isMultiHitZ = tpctofmatch.getHitPatternUpDown();
255 bool isMultiHitX = tpctofmatch.getHitPatternLeftRight();
256 bool isMultiStripMatch = tpctofmatch.getChi2() < 1E-9;
257 float chi2 = tpctofmatch.getChi2();
258 bool hasT0_1BCbefore = (t0array.find(bclongtof - 1) != t0array.end());
259 bool hasT0_2BCbefore = (t0array.find(bclongtof - 2) != t0array.end());
267 if (fabs(dy) > 0.5) {
270 if (isMultiStripMatch) {
282 if (hasT0_1BCbefore) {
285 if (hasT0_2BCbefore) {
289 idxTPCTrackToTOFCluster[refTPC] = {tpctofmatch.getIdxTOFCl(), tpctofmatch.getDXatTOF(), tpctofmatch.getDZatTOF(), ltIntegral, signal, deltaT,
mask};
296 findNearesVertex(tracksTPC, vertices);
299 if (mUnbinnedWriter) {
300 mTPCTrackClIdx = pc.inputs().get<gsl::span<o2::tpc::TPCClRefElem>>(
"trackTPCClRefs");
305 findNNeighbourTracks(tracksTPC);
308 for (
int i = 0;
i < nBins; ++
i) {
310 mAvgADCAr[
i][
type].clear();
311 mAvgCDCAr[
i][
type].clear();
312 mAvgADCAz[
i][
type].clear();
313 mAvgCDCAz[
i][
type].clear();
315 for (
int type = 0;
type < mMIPdEdxRatioQMaxA[
i].size(); ++
type) {
316 mMIPdEdxRatioQMaxA[
i][
type].clear();
317 mMIPdEdxRatioQMaxC[
i][
type].clear();
318 mMIPdEdxRatioQTotA[
i][
type].clear();
319 mMIPdEdxRatioQTotC[
i][
type].clear();
320 mTPCChi2A[
i][
type].clear();
321 mTPCChi2C[
i][
type].clear();
322 mTPCNClA[
i][
type].clear();
323 mTPCNClC[
i][
type].clear();
324 mMIPdEdxRatioQMaxA[
i][
type].setUseWeights(
false);
325 mMIPdEdxRatioQMaxC[
i][
type].setUseWeights(
false);
326 mMIPdEdxRatioQTotA[
i][
type].setUseWeights(
false);
327 mMIPdEdxRatioQTotC[
i][
type].setUseWeights(
false);
328 mTPCChi2A[
i][
type].setUseWeights(
false);
329 mTPCChi2C[
i][
type].setUseWeights(
false);
330 mTPCNClA[
i][
type].setUseWeights(
false);
331 mTPCNClC[
i][
type].setUseWeights(
false);
334 mLogdEdxQTotA[
i][
type].clear();
335 mLogdEdxQTotC[
i][
type].clear();
336 mLogdEdxQMaxA[
i][
type].clear();
337 mLogdEdxQMaxC[
i][
type].clear();
338 mLogdEdxQTotA[
i][
type].setUseWeights(
false);
339 mLogdEdxQTotC[
i][
type].setUseWeights(
false);
340 mLogdEdxQMaxA[
i][
type].setUseWeights(
false);
341 mLogdEdxQMaxC[
i][
type].setUseWeights(
false);
343 for (
int j = 0;
j < mITSPropertiesA[
i].size(); ++
j) {
344 mITSPropertiesA[
i][
j].clear();
345 mITSPropertiesC[
i][
j].clear();
346 mITSPropertiesA[
i][
j].setUseWeights(
false);
347 mITSPropertiesC[
i][
j].setUseWeights(
false);
350 for (
int j = 0;
j < mITSTPCDeltaPA[
i].size(); ++
j) {
351 mITSTPCDeltaPA[
i][
j].clear();
352 mITSTPCDeltaPC[
i][
j].clear();
353 mITSTPCDeltaPA[
i][
j].setUseWeights(
false);
354 mITSTPCDeltaPC[
i][
j].setUseWeights(
false);
357 for (
int j = 0;
j < mSigmaYZA[
i].size(); ++
j) {
358 mSigmaYZA[
i][
j].clear();
359 mSigmaYZC[
i][
j].clear();
360 mSigmaYZA[
i][
j].setUseWeights(
false);
361 mSigmaYZC[
i][
j].setUseWeights(
false);
364 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
365 mAvgMeffA[
i][
j].clear();
366 mAvgMeffC[
i][
j].clear();
367 mAvgChi2MatchA[
i][
j].clear();
368 mAvgChi2MatchC[
i][
j].clear();
369 mAvgMeffA[
i][
j].setUseWeights(
false);
370 mAvgMeffC[
i][
j].setUseWeights(
false);
371 mAvgChi2MatchA[
i][
j].setUseWeights(
false);
372 mAvgChi2MatchC[
i][
j].setUseWeights(
false);
376 for (
int i = 0;
i < mNThreads; ++
i) {
377 mBufferVals[
i].front().clear();
378 mBufferVals[
i].back().clear();
382 const auto nTracks = tracksTPC.size();
383 const size_t loopEnd = (mNMaxTracks < 0) ? nTracks : ((mNMaxTracks > nTracks) ? nTracks : size_t(mNMaxTracks));
386 for (
int i = 0;
i < nBins; ++
i) {
393 if (
i < lastIdxPhi) {
394 resMem = loopEnd / mPhiBins;
395 }
else if (
i < lastIdxTgl) {
396 resMem = loopEnd / mTglBins;
397 }
else if (
i < lastIdxQPt) {
398 resMem = loopEnd / mQPtBins;
399 }
else if (
i < lastIdxMult) {
400 resMem = loopEnd / mMultBins;
407 mAvgADCAr[
i][
type].reserve(resMem);
408 mAvgCDCAr[
i][
type].reserve(resMem);
409 mAvgADCAz[
i][
type].reserve(resMem);
410 mAvgCDCAz[
i][
type].reserve(resMem);
412 for (
int type = 0;
type < mMIPdEdxRatioQMaxA[
i].size(); ++
type) {
413 mMIPdEdxRatioQMaxA[
i][
type].reserve(resMem);
414 mMIPdEdxRatioQMaxC[
i][
type].reserve(resMem);
415 mMIPdEdxRatioQTotA[
i][
type].reserve(resMem);
416 mMIPdEdxRatioQTotC[
i][
type].reserve(resMem);
417 mTPCChi2A[
i][
type].reserve(resMem);
418 mTPCChi2C[
i][
type].reserve(resMem);
419 mTPCNClA[
i][
type].reserve(resMem);
420 mTPCNClC[
i][
type].reserve(resMem);
422 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
423 mAvgMeffA[
i][
j].reserve(resMem);
424 mAvgMeffC[
i][
j].reserve(resMem);
425 mAvgChi2MatchA[
i][
j].reserve(resMem);
426 mAvgChi2MatchC[
i][
j].reserve(resMem);
428 for (
int j = 0;
j < mITSPropertiesA[
i].size(); ++
j) {
429 mITSPropertiesA[
i][
j].reserve(resMem);
430 mITSPropertiesC[
i][
j].reserve(resMem);
432 for (
int j = 0;
j < mITSTPCDeltaPA[
i].size(); ++
j) {
433 mITSTPCDeltaPA[
i][
j].reserve(resMem);
434 mITSTPCDeltaPC[
i][
j].reserve(resMem);
436 for (
int j = 0;
j < mSigmaYZA[
i].size(); ++
j) {
437 mSigmaYZA[
i][
j].reserve(resMem);
438 mSigmaYZC[
i][
j].reserve(resMem);
440 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
441 mLogdEdxQTotA[
i][
j].reserve(resMem);
442 mLogdEdxQTotC[
i][
j].reserve(resMem);
443 mLogdEdxQMaxA[
i][
j].reserve(resMem);
444 mLogdEdxQMaxC[
i][
j].reserve(resMem);
447 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
448 const int resMem = (mNThreads > 0) ? loopEnd / mNThreads : loopEnd;
449 mBufferVals[iThread].front().reserve(loopEnd, 1);
450 mBufferVals[iThread].back().reserve(loopEnd, 0);
453 using timer = std::chrono::high_resolution_clock;
454 auto startTotal = timer::now();
457 if (loopEnd < nTracks) {
459 std::vector<size_t> ind(nTracks);
460 std::iota(ind.begin(), ind.end(), 0);
461 std::minstd_rand rng(std::time(
nullptr));
462 std::shuffle(ind.begin(), ind.end(), rng);
464 auto myThread = [&](
int iThread) {
465 for (
size_t i = iThread;
i < loopEnd;
i += mNThreads) {
466 if (acceptTrack(tracksTPC[
i])) {
467 fillDCA(tracksTPC, tracksITSTPC, vertices,
i, iThread, indicesITSTPC, tracksITS, idxTPCTrackToTOFCluster, tofClusters);
472 std::vector<std::thread> threads(mNThreads);
473 for (
int i = 0;
i < mNThreads;
i++) {
474 threads[
i] = std::thread(myThread,
i);
477 for (
auto& th : threads) {
481 auto myThread = [&](
int iThread) {
482 for (
size_t i = iThread;
i < loopEnd;
i += mNThreads) {
483 if (acceptTrack(tracksTPC[
i])) {
484 fillDCA(tracksTPC, tracksITSTPC, vertices,
i, iThread, indicesITSTPC, tracksITS, idxTPCTrackToTOFCluster, tofClusters);
489 std::vector<std::thread> threads(mNThreads);
490 for (
int i = 0;
i < mNThreads;
i++) {
491 threads[
i] = std::thread(myThread,
i);
494 for (
auto& th : threads) {
500 for (
const auto& vals : mBufferVals) {
503 const auto nPoints =
val.side.size();
504 for (
int i = 0;
i < nPoints; ++
i) {
505 const auto tglBin =
val.tglBin[
i];
506 const auto phiBin =
val.phiBin[
i];
507 const auto qPtBin =
val.qPtBin[
i];
508 const auto multBin =
val.multBin[
i];
509 const auto dcar =
val.dcar[
i];
510 const auto dcaz =
val.dcaz[
i];
511 const auto dcarW =
val.dcarW[
i];
512 const int binInt = nBins - 1;
513 const bool fillCombDCA = ((
type == 1) && (
val.dcarcomb[
i] != -1) && (
val.dcazcomb[
i] != -1));
514 const bool fillDCAR = (
type == 1) ? (dcar != -999) :
true;
515 const std::array<int, 5>
bins{tglBin, phiBin, qPtBin, multBin, binInt};
517 for (
auto bin :
bins) {
520 mAvgCDCAr[bin][
type].addValue(dcar, dcarW);
523 mAvgCDCAr[bin][2].addValue(
val.dcarcomb[
i], dcarW);
524 mAvgCDCAz[bin][2].addValue(
val.dcazcomb[
i], dcarW);
528 mAvgCDCAz[bin][
type].addValue(dcaz, dcarW);
532 mAvgADCAr[bin][
type].addValue(dcar, dcarW);
535 mAvgADCAr[bin][2].addValue(
val.dcarcomb[
i], dcarW);
536 mAvgADCAz[bin][2].addValue(
val.dcazcomb[
i], dcarW);
540 mAvgADCAz[bin][
type].addValue(dcaz, dcarW);
552 for (
int slice = 0; slice < nBins; ++slice) {
555 const auto dcaAr = mAvgADCAr[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
556 bufferDCA.mDCAr_A_Median[slice] = std::get<0>(dcaAr);
557 bufferDCA.mDCAr_A_WeightedMean[slice] = std::get<1>(dcaAr);
558 bufferDCA.mDCAr_A_RMS[slice] = std::get<2>(dcaAr);
559 bufferDCA.mDCAr_A_NTracks[slice] = std::get<3>(dcaAr);
561 const auto dcaAz = mAvgADCAz[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
562 bufferDCA.mDCAz_A_Median[slice] = std::get<0>(dcaAz);
563 bufferDCA.mDCAz_A_WeightedMean[slice] = std::get<1>(dcaAz);
564 bufferDCA.mDCAz_A_RMS[slice] = std::get<2>(dcaAz);
565 bufferDCA.mDCAz_A_NTracks[slice] = std::get<3>(dcaAz);
567 const auto dcaCr = mAvgCDCAr[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
568 bufferDCA.mDCAr_C_Median[slice] = std::get<0>(dcaCr);
569 bufferDCA.mDCAr_C_WeightedMean[slice] = std::get<1>(dcaCr);
570 bufferDCA.mDCAr_C_RMS[slice] = std::get<2>(dcaCr);
571 bufferDCA.mDCAr_C_NTracks[slice] = std::get<3>(dcaCr);
573 const auto dcaCz = mAvgCDCAz[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
574 bufferDCA.mDCAz_C_Median[slice] = std::get<0>(dcaCz);
575 bufferDCA.mDCAz_C_WeightedMean[slice] = std::get<1>(dcaCz);
576 bufferDCA.mDCAz_C_RMS[slice] = std::get<2>(dcaCz);
577 bufferDCA.mDCAz_C_NTracks[slice] = std::get<3>(dcaCz);
580 const auto dcaArComb = mAvgADCAr[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
584 const auto dcaAzCom = mAvgADCAz[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
588 const auto dcaCrComb = mAvgCDCAr[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
592 const auto dcaCzComb = mAvgCDCAz[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
600 for (
const auto& vals : mBufferVals) {
601 const auto&
val = vals.front();
602 const auto nPoints =
val.side.size();
603 for (
int i = 0;
i < nPoints; ++
i) {
604 const auto tglBin =
val.tglBin[
i];
605 const auto phiBin =
val.phiBin[
i];
606 const auto qPtBin =
val.qPtBin[
i];
607 const auto multBin =
val.multBin[
i];
608 const auto dcar =
val.dcar[
i];
609 const auto dcaz =
val.dcaz[
i];
610 const auto hasITS =
val.hasITS[
i];
611 const auto chi2Match =
val.chi2Match[
i];
612 const auto dedxRatioqMax =
val.dedxRatioqMax[
i];
613 const auto dedxRatioqTot =
val.dedxRatioqTot[
i];
614 const auto sqrtChi2TPC =
val.sqrtChi2TPC[
i];
615 const auto nClTPC =
val.nClTPC[
i];
616 const int binInt = nBins - 1;
623 auto& mAvgEff = isCSide ? mAvgMeffC : mAvgMeffA;
624 auto& mAvgChi2Match = isCSide ? mAvgChi2MatchC : mAvgChi2MatchA;
625 auto& mAvgmMIPdEdxRatioqMax = isCSide ? mMIPdEdxRatioQMaxC : mMIPdEdxRatioQMaxA;
626 auto& mAvgmMIPdEdxRatioqTot = isCSide ? mMIPdEdxRatioQTotC : mMIPdEdxRatioQTotA;
627 auto& mAvgmTPCChi2 = isCSide ? mTPCChi2C : mTPCChi2A;
628 auto& mAvgmTPCNCl = isCSide ? mTPCNClC : mTPCNClA;
629 auto& mAvgmdEdxRatioQMax = isCSide ? mLogdEdxQMaxC : mLogdEdxQMaxA;
630 auto& mAvgmdEdxRatioQTot = isCSide ? mLogdEdxQTotC : mLogdEdxQTotA;
631 auto& mITSProperties = isCSide ? mITSPropertiesC : mITSPropertiesA;
632 auto& mSigmaYZ = isCSide ? mSigmaYZC : mSigmaYZA;
633 auto& mITSTPCDeltaP = isCSide ? mITSTPCDeltaPC : mITSTPCDeltaPA;
635 const std::array<int, 5>
bins{tglBin, phiBin, qPtBin, multBin, binInt};
637 for (
auto bin :
bins) {
639 if ((std::abs(dcar - bufferDCAMedR[bin]) < (bufferDCARMSR[bin] * mCutRMS)) && (std::abs(dcaz - bufferDCAMedZ[bin]) < (bufferDCARMSZ[bin] * mCutRMS))) {
640 const auto gID =
val.gID[
i];
641 mAvgEff[bin][0].addValue(hasITS);
644 mAvgEff[bin][1].addValue(hasITS);
645 mAvgEff[bin][2].addValue(hasITS);
649 mAvgEff[bin][1].addValue(hasITS);
651 mAvgEff[bin][2].addValue(hasITS);
654 mAvgChi2Match[bin][0].addValue(chi2Match);
656 mAvgChi2Match[bin][1].addValue(chi2Match);
658 mAvgChi2Match[bin][2].addValue(chi2Match);
661 if (dedxRatioqMax > 0) {
662 mAvgmMIPdEdxRatioqMax[bin][0].addValue(dedxRatioqMax);
664 if (dedxRatioqTot > 0) {
665 mAvgmMIPdEdxRatioqTot[bin][0].addValue(dedxRatioqTot);
667 mAvgmTPCChi2[bin][0].addValue(sqrtChi2TPC);
668 mAvgmTPCNCl[bin][0].addValue(nClTPC);
670 if (dedxRatioqMax > 0) {
671 mAvgmMIPdEdxRatioqMax[bin][1].addValue(dedxRatioqMax);
673 if (dedxRatioqTot > 0) {
674 mAvgmMIPdEdxRatioqTot[bin][1].addValue(dedxRatioqTot);
676 mAvgmTPCChi2[bin][1].addValue(sqrtChi2TPC);
677 mAvgmTPCNCl[bin][1].addValue(nClTPC);
680 float dedxNormQMax =
val.dedxValsqMax[
i].dedxNorm;
681 if (dedxNormQMax > 0) {
682 mAvgmdEdxRatioQMax[bin][0].addValue(dedxNormQMax);
685 float dedxNormQTot =
val.dedxValsqTot[
i].dedxNorm;
686 if (dedxNormQTot > 0) {
687 mAvgmdEdxRatioQTot[bin][0].addValue(dedxNormQTot);
690 float dedxIROCQMax =
val.dedxValsqMax[
i].dedxIROC;
691 if (dedxIROCQMax > 0) {
692 mAvgmdEdxRatioQMax[bin][1].addValue(dedxIROCQMax);
695 float dedxIROCQTot =
val.dedxValsqTot[
i].dedxIROC;
696 if (dedxIROCQTot > 0) {
697 mAvgmdEdxRatioQTot[bin][1].addValue(dedxIROCQTot);
700 float dedxOROC1QMax =
val.dedxValsqMax[
i].dedxOROC1;
701 if (dedxOROC1QMax > 0) {
702 mAvgmdEdxRatioQMax[bin][2].addValue(dedxOROC1QMax);
705 float dedxOROC1QTot =
val.dedxValsqTot[
i].dedxOROC1;
706 if (dedxOROC1QTot > 0) {
707 mAvgmdEdxRatioQTot[bin][2].addValue(dedxOROC1QTot);
710 float dedxOROC2QMax =
val.dedxValsqMax[
i].dedxOROC2;
711 if (dedxOROC2QMax > 0) {
712 mAvgmdEdxRatioQMax[bin][3].addValue(dedxOROC2QMax);
715 float dedxOROC2QTot =
val.dedxValsqTot[
i].dedxOROC2;
716 if (dedxOROC2QTot > 0) {
717 mAvgmdEdxRatioQTot[bin][3].addValue(dedxOROC2QTot);
720 float dedxOROC3QMax =
val.dedxValsqMax[
i].dedxOROC3;
721 if (dedxOROC3QMax > 0) {
722 mAvgmdEdxRatioQMax[bin][4].addValue(dedxOROC3QMax);
725 float dedxOROC3QTot =
val.dedxValsqTot[
i].dedxOROC3;
726 if (dedxOROC3QTot > 0) {
727 mAvgmdEdxRatioQTot[bin][4].addValue(dedxOROC3QTot);
730 float nClITS =
val.nClITS[
i];
732 mITSProperties[bin][0].addValue(nClITS);
734 float chi2ITS =
val.chi2ITS[
i];
736 mITSProperties[bin][1].addValue(chi2ITS);
739 float sigmay2 =
val.sigmaY2[
i];
741 mSigmaYZ[bin][0].addValue(sigmay2);
743 float sigmaz2 =
val.sigmaZ2[
i];
745 mSigmaYZ[bin][1].addValue(sigmaz2);
748 float deltaP2 =
val.deltaP2[
i];
749 if (deltaP2 != -999) {
750 mITSTPCDeltaP[bin][0].addValue(deltaP2);
753 float deltaP3 =
val.deltaP3[
i];
754 if (deltaP3 != -999) {
755 mITSTPCDeltaP[bin][1].addValue(deltaP3);
758 float deltaP4 =
val.deltaP4[
i];
759 if (deltaP4 != -999) {
760 mITSTPCDeltaP[bin][2].addValue(deltaP4);
768 for (
int slice = 0; slice < nBins; ++slice) {
769 for (
int i = 0;
i < mAvgMeffA[slice].size(); ++
i) {
771 itsBuf.mITSTPC_A_MatchEff[slice] = mAvgMeffA[slice][
i].getMean();
772 itsBuf.mITSTPC_C_MatchEff[slice] = mAvgMeffC[slice][
i].getMean();
773 itsBuf.mITSTPC_A_Chi2Match[slice] = mAvgChi2MatchA[slice][
i].getMean();
774 itsBuf.mITSTPC_C_Chi2Match[slice] = mAvgChi2MatchC[slice][
i].getMean();
778 for (
int i = 0;
i < mMIPdEdxRatioQMaxC[slice].size(); ++
i) {
781 buff.mMIPdEdxRatioQMaxC[slice] = mMIPdEdxRatioQMaxC[slice][
i].getMean();
782 buff.mMIPdEdxRatioQTotA[slice] = mMIPdEdxRatioQTotA[slice][
i].getMean();
783 buff.mMIPdEdxRatioQTotC[slice] = mMIPdEdxRatioQTotC[slice][
i].getMean();
784 buff.mTPCChi2C[slice] = mTPCChi2C[slice][
i].getMean();
785 buff.mTPCChi2A[slice] = mTPCChi2A[slice][
i].getMean();
786 buff.mTPCNClC[slice] = mTPCNClC[slice][
i].getMean();
787 buff.mTPCNClA[slice] = mTPCNClA[slice][
i].getMean();
792 auto& logdEdxA = (
type == 0) ? mLogdEdxQMaxA : mLogdEdxQTotA;
796 buffer.mLogdEdx_A_RMS[slice] = logdEdxA[slice][0].getStdDev();
797 buffer.mLogdEdx_A_IROC_Median[slice] = logdEdxA[slice][1].getMedian();
798 buffer.mLogdEdx_A_IROC_RMS[slice] = logdEdxA[slice][1].getStdDev();
799 buffer.mLogdEdx_A_OROC1_Median[slice] = logdEdxA[slice][2].getMedian();
800 buffer.mLogdEdx_A_OROC1_RMS[slice] = logdEdxA[slice][2].getStdDev();
801 buffer.mLogdEdx_A_OROC2_Median[slice] = logdEdxA[slice][3].getMedian();
802 buffer.mLogdEdx_A_OROC2_RMS[slice] = logdEdxA[slice][3].getStdDev();
803 buffer.mLogdEdx_A_OROC3_Median[slice] = logdEdxA[slice][4].getMedian();
804 buffer.mLogdEdx_A_OROC3_RMS[slice] = logdEdxA[slice][4].getStdDev();
806 auto& logdEdxC = (
type == 0) ? mLogdEdxQMaxC : mLogdEdxQTotC;
807 buffer.mLogdEdx_C_Median[slice] = logdEdxC[slice][0].getMedian();
808 buffer.mLogdEdx_C_RMS[slice] = logdEdxC[slice][0].getStdDev();
809 buffer.mLogdEdx_C_IROC_Median[slice] = logdEdxC[slice][1].getMedian();
810 buffer.mLogdEdx_C_IROC_RMS[slice] = logdEdxC[slice][1].getStdDev();
811 buffer.mLogdEdx_C_OROC1_Median[slice] = logdEdxC[slice][2].getMedian();
812 buffer.mLogdEdx_C_OROC1_RMS[slice] = logdEdxC[slice][2].getStdDev();
813 buffer.mLogdEdx_C_OROC2_Median[slice] = logdEdxC[slice][3].getMedian();
814 buffer.mLogdEdx_C_OROC2_RMS[slice] = logdEdxC[slice][3].getStdDev();
815 buffer.mLogdEdx_C_OROC3_Median[slice] = logdEdxC[slice][4].getMedian();
816 buffer.mLogdEdx_C_OROC3_RMS[slice] = logdEdxC[slice][4].getStdDev();
822 mBufferDCA.
mITS_A_NCl_RMS[slice] = mITSPropertiesA[slice][0].getStdDev();
827 mBufferDCA.
mITS_C_NCl_RMS[slice] = mITSPropertiesC[slice][0].getStdDev();
854 auto stop = timer::now();
855 std::chrono::duration<float>
time = stop - startTotal;
856 LOGP(info,
"Time series creation took {}",
time.count());
864 for (
auto& streamer : mStreamer) {
867 eos.services().get<
ControlService>().readyToQuit(QuitRequest::Me);
887 void reserve(
int n,
int type)
897 dedxRatioqTot.reserve(
n);
898 dedxRatioqMax.reserve(
n);
899 sqrtChi2TPC.reserve(
n);
903 chi2Match.reserve(
n);
905 dedxValsqTot.reserve(
n);
906 dedxValsqMax.reserve(
n);
914 }
else if (
type == 0) {
932 dedxRatioqTot.clear();
933 dedxRatioqMax.clear();
941 dedxValsqTot.clear();
942 dedxValsqMax.clear();
950 void emplace_back(
Side sideTmp,
int tglBinTmp,
int phiBinTmp,
int qPtBinTmp,
int multBinTmp,
float dcarTmp,
float dcazTmp,
float dcarWTmp,
float dedxRatioqTotTmp,
float dedxRatioqMaxTmp,
float sqrtChi2TPCTmp,
float nClTPCTmp,
o2::dataformats::GlobalTrackID::Source gIDTmp,
float chi2MatchTmp,
int hasITSTmp,
int nClITSTmp,
float chi2ITSTmp,
const ValsdEdx& dedxValsqTotTmp,
const ValsdEdx& dedxValsqMaxTmp,
float sigmaY2Tmp,
float sigmaZ2Tmp)
952 side.emplace_back(sideTmp);
953 tglBin.emplace_back(tglBinTmp);
954 phiBin.emplace_back(phiBinTmp);
955 qPtBin.emplace_back(qPtBinTmp);
956 multBin.emplace_back(multBinTmp);
957 dcar.emplace_back(dcarTmp);
958 dcaz.emplace_back(dcazTmp);
959 dcarW.emplace_back(dcarWTmp);
960 dedxRatioqTot.emplace_back(dedxRatioqTotTmp);
961 dedxRatioqMax.emplace_back(dedxRatioqMaxTmp);
962 sqrtChi2TPC.emplace_back(sqrtChi2TPCTmp);
963 nClTPC.emplace_back(nClTPCTmp);
964 chi2Match.emplace_back(chi2MatchTmp);
965 hasITS.emplace_back(hasITSTmp);
966 gID.emplace_back(gIDTmp);
967 dedxValsqMax.emplace_back(dedxValsqMaxTmp);
968 dedxValsqTot.emplace_back(dedxValsqTotTmp);
969 nClITS.emplace_back(nClITSTmp);
970 chi2ITS.emplace_back(chi2ITSTmp);
971 sigmaY2.emplace_back(sigmaY2Tmp);
972 sigmaZ2.emplace_back(sigmaZ2Tmp);
973 deltaP2.emplace_back(-999);
974 deltaP3.emplace_back(-999);
975 deltaP4.emplace_back(-999);
978 void setDeltaParam(
float deltaP2Tmp,
float deltaP3Tmp,
float deltaP4Tmp)
980 if (!deltaP2.empty()) {
981 deltaP2.back() = deltaP2Tmp;
982 deltaP3.back() = deltaP3Tmp;
983 deltaP4.back() = deltaP4Tmp;
987 void emplace_back_ITSTPC(
Side sideTmp,
int tglBinTmp,
int phiBinTmp,
int qPtBinTmp,
int multBinTmp,
float dcarTmp,
float dcazTmp,
float dcarWTmp,
float dedxRatioqTotTmp,
float dedxRatioqMaxTmp,
float sqrtChi2TPCTmp,
float nClTPCTmp,
float dcarCombTmp,
float dcazCombTmp)
989 side.emplace_back(sideTmp);
990 tglBin.emplace_back(tglBinTmp);
991 phiBin.emplace_back(phiBinTmp);
992 qPtBin.emplace_back(qPtBinTmp);
993 multBin.emplace_back(multBinTmp);
994 dcar.emplace_back(dcarTmp);
995 dcaz.emplace_back(dcazTmp);
996 dcarW.emplace_back(dcarWTmp);
997 dedxRatioqTot.emplace_back(dedxRatioqTotTmp);
998 dedxRatioqMax.emplace_back(dedxRatioqMaxTmp);
999 sqrtChi2TPC.emplace_back(sqrtChi2TPCTmp);
1000 nClTPC.emplace_back(nClTPCTmp);
1001 dcarcomb.emplace_back(dcarCombTmp);
1002 dcazcomb.emplace_back(dcazCombTmp);
1005 std::vector<Side>
side;
1006 std::vector<int> tglBin;
1007 std::vector<int> phiBin;
1008 std::vector<int> qPtBin;
1009 std::vector<int> multBin;
1010 std::vector<float> dcar;
1011 std::vector<float> dcaz;
1012 std::vector<float> dcarW;
1013 std::vector<bool> hasITS;
1014 std::vector<float> chi2Match;
1015 std::vector<float> dedxRatioqTot;
1016 std::vector<float> dedxRatioqMax;
1017 std::vector<float> sqrtChi2TPC;
1018 std::vector<float> nClTPC;
1019 std::vector<float> dcarcomb;
1020 std::vector<float> dcazcomb;
1021 std::vector<ValsdEdx> dedxValsqTot;
1022 std::vector<ValsdEdx> dedxValsqMax;
1023 std::vector<int> nClITS;
1024 std::vector<float> chi2ITS;
1025 std::vector<o2::dataformats::GlobalTrackID::Source> gID;
1026 std::vector<float> deltaP2;
1027 std::vector<float> deltaP3;
1028 std::vector<float> deltaP4;
1029 std::vector<float> sigmaY2;
1030 std::vector<float> sigmaZ2;
1032 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
1033 const bool mDisableWriter{
false};
1035 const bool mUnbinnedWriter{
false};
1036 const bool mTPCOnly{
false};
1037 std::shared_ptr<o2::globaltracking::DataRequest> mDataRequest;
1041 TimeSeriesITSTPC mBufferDCA;
1042 std::vector<std::array<RobustAverage, 3>> mAvgADCAr;
1043 std::vector<std::array<RobustAverage, 3>> mAvgCDCAr;
1044 std::vector<std::array<RobustAverage, 3>> mAvgADCAz;
1045 std::vector<std::array<RobustAverage, 3>> mAvgCDCAz;
1046 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQMaxA;
1047 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQMaxC;
1048 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQTotA;
1049 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQTotC;
1050 std::vector<std::array<RobustAverage, 2>> mTPCChi2A;
1051 std::vector<std::array<RobustAverage, 2>> mTPCChi2C;
1052 std::vector<std::array<RobustAverage, 2>> mTPCNClA;
1053 std::vector<std::array<RobustAverage, 2>> mTPCNClC;
1054 std::vector<std::array<RobustAverage, 3>> mAvgMeffA;
1055 std::vector<std::array<RobustAverage, 3>> mAvgMeffC;
1056 std::vector<std::array<RobustAverage, 3>> mAvgChi2MatchA;
1057 std::vector<std::array<RobustAverage, 3>> mAvgChi2MatchC;
1058 std::vector<std::array<RobustAverage, 10>> mLogdEdxQTotA;
1059 std::vector<std::array<RobustAverage, 10>> mLogdEdxQTotC;
1060 std::vector<std::array<RobustAverage, 10>> mLogdEdxQMaxA;
1061 std::vector<std::array<RobustAverage, 10>> mLogdEdxQMaxC;
1062 std::vector<std::array<RobustAverage, 2>> mITSPropertiesA;
1063 std::vector<std::array<RobustAverage, 2>> mITSPropertiesC;
1064 std::vector<std::array<RobustAverage, 3>> mITSTPCDeltaPA;
1065 std::vector<std::array<RobustAverage, 3>> mITSTPCDeltaPC;
1066 std::vector<std::array<RobustAverage, 2>> mSigmaYZA;
1067 std::vector<std::array<RobustAverage, 2>> mSigmaYZC;
1068 int mNMaxTracks{-1};
1073 float mCoarseStep{1};
1074 float mFineStep{0.005};
1077 float mRefXSec{108.475};
1079 float maxITSTPCDCAr{0.2};
1080 float maxITSTPCDCAz{10};
1081 float maxITSTPCDCAr_comb{0.2};
1082 float maxITSTPCDCAz_comb{0.2};
1083 gsl::span<const TPCClRefElem> mTPCTrackClIdx{};
1084 std::vector<std::array<FillVals, 2>> mBufferVals;
1085 uint32_t mFirstTFOrbit{0};
1086 float mTimeWindowMUS{50};
1088 std::vector<int> mNTracksWindow;
1089 std::vector<int> mNearestVtxTPC;
1091 float mVDrift{2.64};
1092 float mMaxSnp{0.85};
1096 int mMultMax{80000};
1098 int mMinTracksPerVertex{5};
1099 float mMaxdEdxRatio{0.3};
1100 float mMaxdEdxRegionRatio{0.5};
1101 float mSamplingFactor{0.1};
1102 bool mSampleTsallis{
false};
1103 std::vector<std::mt19937> mGenerator;
1104 std::vector<std::unique_ptr<o2::utils::TreeStreamRedirector>> mStreamer;
1105 float mXOuterMatching{60};
1106 bool mUseMinBiasTrigger{
false};
1109 int mMaxOccupancyHistBins{912};
1112 bool acceptTrack(
const TrackTPC& track)
const {
return std::abs(track.getTgl()) < mMaxTgl; }
1114 bool checkTrack(
const TrackTPC& track)
const
1116 const bool isGoodTrack = ((track.getNClusters() < mMinNCl) || (track.getP() < mMinMom)) ? false :
true;
1120 void fillDCA(
const gsl::span<const TrackTPC> tracksTPC,
const gsl::span<const o2::dataformats::TrackTPCITS> tracksITSTPC,
const gsl::span<const o2::dataformats::PrimaryVertex> vertices,
const int iTrk,
const int iThread,
const std::unordered_map<
unsigned int, std::array<int, 2>>& indicesITSTPC,
const gsl::span<const o2::its::TrackITS> tracksITS,
const std::vector<std::tuple<int, float, float, o2::track::TrackLTIntegral, double, float, unsigned int>>& idxTPCTrackToTOFCluster,
const gsl::span<const o2::tof::Cluster> tofClusters)
1122 const auto& trackFull = tracksTPC[iTrk];
1123 const bool isGoodTrack = checkTrack(trackFull);
1126 bool minBiasOk =
false;
1127 const float factorMinBias = 0.1 * mSamplingFactor;
1128 if (mUnbinnedWriter && mUseMinBiasTrigger) {
1129 std::uniform_real_distribution<>
distr(0., 1.);
1130 if (
distr(mGenerator[iThread]) < factorMinBias) {
1136 if (!isGoodTrack && !minBiasOk) {
1150 if (!propagator->PropagateToXBxByBz(track, mXCoarse, mMaxSnp, mCoarseStep, mMatType)) {
1155 if (!propagator->propagateToDCA(refPoint, track, propagator->getNominalBz(), mFineStep, mMatType, &dca)) {
1162 if (!propagator->propagateTo(trackTmp, mRefXSec,
false, mMaxSnp, mCoarseStep, mMatType)) {
1166 const int tglBin = mTglBins * std::abs(trackTmp.getTgl()) / mMaxTgl + mPhiBins;
1169 const int offsQPtBin = mPhiBins + mTglBins;
1170 const int qPtBin = offsQPtBin + mQPtBins * (trackTmp.getQ2Pt() + mMaxQPt) / (2 * mMaxQPt);
1171 const int localMult = mNTracksWindow[iTrk];
1173 const int offsMult = offsQPtBin + mQPtBins;
1174 const int multBin = offsMult + mMultBins * localMult / mMultMax;
1175 const int nBins = getNBins();
1177 if ((phiBin < 0) || (phiBin > mPhiBins) || (tglBin < mPhiBins) || (tglBin > offsQPtBin) || (qPtBin < offsQPtBin) || (qPtBin > offsMult) || (multBin < offsMult) || (multBin > offsMult + mMultBins)) {
1185 auto it = indicesITSTPC.find(iTrk);
1186 const auto idxITSTPC = (it != indicesITSTPC.end()) ? (it->second) : std::array<int, 2>{-1, -1};
1189 const auto vertex = (idxITSTPC.back() != -1) ? vertices[idxITSTPC.back()] : ((mNearestVtxTPC[iTrk] != -1) ? vertices[mNearestVtxTPC[iTrk]] :
o2::dataformats::PrimaryVertex{});
1192 const float signSide = trackFull.hasCSideClustersOnly() ? -1 : 1;
1193 const float dcaZFromDeltaTime = (
vertex.getTimeStamp().getTimeStamp() == 0) ? 0 : (
o2::tpc::ParameterElectronics::Instance().ZbinWidth * trackFull.getTime0() -
vertex.
getTimeStamp().
getTimeStamp()) * mVDrift + signSide *
vertex.getZ();
1198 const float div = (resCl * track.getPt());
1203 const float fB = 0.2 / div;
1204 const float fA = 0.15 + 0.15;
1205 const float dcarW = 1. / std::sqrt(fA * fA + fB * fB);
1208 const bool hasITSTPC = idxITSTPC.front() != -1;
1211 const float chi2 = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getChi2Match() : -1;
1215 const auto src = tracksITSTPC[idxITSTPC.front()].getRefITS().getSource();
1223 const float chi2Match = (chi2 > 0) ? std::sqrt(chi2) : -1;
1224 const float sqrtChi2TPC = (trackFull.getChi2() > 0) ? std::sqrt(trackFull.getChi2()) : 0;
1225 const float nClTPC = trackFull.getNClusters();
1228 const float dedxRatioqTot = (trackFull.getdEdx().dEdxTotTPC > 0) ? (mMIPdEdx / trackFull.getdEdx().dEdxTotTPC) : -1;
1229 const float dedxRatioqMax = (trackFull.getdEdx().dEdxMaxTPC > 0) ? (mMIPdEdx / trackFull.getdEdx().dEdxMaxTPC) : -1;
1231 const auto dedxQTotVars = getdEdxVars(0, trackFull);
1232 const auto dedxQMaxVars = getdEdxVars(1, trackFull);
1236 const bool idxITSCheck = (idxITSTrack != -1);
1238 const int nClITS = idxITSCheck ? tracksITS[idxITSTrack].getNClusters() : -1;
1239 float chi2ITS = idxITSCheck ? tracksITS[idxITSTrack].getChi2() : -1;
1240 if ((chi2ITS > 0) && (nClITS > 0)) {
1241 chi2ITS = std::sqrt(chi2ITS / nClITS);
1243 sigmaY2 = track.getSigmaY2();
1244 sigmaZ2 = track.getSigmaZ2();
1246 if (trackFull.hasCSideClustersOnly()) {
1247 mBufferVals[iThread].front().emplace_back(
Side::C, tglBin, phiBin, qPtBin, multBin, dca[0], dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, gID, chi2Match, hasITSTPC, nClITS, chi2ITS, dedxQTotVars, dedxQMaxVars, sigmaY2, sigmaZ2);
1248 }
else if (trackFull.hasASideClustersOnly()) {
1249 mBufferVals[iThread].front().emplace_back(
Side::A, tglBin, phiBin, qPtBin, multBin, dca[0], dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, gID, chi2Match, hasITSTPC, nClITS, chi2ITS, dedxQTotVars, dedxQMaxVars, sigmaY2, sigmaZ2);
1256 float deltaP0 = -999;
1257 float deltaP1 = -999;
1258 float deltaP2 = -999;
1259 float deltaP3 = -999;
1260 float deltaP4 = -999;
1261 float phiITSTPCAtVertex = -999;
1262 float dcaTPCAtVertex = -999;
1265 auto trackITSTPCTmp = tracksITSTPC[idxITSTPC.front()];
1267 if (propagator->propagateToDCA(refPoint, trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPC)) {
1269 if ((std::abs(dcaITSTPC[0]) < maxITSTPCDCAr) && (std::abs(dcaITSTPC[1]) < maxITSTPCDCAz)) {
1272 const bool contributeToVertex = (idxITSTPC.back() != -1);
1275 if (contributeToVertex) {
1276 if (propagator->propagateToDCA(
vertex.getXYZ(), trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPCTmp)) {
1277 phiITSTPCAtVertex = trackITSTPCTmp.getPhi();
1278 dcaITSTPC = dcaITSTPCTmp;
1283 if (propagator->propagateToDCA(
vertex.getXYZ(), track, propagator->getNominalBz(), mFineStep, mMatType, &dcaTPCTmp)) {
1284 dcaTPCAtVertex = dcaTPCTmp[0];
1289 if ((std::abs(dcaITSTPCTmp[0]) < maxITSTPCDCAr_comb) && (std::abs(dcaITSTPCTmp[1]) < maxITSTPCDCAz_comb)) {
1291 if (idxITSTrack >= 0 && track.rotate(tracksITS[idxITSTrack].getAlpha()) && propagator->propagateTo(track, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1293 const bool propITSOk = propagator->propagateTo(trackITS, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType);
1295 deltaP0 = track.getParam(0) - trackITS.getParam(0);
1296 deltaP1 = track.getParam(1) - trackITS.getParam(1);
1297 deltaP2 = track.getParam(2) - trackITS.getParam(2);
1298 deltaP3 = track.getParam(3) - trackITS.getParam(3);
1299 deltaP4 = track.getParam(4) - trackITS.getParam(4);
1300 mBufferVals[iThread].front().setDeltaParam(deltaP2, deltaP3, deltaP4);
1304 dcaITSTPCTmp[0] = -1;
1305 dcaITSTPCTmp[1] = -1;
1309 if (trackFull.hasCSideClustersOnly()) {
1310 mBufferVals[iThread].back().emplace_back_ITSTPC(
Side::C, tglBin, phiBin, qPtBin, multBin, dcaTPCAtVertex, dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, dcaITSTPCTmp[0], dcaITSTPCTmp[1]);
1311 }
else if (trackFull.hasASideClustersOnly()) {
1312 mBufferVals[iThread].back().emplace_back_ITSTPC(
Side::A, tglBin, phiBin, qPtBin, multBin, dcaTPCAtVertex, dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, dcaITSTPCTmp[0], dcaITSTPCTmp[1]);
1319 if (mUnbinnedWriter && mStreamer[iThread]) {
1320 const float factorPt = mSamplingFactor;
1321 bool writeData =
true;
1323 if (mSampleTsallis) {
1324 std::uniform_real_distribution<>
distr(0., 1.);
1327 if (writeData || minBiasOk) {
1328 auto clusterMask = makeClusterBitMask(trackFull);
1329 const auto& trkOrig = tracksTPC[iTrk];
1330 const bool isNearestVtx = (idxITSTPC.back() == -1);
1331 const float mx_ITS = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getX() : -1;
1332 const float pt_ITS = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getQ2Pt() : -1;
1333 const float chi2match_ITSTPC = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getChi2Match() : -1;
1334 const int nClITS = idxITSCheck ? tracksITS[idxITSTrack].getNClusters() : -1;
1335 const int chi2ITS = idxITSCheck ? tracksITS[idxITSTrack].getChi2() : -1;
1337 if (trackFull.hasASideClustersOnly()) {
1339 }
else if (trackFull.hasCSideClustersOnly()) {
1344 bool hasTOFCluster = (std::get<0>(idxTPCTrackToTOFCluster[iTrk]) != -1);
1345 auto tofCl = hasTOFCluster ? tofClusters[std::get<0>(idxTPCTrackToTOFCluster[iTrk])] :
o2::tof::Cluster();
1347 float tpcYDeltaAtTOF = -999;
1348 float tpcZDeltaAtTOF = -999;
1349 if (hasTOFCluster) {
1351 if (trackTmpOut.rotate(
o2::math_utils::sector2Angle(tofCl.getSector())) && propagator->propagateTo(trackTmpOut, tofCl.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1352 tpcYDeltaAtTOF = trackTmpOut.getY() - tofCl.getY();
1358 float deltaTPCParamInOutTgl = trackFull.getTgl() - trackFull.getParamOut().getTgl();
1359 float deltaTPCParamInOutQPt = trackFull.getQ2Pt() - trackFull.getParamOut().getQ2Pt();
1362 float deltaP0OuterITS = -999;
1363 float deltaP1OuterITS = -999;
1364 float deltaP2OuterITS = -999;
1365 float deltaP3OuterITS = -999;
1366 float deltaP4OuterITS = -999;
1369 const bool propITSOk = propagator->propagateTo(trackTmpOut, mXOuterMatching,
false, mMaxSnp, mCoarseStep, mMatType);
1370 if (propITSOk && trackTmp.rotate(trackTmpOut.getAlpha())) {
1371 const bool propTPCOk = propagator->propagateTo(trackTmp, mXOuterMatching,
false, mMaxSnp, mCoarseStep, mMatType);
1374 deltaP0OuterITS = trackTmp.getParam(0) - trackTmpOut.getParam(0);
1375 deltaP1OuterITS = trackTmp.getParam(1) - trackTmpOut.getParam(2);
1376 deltaP2OuterITS = trackTmp.getParam(2) - trackTmpOut.getParam(2);
1377 deltaP3OuterITS = trackTmp.getParam(3) - trackTmpOut.getParam(3);
1378 deltaP4OuterITS = trackTmp.getParam(4) - trackTmpOut.getParam(4);
1382 const int triggerMask = 0x1 * minBiasOk + 0x2 * writeData;
1384 float deltaP2ConstrVtx = -999;
1385 float deltaP3ConstrVtx = -999;
1386 float deltaP4ConstrVtx = -999;
1389 float covTPCConstrVtxP2 = -999;
1390 float covTPCConstrVtxP3 = -999;
1391 float covTPCConstrVtxP4 = -999;
1394 float covITSTPCConstrVtxP2 = -999;
1395 float covITSTPCConstrVtxP3 = -999;
1396 float covITSTPCConstrVtxP4 = -999;
1398 float covTPCAtVertex0 = -999;
1399 float covTPCAtVertex1 = -999;
1401 const bool contributeToVertex = (idxITSTPC.back() != -1);
1402 if (hasITSTPC && contributeToVertex) {
1405 if (propagator->propagateToDCA(
vertex.getXYZ(), trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPCTmp)) {
1407 if (trackTPC.rotate(trackITSTPCTmp.getAlpha()) && propagator->propagateTo(trackTPC, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1409 covTPCAtVertex0 = trackTPC.getCovarElem(0, 0);
1410 covTPCAtVertex1 = trackTPC.getCovarElem(1, 1);
1413 deltaP2ConstrVtx = trackTPC.getParam(2) - trackITSTPCTmp.getParam(2);
1414 deltaP3ConstrVtx = trackTPC.getParam(3) - trackITSTPCTmp.getParam(3);
1415 deltaP4ConstrVtx = trackTPC.getParam(4) - trackITSTPCTmp.getParam(4);
1416 covTPCConstrVtxP2 = trackTPC.getCovarElem(2, 2);
1417 covTPCConstrVtxP3 = trackTPC.getCovarElem(3, 3);
1418 covTPCConstrVtxP4 = trackTPC.getCovarElem(4, 4);
1419 covITSTPCConstrVtxP2 = trackITSTPCTmp.getCovarElem(2, 2);
1420 covITSTPCConstrVtxP3 = trackITSTPCTmp.getCovarElem(3, 3);
1421 covITSTPCConstrVtxP4 = trackITSTPCTmp.getCovarElem(4, 4);
1425 double vertexTime =
vertex.getTimeStamp().getTimeStamp();
1426 double trackTime0 = trackFull.getTime0();
1427 *mStreamer[iThread] <<
"treeTimeSeries"
1429 <<
"triggerMask=" << triggerMask
1430 <<
"factorMinBias=" << factorMinBias
1431 <<
"factorPt=" << factorPt
1433 <<
"dcar_tpc_vertex=" << dcaTPCAtVertex
1434 <<
"dcar_tpc=" << dca[0]
1435 <<
"dcaz_tpc=" << dca[1]
1436 <<
"dcar_itstpc=" << dcaITSTPC[0]
1437 <<
"dcaz_itstpc=" << dcaITSTPC[1]
1438 <<
"dcarW=" << dcarW
1439 <<
"dcaZFromDeltaTime=" << dcaZFromDeltaTime
1440 <<
"hasITSTPC=" << hasITSTPC
1442 <<
"vertex_x=" <<
vertex.getX()
1443 <<
"vertex_y=" <<
vertex.getY()
1444 <<
"vertex_z=" <<
vertex.getZ()
1445 <<
"vertex_time=" <<
vertex.getTimeStamp().getTimeStamp()
1446 <<
"vertex_nContributors=" <<
vertex.getNContributors()
1447 <<
"isNearestVertex=" << isNearestVtx
1449 <<
"pt=" << trkOrig.getPt()
1450 <<
"qpt_ITSTPC=" << pt_ITS
1451 <<
"tpc_timebin=" << trkOrig.getTime0()
1452 <<
"qpt=" << trkOrig.getParam(4)
1453 <<
"ncl=" << trkOrig.getNClusters()
1454 <<
"ncl_shared=" << trkOrig.getNClusters()
1455 <<
"tgl=" << trkOrig.getTgl()
1456 <<
"side_type=" << typeSide
1457 <<
"phi=" << trkOrig.getPhi()
1458 <<
"clusterMask=" << clusterMask
1459 <<
"dedxTPC=" << trkOrig.getdEdx()
1460 <<
"chi2=" << trkOrig.getChi2()
1461 <<
"mX=" << trkOrig.getX()
1462 <<
"mX_ITS=" << mx_ITS
1463 <<
"nClITS=" << nClITS
1464 <<
"chi2ITS=" << chi2ITS
1465 <<
"chi2match_ITSTPC=" << chi2match_ITSTPC
1466 <<
"PID=" << trkOrig.getPID().getID()
1468 <<
"covTPCAtVertex0=" << covTPCAtVertex0
1469 <<
"covTPCAtVertex1=" << covTPCAtVertex1
1471 <<
"covTPCConstrVtxP2=" << covTPCConstrVtxP2
1472 <<
"covTPCConstrVtxP3=" << covTPCConstrVtxP3
1473 <<
"covTPCConstrVtxP4=" << covTPCConstrVtxP4
1475 <<
"covITSTPCConstrVtxP2=" << covITSTPCConstrVtxP2
1476 <<
"covITSTPCConstrVtxP3=" << covITSTPCConstrVtxP3
1477 <<
"covITSTPCConstrVtxP4=" << covITSTPCConstrVtxP4
1479 <<
"deltaP2ConstrVtx=" << deltaP2ConstrVtx
1480 <<
"deltaP3ConstrVtx=" << deltaP3ConstrVtx
1481 <<
"deltaP4ConstrVtx=" << deltaP4ConstrVtx
1483 <<
"deltaPar0=" << deltaP0
1484 <<
"deltaPar1=" << deltaP1
1485 <<
"deltaPar2=" << deltaP2
1486 <<
"deltaPar3=" << deltaP3
1487 <<
"deltaPar4=" << deltaP4
1488 <<
"sigmaY2=" << sigmaY2
1489 <<
"sigmaZ2=" << sigmaZ2
1491 <<
"mult=" << mNTracksWindow[iTrk]
1492 <<
"time_window_mult=" << mTimeWindowMUS
1493 <<
"firstTFOrbit=" << mFirstTFOrbit
1494 <<
"timeMS=" << mTimeMS
1496 <<
"mVDrift=" << mVDrift
1497 <<
"its_flag=" <<
int(gID)
1498 <<
"sqrtChi2Match=" << chi2Match
1500 <<
"tpcYDeltaAtTOF=" << tpcYDeltaAtTOF
1501 <<
"tpcZDeltaAtTOF=" << tpcZDeltaAtTOF
1502 <<
"mDXatTOF=" << std::get<1>(idxTPCTrackToTOFCluster[iTrk])
1503 <<
"mDZatTOF=" << std::get<2>(idxTPCTrackToTOFCluster[iTrk])
1504 <<
"mTOFLength=" << std::get<3>(idxTPCTrackToTOFCluster[iTrk])
1505 <<
"mTOFSignal=" << std::get<4>(idxTPCTrackToTOFCluster[iTrk])
1506 <<
"mDeltaTTOFTPC=" << std::get<5>(idxTPCTrackToTOFCluster[iTrk])
1507 <<
"vertexTime=" << vertexTime
1508 <<
"trackTime0=" << trackTime0
1509 <<
"TOFmask=" << std::get<6>(idxTPCTrackToTOFCluster[iTrk])
1511 <<
"deltaTPCParamInOutTgl=" << deltaTPCParamInOutTgl
1512 <<
"deltaTPCParamInOutQPt=" << deltaTPCParamInOutQPt
1514 <<
"deltaP0OuterITS=" << deltaP0OuterITS
1515 <<
"deltaP1OuterITS=" << deltaP1OuterITS
1516 <<
"deltaP2OuterITS=" << deltaP2OuterITS
1517 <<
"deltaP3OuterITS=" << deltaP3OuterITS
1518 <<
"deltaP4OuterITS=" << deltaP4OuterITS
1519 <<
"mXOuterMatching=" << mXOuterMatching
1521 <<
"phiITSTPCAtVertex=" << phiITSTPCAtVertex
1529 mBufferDCA.mTSTPC.setStartTime(mTimeMS);
1530 mBufferDCA.mTSITSTPC.setStartTime(mTimeMS);
1533 if (!mDisableWriter) {
1541 void findNearesVertex(
const gsl::span<const TrackTPC> tracksTPC,
const gsl::span<const o2::dataformats::PrimaryVertex> vertices)
1544 const int nVertices = vertices.size();
1546 const int nTracks = tracksTPC.size();
1547 mNearestVtxTPC.clear();
1548 mNearestVtxTPC.resize(nTracks);
1552 std::fill(mNearestVtxTPC.begin(), mNearestVtxTPC.end(), -1);
1557 std::vector<float> times_vtx;
1558 times_vtx.reserve(nVertices);
1559 for (
const auto& vtx : vertices) {
1560 times_vtx.emplace_back(vtx.getTimeStamp().getTimeStamp());
1564 auto myThread = [&](
int iThread) {
1565 for (
int i = iThread;
i < nTracks;
i += mNThreads) {
1567 const auto lower = std::lower_bound(times_vtx.begin(), times_vtx.end(), timeTrack);
1568 int closestVtx = std::distance(times_vtx.begin(), lower);
1570 if (closestVtx == nVertices) {
1572 }
else if (closestVtx > 0) {
1574 double diff1 = std::abs(timeTrack - *lower);
1575 double diff2 = std::abs(timeTrack - *(lower - 1));
1576 if (diff2 < diff1) {
1580 mNearestVtxTPC[
i] = closestVtx;
1584 std::vector<std::thread> threads(mNThreads);
1585 for (
int i = 0;
i < mNThreads;
i++) {
1586 threads[
i] = std::thread(myThread,
i);
1590 for (
auto& th : threads) {
1596 std::vector<bool> makeClusterBitMask(
const TrackTPC& track)
const
1599 const int nCl = track.getNClusterReferences();
1600 for (
int j = 0;
j < nCl; ++
j) {
1602 uint32_t clusterIndexInRow;
1603 track.getClusterReference(mTPCTrackClIdx,
j, sector,
padrow, clusterIndexInRow);
1604 tpcClusterMask[
padrow] =
true;
1606 return tpcClusterMask;
1610 void findNNeighbourTracks(
const gsl::span<const TrackTPC> tracksTPC)
1613 const float windowTimeBins = mTimeWindowMUS / tpcTBinMUS;
1616 std::vector<float>
times;
1617 const int nTracks = tracksTPC.size();
1618 times.reserve(nTracks);
1619 for (
const auto& trk : tracksTPC) {
1620 times.emplace_back(trk.getTime0());
1624 mNTracksWindow.clear();
1625 mNTracksWindow.resize(nTracks);
1628 auto myThread = [&](
int iThread) {
1629 for (
int i = iThread;
i < nTracks;
i += mNThreads) {
1630 const float t0 = tracksTPC[
i].getTime0();
1631 const auto upperV0 = std::upper_bound(
times.begin(),
times.end(),
t0 + windowTimeBins);
1632 const auto lowerV0 = std::lower_bound(
times.begin(),
times.end(),
t0 - windowTimeBins);
1633 const int nMult = std::distance(
times.begin(), upperV0) - std::distance(
times.begin(), lowerV0);
1634 mNTracksWindow[
i] = nMult;
1638 std::vector<std::thread> threads(mNThreads);
1639 for (
int i = 0;
i < mNThreads;
i++) {
1640 threads[
i] = std::thread(myThread,
i);
1644 for (
auto& th : threads) {
1649 std::unordered_map<unsigned int, int> processVertices(
const gsl::span<const o2::dataformats::PrimaryVertex> vertices,
const gsl::span<const o2::dataformats::VtxTrackIndex> primMatchedTracks,
const gsl::span<const o2::dataformats::VtxTrackRef> primMatchedTracksRef,
const RecoContainer& recoData)
1652 std::unordered_map<unsigned int, int> indicesITSTPC_vtx;
1654 std::unordered_map<int, int> nContributors_ITS;
1655 std::unordered_map<int, int> nContributors_ITSTPC;
1658 if (!vertices.empty()) {
1659 for (
const auto&
ref : primMatchedTracksRef) {
1661 const std::array<TrkSrc, 5>
sources = {TrkSrc::ITSTPC, TrkSrc::ITSTPCTRD, TrkSrc::ITSTPCTOF, TrkSrc::ITSTPCTRDTOF, TrkSrc::ITS};
1663 const int vID =
ref.getVtxID();
1664 const int firstEntry =
ref.getFirstEntryOfSource(
source);
1665 const int nEntries =
ref.getEntriesOfSource(
source);
1667 for (
int i = 0;
i < nEntries; ++
i) {
1668 const auto& matchedTrk = primMatchedTracks[
i + firstEntry];
1669 bool pvCont = matchedTrk.isPVContributor();
1673 if (refITSTPC.isIndexSet()) {
1674 indicesITSTPC_vtx[refITSTPC] = vID;
1675 ++nContributors_ITSTPC[vID];
1677 ++nContributors_ITS[vID];
1686 std::array<RobustAverage, 4> avgVtxITS;
1687 std::array<RobustAverage, 4> avgVtxITSTPC;
1688 for (
int i = 0;
i < avgVtxITS.size(); ++
i) {
1689 avgVtxITS[
i].reserve(vertices.size());
1690 avgVtxITSTPC[
i].reserve(vertices.size());
1692 for (
int ivtx = 0; ivtx < vertices.size(); ++ivtx) {
1693 const auto& vtx = vertices[ivtx];
1694 const float itsFrac = nContributors_ITS[ivtx] /
static_cast<float>(vtx.getNContributors());
1695 const float itstpcFrac = (nContributors_ITS[ivtx] + nContributors_ITSTPC[ivtx]) /
static_cast<float>(vtx.getNContributors());
1697 const float itsMin = 0.2;
1698 const float itsMax = 0.8;
1699 if ((itsFrac > itsMin) && (itsFrac < itsMax)) {
1700 avgVtxITS[0].addValue(vtx.getX());
1701 avgVtxITS[1].addValue(vtx.getY());
1702 avgVtxITS[2].addValue(vtx.getZ());
1703 avgVtxITS[3].addValue(vtx.getNContributors());
1706 const float itstpcMax = 0.95;
1707 if (itstpcFrac < itstpcMax) {
1708 avgVtxITSTPC[0].addValue(vtx.getX());
1709 avgVtxITSTPC[1].addValue(vtx.getY());
1710 avgVtxITSTPC[2].addValue(vtx.getZ());
1711 avgVtxITSTPC[3].addValue(vtx.getNContributors());
1716 mBufferDCA.nPrimVertices_ITS.front() = avgVtxITS[3].getValues().size();
1717 mBufferDCA.nVertexContributors_ITS_Median.front() = avgVtxITS[3].getMedian();
1718 mBufferDCA.nVertexContributors_ITS_RMS.front() = avgVtxITS[3].getStdDev();
1719 mBufferDCA.vertexX_ITS_Median.front() = avgVtxITS[0].getMedian();
1720 mBufferDCA.vertexY_ITS_Median.front() = avgVtxITS[1].getMedian();
1721 mBufferDCA.vertexZ_ITS_Median.front() = avgVtxITS[2].getMedian();
1722 mBufferDCA.vertexX_ITS_RMS.front() = avgVtxITS[0].getStdDev();
1723 mBufferDCA.vertexY_ITS_RMS.front() = avgVtxITS[1].getStdDev();
1724 mBufferDCA.vertexZ_ITS_RMS.front() = avgVtxITS[2].getStdDev();
1727 mBufferDCA.nPrimVertices_ITSTPC.front() = avgVtxITSTPC[3].getValues().size();
1728 mBufferDCA.nVertexContributors_ITSTPC_Median.front() = avgVtxITSTPC[3].getMedian();
1729 mBufferDCA.nVertexContributors_ITSTPC_RMS.front() = avgVtxITSTPC[3].getStdDev();
1730 mBufferDCA.vertexX_ITSTPC_Median.front() = avgVtxITSTPC[0].getMedian();
1731 mBufferDCA.vertexY_ITSTPC_Median.front() = avgVtxITSTPC[1].getMedian();
1732 mBufferDCA.vertexZ_ITSTPC_Median.front() = avgVtxITSTPC[2].getMedian();
1733 mBufferDCA.vertexX_ITSTPC_RMS.front() = avgVtxITSTPC[0].getStdDev();
1734 mBufferDCA.vertexY_ITSTPC_RMS.front() = avgVtxITSTPC[1].getStdDev();
1735 mBufferDCA.vertexZ_ITSTPC_RMS.front() = avgVtxITSTPC[2].getStdDev();
1738 RobustAverage avg(vertices.size(),
false);
1739 for (
const auto& vtx : vertices) {
1740 if (vtx.getNContributors() > mMinTracksPerVertex) {
1742 avg.addValue(std::sqrt(vtx.getNContributors()));
1747 int sizeQ = mBufferDCA.nVertexContributors_Quantiles.size();
1748 const int nBinsQ = 20;
1749 if (sizeQ >= (nBinsQ + 3)) {
1750 for (
int iq = 0; iq < nBinsQ; ++iq) {
1751 const float quantile = (iq + 1) /
static_cast<float>(nBinsQ);
1752 const float val = avg.getQuantile(quantile, 1);
1753 mBufferDCA.nVertexContributors_Quantiles[iq] =
val *
val;
1755 const float tr0 = avg.getTrunctedMean(0.05, 0.95);
1756 const float tr1 = avg.getTrunctedMean(0.1, 0.9);
1757 const float tr2 = avg.getTrunctedMean(0.2, 0.8);
1758 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 3] = tr0 * tr0;
1759 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 2] = tr1 * tr1;
1760 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 1] = tr2 * tr2;
1762 mBufferDCA.nPrimVertices.front() = vertices.size();
1764 return indicesITSTPC_vtx;
1768 int getNBins()
const {
return mBufferDCA.mTSTPC.getNBins(); }
1770 ValsdEdx getdEdxVars(
bool useQMax,
const TrackTPC& track)
const
1772 const float dedx = useQMax ? track.getdEdx().dEdxMaxTPC : track.getdEdx().dEdxTotTPC;
1776 if (std::abs(dedxNorm) > mMaxdEdxRatio) {
1781 float dedxIROC = -1;
1782 float dedxOROC1 = -1;
1783 float dedxOROC2 = -1;
1784 float dedxOROC3 = -1;
1786 dedxIROC = useQMax ? track.getdEdx().dEdxMaxIROC : track.getdEdx().dEdxTotIROC;
1787 dedxOROC1 = useQMax ? track.getdEdx().dEdxMaxOROC1 : track.getdEdx().dEdxTotOROC1;
1788 dedxOROC2 = useQMax ? track.getdEdx().dEdxMaxOROC2 : track.getdEdx().dEdxTotOROC2;
1789 dedxOROC3 = useQMax ? track.getdEdx().dEdxMaxOROC3 : track.getdEdx().dEdxTotOROC3;
1794 dedxIROC = (dedxIROC > 0) ? std::log(dedxIROC) : -1;
1795 dedxOROC1 = (dedxOROC1 > 0) ? std::log(dedxOROC1) : -1;
1796 dedxOROC2 = (dedxOROC2 > 0) ? std::log(dedxOROC2) : -1;
1797 dedxOROC3 = (dedxOROC3 > 0) ? std::log(dedxOROC3) : -1;
1800 if (std::abs(dedxIROC) > mMaxdEdxRegionRatio) {
1803 if (std::abs(dedxOROC1) > mMaxdEdxRegionRatio) {
1806 if (std::abs(dedxOROC2) > mMaxdEdxRegionRatio) {
1809 if (std::abs(dedxOROC3) > mMaxdEdxRegionRatio) {
1813 return ValsdEdx{dedxNorm, dedxIROC, dedxOROC1, dedxOROC2, dedxOROC3};