77 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) {};
82 mNMaxTracks = ic.options().get<
int>(
"max-tracks");
83 mMinMom = ic.options().get<
float>(
"min-momentum");
84 mMinNCl = ic.options().get<
int>(
"min-cluster");
85 mMaxTgl = ic.options().get<
float>(
"max-tgl");
86 mMaxQPt = ic.options().get<
float>(
"max-qPt");
87 mCoarseStep = ic.options().get<
float>(
"coarse-step");
88 mFineStep = ic.options().get<
float>(
"fine-step");
89 mCutDCA = ic.options().get<
float>(
"cut-DCA-median");
90 mCutRMS = ic.options().get<
float>(
"cut-DCA-RMS");
91 mRefXSec = ic.options().get<
float>(
"refX-for-sector");
92 mTglBins = ic.options().get<
int>(
"tgl-bins");
93 mPhiBins = ic.options().get<
int>(
"phi-bins");
94 mQPtBins = ic.options().get<
int>(
"qPt-bins");
95 mNThreads = ic.options().get<
int>(
"threads");
96 maxITSTPCDCAr = ic.options().get<
float>(
"max-ITS-TPC-DCAr");
97 maxITSTPCDCAz = ic.options().get<
float>(
"max-ITS-TPC-DCAz");
98 maxITSTPCDCAr_comb = ic.options().get<
float>(
"max-ITS-TPC-DCAr_comb");
99 maxITSTPCDCAz_comb = ic.options().get<
float>(
"max-ITS-TPC-DCAz_comb");
100 mTimeWindowMUS = ic.options().get<
float>(
"time-window-mult-mus");
101 mMIPdEdx = ic.options().get<
float>(
"MIP-dedx");
102 mMaxSnp = ic.options().get<
float>(
"max-snp");
103 mXCoarse = ic.options().get<
float>(
"mX-coarse");
104 mSqrt = ic.options().get<
float>(
"sqrts");
105 mMultBins = ic.options().get<
int>(
"mult-bins");
106 mMultMax = ic.options().get<
int>(
"mult-max");
107 mMinTracksPerVertex = ic.options().get<
int>(
"min-tracks-per-vertex");
108 mMaxdEdxRatio = ic.options().get<
float>(
"max-dedx-ratio");
109 mMaxdEdxRegionRatio = ic.options().get<
float>(
"max-dedx-region-ratio");
110 mSamplingFactor = ic.options().get<
float>(
"sampling-factor");
111 mSampleTsallis = ic.options().get<
bool>(
"sample-unbinned-tsallis");
112 mXOuterMatching = ic.options().get<
float>(
"refX-for-outer-ITS");
113 mUseMinBiasTrigger = !ic.options().get<
bool>(
"disable-min-bias-trigger");
114 mMaxOccupancyHistBins = ic.options().get<
int>(
"max-occupancy-bins");
116 if (mUnbinnedWriter) {
117 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
118 mGenerator.emplace_back(std::mt19937(std::random_device{}()));
121 mBufferVals.resize(mNThreads);
122 mBufferDCA.
setBinning(mPhiBins, mTglBins, mQPtBins, mMultBins, mMaxTgl, mMaxQPt, mMultMax);
123 if (mUnbinnedWriter) {
124 std::string outfile = ic.options().get<std::string>(
"out-file-unbinned");
126 ROOT::EnableThreadSafety();
128 mStreamer.resize(mNThreads);
129 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
130 std::string outfileThr = outfile;
131 outfileThr.replace(outfileThr.length() - 5, outfileThr.length(), fmt::format(
"_{}.root", iThread));
132 LOGP(info,
"Writing unbinned data to: {}", outfileThr);
133 mStreamer[iThread] = std::make_unique<o2::utils::TreeStreamRedirector>(outfileThr.data(),
"recreate");
146 LOGP(info,
"Updated reference drift velocity to: {}", mVDrift);
148 pc.inputs().get<TTree*>(
"tpcSecFlucInfo");
151 const int nBins = getNBins();
160 if (mAvgADCAr.size() != nBins) {
162 mAvgADCAr.resize(nBins);
163 mAvgCDCAr.resize(nBins);
164 mAvgADCAz.resize(nBins);
165 mAvgCDCAz.resize(nBins);
166 mAvgMeffA.resize(nBins);
167 mAvgMeffC.resize(nBins);
168 mAvgChi2MatchA.resize(nBins);
169 mAvgChi2MatchC.resize(nBins);
170 mMIPdEdxRatioQMaxA.resize(nBins);
171 mMIPdEdxRatioQMaxC.resize(nBins);
172 mMIPdEdxRatioQTotA.resize(nBins);
173 mMIPdEdxRatioQTotC.resize(nBins);
174 mTPCChi2A.resize(nBins);
175 mTPCChi2C.resize(nBins);
176 mTPCNClA.resize(nBins);
177 mTPCNClC.resize(nBins);
178 mLogdEdxQTotA.resize(nBins);
179 mLogdEdxQTotC.resize(nBins);
180 mLogdEdxQMaxA.resize(nBins);
181 mLogdEdxQMaxC.resize(nBins);
182 mITSPropertiesA.resize(nBins);
183 mITSPropertiesC.resize(nBins);
184 mITSTPCDeltaPA.resize(nBins);
185 mITSTPCDeltaPC.resize(nBins);
186 mSigmaYZA.resize(nBins);
187 mSigmaYZC.resize(nBins);
195 auto tracksITSTPC = mTPCOnly ? gsl::span<o2::dataformats::TrackTPCITS>() : recoData.
getTPCITSTracks();
196 auto tracksITS = mTPCOnly ? gsl::span<o2::its::TrackITS>() : recoData.
getITSTracks();
199 auto vertices = mTPCOnly ? gsl::span<o2::dataformats::PrimaryVertex>() : recoData.
getPrimaryVertices();
210 const auto& tofClusters = mTPCOnly ? gsl::span<o2::tof::Cluster>() : recoData.
getTOFClusters();
212 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());
215 auto indicesITSTPC_vtx = processVertices(vertices, primMatchedTracks, primMatchedTracksRef, recoData);
218 std::unordered_map<unsigned int, std::array<int, 2>> indicesITSTPC;
220 for (
int i = 0;
i < tracksITSTPC.size(); ++
i) {
221 auto it = indicesITSTPC_vtx.find(
i);
223 const auto idxVtx = (it != indicesITSTPC_vtx.end()) ? (it->second) : -1;
225 indicesITSTPC[tracksITSTPC[
i].getRefTPC().getIndex()] = {
i, idxVtx};
228 std::vector<std::tuple<int, float, float, o2::track::TrackLTIntegral, double, float, unsigned int, unsigned short>> idxTPCTrackToTOFCluster;
231 if (mUnbinnedWriter) {
235 idxTPCTrackToTOFCluster = std::vector<std::tuple<int, float, float, o2::track::TrackLTIntegral, double, float, unsigned int, unsigned short>>(tracksTPC.size(), {-1, -999, -999, defLT, 0, 0, 0, 0});
240 std::map<ULong64_t, short> t0array;
241 for (
const auto&
t0 : ft0rec) {
242 if (!(
t0.isValidTime(1) &&
t0.isValidTime(2))) {
246 auto bclong =
t0.mIntRecord.differenceInBC(recoData.
startIR);
247 if (t0array.find(bclong) == t0array.end()) {
248 t0array.emplace(std::make_pair(bclong,
t0.getCollisionTime(0)));
255 for (
const auto& tofMatch : tofMatches) {
256 for (
const auto& tpctofmatch : tofMatch) {
258 if (refTPC.isIndexSet()) {
260 ULong64_t bclongtof = (tpctofmatch.getSignal() - 10000) * BC_TIME_INPS_INV;
262 unsigned int mask = 0;
263 if (!(t0array.find(bclongtof) == t0array.end())) {
264 t0 += t0array.find(bclongtof)->second;
268 double signal = tpctofmatch.getSignal() -
t0;
269 float deltaT = tpctofmatch.getDeltaT();
271 float dy = tpctofmatch.getDYatTOF();
272 bool isMultiHitZ = tpctofmatch.getHitPatternUpDown();
273 bool isMultiHitX = tpctofmatch.getHitPatternLeftRight();
274 bool isMultiStripMatch = tpctofmatch.getChi2() < 1E-9;
275 float chi2 = tpctofmatch.getChi2();
276 bool hasT0_1BCbefore = (t0array.find(bclongtof - 1) != t0array.end());
277 bool hasT0_2BCbefore = (t0array.find(bclongtof - 2) != t0array.end());
285 if (fabs(dy) > 0.5) {
288 if (isMultiStripMatch) {
300 if (hasT0_1BCbefore) {
303 if (hasT0_2BCbefore) {
307 idxTPCTrackToTOFCluster[refTPC] = {tpctofmatch.getIdxTOFCl(), tpctofmatch.getDXatTOF(), tpctofmatch.getDZatTOF(), ltIntegral, signal, deltaT,
mask, tpctofmatch.getChannel() % 8736};
314 findNearesVertex(tracksTPC, vertices);
318 std::unordered_map<unsigned int, TRDTrackletData> tpcToTRDMap;
319 auto trdTracklets = (mTPCOnly || !recoData.
inputsTRD) ? gsl::span<const o2::trd::Tracklet64>() : recoData.
getTRDTracklets();
321 if (mUnbinnedWriter && !mTPCOnly) {
324 for (
unsigned int ig = 0; ig < itstpctrdTracks.size(); ++ig) {
327 if (!refTPC.isIndexSet()) {
331 if (!refTRD.isIndexSet()) {
336 for (
int iLay = 0; iLay < 6; ++iLay) {
337 auto trkltId = trdTrack.getTrackletIndex(iLay);
340 trdData.nTRDTracklets++;
341 trdData.trackletIndices[iLay] = trkltId;
344 tpcToTRDMap[refTPC] = trdData;
349 if (mUnbinnedWriter) {
350 mTPCTrackClIdx = pc.inputs().get<gsl::span<o2::tpc::TPCClRefElem>>(
"trackTPCClRefs");
355 findNNeighbourTracks(tracksTPC);
358 for (
int i = 0;
i < nBins; ++
i) {
360 mAvgADCAr[
i][
type].clear();
361 mAvgCDCAr[
i][
type].clear();
362 mAvgADCAz[
i][
type].clear();
363 mAvgCDCAz[
i][
type].clear();
365 for (
int type = 0;
type < mMIPdEdxRatioQMaxA[
i].size(); ++
type) {
366 mMIPdEdxRatioQMaxA[
i][
type].clear();
367 mMIPdEdxRatioQMaxC[
i][
type].clear();
368 mMIPdEdxRatioQTotA[
i][
type].clear();
369 mMIPdEdxRatioQTotC[
i][
type].clear();
370 mTPCChi2A[
i][
type].clear();
371 mTPCChi2C[
i][
type].clear();
372 mTPCNClA[
i][
type].clear();
373 mTPCNClC[
i][
type].clear();
374 mMIPdEdxRatioQMaxA[
i][
type].setUseWeights(
false);
375 mMIPdEdxRatioQMaxC[
i][
type].setUseWeights(
false);
376 mMIPdEdxRatioQTotA[
i][
type].setUseWeights(
false);
377 mMIPdEdxRatioQTotC[
i][
type].setUseWeights(
false);
378 mTPCChi2A[
i][
type].setUseWeights(
false);
379 mTPCChi2C[
i][
type].setUseWeights(
false);
380 mTPCNClA[
i][
type].setUseWeights(
false);
381 mTPCNClC[
i][
type].setUseWeights(
false);
384 mLogdEdxQTotA[
i][
type].clear();
385 mLogdEdxQTotC[
i][
type].clear();
386 mLogdEdxQMaxA[
i][
type].clear();
387 mLogdEdxQMaxC[
i][
type].clear();
388 mLogdEdxQTotA[
i][
type].setUseWeights(
false);
389 mLogdEdxQTotC[
i][
type].setUseWeights(
false);
390 mLogdEdxQMaxA[
i][
type].setUseWeights(
false);
391 mLogdEdxQMaxC[
i][
type].setUseWeights(
false);
393 for (
int j = 0;
j < mITSPropertiesA[
i].size(); ++
j) {
394 mITSPropertiesA[
i][
j].clear();
395 mITSPropertiesC[
i][
j].clear();
396 mITSPropertiesA[
i][
j].setUseWeights(
false);
397 mITSPropertiesC[
i][
j].setUseWeights(
false);
400 for (
int j = 0;
j < mITSTPCDeltaPA[
i].size(); ++
j) {
401 mITSTPCDeltaPA[
i][
j].clear();
402 mITSTPCDeltaPC[
i][
j].clear();
403 mITSTPCDeltaPA[
i][
j].setUseWeights(
false);
404 mITSTPCDeltaPC[
i][
j].setUseWeights(
false);
407 for (
int j = 0;
j < mSigmaYZA[
i].size(); ++
j) {
408 mSigmaYZA[
i][
j].clear();
409 mSigmaYZC[
i][
j].clear();
410 mSigmaYZA[
i][
j].setUseWeights(
false);
411 mSigmaYZC[
i][
j].setUseWeights(
false);
414 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
415 mAvgMeffA[
i][
j].clear();
416 mAvgMeffC[
i][
j].clear();
417 mAvgChi2MatchA[
i][
j].clear();
418 mAvgChi2MatchC[
i][
j].clear();
419 mAvgMeffA[
i][
j].setUseWeights(
false);
420 mAvgMeffC[
i][
j].setUseWeights(
false);
421 mAvgChi2MatchA[
i][
j].setUseWeights(
false);
422 mAvgChi2MatchC[
i][
j].setUseWeights(
false);
426 for (
int i = 0;
i < mNThreads; ++
i) {
427 mBufferVals[
i].front().clear();
428 mBufferVals[
i].back().clear();
432 const auto nTracks = tracksTPC.size();
433 const size_t loopEnd = (mNMaxTracks < 0) ? nTracks : ((mNMaxTracks > nTracks) ? nTracks : size_t(mNMaxTracks));
436 for (
int i = 0;
i < nBins; ++
i) {
443 if (
i < lastIdxPhi) {
444 resMem = loopEnd / mPhiBins;
445 }
else if (
i < lastIdxTgl) {
446 resMem = loopEnd / mTglBins;
447 }
else if (
i < lastIdxQPt) {
448 resMem = loopEnd / mQPtBins;
449 }
else if (
i < lastIdxMult) {
450 resMem = loopEnd / mMultBins;
457 mAvgADCAr[
i][
type].reserve(resMem);
458 mAvgCDCAr[
i][
type].reserve(resMem);
459 mAvgADCAz[
i][
type].reserve(resMem);
460 mAvgCDCAz[
i][
type].reserve(resMem);
462 for (
int type = 0;
type < mMIPdEdxRatioQMaxA[
i].size(); ++
type) {
463 mMIPdEdxRatioQMaxA[
i][
type].reserve(resMem);
464 mMIPdEdxRatioQMaxC[
i][
type].reserve(resMem);
465 mMIPdEdxRatioQTotA[
i][
type].reserve(resMem);
466 mMIPdEdxRatioQTotC[
i][
type].reserve(resMem);
467 mTPCChi2A[
i][
type].reserve(resMem);
468 mTPCChi2C[
i][
type].reserve(resMem);
469 mTPCNClA[
i][
type].reserve(resMem);
470 mTPCNClC[
i][
type].reserve(resMem);
472 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
473 mAvgMeffA[
i][
j].reserve(resMem);
474 mAvgMeffC[
i][
j].reserve(resMem);
475 mAvgChi2MatchA[
i][
j].reserve(resMem);
476 mAvgChi2MatchC[
i][
j].reserve(resMem);
478 for (
int j = 0;
j < mITSPropertiesA[
i].size(); ++
j) {
479 mITSPropertiesA[
i][
j].reserve(resMem);
480 mITSPropertiesC[
i][
j].reserve(resMem);
482 for (
int j = 0;
j < mITSTPCDeltaPA[
i].size(); ++
j) {
483 mITSTPCDeltaPA[
i][
j].reserve(resMem);
484 mITSTPCDeltaPC[
i][
j].reserve(resMem);
486 for (
int j = 0;
j < mSigmaYZA[
i].size(); ++
j) {
487 mSigmaYZA[
i][
j].reserve(resMem);
488 mSigmaYZC[
i][
j].reserve(resMem);
490 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
491 mLogdEdxQTotA[
i][
j].reserve(resMem);
492 mLogdEdxQTotC[
i][
j].reserve(resMem);
493 mLogdEdxQMaxA[
i][
j].reserve(resMem);
494 mLogdEdxQMaxC[
i][
j].reserve(resMem);
497 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
498 const int resMem = (mNThreads > 0) ? loopEnd / mNThreads : loopEnd;
499 mBufferVals[iThread].front().reserve(loopEnd, 1);
500 mBufferVals[iThread].back().reserve(loopEnd, 0);
503 using timer = std::chrono::high_resolution_clock;
504 auto startTotal = timer::now();
507 if (loopEnd < nTracks) {
509 std::vector<size_t> ind(nTracks);
510 std::iota(ind.begin(), ind.end(), 0);
511 std::minstd_rand rng(std::time(
nullptr));
512 std::shuffle(ind.begin(), ind.end(), rng);
514 auto myThread = [&](
int iThread) {
515 for (
size_t i = iThread;
i < loopEnd;
i += mNThreads) {
516 if (acceptTrack(tracksTPC[
i])) {
517 fillDCA(tracksTPC, tracksITSTPC, vertices,
i, iThread, indicesITSTPC, tracksITS, idxTPCTrackToTOFCluster, tofClusters, tpcToTRDMap, trdTracklets, trdCalibTracklets);
522 std::vector<std::thread> threads(mNThreads);
523 for (
int i = 0;
i < mNThreads;
i++) {
524 threads[
i] = std::thread(myThread,
i);
527 for (
auto& th : threads) {
531 auto myThread = [&](
int iThread) {
532 for (
size_t i = iThread;
i < loopEnd;
i += mNThreads) {
533 if (acceptTrack(tracksTPC[
i])) {
534 fillDCA(tracksTPC, tracksITSTPC, vertices,
i, iThread, indicesITSTPC, tracksITS, idxTPCTrackToTOFCluster, tofClusters, tpcToTRDMap, trdTracklets, trdCalibTracklets);
539 std::vector<std::thread> threads(mNThreads);
540 for (
int i = 0;
i < mNThreads;
i++) {
541 threads[
i] = std::thread(myThread,
i);
544 for (
auto& th : threads) {
550 for (
const auto& vals : mBufferVals) {
553 const auto nPoints =
val.side.size();
554 for (
int i = 0;
i < nPoints; ++
i) {
555 const auto tglBin =
val.tglBin[
i];
556 const auto phiBin =
val.phiBin[
i];
557 const auto qPtBin =
val.qPtBin[
i];
558 const auto multBin =
val.multBin[
i];
559 const auto dcar =
val.dcar[
i];
560 const auto dcaz =
val.dcaz[
i];
561 const auto dcarW =
val.dcarW[
i];
562 const int binInt = nBins - 1;
563 const bool fillCombDCA = ((
type == 1) && (
val.dcarcomb[
i] != -1) && (
val.dcazcomb[
i] != -1));
564 const bool fillDCAR = (
type == 1) ? (dcar != -999) :
true;
565 const std::array<int, 5>
bins{tglBin, phiBin, qPtBin, multBin, binInt};
567 for (
auto bin :
bins) {
570 mAvgCDCAr[bin][
type].addValue(dcar, dcarW);
573 mAvgCDCAr[bin][2].addValue(
val.dcarcomb[
i], dcarW);
574 mAvgCDCAz[bin][2].addValue(
val.dcazcomb[
i], dcarW);
578 mAvgCDCAz[bin][
type].addValue(dcaz, dcarW);
582 mAvgADCAr[bin][
type].addValue(dcar, dcarW);
585 mAvgADCAr[bin][2].addValue(
val.dcarcomb[
i], dcarW);
586 mAvgADCAz[bin][2].addValue(
val.dcazcomb[
i], dcarW);
590 mAvgADCAz[bin][
type].addValue(dcaz, dcarW);
602 for (
int slice = 0; slice < nBins; ++slice) {
605 const auto dcaAr = mAvgADCAr[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
606 bufferDCA.mDCAr_A_Median[slice] = std::get<0>(dcaAr);
607 bufferDCA.mDCAr_A_WeightedMean[slice] = std::get<1>(dcaAr);
608 bufferDCA.mDCAr_A_RMS[slice] = std::get<2>(dcaAr);
609 bufferDCA.mDCAr_A_NTracks[slice] = std::get<3>(dcaAr);
611 const auto dcaAz = mAvgADCAz[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
612 bufferDCA.mDCAz_A_Median[slice] = std::get<0>(dcaAz);
613 bufferDCA.mDCAz_A_WeightedMean[slice] = std::get<1>(dcaAz);
614 bufferDCA.mDCAz_A_RMS[slice] = std::get<2>(dcaAz);
615 bufferDCA.mDCAz_A_NTracks[slice] = std::get<3>(dcaAz);
617 const auto dcaCr = mAvgCDCAr[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
618 bufferDCA.mDCAr_C_Median[slice] = std::get<0>(dcaCr);
619 bufferDCA.mDCAr_C_WeightedMean[slice] = std::get<1>(dcaCr);
620 bufferDCA.mDCAr_C_RMS[slice] = std::get<2>(dcaCr);
621 bufferDCA.mDCAr_C_NTracks[slice] = std::get<3>(dcaCr);
623 const auto dcaCz = mAvgCDCAz[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
624 bufferDCA.mDCAz_C_Median[slice] = std::get<0>(dcaCz);
625 bufferDCA.mDCAz_C_WeightedMean[slice] = std::get<1>(dcaCz);
626 bufferDCA.mDCAz_C_RMS[slice] = std::get<2>(dcaCz);
627 bufferDCA.mDCAz_C_NTracks[slice] = std::get<3>(dcaCz);
630 const auto dcaArComb = mAvgADCAr[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
634 const auto dcaAzCom = mAvgADCAz[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
638 const auto dcaCrComb = mAvgCDCAr[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
642 const auto dcaCzComb = mAvgCDCAz[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
650 for (
const auto& vals : mBufferVals) {
651 const auto&
val = vals.front();
652 const auto nPoints =
val.side.size();
653 for (
int i = 0;
i < nPoints; ++
i) {
654 const auto tglBin =
val.tglBin[
i];
655 const auto phiBin =
val.phiBin[
i];
656 const auto qPtBin =
val.qPtBin[
i];
657 const auto multBin =
val.multBin[
i];
658 const auto dcar =
val.dcar[
i];
659 const auto dcaz =
val.dcaz[
i];
660 const auto hasITS =
val.hasITS[
i];
661 const auto chi2Match =
val.chi2Match[
i];
662 const auto dedxRatioqMax =
val.dedxRatioqMax[
i];
663 const auto dedxRatioqTot =
val.dedxRatioqTot[
i];
664 const auto sqrtChi2TPC =
val.sqrtChi2TPC[
i];
665 const auto nClTPC =
val.nClTPC[
i];
666 const int binInt = nBins - 1;
673 auto& mAvgEff = isCSide ? mAvgMeffC : mAvgMeffA;
674 auto& mAvgChi2Match = isCSide ? mAvgChi2MatchC : mAvgChi2MatchA;
675 auto& mAvgmMIPdEdxRatioqMax = isCSide ? mMIPdEdxRatioQMaxC : mMIPdEdxRatioQMaxA;
676 auto& mAvgmMIPdEdxRatioqTot = isCSide ? mMIPdEdxRatioQTotC : mMIPdEdxRatioQTotA;
677 auto& mAvgmTPCChi2 = isCSide ? mTPCChi2C : mTPCChi2A;
678 auto& mAvgmTPCNCl = isCSide ? mTPCNClC : mTPCNClA;
679 auto& mAvgmdEdxRatioQMax = isCSide ? mLogdEdxQMaxC : mLogdEdxQMaxA;
680 auto& mAvgmdEdxRatioQTot = isCSide ? mLogdEdxQTotC : mLogdEdxQTotA;
681 auto& mITSProperties = isCSide ? mITSPropertiesC : mITSPropertiesA;
682 auto& mSigmaYZ = isCSide ? mSigmaYZC : mSigmaYZA;
683 auto& mITSTPCDeltaP = isCSide ? mITSTPCDeltaPC : mITSTPCDeltaPA;
685 const std::array<int, 5>
bins{tglBin, phiBin, qPtBin, multBin, binInt};
687 for (
auto bin :
bins) {
689 if ((std::abs(dcar - bufferDCAMedR[bin]) < (bufferDCARMSR[bin] * mCutRMS)) && (std::abs(dcaz - bufferDCAMedZ[bin]) < (bufferDCARMSZ[bin] * mCutRMS))) {
690 const auto gID =
val.gID[
i];
691 mAvgEff[bin][0].addValue(hasITS);
694 mAvgEff[bin][1].addValue(hasITS);
695 mAvgEff[bin][2].addValue(hasITS);
699 mAvgEff[bin][1].addValue(hasITS);
701 mAvgEff[bin][2].addValue(hasITS);
704 mAvgChi2Match[bin][0].addValue(chi2Match);
706 mAvgChi2Match[bin][1].addValue(chi2Match);
708 mAvgChi2Match[bin][2].addValue(chi2Match);
711 if (dedxRatioqMax > 0) {
712 mAvgmMIPdEdxRatioqMax[bin][0].addValue(dedxRatioqMax);
714 if (dedxRatioqTot > 0) {
715 mAvgmMIPdEdxRatioqTot[bin][0].addValue(dedxRatioqTot);
717 mAvgmTPCChi2[bin][0].addValue(sqrtChi2TPC);
718 mAvgmTPCNCl[bin][0].addValue(nClTPC);
720 if (dedxRatioqMax > 0) {
721 mAvgmMIPdEdxRatioqMax[bin][1].addValue(dedxRatioqMax);
723 if (dedxRatioqTot > 0) {
724 mAvgmMIPdEdxRatioqTot[bin][1].addValue(dedxRatioqTot);
726 mAvgmTPCChi2[bin][1].addValue(sqrtChi2TPC);
727 mAvgmTPCNCl[bin][1].addValue(nClTPC);
730 float dedxNormQMax =
val.dedxValsqMax[
i].dedxNorm;
731 if (dedxNormQMax > 0) {
732 mAvgmdEdxRatioQMax[bin][0].addValue(dedxNormQMax);
735 float dedxNormQTot =
val.dedxValsqTot[
i].dedxNorm;
736 if (dedxNormQTot > 0) {
737 mAvgmdEdxRatioQTot[bin][0].addValue(dedxNormQTot);
740 float dedxIROCQMax =
val.dedxValsqMax[
i].dedxIROC;
741 if (dedxIROCQMax > 0) {
742 mAvgmdEdxRatioQMax[bin][1].addValue(dedxIROCQMax);
745 float dedxIROCQTot =
val.dedxValsqTot[
i].dedxIROC;
746 if (dedxIROCQTot > 0) {
747 mAvgmdEdxRatioQTot[bin][1].addValue(dedxIROCQTot);
750 float dedxOROC1QMax =
val.dedxValsqMax[
i].dedxOROC1;
751 if (dedxOROC1QMax > 0) {
752 mAvgmdEdxRatioQMax[bin][2].addValue(dedxOROC1QMax);
755 float dedxOROC1QTot =
val.dedxValsqTot[
i].dedxOROC1;
756 if (dedxOROC1QTot > 0) {
757 mAvgmdEdxRatioQTot[bin][2].addValue(dedxOROC1QTot);
760 float dedxOROC2QMax =
val.dedxValsqMax[
i].dedxOROC2;
761 if (dedxOROC2QMax > 0) {
762 mAvgmdEdxRatioQMax[bin][3].addValue(dedxOROC2QMax);
765 float dedxOROC2QTot =
val.dedxValsqTot[
i].dedxOROC2;
766 if (dedxOROC2QTot > 0) {
767 mAvgmdEdxRatioQTot[bin][3].addValue(dedxOROC2QTot);
770 float dedxOROC3QMax =
val.dedxValsqMax[
i].dedxOROC3;
771 if (dedxOROC3QMax > 0) {
772 mAvgmdEdxRatioQMax[bin][4].addValue(dedxOROC3QMax);
775 float dedxOROC3QTot =
val.dedxValsqTot[
i].dedxOROC3;
776 if (dedxOROC3QTot > 0) {
777 mAvgmdEdxRatioQTot[bin][4].addValue(dedxOROC3QTot);
780 float nClITS =
val.nClITS[
i];
782 mITSProperties[bin][0].addValue(nClITS);
784 float chi2ITS =
val.chi2ITS[
i];
786 mITSProperties[bin][1].addValue(chi2ITS);
789 float sigmay2 =
val.sigmaY2[
i];
791 mSigmaYZ[bin][0].addValue(sigmay2);
793 float sigmaz2 =
val.sigmaZ2[
i];
795 mSigmaYZ[bin][1].addValue(sigmaz2);
798 float deltaP2 =
val.deltaP2[
i];
799 if (deltaP2 != -999) {
800 mITSTPCDeltaP[bin][0].addValue(deltaP2);
803 float deltaP3 =
val.deltaP3[
i];
804 if (deltaP3 != -999) {
805 mITSTPCDeltaP[bin][1].addValue(deltaP3);
808 float deltaP4 =
val.deltaP4[
i];
809 if (deltaP4 != -999) {
810 mITSTPCDeltaP[bin][2].addValue(deltaP4);
818 for (
int slice = 0; slice < nBins; ++slice) {
819 for (
int i = 0;
i < mAvgMeffA[slice].size(); ++
i) {
821 itsBuf.mITSTPC_A_MatchEff[slice] = mAvgMeffA[slice][
i].getMean();
822 itsBuf.mITSTPC_C_MatchEff[slice] = mAvgMeffC[slice][
i].getMean();
823 itsBuf.mITSTPC_A_Chi2Match[slice] = mAvgChi2MatchA[slice][
i].getMean();
824 itsBuf.mITSTPC_C_Chi2Match[slice] = mAvgChi2MatchC[slice][
i].getMean();
828 for (
int i = 0;
i < mMIPdEdxRatioQMaxC[slice].size(); ++
i) {
831 buff.mMIPdEdxRatioQMaxC[slice] = mMIPdEdxRatioQMaxC[slice][
i].getMean();
832 buff.mMIPdEdxRatioQTotA[slice] = mMIPdEdxRatioQTotA[slice][
i].getMean();
833 buff.mMIPdEdxRatioQTotC[slice] = mMIPdEdxRatioQTotC[slice][
i].getMean();
834 buff.mTPCChi2C[slice] = mTPCChi2C[slice][
i].getMean();
835 buff.mTPCChi2A[slice] = mTPCChi2A[slice][
i].getMean();
836 buff.mTPCNClC[slice] = mTPCNClC[slice][
i].getMean();
837 buff.mTPCNClA[slice] = mTPCNClA[slice][
i].getMean();
842 auto& logdEdxA = (
type == 0) ? mLogdEdxQMaxA : mLogdEdxQTotA;
846 buffer.mLogdEdx_A_RMS[slice] = logdEdxA[slice][0].getStdDev();
847 buffer.mLogdEdx_A_IROC_Median[slice] = logdEdxA[slice][1].getMedian();
848 buffer.mLogdEdx_A_IROC_RMS[slice] = logdEdxA[slice][1].getStdDev();
849 buffer.mLogdEdx_A_OROC1_Median[slice] = logdEdxA[slice][2].getMedian();
850 buffer.mLogdEdx_A_OROC1_RMS[slice] = logdEdxA[slice][2].getStdDev();
851 buffer.mLogdEdx_A_OROC2_Median[slice] = logdEdxA[slice][3].getMedian();
852 buffer.mLogdEdx_A_OROC2_RMS[slice] = logdEdxA[slice][3].getStdDev();
853 buffer.mLogdEdx_A_OROC3_Median[slice] = logdEdxA[slice][4].getMedian();
854 buffer.mLogdEdx_A_OROC3_RMS[slice] = logdEdxA[slice][4].getStdDev();
856 auto& logdEdxC = (
type == 0) ? mLogdEdxQMaxC : mLogdEdxQTotC;
857 buffer.mLogdEdx_C_Median[slice] = logdEdxC[slice][0].getMedian();
858 buffer.mLogdEdx_C_RMS[slice] = logdEdxC[slice][0].getStdDev();
859 buffer.mLogdEdx_C_IROC_Median[slice] = logdEdxC[slice][1].getMedian();
860 buffer.mLogdEdx_C_IROC_RMS[slice] = logdEdxC[slice][1].getStdDev();
861 buffer.mLogdEdx_C_OROC1_Median[slice] = logdEdxC[slice][2].getMedian();
862 buffer.mLogdEdx_C_OROC1_RMS[slice] = logdEdxC[slice][2].getStdDev();
863 buffer.mLogdEdx_C_OROC2_Median[slice] = logdEdxC[slice][3].getMedian();
864 buffer.mLogdEdx_C_OROC2_RMS[slice] = logdEdxC[slice][3].getStdDev();
865 buffer.mLogdEdx_C_OROC3_Median[slice] = logdEdxC[slice][4].getMedian();
866 buffer.mLogdEdx_C_OROC3_RMS[slice] = logdEdxC[slice][4].getStdDev();
872 mBufferDCA.
mITS_A_NCl_RMS[slice] = mITSPropertiesA[slice][0].getStdDev();
877 mBufferDCA.
mITS_C_NCl_RMS[slice] = mITSPropertiesC[slice][0].getStdDev();
904 auto stop = timer::now();
905 std::chrono::duration<float>
time = stop - startTotal;
906 LOGP(info,
"Time series creation took {}",
time.count());
914 for (
auto& streamer : mStreamer) {
917 eos.services().get<
ControlService>().readyToQuit(QuitRequest::Me);
926 LOGP(info,
"Updating TPC sector edge fluctuation info");
928 LOGP(info,
"Loaded sector edge fluctuation information with {} intervals for {} runs", mSecEdgeFlucInfo.
size(), mSecEdgeFlucInfo.
getNRuns());
943 void reserve(
int n,
int type)
953 dedxRatioqTot.reserve(
n);
954 dedxRatioqMax.reserve(
n);
955 sqrtChi2TPC.reserve(
n);
959 chi2Match.reserve(
n);
961 dedxValsqTot.reserve(
n);
962 dedxValsqMax.reserve(
n);
970 }
else if (
type == 0) {
988 dedxRatioqTot.clear();
989 dedxRatioqMax.clear();
997 dedxValsqTot.clear();
998 dedxValsqMax.clear();
1006 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)
1008 side.emplace_back(sideTmp);
1009 tglBin.emplace_back(tglBinTmp);
1010 phiBin.emplace_back(phiBinTmp);
1011 qPtBin.emplace_back(qPtBinTmp);
1012 multBin.emplace_back(multBinTmp);
1013 dcar.emplace_back(dcarTmp);
1014 dcaz.emplace_back(dcazTmp);
1015 dcarW.emplace_back(dcarWTmp);
1016 dedxRatioqTot.emplace_back(dedxRatioqTotTmp);
1017 dedxRatioqMax.emplace_back(dedxRatioqMaxTmp);
1018 sqrtChi2TPC.emplace_back(sqrtChi2TPCTmp);
1019 nClTPC.emplace_back(nClTPCTmp);
1020 chi2Match.emplace_back(chi2MatchTmp);
1021 hasITS.emplace_back(hasITSTmp);
1022 gID.emplace_back(gIDTmp);
1023 dedxValsqMax.emplace_back(dedxValsqMaxTmp);
1024 dedxValsqTot.emplace_back(dedxValsqTotTmp);
1025 nClITS.emplace_back(nClITSTmp);
1026 chi2ITS.emplace_back(chi2ITSTmp);
1027 sigmaY2.emplace_back(sigmaY2Tmp);
1028 sigmaZ2.emplace_back(sigmaZ2Tmp);
1029 deltaP2.emplace_back(-999);
1030 deltaP3.emplace_back(-999);
1031 deltaP4.emplace_back(-999);
1034 void setDeltaParam(
float deltaP2Tmp,
float deltaP3Tmp,
float deltaP4Tmp)
1036 if (!deltaP2.empty()) {
1037 deltaP2.back() = deltaP2Tmp;
1038 deltaP3.back() = deltaP3Tmp;
1039 deltaP4.back() = deltaP4Tmp;
1043 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)
1045 side.emplace_back(sideTmp);
1046 tglBin.emplace_back(tglBinTmp);
1047 phiBin.emplace_back(phiBinTmp);
1048 qPtBin.emplace_back(qPtBinTmp);
1049 multBin.emplace_back(multBinTmp);
1050 dcar.emplace_back(dcarTmp);
1051 dcaz.emplace_back(dcazTmp);
1052 dcarW.emplace_back(dcarWTmp);
1053 dedxRatioqTot.emplace_back(dedxRatioqTotTmp);
1054 dedxRatioqMax.emplace_back(dedxRatioqMaxTmp);
1055 sqrtChi2TPC.emplace_back(sqrtChi2TPCTmp);
1056 nClTPC.emplace_back(nClTPCTmp);
1057 dcarcomb.emplace_back(dcarCombTmp);
1058 dcazcomb.emplace_back(dcazCombTmp);
1061 std::vector<Side>
side;
1062 std::vector<int> tglBin;
1063 std::vector<int> phiBin;
1064 std::vector<int> qPtBin;
1065 std::vector<int> multBin;
1066 std::vector<float> dcar;
1067 std::vector<float> dcaz;
1068 std::vector<float> dcarW;
1069 std::vector<bool> hasITS;
1070 std::vector<float> chi2Match;
1071 std::vector<float> dedxRatioqTot;
1072 std::vector<float> dedxRatioqMax;
1073 std::vector<float> sqrtChi2TPC;
1074 std::vector<float> nClTPC;
1075 std::vector<float> dcarcomb;
1076 std::vector<float> dcazcomb;
1077 std::vector<ValsdEdx> dedxValsqTot;
1078 std::vector<ValsdEdx> dedxValsqMax;
1079 std::vector<int> nClITS;
1080 std::vector<float> chi2ITS;
1081 std::vector<o2::dataformats::GlobalTrackID::Source> gID;
1082 std::vector<float> deltaP2;
1083 std::vector<float> deltaP3;
1084 std::vector<float> deltaP4;
1085 std::vector<float> sigmaY2;
1086 std::vector<float> sigmaZ2;
1088 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
1089 const bool mDisableWriter{
false};
1091 const bool mUnbinnedWriter{
false};
1092 const bool mTPCOnly{
false};
1093 std::shared_ptr<o2::globaltracking::DataRequest> mDataRequest;
1097 TimeSeriesITSTPC mBufferDCA;
1098 std::vector<std::array<RobustAverage, 3>> mAvgADCAr;
1099 std::vector<std::array<RobustAverage, 3>> mAvgCDCAr;
1100 std::vector<std::array<RobustAverage, 3>> mAvgADCAz;
1101 std::vector<std::array<RobustAverage, 3>> mAvgCDCAz;
1102 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQMaxA;
1103 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQMaxC;
1104 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQTotA;
1105 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQTotC;
1106 std::vector<std::array<RobustAverage, 2>> mTPCChi2A;
1107 std::vector<std::array<RobustAverage, 2>> mTPCChi2C;
1108 std::vector<std::array<RobustAverage, 2>> mTPCNClA;
1109 std::vector<std::array<RobustAverage, 2>> mTPCNClC;
1110 std::vector<std::array<RobustAverage, 3>> mAvgMeffA;
1111 std::vector<std::array<RobustAverage, 3>> mAvgMeffC;
1112 std::vector<std::array<RobustAverage, 3>> mAvgChi2MatchA;
1113 std::vector<std::array<RobustAverage, 3>> mAvgChi2MatchC;
1114 std::vector<std::array<RobustAverage, 10>> mLogdEdxQTotA;
1115 std::vector<std::array<RobustAverage, 10>> mLogdEdxQTotC;
1116 std::vector<std::array<RobustAverage, 10>> mLogdEdxQMaxA;
1117 std::vector<std::array<RobustAverage, 10>> mLogdEdxQMaxC;
1118 std::vector<std::array<RobustAverage, 2>> mITSPropertiesA;
1119 std::vector<std::array<RobustAverage, 2>> mITSPropertiesC;
1120 std::vector<std::array<RobustAverage, 3>> mITSTPCDeltaPA;
1121 std::vector<std::array<RobustAverage, 3>> mITSTPCDeltaPC;
1122 std::vector<std::array<RobustAverage, 2>> mSigmaYZA;
1123 std::vector<std::array<RobustAverage, 2>> mSigmaYZC;
1124 int mNMaxTracks{-1};
1129 float mCoarseStep{1};
1130 float mFineStep{0.005};
1133 float mRefXSec{108.475};
1135 float maxITSTPCDCAr{0.2};
1136 float maxITSTPCDCAz{10};
1137 float maxITSTPCDCAr_comb{0.2};
1138 float maxITSTPCDCAz_comb{0.2};
1139 gsl::span<const TPCClRefElem> mTPCTrackClIdx{};
1140 std::vector<std::array<FillVals, 2>> mBufferVals;
1141 uint32_t mFirstTFOrbit{0};
1142 float mTimeWindowMUS{50};
1144 std::vector<int> mNTracksWindow;
1145 std::vector<int> mNearestVtxTPC;
1147 float mVDrift{2.64};
1148 float mMaxSnp{0.85};
1152 int mMultMax{80000};
1154 int mMinTracksPerVertex{5};
1155 float mMaxdEdxRatio{0.3};
1156 float mMaxdEdxRegionRatio{0.5};
1157 float mSamplingFactor{0.1};
1158 bool mSampleTsallis{
false};
1159 std::vector<std::mt19937> mGenerator;
1160 std::vector<std::unique_ptr<o2::utils::TreeStreamRedirector>> mStreamer;
1161 float mXOuterMatching{60};
1162 bool mUseMinBiasTrigger{
false};
1165 int mMaxOccupancyHistBins{912};
1166 PressureTemperatureHelper mPTHelper;
1170 bool acceptTrack(
const TrackTPC& track)
const {
return std::abs(
track.getTgl()) < mMaxTgl; }
1172 bool checkTrack(
const TrackTPC& track)
const
1174 const bool isGoodTrack = ((
track.getNClusters() < mMinNCl) || (
track.getP() < mMinMom)) ? false :
true;
1178 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, unsigned short>>& idxTPCTrackToTOFCluster,
const gsl::span<const o2::tof::Cluster> tofClusters,
const std::unordered_map<unsigned int, TRDTrackletData>& tpcToTRDMap,
const gsl::span<const o2::trd::Tracklet64> trdTracklets,
const gsl::span<const o2::trd::CalibratedTracklet> trdCalibTracklets)
1180 const auto& trackFull = tracksTPC[iTrk];
1181 const bool isGoodTrack = checkTrack(trackFull);
1184 bool minBiasOk =
false;
1185 const float factorMinBias = 0.1 * mSamplingFactor;
1186 if (mUnbinnedWriter && mUseMinBiasTrigger) {
1187 std::uniform_real_distribution<>
distr(0., 1.);
1188 if (
distr(mGenerator[iThread]) < factorMinBias) {
1194 if (!isGoodTrack && !minBiasOk) {
1204 std::array<float, 2> dca;
1208 if (!propagator->PropagateToXBxByBz(track, mXCoarse, mMaxSnp, mCoarseStep, mMatType)) {
1213 if (!propagator->propagateToDCA(refPoint, track, propagator->getNominalBz(), mFineStep, mMatType, &dca)) {
1220 if (!propagator->propagateTo(trackTmp, mRefXSec,
false, mMaxSnp, mCoarseStep, mMatType)) {
1225 const int tglBin = std::clamp(
static_cast<int>(mTglBins * std::abs(trackTmp.getTgl()) / mMaxTgl) + mPhiBins,
1226 mPhiBins, mPhiBins + mTglBins - 1);
1230 const int offsQPtBin = mPhiBins + mTglBins;
1231 const int qPtBin = std::clamp(offsQPtBin +
static_cast<int>(mQPtBins * (trackTmp.getQ2Pt() + mMaxQPt) / (2 * mMaxQPt)),
1232 offsQPtBin, offsQPtBin + mQPtBins - 1);
1233 const int localMult = mNTracksWindow[iTrk];
1235 const int offsMult = offsQPtBin + mQPtBins;
1236 const int multBin = std::clamp(offsMult +
static_cast<int>(mMultBins * localMult / mMultMax),
1237 offsMult, offsMult + mMultBins - 1);
1238 const int nBins = getNBins();
1244 auto it = indicesITSTPC.find(iTrk);
1245 const auto idxITSTPC = (it != indicesITSTPC.end()) ? (it->second) : std::array<int, 2>{-1, -1};
1248 const auto vertex = (idxITSTPC.back() != -1) ? vertices[idxITSTPC.back()] : ((mNearestVtxTPC[iTrk] != -1) ? vertices[mNearestVtxTPC[iTrk]] :
o2::dataformats::PrimaryVertex{});
1251 const float signSide = trackFull.hasCSideClustersOnly() ? -1 : 1;
1252 const float dcaZFromDeltaTime = (
vertex.getTimeStamp().getTimeStamp() == 0) ? 0 : (
o2::tpc::ParameterElectronics::Instance().ZbinWidth * trackFull.getTime0() -
vertex.
getTimeStamp().
getTimeStamp()) * mVDrift + signSide *
vertex.getZ();
1257 const float div = (resCl *
track.getPt());
1262 const float fB = 0.2 / div;
1263 const float fA = 0.15 + 0.15;
1264 const float dcarW = 1. / std::sqrt(fA * fA + fB * fB);
1267 const bool hasITSTPC = idxITSTPC.front() != -1;
1270 const float chi2 = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getChi2Match() : -1;
1274 const auto src = tracksITSTPC[idxITSTPC.front()].getRefITS().getSource();
1282 const float chi2Match = (chi2 > 0) ? std::sqrt(chi2) : -1;
1283 const float sqrtChi2TPC = (trackFull.getChi2() > 0) ? std::sqrt(trackFull.getChi2()) : 0;
1284 const float nClTPC = trackFull.getNClusters();
1287 const float dedxRatioqTot = (trackFull.getdEdx().dEdxTotTPC > 0) ? (mMIPdEdx / trackFull.getdEdx().dEdxTotTPC) : -1;
1288 const float dedxRatioqMax = (trackFull.getdEdx().dEdxMaxTPC > 0) ? (mMIPdEdx / trackFull.getdEdx().dEdxMaxTPC) : -1;
1290 const auto dedxQTotVars = getdEdxVars(0, trackFull);
1291 const auto dedxQMaxVars = getdEdxVars(1, trackFull);
1295 const bool idxITSCheck = (idxITSTrack != -1);
1297 const int nClITS = idxITSCheck ? tracksITS[idxITSTrack].getNClusters() : -1;
1298 float chi2ITS = idxITSCheck ? tracksITS[idxITSTrack].getChi2() : -1;
1299 if ((chi2ITS > 0) && (nClITS > 0)) {
1300 chi2ITS = std::sqrt(chi2ITS / nClITS);
1302 sigmaY2 =
track.getSigmaY2();
1303 sigmaZ2 =
track.getSigmaZ2();
1305 if (trackFull.hasCSideClustersOnly()) {
1306 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);
1307 }
else if (trackFull.hasASideClustersOnly()) {
1308 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);
1314 std::array<float, 2> dcaITSTPC{0, 0};
1315 float deltaP0 = -999;
1316 float deltaP1 = -999;
1317 float deltaP2 = -999;
1318 float deltaP3 = -999;
1319 float deltaP4 = -999;
1320 float phiITSTPCAtVertex = -999;
1321 float dcaTPCAtVertex = -999;
1324 auto trackITSTPCTmp = tracksITSTPC[idxITSTPC.front()];
1326 if (propagator->propagateToDCA(refPoint, trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPC)) {
1328 if ((std::abs(dcaITSTPC[0]) < maxITSTPCDCAr) && (std::abs(dcaITSTPC[1]) < maxITSTPCDCAz)) {
1331 const bool contributeToVertex = (idxITSTPC.back() != -1);
1332 std::array<float, 2> dcaITSTPCTmp{-1, -1};
1334 if (contributeToVertex) {
1335 if (propagator->propagateToDCA(
vertex.getXYZ(), trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPCTmp)) {
1336 phiITSTPCAtVertex = trackITSTPCTmp.getPhi();
1337 dcaITSTPC = dcaITSTPCTmp;
1341 std::array<float, 2> dcaTPCTmp{-1, -1};
1342 if (propagator->propagateToDCA(
vertex.getXYZ(), track, propagator->getNominalBz(), mFineStep, mMatType, &dcaTPCTmp)) {
1343 dcaTPCAtVertex = dcaTPCTmp[0];
1348 if ((std::abs(dcaITSTPCTmp[0]) < maxITSTPCDCAr_comb) && (std::abs(dcaITSTPCTmp[1]) < maxITSTPCDCAz_comb)) {
1350 if (idxITSTrack >= 0 &&
track.rotate(tracksITS[idxITSTrack].getAlpha()) && propagator->propagateTo(track, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1352 const bool propITSOk = propagator->propagateTo(trackITS, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType);
1354 deltaP0 =
track.getParam(0) - trackITS.getParam(0);
1355 deltaP1 =
track.getParam(1) - trackITS.getParam(1);
1356 deltaP2 =
track.getParam(2) - trackITS.getParam(2);
1357 deltaP3 =
track.getParam(3) - trackITS.getParam(3);
1358 deltaP4 =
track.getParam(4) - trackITS.getParam(4);
1359 mBufferVals[iThread].front().setDeltaParam(deltaP2, deltaP3, deltaP4);
1363 dcaITSTPCTmp[0] = -1;
1364 dcaITSTPCTmp[1] = -1;
1368 if (trackFull.hasCSideClustersOnly()) {
1369 mBufferVals[iThread].back().emplace_back_ITSTPC(
Side::C, tglBin, phiBin, qPtBin, multBin, dcaTPCAtVertex, dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, dcaITSTPCTmp[0], dcaITSTPCTmp[1]);
1370 }
else if (trackFull.hasASideClustersOnly()) {
1371 mBufferVals[iThread].back().emplace_back_ITSTPC(
Side::A, tglBin, phiBin, qPtBin, multBin, dcaTPCAtVertex, dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, dcaITSTPCTmp[0], dcaITSTPCTmp[1]);
1378 if (mUnbinnedWriter && mStreamer[iThread]) {
1379 const float factorPt = mSamplingFactor;
1380 bool writeData =
true;
1381 bool writeDataITSTPC =
false;
1383 float weightITSTPC = 0;
1384 if (mSampleTsallis) {
1385 std::uniform_real_distribution<>
distr(0., 1.);
1391 if (writeData || writeDataITSTPC || minBiasOk) {
1392 auto clusterMask = makeClusterBitMask(trackFull);
1393 const auto& trkOrig = tracksTPC[iTrk];
1394 const bool isNearestVtx = (idxITSTPC.back() == -1);
1395 const float mx_ITS = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getX() : -1;
1396 const float pt_ITS = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getQ2Pt() : -1;
1397 const float chi2match_ITSTPC = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getChi2Match() : -1;
1398 const int nClITS = idxITSCheck ? tracksITS[idxITSTrack].getNClusters() : -1;
1399 const int chi2ITS = idxITSCheck ? tracksITS[idxITSTrack].getChi2() : -1;
1401 const uint32_t itsClusterSizes = idxITSCheck ? (
static_cast<uint32_t
>(tracksITS[idxITSTrack].getClusterSizes()) & 0x0FFFFFFFu) : 0u;
1402 const bool itsHasSharedClusters = idxITSCheck ? tracksITS[idxITSTrack].hasSharedClusters() :
false;
1403 const uint32_t itsPattern = idxITSCheck ? (tracksITS[idxITSTrack].getPattern() & 0x7Fu) : 0u;
1408 std::vector<o2::trd::Tracklet64> trdTrackletVec(6);
1409 std::vector<o2::trd::CalibratedTracklet> trdCalibVec(6);
1410 auto itTRD = tpcToTRDMap.find(iTrk);
1411 if (itTRD != tpcToTRDMap.end()) {
1412 const auto& trdData = itTRD->second;
1413 trdPattern = trdData.trdPattern;
1414 nTRDTracklets = trdData.nTRDTracklets;
1415 for (
int iLay = 0; iLay < 6; ++iLay) {
1416 if (trdData.trackletIndices[iLay] >= 0) {
1417 trdTrackletVec[iLay] = trdTracklets[trdData.trackletIndices[iLay]];
1418 if (trdData.trackletIndices[iLay] <
static_cast<int>(trdCalibTracklets.size())) {
1419 trdCalibVec[iLay] = trdCalibTracklets[trdData.trackletIndices[iLay]];
1425 if (trackFull.hasASideClustersOnly()) {
1427 }
else if (trackFull.hasCSideClustersOnly()) {
1432 bool hasTOFCluster = (std::get<0>(idxTPCTrackToTOFCluster[iTrk]) != -1);
1433 auto tofCl = hasTOFCluster ? tofClusters[std::get<0>(idxTPCTrackToTOFCluster[iTrk])] :
o2::tof::Cluster();
1435 float tpcYDeltaAtTOF = -999;
1436 float tpcZDeltaAtTOF = -999;
1437 if (hasTOFCluster) {
1439 if (trackTmpOut.rotate(
o2::math_utils::sector2Angle(tofCl.getSector())) && propagator->propagateTo(trackTmpOut, tofCl.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1440 tpcYDeltaAtTOF = trackTmpOut.getY() - tofCl.getY();
1446 float deltaTPCParamInOutTgl = trackFull.getTgl() - trackFull.getParamOut().getTgl();
1447 float deltaTPCParamInOutQPt = trackFull.getQ2Pt() - trackFull.getParamOut().getQ2Pt();
1450 float deltaP0OuterITS = -999;
1451 float deltaP1OuterITS = -999;
1452 float deltaP2OuterITS = -999;
1453 float deltaP3OuterITS = -999;
1454 float deltaP4OuterITS = -999;
1457 const bool propITSOk = propagator->propagateTo(trackTmpOut, mXOuterMatching,
false, mMaxSnp, mCoarseStep, mMatType);
1458 if (propITSOk && trackTmp.rotate(trackTmpOut.getAlpha())) {
1459 const bool propTPCOk = propagator->propagateTo(trackTmp, mXOuterMatching,
false, mMaxSnp, mCoarseStep, mMatType);
1462 deltaP0OuterITS = trackTmp.getParam(0) - trackTmpOut.getParam(0);
1463 deltaP1OuterITS = trackTmp.getParam(1) - trackTmpOut.getParam(1);
1464 deltaP2OuterITS = trackTmp.getParam(2) - trackTmpOut.getParam(2);
1465 deltaP3OuterITS = trackTmp.getParam(3) - trackTmpOut.getParam(3);
1466 deltaP4OuterITS = trackTmp.getParam(4) - trackTmpOut.getParam(4);
1474 const int triggerMask = 0x1 * minBiasOk + 0x2 * writeData + 0x4 * writeDataITSTPC;
1476 float deltaP2ConstrVtx = -999;
1477 float deltaP3ConstrVtx = -999;
1478 float deltaP4ConstrVtx = -999;
1481 float covTPCConstrVtxP2 = -999;
1482 float covTPCConstrVtxP3 = -999;
1483 float covTPCConstrVtxP4 = -999;
1486 float covITSTPCConstrVtxP2 = -999;
1487 float covITSTPCConstrVtxP3 = -999;
1488 float covITSTPCConstrVtxP4 = -999;
1490 float covTPCAtVertex0 = -999;
1491 float covTPCAtVertex1 = -999;
1493 const bool contributeToVertex = (idxITSTPC.back() != -1);
1494 if (hasITSTPC && contributeToVertex) {
1496 std::array<float, 2> dcaITSTPCTmp{-1, -1};
1497 if (propagator->propagateToDCA(
vertex.getXYZ(), trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPCTmp)) {
1499 if (trackTPC.rotate(trackITSTPCTmp.getAlpha()) && propagator->propagateTo(trackTPC, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1501 covTPCAtVertex0 = trackTPC.getCovarElem(0, 0);
1502 covTPCAtVertex1 = trackTPC.getCovarElem(1, 1);
1505 deltaP2ConstrVtx = trackTPC.getParam(2) - trackITSTPCTmp.getParam(2);
1506 deltaP3ConstrVtx = trackTPC.getParam(3) - trackITSTPCTmp.getParam(3);
1507 deltaP4ConstrVtx = trackTPC.getParam(4) - trackITSTPCTmp.getParam(4);
1508 covTPCConstrVtxP2 = trackTPC.getCovarElem(2, 2);
1509 covTPCConstrVtxP3 = trackTPC.getCovarElem(3, 3);
1510 covTPCConstrVtxP4 = trackTPC.getCovarElem(4, 4);
1511 covITSTPCConstrVtxP2 = trackITSTPCTmp.getCovarElem(2, 2);
1512 covITSTPCConstrVtxP3 = trackITSTPCTmp.getCovarElem(3, 3);
1513 covITSTPCConstrVtxP4 = trackITSTPCTmp.getCovarElem(4, 4);
1517 double vertexTime =
vertex.getTimeStamp().getTimeStamp();
1518 double trackTime0 = trackFull.getTime0();
1519 *mStreamer[iThread] <<
"treeTimeSeries"
1521 <<
"triggerMask=" << triggerMask
1522 <<
"factorMinBias=" << factorMinBias
1523 <<
"factorPt=" << factorPt
1525 <<
"weight_ITSTPC=" << weightITSTPC
1526 <<
"dcar_tpc_vertex=" << dcaTPCAtVertex
1527 <<
"dcar_tpc=" << dca[0]
1528 <<
"dcaz_tpc=" << dca[1]
1529 <<
"dcar_itstpc=" << dcaITSTPC[0]
1530 <<
"dcaz_itstpc=" << dcaITSTPC[1]
1531 <<
"dcarW=" << dcarW
1532 <<
"dcaZFromDeltaTime=" << dcaZFromDeltaTime
1533 <<
"hasITSTPC=" << hasITSTPC
1535 <<
"vertex_x=" <<
vertex.getX()
1536 <<
"vertex_y=" <<
vertex.getY()
1537 <<
"vertex_z=" <<
vertex.getZ()
1538 <<
"vertex_time=" <<
vertex.getTimeStamp().getTimeStamp()
1539 <<
"vertex_nContributors=" <<
vertex.getNContributors()
1540 <<
"isNearestVertex=" << isNearestVtx
1542 <<
"pt=" << trkOrig.getPt()
1543 <<
"qpt_ITSTPC=" << pt_ITS
1544 <<
"tpc_timebin=" << trkOrig.getTime0()
1545 <<
"qpt=" << trkOrig.getParam(4)
1546 <<
"ncl=" << trkOrig.getNClusters()
1547 <<
"ncl_shared=" << trkOrig.getNClusters()
1548 <<
"tgl=" << trkOrig.getTgl()
1549 <<
"side_type=" << typeSide
1550 <<
"phi=" << trkOrig.getPhi()
1551 <<
"clusterMask=" << clusterMask
1552 <<
"dedxTPC=" << trkOrig.getdEdx()
1553 <<
"chi2=" << trkOrig.getChi2()
1554 <<
"mX=" << trkOrig.getX()
1555 <<
"mX_ITS=" << mx_ITS
1556 <<
"nClITS=" << nClITS
1557 <<
"chi2ITS=" << chi2ITS
1558 <<
"itsClusterSizes=" << itsClusterSizes
1559 <<
"itsHasSharedClusters=" << itsHasSharedClusters
1560 <<
"itsPattern=" << itsPattern
1562 <<
"trdPattern=" << trdPattern
1563 <<
"nTRDTracklets=" << nTRDTracklets
1564 <<
"trdTracklets=" << trdTrackletVec
1565 <<
"trdCalibTracklets=" << trdCalibVec
1566 <<
"chi2match_ITSTPC=" << chi2match_ITSTPC
1567 <<
"PID=" << trkOrig.getPID().getID()
1569 <<
"covTPCAtVertex0=" << covTPCAtVertex0
1570 <<
"covTPCAtVertex1=" << covTPCAtVertex1
1572 <<
"covTPCConstrVtxP2=" << covTPCConstrVtxP2
1573 <<
"covTPCConstrVtxP3=" << covTPCConstrVtxP3
1574 <<
"covTPCConstrVtxP4=" << covTPCConstrVtxP4
1576 <<
"covITSTPCConstrVtxP2=" << covITSTPCConstrVtxP2
1577 <<
"covITSTPCConstrVtxP3=" << covITSTPCConstrVtxP3
1578 <<
"covITSTPCConstrVtxP4=" << covITSTPCConstrVtxP4
1580 <<
"deltaP2ConstrVtx=" << deltaP2ConstrVtx
1581 <<
"deltaP3ConstrVtx=" << deltaP3ConstrVtx
1582 <<
"deltaP4ConstrVtx=" << deltaP4ConstrVtx
1584 <<
"deltaPar0=" << deltaP0
1585 <<
"deltaPar1=" << deltaP1
1586 <<
"deltaPar2=" << deltaP2
1587 <<
"deltaPar3=" << deltaP3
1588 <<
"deltaPar4=" << deltaP4
1589 <<
"sigmaY2=" << sigmaY2
1590 <<
"sigmaZ2=" << sigmaZ2
1592 <<
"mult=" << mNTracksWindow[iTrk]
1593 <<
"time_window_mult=" << mTimeWindowMUS
1594 <<
"firstTFOrbit=" << mFirstTFOrbit
1595 <<
"timeMS=" << mTimeMS
1597 <<
"mVDrift=" << mVDrift
1598 <<
"its_flag=" <<
int(gID)
1599 <<
"sqrtChi2Match=" << chi2Match
1601 <<
"tpcYDeltaAtTOF=" << tpcYDeltaAtTOF
1602 <<
"tpcZDeltaAtTOF=" << tpcZDeltaAtTOF
1603 <<
"mDXatTOF=" << std::get<1>(idxTPCTrackToTOFCluster[iTrk])
1604 <<
"mDZatTOF=" << std::get<2>(idxTPCTrackToTOFCluster[iTrk])
1605 <<
"mTOFLength=" << std::get<3>(idxTPCTrackToTOFCluster[iTrk])
1606 <<
"mTOFSignal=" << std::get<4>(idxTPCTrackToTOFCluster[iTrk])
1607 <<
"mDeltaTTOFTPC=" << std::get<5>(idxTPCTrackToTOFCluster[iTrk])
1608 <<
"vertexTime=" << vertexTime
1609 <<
"trackTime0=" << trackTime0
1610 <<
"TOFmask=" << std::get<6>(idxTPCTrackToTOFCluster[iTrk])
1611 <<
"TOFchannel=" << std::get<7>(idxTPCTrackToTOFCluster[iTrk])
1613 <<
"deltaTPCParamInOutTgl=" << deltaTPCParamInOutTgl
1614 <<
"deltaTPCParamInOutQPt=" << deltaTPCParamInOutQPt
1616 <<
"deltaP0OuterITS=" << deltaP0OuterITS
1617 <<
"deltaP1OuterITS=" << deltaP1OuterITS
1618 <<
"deltaP2OuterITS=" << deltaP2OuterITS
1619 <<
"deltaP3OuterITS=" << deltaP3OuterITS
1620 <<
"deltaP4OuterITS=" << deltaP4OuterITS
1621 <<
"mXOuterMatching=" << mXOuterMatching
1623 <<
"phiITSTPCAtVertex=" << phiITSTPCAtVertex
1631 mBufferDCA.mTSTPC.setStartTime(mTimeMS);
1632 mBufferDCA.mTSITSTPC.setStartTime(mTimeMS);
1635 if (!mDisableWriter) {
1643 void findNearesVertex(
const gsl::span<const TrackTPC> tracksTPC,
const gsl::span<const o2::dataformats::PrimaryVertex> vertices)
1646 const int nVertices = vertices.size();
1648 const int nTracks = tracksTPC.size();
1649 mNearestVtxTPC.clear();
1650 mNearestVtxTPC.resize(nTracks);
1654 std::fill(mNearestVtxTPC.begin(), mNearestVtxTPC.end(), -1);
1659 std::vector<float> times_vtx;
1660 times_vtx.reserve(nVertices);
1661 for (
const auto& vtx : vertices) {
1662 times_vtx.emplace_back(vtx.getTimeStamp().getTimeStamp());
1666 auto myThread = [&](
int iThread) {
1667 for (
int i = iThread;
i < nTracks;
i += mNThreads) {
1669 const auto lower = std::lower_bound(times_vtx.begin(), times_vtx.end(), timeTrack);
1670 int closestVtx = std::distance(times_vtx.begin(), lower);
1672 if (closestVtx == nVertices) {
1674 }
else if (closestVtx > 0) {
1676 double diff1 = std::abs(timeTrack - *lower);
1677 double diff2 = std::abs(timeTrack - *(lower - 1));
1678 if (diff2 < diff1) {
1682 mNearestVtxTPC[
i] = closestVtx;
1686 std::vector<std::thread> threads(mNThreads);
1687 for (
int i = 0;
i < mNThreads;
i++) {
1688 threads[
i] = std::thread(myThread,
i);
1692 for (
auto& th : threads) {
1698 std::vector<bool> makeClusterBitMask(
const TrackTPC& track)
const
1701 const int nCl =
track.getNClusterReferences();
1702 for (
int j = 0;
j <
nCl; ++
j) {
1704 uint32_t clusterIndexInRow;
1705 track.getClusterReference(mTPCTrackClIdx,
j, sector,
padrow, clusterIndexInRow);
1706 tpcClusterMask[
padrow] =
true;
1708 return tpcClusterMask;
1712 void findNNeighbourTracks(
const gsl::span<const TrackTPC> tracksTPC)
1715 const float windowTimeBins = mTimeWindowMUS / tpcTBinMUS;
1718 std::vector<float>
times;
1719 const int nTracks = tracksTPC.size();
1720 times.reserve(nTracks);
1721 for (
const auto& trk : tracksTPC) {
1722 times.emplace_back(trk.getTime0());
1726 mNTracksWindow.clear();
1727 mNTracksWindow.resize(nTracks);
1730 auto myThread = [&](
int iThread) {
1731 for (
int i = iThread;
i < nTracks;
i += mNThreads) {
1732 const float t0 = tracksTPC[
i].getTime0();
1733 const auto upperV0 = std::upper_bound(
times.begin(),
times.end(),
t0 + windowTimeBins);
1734 const auto lowerV0 = std::lower_bound(
times.begin(),
times.end(),
t0 - windowTimeBins);
1735 const int nMult = std::distance(
times.begin(), upperV0) - std::distance(
times.begin(), lowerV0);
1736 mNTracksWindow[
i] = nMult;
1740 std::vector<std::thread> threads(mNThreads);
1741 for (
int i = 0;
i < mNThreads;
i++) {
1742 threads[
i] = std::thread(myThread,
i);
1746 for (
auto& th : threads) {
1751 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)
1754 std::unordered_map<unsigned int, int> indicesITSTPC_vtx;
1756 std::unordered_map<int, int> nContributors_ITS;
1757 std::unordered_map<int, int> nContributors_ITSTPC;
1758 std::unordered_map<int, int> nContributors_TRD;
1761 if (!vertices.empty()) {
1762 for (
const auto&
ref : primMatchedTracksRef) {
1764 const std::array<TrkSrc, 5>
sources = {TrkSrc::ITSTPC, TrkSrc::ITSTPCTRD, TrkSrc::ITSTPCTOF, TrkSrc::ITSTPCTRDTOF, TrkSrc::ITS};
1766 const int vID =
ref.getVtxID();
1767 const int firstEntry =
ref.getFirstEntryOfSource(
source);
1768 const int nEntries =
ref.getEntriesOfSource(
source);
1770 for (
int i = 0;
i < nEntries; ++
i) {
1771 const auto& matchedTrk = primMatchedTracks[
i + firstEntry];
1772 bool pvCont = matchedTrk.isPVContributor();
1776 if (refITSTPC.isIndexSet()) {
1777 indicesITSTPC_vtx[refITSTPC] = vID;
1778 ++nContributors_ITSTPC[vID];
1780 if (
source == TrkSrc::ITSTPCTRD ||
source == TrkSrc::ITSTPCTRDTOF) {
1781 ++nContributors_TRD[vID];
1784 ++nContributors_ITS[vID];
1793 std::array<RobustAverage, 4> avgVtxITS;
1794 std::array<RobustAverage, 4> avgVtxITSTPC;
1795 for (
int i = 0;
i < avgVtxITS.size(); ++
i) {
1796 avgVtxITS[
i].reserve(vertices.size());
1797 avgVtxITSTPC[
i].reserve(vertices.size());
1799 for (
int ivtx = 0; ivtx < vertices.size(); ++ivtx) {
1800 const auto& vtx = vertices[ivtx];
1801 const float itsFrac = nContributors_ITS[ivtx] /
static_cast<float>(vtx.getNContributors());
1802 const float itstpcFrac = (nContributors_ITS[ivtx] + nContributors_ITSTPC[ivtx]) /
static_cast<float>(vtx.getNContributors());
1804 const float itsMin = 0.2;
1805 const float itsMax = 0.8;
1806 if ((itsFrac > itsMin) && (itsFrac < itsMax)) {
1807 avgVtxITS[0].addValue(vtx.getX());
1808 avgVtxITS[1].addValue(vtx.getY());
1809 avgVtxITS[2].addValue(vtx.getZ());
1810 avgVtxITS[3].addValue(vtx.getNContributors());
1813 const float itstpcMax = 0.95;
1814 if (itstpcFrac < itstpcMax) {
1815 avgVtxITSTPC[0].addValue(vtx.getX());
1816 avgVtxITSTPC[1].addValue(vtx.getY());
1817 avgVtxITSTPC[2].addValue(vtx.getZ());
1818 avgVtxITSTPC[3].addValue(vtx.getNContributors());
1823 mBufferDCA.nPrimVertices_ITS.front() = avgVtxITS[3].getValues().size();
1824 mBufferDCA.nVertexContributors_ITS_Median.front() = avgVtxITS[3].getMedian();
1825 mBufferDCA.nVertexContributors_ITS_RMS.front() = avgVtxITS[3].getStdDev();
1826 mBufferDCA.vertexX_ITS_Median.front() = avgVtxITS[0].getMedian();
1827 mBufferDCA.vertexY_ITS_Median.front() = avgVtxITS[1].getMedian();
1828 mBufferDCA.vertexZ_ITS_Median.front() = avgVtxITS[2].getMedian();
1829 mBufferDCA.vertexX_ITS_RMS.front() = avgVtxITS[0].getStdDev();
1830 mBufferDCA.vertexY_ITS_RMS.front() = avgVtxITS[1].getStdDev();
1831 mBufferDCA.vertexZ_ITS_RMS.front() = avgVtxITS[2].getStdDev();
1834 mBufferDCA.nPrimVertices_ITSTPC.front() = avgVtxITSTPC[3].getValues().size();
1835 mBufferDCA.nVertexContributors_ITSTPC_Median.front() = avgVtxITSTPC[3].getMedian();
1836 mBufferDCA.nVertexContributors_ITSTPC_RMS.front() = avgVtxITSTPC[3].getStdDev();
1837 mBufferDCA.vertexX_ITSTPC_Median.front() = avgVtxITSTPC[0].getMedian();
1838 mBufferDCA.vertexY_ITSTPC_Median.front() = avgVtxITSTPC[1].getMedian();
1839 mBufferDCA.vertexZ_ITSTPC_Median.front() = avgVtxITSTPC[2].getMedian();
1840 mBufferDCA.vertexX_ITSTPC_RMS.front() = avgVtxITSTPC[0].getStdDev();
1841 mBufferDCA.vertexY_ITSTPC_RMS.front() = avgVtxITSTPC[1].getStdDev();
1842 mBufferDCA.vertexZ_ITSTPC_RMS.front() = avgVtxITSTPC[2].getStdDev();
1845 int sumITSTPCBased = 0;
1847 for (
int ivtx = 0; ivtx < vertices.size(); ++ivtx) {
1848 sumITSTPCBased += nContributors_ITSTPC[ivtx];
1849 sumWithTRD += nContributors_TRD[ivtx];
1851 mBufferDCA.nITSTPCBasedPVContributors.front() = sumITSTPCBased;
1852 mBufferDCA.nITSTPCWithTRDPVContributors.front() = sumWithTRD;
1853 mBufferDCA.fracTRD.front() = (sumITSTPCBased > 0) ?
static_cast<float>(sumWithTRD) / sumITSTPCBased : std::nanf(
"");
1856 RobustAverage avg(vertices.size(),
false);
1857 for (
const auto& vtx : vertices) {
1858 if (vtx.getNContributors() > mMinTracksPerVertex) {
1860 avg.addValue(std::sqrt(vtx.getNContributors()));
1865 int sizeQ = mBufferDCA.nVertexContributors_Quantiles.size();
1866 const int nBinsQ = 20;
1867 if (sizeQ >= (nBinsQ + 3)) {
1868 for (
int iq = 0; iq < nBinsQ; ++iq) {
1869 const float quantile = (iq + 1) /
static_cast<float>(nBinsQ);
1870 const float val = avg.getQuantile(quantile, 1);
1871 mBufferDCA.nVertexContributors_Quantiles[iq] =
val *
val;
1873 const float tr0 = avg.getTrunctedMean(0.05, 0.95);
1874 const float tr1 = avg.getTrunctedMean(0.1, 0.9);
1875 const float tr2 = avg.getTrunctedMean(0.2, 0.8);
1876 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 3] = tr0 * tr0;
1877 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 2] = tr1 * tr1;
1878 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 1] = tr2 * tr2;
1880 mBufferDCA.nPrimVertices.front() = vertices.size();
1882 return indicesITSTPC_vtx;
1886 int getNBins()
const {
return mBufferDCA.mTSTPC.getNBins(); }
1888 ValsdEdx getdEdxVars(
bool useQMax,
const TrackTPC& track)
const
1890 const float dedx = useQMax ?
track.getdEdx().dEdxMaxTPC :
track.getdEdx().dEdxTotTPC;
1894 if (std::abs(dedxNorm) > mMaxdEdxRatio) {
1899 float dedxIROC = -1;
1900 float dedxOROC1 = -1;
1901 float dedxOROC2 = -1;
1902 float dedxOROC3 = -1;
1904 dedxIROC = useQMax ?
track.getdEdx().dEdxMaxIROC :
track.getdEdx().dEdxTotIROC;
1905 dedxOROC1 = useQMax ?
track.getdEdx().dEdxMaxOROC1 :
track.getdEdx().dEdxTotOROC1;
1906 dedxOROC2 = useQMax ?
track.getdEdx().dEdxMaxOROC2 :
track.getdEdx().dEdxTotOROC2;
1907 dedxOROC3 = useQMax ?
track.getdEdx().dEdxMaxOROC3 :
track.getdEdx().dEdxTotOROC3;
1912 dedxIROC = (dedxIROC > 0) ? std::log(dedxIROC) : -1;
1913 dedxOROC1 = (dedxOROC1 > 0) ? std::log(dedxOROC1) : -1;
1914 dedxOROC2 = (dedxOROC2 > 0) ? std::log(dedxOROC2) : -1;
1915 dedxOROC3 = (dedxOROC3 > 0) ? std::log(dedxOROC3) : -1;
1918 if (std::abs(dedxIROC) > mMaxdEdxRegionRatio) {
1921 if (std::abs(dedxOROC1) > mMaxdEdxRegionRatio) {
1924 if (std::abs(dedxOROC2) > mMaxdEdxRegionRatio) {
1927 if (std::abs(dedxOROC3) > mMaxdEdxRegionRatio) {
1931 return ValsdEdx{dedxNorm, dedxIROC, dedxOROC1, dedxOROC2, dedxOROC3};