86 float d0 = trk1.getY() - trk2.getY();
87 float d1 = trk1.getSnp() - trk2.getSnp();
88 float d2 = trk1.getQ2Pt() - trk2.getQ2Pt();
90 float c00 = trk1.getSigmaY2() + trk2.getSigmaY2();
91 float c01 = trk1.getSigmaSnpY() + trk2.getSigmaSnpY();
92 float c02 = trk1.getSigma1PtY() + trk2.getSigma1PtY();
93 float c11 = trk1.getSigmaSnp2() + trk2.getSigmaSnp2();
94 float c12 = trk1.getSigma1PtSnp() + trk2.getSigma1PtSnp();
95 float c22 = trk1.getSigma1Pt2() + trk2.getSigma1Pt2();
96 float det = c00 * (c11 * c22 - c12 * c12) - c01 * (c01 * c22 - c12 * c02) + c02 * (c01 * c12 - c11 * c02);
97 if (std::abs(det) < 1e-30f) {
100 float detInv = 1.f / det;
101 float i00 = (c11 * c22 - c12 * c12) * detInv;
102 float i01 = (c02 * c12 - c01 * c22) * detInv;
103 float i02 = (c01 * c12 - c02 * c11) * detInv;
104 float i11 = (c00 * c22 - c02 * c02) * detInv;
105 float i12 = (c01 * c02 - c00 * c12) * detInv;
106 float i22 = (c00 * c11 - c01 * c01) * detInv;
107 return d0 * (i00 * d0 + i01 * d1 + i02 * d2) + d1 * (i01 * d0 + i11 * d1 + i12 * d2) + d2 * (i02 * d0 + i12 * d1 + i22 * d2);
115 float d0 = trk1.getZ() - trk2.getZ();
116 float d1 = trk1.getTgl() - trk2.getTgl();
117 float c00 = trk1.getSigmaZ2() + trk2.getSigmaZ2();
118 float c01 = trk1.getSigmaTglZ() + trk2.getSigmaTglZ();
119 float c11 = trk1.getSigmaTgl2() + trk2.getSigmaTgl2();
120 float det = c00 * c11 - c01 * c01;
121 if (std::abs(det) < 1e-30f) {
124 float detInv = 1.f / det;
125 return (d0 * d0 * c11 - 2.f * d0 * d1 * c01 + d1 * d1 * c00) * detInv;
129 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) {};
134 mNMaxTracks = ic.options().get<
int>(
"max-tracks");
135 mMinMom = ic.options().get<
float>(
"min-momentum");
136 mMinNCl = ic.options().get<
int>(
"min-cluster");
137 mMaxTgl = ic.options().get<
float>(
"max-tgl");
138 mMaxQPt = ic.options().get<
float>(
"max-qPt");
139 mCoarseStep = ic.options().get<
float>(
"coarse-step");
140 mFineStep = ic.options().get<
float>(
"fine-step");
141 mCutDCA = ic.options().get<
float>(
"cut-DCA-median");
142 mCutRMS = ic.options().get<
float>(
"cut-DCA-RMS");
143 mRefXSec = ic.options().get<
float>(
"refX-for-sector");
144 mTglBins = ic.options().get<
int>(
"tgl-bins");
145 mPhiBins = ic.options().get<
int>(
"phi-bins");
146 mQPtBins = ic.options().get<
int>(
"qPt-bins");
147 mNThreads = ic.options().get<
int>(
"threads");
148 maxITSTPCDCAr = ic.options().get<
float>(
"max-ITS-TPC-DCAr");
149 maxITSTPCDCAz = ic.options().get<
float>(
"max-ITS-TPC-DCAz");
150 maxITSTPCDCAr_comb = ic.options().get<
float>(
"max-ITS-TPC-DCAr_comb");
151 maxITSTPCDCAz_comb = ic.options().get<
float>(
"max-ITS-TPC-DCAz_comb");
152 mTimeWindowMUS = ic.options().get<
float>(
"time-window-mult-mus");
153 mMIPdEdx = ic.options().get<
float>(
"MIP-dedx");
154 mMaxSnp = ic.options().get<
float>(
"max-snp");
155 mXCoarse = ic.options().get<
float>(
"mX-coarse");
156 mSqrt = ic.options().get<
float>(
"sqrts");
157 mMultBins = ic.options().get<
int>(
"mult-bins");
158 mMultMax = ic.options().get<
int>(
"mult-max");
159 mMinTracksPerVertex = ic.options().get<
int>(
"min-tracks-per-vertex");
160 mMaxdEdxRatio = ic.options().get<
float>(
"max-dedx-ratio");
161 mMaxdEdxRegionRatio = ic.options().get<
float>(
"max-dedx-region-ratio");
162 mSamplingFactor = ic.options().get<
float>(
"sampling-factor");
163 mSampleTsallis = ic.options().get<
bool>(
"sample-unbinned-tsallis");
164 mXOuterMatching = ic.options().get<
float>(
"refX-for-outer-ITS");
165 mUseMinBiasTrigger = !ic.options().get<
bool>(
"disable-min-bias-trigger");
166 mMaxOccupancyHistBins = ic.options().get<
int>(
"max-occupancy-bins");
167 mStoreFullTrackPar = ic.options().get<
bool>(
"store-full-trackpar");
169 if (mUnbinnedWriter) {
170 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
171 mGenerator.emplace_back(std::mt19937(std::random_device{}()));
174 mBufferVals.resize(mNThreads);
175 mBufferDCA.
setBinning(mPhiBins, mTglBins, mQPtBins, mMultBins, mMaxTgl, mMaxQPt, mMultMax);
176 if (mUnbinnedWriter) {
177 std::string outfile = ic.options().get<std::string>(
"out-file-unbinned");
179 ROOT::EnableThreadSafety();
181 mStreamer.resize(mNThreads);
182 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
183 std::string outfileThr = outfile;
184 outfileThr.replace(outfileThr.length() - 5, outfileThr.length(), fmt::format(
"_{}.root", iThread));
185 LOGP(info,
"Writing unbinned data to: {}", outfileThr);
186 mStreamer[iThread] = std::make_unique<o2::utils::TreeStreamRedirector>(outfileThr.data(),
"recreate");
197 if (mUnbinnedWriter) {
199 mTRDInReadout = grpecs ?
static_cast<uint8_t
>(grpecs->isDetReadOut(DetID::TRD) ? 1 : 0) :
static_cast<uint8_t
>(255);
206 LOGP(info,
"Updated reference drift velocity to: {}", mVDrift);
208 pc.inputs().get<TTree*>(
"tpcSecFlucInfo");
211 const int nBins = getNBins();
220 if (mAvgADCAr.size() != nBins) {
222 mAvgADCAr.resize(nBins);
223 mAvgCDCAr.resize(nBins);
224 mAvgADCAz.resize(nBins);
225 mAvgCDCAz.resize(nBins);
226 mAvgMeffA.resize(nBins);
227 mAvgMeffC.resize(nBins);
228 mAvgChi2MatchA.resize(nBins);
229 mAvgChi2MatchC.resize(nBins);
230 mMIPdEdxRatioQMaxA.resize(nBins);
231 mMIPdEdxRatioQMaxC.resize(nBins);
232 mMIPdEdxRatioQTotA.resize(nBins);
233 mMIPdEdxRatioQTotC.resize(nBins);
234 mTPCChi2A.resize(nBins);
235 mTPCChi2C.resize(nBins);
236 mTPCNClA.resize(nBins);
237 mTPCNClC.resize(nBins);
238 mLogdEdxQTotA.resize(nBins);
239 mLogdEdxQTotC.resize(nBins);
240 mLogdEdxQMaxA.resize(nBins);
241 mLogdEdxQMaxC.resize(nBins);
242 mITSPropertiesA.resize(nBins);
243 mITSPropertiesC.resize(nBins);
244 mITSTPCDeltaPA.resize(nBins);
245 mITSTPCDeltaPC.resize(nBins);
246 mSigmaYZA.resize(nBins);
247 mSigmaYZC.resize(nBins);
255 auto tracksITSTPC = mTPCOnly ? gsl::span<o2::dataformats::TrackTPCITS>() : recoData.
getTPCITSTracks();
256 auto tracksITS = mTPCOnly ? gsl::span<o2::its::TrackITS>() : recoData.
getITSTracks();
259 auto vertices = mTPCOnly ? gsl::span<o2::dataformats::PrimaryVertex>() : recoData.
getPrimaryVertices();
270 const auto& tofClusters = mTPCOnly ? gsl::span<o2::tof::Cluster>() : recoData.
getTOFClusters();
272 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());
275 auto indicesITSTPC_vtx = processVertices(vertices, primMatchedTracks, primMatchedTracksRef, recoData);
278 std::unordered_map<unsigned int, std::array<int, 2>> indicesITSTPC;
280 for (
int i = 0;
i < tracksITSTPC.size(); ++
i) {
281 auto it = indicesITSTPC_vtx.find(
i);
283 const auto idxVtx = (it != indicesITSTPC_vtx.end()) ? (it->second) : -1;
285 indicesITSTPC[tracksITSTPC[
i].getRefTPC().getIndex()] = {
i, idxVtx};
288 std::vector<std::tuple<int, float, float, o2::track::TrackLTIntegral, double, float, unsigned int, unsigned short>> idxTPCTrackToTOFCluster;
291 if (mUnbinnedWriter) {
295 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});
300 std::map<ULong64_t, short> t0array;
301 for (
const auto&
t0 : ft0rec) {
302 if (!(
t0.isValidTime(1) &&
t0.isValidTime(2))) {
306 auto bclong =
t0.mIntRecord.differenceInBC(recoData.
startIR);
307 if (t0array.find(bclong) == t0array.end()) {
308 t0array.emplace(std::make_pair(bclong,
t0.getCollisionTime(0)));
312 static const double BC_TIME_INPS_INV = 1E-3 / o2::constants::lhc::LHCBunchSpacingNS;
315 for (
const auto& tofMatch : tofMatches) {
316 for (
const auto& tpctofmatch : tofMatch) {
318 if (refTPC.isIndexSet()) {
320 ULong64_t bclongtof = (tpctofmatch.getSignal() - 10000) * BC_TIME_INPS_INV;
322 unsigned int mask = 0;
323 if (!(t0array.find(bclongtof) == t0array.end())) {
324 t0 += t0array.find(bclongtof)->second;
328 double signal = tpctofmatch.getSignal() -
t0;
329 float deltaT = tpctofmatch.getDeltaT();
331 float dy = tpctofmatch.getDYatTOF();
332 bool isMultiHitZ = tpctofmatch.getHitPatternUpDown();
333 bool isMultiHitX = tpctofmatch.getHitPatternLeftRight();
334 bool isMultiStripMatch = tpctofmatch.getChi2() < 1E-9;
335 float chi2 = tpctofmatch.getChi2();
336 bool hasT0_1BCbefore = (t0array.find(bclongtof - 1) != t0array.end());
337 bool hasT0_2BCbefore = (t0array.find(bclongtof - 2) != t0array.end());
345 if (fabs(dy) > 0.5) {
348 if (isMultiStripMatch) {
360 if (hasT0_1BCbefore) {
363 if (hasT0_2BCbefore) {
367 idxTPCTrackToTOFCluster[refTPC] = {tpctofmatch.getIdxTOFCl(), tpctofmatch.getDXatTOF(), tpctofmatch.getDZatTOF(), ltIntegral, signal, deltaT,
mask, tpctofmatch.getChannel() % 8736};
374 findNearesVertex(tracksTPC, vertices);
378 std::unordered_map<unsigned int, TRDTrackletData> tpcToTRDMap;
379 auto trdTracklets = (mTPCOnly || !recoData.
inputsTRD) ? gsl::span<const o2::trd::Tracklet64>() : recoData.
getTRDTracklets();
385 mTRDTrigBCsInTF.clear();
386 if (mUnbinnedWriter && !mTPCOnly && recoData.
inputsTRD) {
388 mTRDTrigBCs.reserve(trdTrig.size());
389 for (
const auto& trg : trdTrig) {
390 if (trg.getBCData().bc < o2::constants::lhc::LHCMaxBunches) {
391 mTRDTrigBCs.push_back(trg.getBCData());
394 std::sort(mTRDTrigBCs.begin(), mTRDTrigBCs.end());
396 if (mUnbinnedWriter && !mTPCOnly) {
399 for (
unsigned int ig = 0; ig < itstpctrdTracks.size(); ++ig) {
402 if (!refTPC.isIndexSet()) {
406 if (!refTRD.isIndexSet()) {
411 for (
int iLay = 0; iLay < 6; ++iLay) {
412 auto trkltId = trdTrack.getTrackletIndex(iLay);
415 trdData.nTRDTracklets++;
416 trdData.trackletIndices[iLay] = trkltId;
422 trdData.hasTRDTrackPar =
true;
423 tpcToTRDMap[refTPC] = trdData;
428 if (mUnbinnedWriter) {
429 mTPCTrackClIdx = pc.inputs().get<gsl::span<o2::tpc::TPCClRefElem>>(
"trackTPCClRefs");
433 mTRDTrigBCsInTF.reserve(mTRDTrigBCs.size());
434 for (
const auto&
ir : mTRDTrigBCs) {
440 findNNeighbourTracks(tracksTPC);
443 for (
int i = 0;
i < nBins; ++
i) {
445 mAvgADCAr[
i][
type].clear();
446 mAvgCDCAr[
i][
type].clear();
447 mAvgADCAz[
i][
type].clear();
448 mAvgCDCAz[
i][
type].clear();
450 for (
int type = 0;
type < mMIPdEdxRatioQMaxA[
i].size(); ++
type) {
451 mMIPdEdxRatioQMaxA[
i][
type].clear();
452 mMIPdEdxRatioQMaxC[
i][
type].clear();
453 mMIPdEdxRatioQTotA[
i][
type].clear();
454 mMIPdEdxRatioQTotC[
i][
type].clear();
455 mTPCChi2A[
i][
type].clear();
456 mTPCChi2C[
i][
type].clear();
457 mTPCNClA[
i][
type].clear();
458 mTPCNClC[
i][
type].clear();
459 mMIPdEdxRatioQMaxA[
i][
type].setUseWeights(
false);
460 mMIPdEdxRatioQMaxC[
i][
type].setUseWeights(
false);
461 mMIPdEdxRatioQTotA[
i][
type].setUseWeights(
false);
462 mMIPdEdxRatioQTotC[
i][
type].setUseWeights(
false);
463 mTPCChi2A[
i][
type].setUseWeights(
false);
464 mTPCChi2C[
i][
type].setUseWeights(
false);
465 mTPCNClA[
i][
type].setUseWeights(
false);
466 mTPCNClC[
i][
type].setUseWeights(
false);
469 mLogdEdxQTotA[
i][
type].clear();
470 mLogdEdxQTotC[
i][
type].clear();
471 mLogdEdxQMaxA[
i][
type].clear();
472 mLogdEdxQMaxC[
i][
type].clear();
473 mLogdEdxQTotA[
i][
type].setUseWeights(
false);
474 mLogdEdxQTotC[
i][
type].setUseWeights(
false);
475 mLogdEdxQMaxA[
i][
type].setUseWeights(
false);
476 mLogdEdxQMaxC[
i][
type].setUseWeights(
false);
478 for (
int j = 0;
j < mITSPropertiesA[
i].size(); ++
j) {
479 mITSPropertiesA[
i][
j].clear();
480 mITSPropertiesC[
i][
j].clear();
481 mITSPropertiesA[
i][
j].setUseWeights(
false);
482 mITSPropertiesC[
i][
j].setUseWeights(
false);
485 for (
int j = 0;
j < mITSTPCDeltaPA[
i].size(); ++
j) {
486 mITSTPCDeltaPA[
i][
j].clear();
487 mITSTPCDeltaPC[
i][
j].clear();
488 mITSTPCDeltaPA[
i][
j].setUseWeights(
false);
489 mITSTPCDeltaPC[
i][
j].setUseWeights(
false);
492 for (
int j = 0;
j < mSigmaYZA[
i].size(); ++
j) {
493 mSigmaYZA[
i][
j].clear();
494 mSigmaYZC[
i][
j].clear();
495 mSigmaYZA[
i][
j].setUseWeights(
false);
496 mSigmaYZC[
i][
j].setUseWeights(
false);
499 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
500 mAvgMeffA[
i][
j].clear();
501 mAvgMeffC[
i][
j].clear();
502 mAvgChi2MatchA[
i][
j].clear();
503 mAvgChi2MatchC[
i][
j].clear();
504 mAvgMeffA[
i][
j].setUseWeights(
false);
505 mAvgMeffC[
i][
j].setUseWeights(
false);
506 mAvgChi2MatchA[
i][
j].setUseWeights(
false);
507 mAvgChi2MatchC[
i][
j].setUseWeights(
false);
511 for (
int i = 0;
i < mNThreads; ++
i) {
512 mBufferVals[
i].front().clear();
513 mBufferVals[
i].back().clear();
517 const auto nTracks = tracksTPC.size();
518 const size_t loopEnd = (mNMaxTracks < 0) ? nTracks : ((mNMaxTracks > nTracks) ? nTracks : size_t(mNMaxTracks));
521 for (
int i = 0;
i < nBins; ++
i) {
528 if (
i < lastIdxPhi) {
529 resMem = loopEnd / mPhiBins;
530 }
else if (
i < lastIdxTgl) {
531 resMem = loopEnd / mTglBins;
532 }
else if (
i < lastIdxQPt) {
533 resMem = loopEnd / mQPtBins;
534 }
else if (
i < lastIdxMult) {
535 resMem = loopEnd / mMultBins;
542 mAvgADCAr[
i][
type].reserve(resMem);
543 mAvgCDCAr[
i][
type].reserve(resMem);
544 mAvgADCAz[
i][
type].reserve(resMem);
545 mAvgCDCAz[
i][
type].reserve(resMem);
547 for (
int type = 0;
type < mMIPdEdxRatioQMaxA[
i].size(); ++
type) {
548 mMIPdEdxRatioQMaxA[
i][
type].reserve(resMem);
549 mMIPdEdxRatioQMaxC[
i][
type].reserve(resMem);
550 mMIPdEdxRatioQTotA[
i][
type].reserve(resMem);
551 mMIPdEdxRatioQTotC[
i][
type].reserve(resMem);
552 mTPCChi2A[
i][
type].reserve(resMem);
553 mTPCChi2C[
i][
type].reserve(resMem);
554 mTPCNClA[
i][
type].reserve(resMem);
555 mTPCNClC[
i][
type].reserve(resMem);
557 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
558 mAvgMeffA[
i][
j].reserve(resMem);
559 mAvgMeffC[
i][
j].reserve(resMem);
560 mAvgChi2MatchA[
i][
j].reserve(resMem);
561 mAvgChi2MatchC[
i][
j].reserve(resMem);
563 for (
int j = 0;
j < mITSPropertiesA[
i].size(); ++
j) {
564 mITSPropertiesA[
i][
j].reserve(resMem);
565 mITSPropertiesC[
i][
j].reserve(resMem);
567 for (
int j = 0;
j < mITSTPCDeltaPA[
i].size(); ++
j) {
568 mITSTPCDeltaPA[
i][
j].reserve(resMem);
569 mITSTPCDeltaPC[
i][
j].reserve(resMem);
571 for (
int j = 0;
j < mSigmaYZA[
i].size(); ++
j) {
572 mSigmaYZA[
i][
j].reserve(resMem);
573 mSigmaYZC[
i][
j].reserve(resMem);
575 for (
int j = 0;
j < mAvgMeffA[
i].size(); ++
j) {
576 mLogdEdxQTotA[
i][
j].reserve(resMem);
577 mLogdEdxQTotC[
i][
j].reserve(resMem);
578 mLogdEdxQMaxA[
i][
j].reserve(resMem);
579 mLogdEdxQMaxC[
i][
j].reserve(resMem);
582 for (
int iThread = 0; iThread < mNThreads; ++iThread) {
583 const int resMem = (mNThreads > 0) ? loopEnd / mNThreads : loopEnd;
584 mBufferVals[iThread].front().reserve(loopEnd, 1);
585 mBufferVals[iThread].back().reserve(loopEnd, 0);
588 using timer = std::chrono::high_resolution_clock;
589 auto startTotal = timer::now();
592 if (loopEnd < nTracks) {
594 std::vector<size_t> ind(nTracks);
595 std::iota(ind.begin(), ind.end(), 0);
596 std::minstd_rand rng(std::time(
nullptr));
597 std::shuffle(ind.begin(), ind.end(), rng);
599 auto myThread = [&](
int iThread) {
600 for (
size_t i = iThread;
i < loopEnd;
i += mNThreads) {
601 if (acceptTrack(tracksTPC[
i])) {
602 fillDCA(tracksTPC, tracksITSTPC, vertices,
i, iThread, indicesITSTPC, tracksITS, idxTPCTrackToTOFCluster, tofClusters, tpcToTRDMap, trdTracklets, trdCalibTracklets);
607 std::vector<std::thread> threads(mNThreads);
608 for (
int i = 0;
i < mNThreads;
i++) {
609 threads[
i] = std::thread(myThread,
i);
612 for (
auto& th : threads) {
616 auto myThread = [&](
int iThread) {
617 for (
size_t i = iThread;
i < loopEnd;
i += mNThreads) {
618 if (acceptTrack(tracksTPC[
i])) {
619 fillDCA(tracksTPC, tracksITSTPC, vertices,
i, iThread, indicesITSTPC, tracksITS, idxTPCTrackToTOFCluster, tofClusters, tpcToTRDMap, trdTracklets, trdCalibTracklets);
624 std::vector<std::thread> threads(mNThreads);
625 for (
int i = 0;
i < mNThreads;
i++) {
626 threads[
i] = std::thread(myThread,
i);
629 for (
auto& th : threads) {
635 for (
const auto& vals : mBufferVals) {
638 const auto nPoints =
val.side.size();
639 for (
int i = 0;
i < nPoints; ++
i) {
640 const auto tglBin =
val.tglBin[
i];
641 const auto phiBin =
val.phiBin[
i];
642 const auto qPtBin =
val.qPtBin[
i];
643 const auto multBin =
val.multBin[
i];
644 const auto dcar =
val.dcar[
i];
645 const auto dcaz =
val.dcaz[
i];
646 const auto dcarW =
val.dcarW[
i];
647 const int binInt = nBins - 1;
648 const bool fillCombDCA = ((
type == 1) && (
val.dcarcomb[
i] != -1) && (
val.dcazcomb[
i] != -1));
649 const bool fillDCAR = (
type == 1) ? (dcar != -999) :
true;
650 const std::array<int, 5>
bins{tglBin, phiBin, qPtBin, multBin, binInt};
652 for (
auto bin :
bins) {
655 mAvgCDCAr[bin][
type].addValue(dcar, dcarW);
658 mAvgCDCAr[bin][2].addValue(
val.dcarcomb[
i], dcarW);
659 mAvgCDCAz[bin][2].addValue(
val.dcazcomb[
i], dcarW);
663 mAvgCDCAz[bin][
type].addValue(dcaz, dcarW);
667 mAvgADCAr[bin][
type].addValue(dcar, dcarW);
670 mAvgADCAr[bin][2].addValue(
val.dcarcomb[
i], dcarW);
671 mAvgADCAz[bin][2].addValue(
val.dcazcomb[
i], dcarW);
675 mAvgADCAz[bin][
type].addValue(dcaz, dcarW);
687 for (
int slice = 0; slice < nBins; ++slice) {
690 const auto dcaAr = mAvgADCAr[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
691 bufferDCA.mDCAr_A_Median[slice] = std::get<0>(dcaAr);
692 bufferDCA.mDCAr_A_WeightedMean[slice] = std::get<1>(dcaAr);
693 bufferDCA.mDCAr_A_RMS[slice] = std::get<2>(dcaAr);
694 bufferDCA.mDCAr_A_NTracks[slice] = std::get<3>(dcaAr);
696 const auto dcaAz = mAvgADCAz[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
697 bufferDCA.mDCAz_A_Median[slice] = std::get<0>(dcaAz);
698 bufferDCA.mDCAz_A_WeightedMean[slice] = std::get<1>(dcaAz);
699 bufferDCA.mDCAz_A_RMS[slice] = std::get<2>(dcaAz);
700 bufferDCA.mDCAz_A_NTracks[slice] = std::get<3>(dcaAz);
702 const auto dcaCr = mAvgCDCAr[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
703 bufferDCA.mDCAr_C_Median[slice] = std::get<0>(dcaCr);
704 bufferDCA.mDCAr_C_WeightedMean[slice] = std::get<1>(dcaCr);
705 bufferDCA.mDCAr_C_RMS[slice] = std::get<2>(dcaCr);
706 bufferDCA.mDCAr_C_NTracks[slice] = std::get<3>(dcaCr);
708 const auto dcaCz = mAvgCDCAz[slice][
type].filterPointsMedian(mCutDCA, mCutRMS);
709 bufferDCA.mDCAz_C_Median[slice] = std::get<0>(dcaCz);
710 bufferDCA.mDCAz_C_WeightedMean[slice] = std::get<1>(dcaCz);
711 bufferDCA.mDCAz_C_RMS[slice] = std::get<2>(dcaCz);
712 bufferDCA.mDCAz_C_NTracks[slice] = std::get<3>(dcaCz);
715 const auto dcaArComb = mAvgADCAr[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
719 const auto dcaAzCom = mAvgADCAz[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
723 const auto dcaCrComb = mAvgCDCAr[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
727 const auto dcaCzComb = mAvgCDCAz[slice][2].filterPointsMedian(mCutDCA, mCutRMS);
735 for (
const auto& vals : mBufferVals) {
736 const auto&
val = vals.front();
737 const auto nPoints =
val.side.size();
738 for (
int i = 0;
i < nPoints; ++
i) {
739 const auto tglBin =
val.tglBin[
i];
740 const auto phiBin =
val.phiBin[
i];
741 const auto qPtBin =
val.qPtBin[
i];
742 const auto multBin =
val.multBin[
i];
743 const auto dcar =
val.dcar[
i];
744 const auto dcaz =
val.dcaz[
i];
745 const auto hasITS =
val.hasITS[
i];
746 const auto chi2Match =
val.chi2Match[
i];
747 const auto dedxRatioqMax =
val.dedxRatioqMax[
i];
748 const auto dedxRatioqTot =
val.dedxRatioqTot[
i];
749 const auto sqrtChi2TPC =
val.sqrtChi2TPC[
i];
750 const auto nClTPC =
val.nClTPC[
i];
751 const int binInt = nBins - 1;
758 auto& mAvgEff = isCSide ? mAvgMeffC : mAvgMeffA;
759 auto& mAvgChi2Match = isCSide ? mAvgChi2MatchC : mAvgChi2MatchA;
760 auto& mAvgmMIPdEdxRatioqMax = isCSide ? mMIPdEdxRatioQMaxC : mMIPdEdxRatioQMaxA;
761 auto& mAvgmMIPdEdxRatioqTot = isCSide ? mMIPdEdxRatioQTotC : mMIPdEdxRatioQTotA;
762 auto& mAvgmTPCChi2 = isCSide ? mTPCChi2C : mTPCChi2A;
763 auto& mAvgmTPCNCl = isCSide ? mTPCNClC : mTPCNClA;
764 auto& mAvgmdEdxRatioQMax = isCSide ? mLogdEdxQMaxC : mLogdEdxQMaxA;
765 auto& mAvgmdEdxRatioQTot = isCSide ? mLogdEdxQTotC : mLogdEdxQTotA;
766 auto& mITSProperties = isCSide ? mITSPropertiesC : mITSPropertiesA;
767 auto& mSigmaYZ = isCSide ? mSigmaYZC : mSigmaYZA;
768 auto& mITSTPCDeltaP = isCSide ? mITSTPCDeltaPC : mITSTPCDeltaPA;
770 const std::array<int, 5>
bins{tglBin, phiBin, qPtBin, multBin, binInt};
772 for (
auto bin :
bins) {
774 if ((std::abs(dcar - bufferDCAMedR[bin]) < (bufferDCARMSR[bin] * mCutRMS)) && (std::abs(dcaz - bufferDCAMedZ[bin]) < (bufferDCARMSZ[bin] * mCutRMS))) {
775 const auto gID =
val.gID[
i];
776 mAvgEff[bin][0].addValue(hasITS);
779 mAvgEff[bin][1].addValue(hasITS);
780 mAvgEff[bin][2].addValue(hasITS);
784 mAvgEff[bin][1].addValue(hasITS);
786 mAvgEff[bin][2].addValue(hasITS);
789 mAvgChi2Match[bin][0].addValue(chi2Match);
791 mAvgChi2Match[bin][1].addValue(chi2Match);
793 mAvgChi2Match[bin][2].addValue(chi2Match);
796 if (dedxRatioqMax > 0) {
797 mAvgmMIPdEdxRatioqMax[bin][0].addValue(dedxRatioqMax);
799 if (dedxRatioqTot > 0) {
800 mAvgmMIPdEdxRatioqTot[bin][0].addValue(dedxRatioqTot);
802 mAvgmTPCChi2[bin][0].addValue(sqrtChi2TPC);
803 mAvgmTPCNCl[bin][0].addValue(nClTPC);
805 if (dedxRatioqMax > 0) {
806 mAvgmMIPdEdxRatioqMax[bin][1].addValue(dedxRatioqMax);
808 if (dedxRatioqTot > 0) {
809 mAvgmMIPdEdxRatioqTot[bin][1].addValue(dedxRatioqTot);
811 mAvgmTPCChi2[bin][1].addValue(sqrtChi2TPC);
812 mAvgmTPCNCl[bin][1].addValue(nClTPC);
815 float dedxNormQMax =
val.dedxValsqMax[
i].dedxNorm;
816 if (dedxNormQMax > 0) {
817 mAvgmdEdxRatioQMax[bin][0].addValue(dedxNormQMax);
820 float dedxNormQTot =
val.dedxValsqTot[
i].dedxNorm;
821 if (dedxNormQTot > 0) {
822 mAvgmdEdxRatioQTot[bin][0].addValue(dedxNormQTot);
825 float dedxIROCQMax =
val.dedxValsqMax[
i].dedxIROC;
826 if (dedxIROCQMax > 0) {
827 mAvgmdEdxRatioQMax[bin][1].addValue(dedxIROCQMax);
830 float dedxIROCQTot =
val.dedxValsqTot[
i].dedxIROC;
831 if (dedxIROCQTot > 0) {
832 mAvgmdEdxRatioQTot[bin][1].addValue(dedxIROCQTot);
835 float dedxOROC1QMax =
val.dedxValsqMax[
i].dedxOROC1;
836 if (dedxOROC1QMax > 0) {
837 mAvgmdEdxRatioQMax[bin][2].addValue(dedxOROC1QMax);
840 float dedxOROC1QTot =
val.dedxValsqTot[
i].dedxOROC1;
841 if (dedxOROC1QTot > 0) {
842 mAvgmdEdxRatioQTot[bin][2].addValue(dedxOROC1QTot);
845 float dedxOROC2QMax =
val.dedxValsqMax[
i].dedxOROC2;
846 if (dedxOROC2QMax > 0) {
847 mAvgmdEdxRatioQMax[bin][3].addValue(dedxOROC2QMax);
850 float dedxOROC2QTot =
val.dedxValsqTot[
i].dedxOROC2;
851 if (dedxOROC2QTot > 0) {
852 mAvgmdEdxRatioQTot[bin][3].addValue(dedxOROC2QTot);
855 float dedxOROC3QMax =
val.dedxValsqMax[
i].dedxOROC3;
856 if (dedxOROC3QMax > 0) {
857 mAvgmdEdxRatioQMax[bin][4].addValue(dedxOROC3QMax);
860 float dedxOROC3QTot =
val.dedxValsqTot[
i].dedxOROC3;
861 if (dedxOROC3QTot > 0) {
862 mAvgmdEdxRatioQTot[bin][4].addValue(dedxOROC3QTot);
865 float nClITS =
val.nClITS[
i];
867 mITSProperties[bin][0].addValue(nClITS);
869 float chi2ITS =
val.chi2ITS[
i];
871 mITSProperties[bin][1].addValue(chi2ITS);
874 float sigmay2 =
val.sigmaY2[
i];
876 mSigmaYZ[bin][0].addValue(sigmay2);
878 float sigmaz2 =
val.sigmaZ2[
i];
880 mSigmaYZ[bin][1].addValue(sigmaz2);
883 float deltaP2 =
val.deltaP2[
i];
884 if (deltaP2 != -999) {
885 mITSTPCDeltaP[bin][0].addValue(deltaP2);
888 float deltaP3 =
val.deltaP3[
i];
889 if (deltaP3 != -999) {
890 mITSTPCDeltaP[bin][1].addValue(deltaP3);
893 float deltaP4 =
val.deltaP4[
i];
894 if (deltaP4 != -999) {
895 mITSTPCDeltaP[bin][2].addValue(deltaP4);
903 for (
int slice = 0; slice < nBins; ++slice) {
904 for (
int i = 0;
i < mAvgMeffA[slice].size(); ++
i) {
906 itsBuf.mITSTPC_A_MatchEff[slice] = mAvgMeffA[slice][
i].getMean();
907 itsBuf.mITSTPC_C_MatchEff[slice] = mAvgMeffC[slice][
i].getMean();
908 itsBuf.mITSTPC_A_Chi2Match[slice] = mAvgChi2MatchA[slice][
i].getMean();
909 itsBuf.mITSTPC_C_Chi2Match[slice] = mAvgChi2MatchC[slice][
i].getMean();
913 for (
int i = 0;
i < mMIPdEdxRatioQMaxC[slice].size(); ++
i) {
916 buff.mMIPdEdxRatioQMaxC[slice] = mMIPdEdxRatioQMaxC[slice][
i].getMean();
917 buff.mMIPdEdxRatioQTotA[slice] = mMIPdEdxRatioQTotA[slice][
i].getMean();
918 buff.mMIPdEdxRatioQTotC[slice] = mMIPdEdxRatioQTotC[slice][
i].getMean();
919 buff.mTPCChi2C[slice] = mTPCChi2C[slice][
i].getMean();
920 buff.mTPCChi2A[slice] = mTPCChi2A[slice][
i].getMean();
921 buff.mTPCNClC[slice] = mTPCNClC[slice][
i].getMean();
922 buff.mTPCNClA[slice] = mTPCNClA[slice][
i].getMean();
927 auto& logdEdxA = (
type == 0) ? mLogdEdxQMaxA : mLogdEdxQTotA;
931 buffer.mLogdEdx_A_RMS[slice] = logdEdxA[slice][0].getStdDev();
932 buffer.mLogdEdx_A_IROC_Median[slice] = logdEdxA[slice][1].getMedian();
933 buffer.mLogdEdx_A_IROC_RMS[slice] = logdEdxA[slice][1].getStdDev();
934 buffer.mLogdEdx_A_OROC1_Median[slice] = logdEdxA[slice][2].getMedian();
935 buffer.mLogdEdx_A_OROC1_RMS[slice] = logdEdxA[slice][2].getStdDev();
936 buffer.mLogdEdx_A_OROC2_Median[slice] = logdEdxA[slice][3].getMedian();
937 buffer.mLogdEdx_A_OROC2_RMS[slice] = logdEdxA[slice][3].getStdDev();
938 buffer.mLogdEdx_A_OROC3_Median[slice] = logdEdxA[slice][4].getMedian();
939 buffer.mLogdEdx_A_OROC3_RMS[slice] = logdEdxA[slice][4].getStdDev();
941 auto& logdEdxC = (
type == 0) ? mLogdEdxQMaxC : mLogdEdxQTotC;
942 buffer.mLogdEdx_C_Median[slice] = logdEdxC[slice][0].getMedian();
943 buffer.mLogdEdx_C_RMS[slice] = logdEdxC[slice][0].getStdDev();
944 buffer.mLogdEdx_C_IROC_Median[slice] = logdEdxC[slice][1].getMedian();
945 buffer.mLogdEdx_C_IROC_RMS[slice] = logdEdxC[slice][1].getStdDev();
946 buffer.mLogdEdx_C_OROC1_Median[slice] = logdEdxC[slice][2].getMedian();
947 buffer.mLogdEdx_C_OROC1_RMS[slice] = logdEdxC[slice][2].getStdDev();
948 buffer.mLogdEdx_C_OROC2_Median[slice] = logdEdxC[slice][3].getMedian();
949 buffer.mLogdEdx_C_OROC2_RMS[slice] = logdEdxC[slice][3].getStdDev();
950 buffer.mLogdEdx_C_OROC3_Median[slice] = logdEdxC[slice][4].getMedian();
951 buffer.mLogdEdx_C_OROC3_RMS[slice] = logdEdxC[slice][4].getStdDev();
957 mBufferDCA.
mITS_A_NCl_RMS[slice] = mITSPropertiesA[slice][0].getStdDev();
962 mBufferDCA.
mITS_C_NCl_RMS[slice] = mITSPropertiesC[slice][0].getStdDev();
989 auto stop = timer::now();
990 std::chrono::duration<float>
time = stop - startTotal;
991 LOGP(info,
"Time series creation took {}",
time.count());
999 for (
auto& streamer : mStreamer) {
1002 eos.services().get<
ControlService>().readyToQuit(QuitRequest::Me);
1011 LOGP(info,
"Updating TPC sector edge fluctuation info");
1013 LOGP(info,
"Loaded sector edge fluctuation information with {} intervals for {} runs", mSecEdgeFlucInfo.
size(), mSecEdgeFlucInfo.
getNRuns());
1022 float dedxOROC1 = 0;
1023 float dedxOROC2 = 0;
1024 float dedxOROC3 = 0;
1028 void reserve(
int n,
int type)
1038 dedxRatioqTot.reserve(
n);
1039 dedxRatioqMax.reserve(
n);
1040 sqrtChi2TPC.reserve(
n);
1044 chi2Match.reserve(
n);
1046 dedxValsqTot.reserve(
n);
1047 dedxValsqMax.reserve(
n);
1055 }
else if (
type == 0) {
1056 dcarcomb.reserve(
n);
1057 dcazcomb.reserve(
n);
1073 dedxRatioqTot.clear();
1074 dedxRatioqMax.clear();
1075 sqrtChi2TPC.clear();
1082 dedxValsqTot.clear();
1083 dedxValsqMax.clear();
1091 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)
1093 side.emplace_back(sideTmp);
1094 tglBin.emplace_back(tglBinTmp);
1095 phiBin.emplace_back(phiBinTmp);
1096 qPtBin.emplace_back(qPtBinTmp);
1097 multBin.emplace_back(multBinTmp);
1098 dcar.emplace_back(dcarTmp);
1099 dcaz.emplace_back(dcazTmp);
1100 dcarW.emplace_back(dcarWTmp);
1101 dedxRatioqTot.emplace_back(dedxRatioqTotTmp);
1102 dedxRatioqMax.emplace_back(dedxRatioqMaxTmp);
1103 sqrtChi2TPC.emplace_back(sqrtChi2TPCTmp);
1104 nClTPC.emplace_back(nClTPCTmp);
1105 chi2Match.emplace_back(chi2MatchTmp);
1106 hasITS.emplace_back(hasITSTmp);
1107 gID.emplace_back(gIDTmp);
1108 dedxValsqMax.emplace_back(dedxValsqMaxTmp);
1109 dedxValsqTot.emplace_back(dedxValsqTotTmp);
1110 nClITS.emplace_back(nClITSTmp);
1111 chi2ITS.emplace_back(chi2ITSTmp);
1112 sigmaY2.emplace_back(sigmaY2Tmp);
1113 sigmaZ2.emplace_back(sigmaZ2Tmp);
1114 deltaP2.emplace_back(-999);
1115 deltaP3.emplace_back(-999);
1116 deltaP4.emplace_back(-999);
1119 void setDeltaParam(
float deltaP2Tmp,
float deltaP3Tmp,
float deltaP4Tmp)
1121 if (!deltaP2.empty()) {
1122 deltaP2.back() = deltaP2Tmp;
1123 deltaP3.back() = deltaP3Tmp;
1124 deltaP4.back() = deltaP4Tmp;
1128 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)
1130 side.emplace_back(sideTmp);
1131 tglBin.emplace_back(tglBinTmp);
1132 phiBin.emplace_back(phiBinTmp);
1133 qPtBin.emplace_back(qPtBinTmp);
1134 multBin.emplace_back(multBinTmp);
1135 dcar.emplace_back(dcarTmp);
1136 dcaz.emplace_back(dcazTmp);
1137 dcarW.emplace_back(dcarWTmp);
1138 dedxRatioqTot.emplace_back(dedxRatioqTotTmp);
1139 dedxRatioqMax.emplace_back(dedxRatioqMaxTmp);
1140 sqrtChi2TPC.emplace_back(sqrtChi2TPCTmp);
1141 nClTPC.emplace_back(nClTPCTmp);
1142 dcarcomb.emplace_back(dcarCombTmp);
1143 dcazcomb.emplace_back(dcazCombTmp);
1146 std::vector<Side>
side;
1147 std::vector<int> tglBin;
1148 std::vector<int> phiBin;
1149 std::vector<int> qPtBin;
1150 std::vector<int> multBin;
1151 std::vector<float> dcar;
1152 std::vector<float> dcaz;
1153 std::vector<float> dcarW;
1154 std::vector<bool> hasITS;
1155 std::vector<float> chi2Match;
1156 std::vector<float> dedxRatioqTot;
1157 std::vector<float> dedxRatioqMax;
1158 std::vector<float> sqrtChi2TPC;
1159 std::vector<float> nClTPC;
1160 std::vector<float> dcarcomb;
1161 std::vector<float> dcazcomb;
1162 std::vector<ValsdEdx> dedxValsqTot;
1163 std::vector<ValsdEdx> dedxValsqMax;
1164 std::vector<int> nClITS;
1165 std::vector<float> chi2ITS;
1166 std::vector<o2::dataformats::GlobalTrackID::Source> gID;
1167 std::vector<float> deltaP2;
1168 std::vector<float> deltaP3;
1169 std::vector<float> deltaP4;
1170 std::vector<float> sigmaY2;
1171 std::vector<float> sigmaZ2;
1173 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
1174 const bool mDisableWriter{
false};
1176 const bool mUnbinnedWriter{
false};
1177 const bool mTPCOnly{
false};
1178 std::shared_ptr<o2::globaltracking::DataRequest> mDataRequest;
1179 int mPhiBins = SECTORSPERSIDE;
1182 TimeSeriesITSTPC mBufferDCA;
1183 std::vector<std::array<RobustAverage, 3>> mAvgADCAr;
1184 std::vector<std::array<RobustAverage, 3>> mAvgCDCAr;
1185 std::vector<std::array<RobustAverage, 3>> mAvgADCAz;
1186 std::vector<std::array<RobustAverage, 3>> mAvgCDCAz;
1187 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQMaxA;
1188 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQMaxC;
1189 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQTotA;
1190 std::vector<std::array<RobustAverage, 2>> mMIPdEdxRatioQTotC;
1191 std::vector<std::array<RobustAverage, 2>> mTPCChi2A;
1192 std::vector<std::array<RobustAverage, 2>> mTPCChi2C;
1193 std::vector<std::array<RobustAverage, 2>> mTPCNClA;
1194 std::vector<std::array<RobustAverage, 2>> mTPCNClC;
1195 std::vector<std::array<RobustAverage, 3>> mAvgMeffA;
1196 std::vector<std::array<RobustAverage, 3>> mAvgMeffC;
1197 std::vector<std::array<RobustAverage, 3>> mAvgChi2MatchA;
1198 std::vector<std::array<RobustAverage, 3>> mAvgChi2MatchC;
1199 std::vector<std::array<RobustAverage, 10>> mLogdEdxQTotA;
1200 std::vector<std::array<RobustAverage, 10>> mLogdEdxQTotC;
1201 std::vector<std::array<RobustAverage, 10>> mLogdEdxQMaxA;
1202 std::vector<std::array<RobustAverage, 10>> mLogdEdxQMaxC;
1203 std::vector<std::array<RobustAverage, 2>> mITSPropertiesA;
1204 std::vector<std::array<RobustAverage, 2>> mITSPropertiesC;
1205 std::vector<std::array<RobustAverage, 3>> mITSTPCDeltaPA;
1206 std::vector<std::array<RobustAverage, 3>> mITSTPCDeltaPC;
1207 std::vector<std::array<RobustAverage, 2>> mSigmaYZA;
1208 std::vector<std::array<RobustAverage, 2>> mSigmaYZC;
1209 int mNMaxTracks{-1};
1214 float mCoarseStep{1};
1215 float mFineStep{0.005};
1218 float mRefXSec{108.475};
1220 float maxITSTPCDCAr{0.2};
1221 float maxITSTPCDCAz{10};
1222 float maxITSTPCDCAr_comb{0.2};
1223 float maxITSTPCDCAz_comb{0.2};
1224 gsl::span<const TPCClRefElem> mTPCTrackClIdx{};
1225 std::vector<std::array<FillVals, 2>> mBufferVals;
1226 uint32_t mFirstTFOrbit{0};
1227 float mTimeWindowMUS{50};
1229 std::vector<int> mNTracksWindow;
1230 std::vector<int> mNearestVtxTPC;
1232 float mVDrift{2.64};
1233 float mMaxSnp{0.85};
1237 int mMultMax{80000};
1239 int mMinTracksPerVertex{5};
1240 float mMaxdEdxRatio{0.3};
1241 float mMaxdEdxRegionRatio{0.5};
1242 float mSamplingFactor{0.1};
1243 bool mSampleTsallis{
false};
1244 bool mStoreFullTrackPar{
false};
1246 std::vector<o2::InteractionRecord> mTRDTrigBCs;
1247 std::vector<int> mTRDTrigBCsInTF;
1248 std::vector<int> mNContributorsITS;
1249 std::vector<int> mNContributorsITSTPC;
1250 std::vector<int> mNContributorsTRD;
1251 std::vector<std::mt19937> mGenerator;
1252 std::vector<std::unique_ptr<o2::utils::TreeStreamRedirector>> mStreamer;
1253 float mXOuterMatching{60};
1254 bool mUseMinBiasTrigger{
false};
1257 int mMaxOccupancyHistBins{912};
1258 PressureTemperatureHelper mPTHelper;
1262 bool acceptTrack(
const TrackTPC& track)
const {
return std::abs(
track.getTgl()) < mMaxTgl; }
1264 bool checkTrack(
const TrackTPC& track)
const
1266 const bool isGoodTrack = ((
track.getNClusters() < mMinNCl) || (
track.getP() < mMinMom)) ? false :
true;
1270 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)
1272 const auto& trackFull = tracksTPC[iTrk];
1273 const bool isGoodTrack = checkTrack(trackFull);
1276 bool minBiasOk =
false;
1277 const float factorMinBias = 0.1 * mSamplingFactor;
1278 if (mUnbinnedWriter && mUseMinBiasTrigger) {
1279 std::uniform_real_distribution<>
distr(0., 1.);
1280 if (
distr(mGenerator[iThread]) < factorMinBias) {
1286 if (!isGoodTrack && !minBiasOk) {
1296 std::array<float, 2> dca;
1300 if (!propagator->PropagateToXBxByBz(track, mXCoarse, mMaxSnp, mCoarseStep, mMatType)) {
1305 if (!propagator->propagateToDCA(refPoint, track, propagator->getNominalBz(), mFineStep, mMatType, &dca)) {
1312 if (!propagator->propagateTo(trackTmp, mRefXSec,
false, mMaxSnp, mCoarseStep, mMatType)) {
1317 const int tglBin = std::clamp(
static_cast<int>(mTglBins * std::abs(trackTmp.getTgl()) / mMaxTgl) + mPhiBins,
1318 mPhiBins, mPhiBins + mTglBins - 1);
1319 const int phiBin = std::clamp(
static_cast<int>(mPhiBins * trackTmp.getPhi() / o2::constants::math::TwoPI),
1322 const int offsQPtBin = mPhiBins + mTglBins;
1323 const int qPtBin = std::clamp(offsQPtBin +
static_cast<int>(mQPtBins * (trackTmp.getQ2Pt() + mMaxQPt) / (2 * mMaxQPt)),
1324 offsQPtBin, offsQPtBin + mQPtBins - 1);
1325 const int localMult = mNTracksWindow[iTrk];
1327 const int offsMult = offsQPtBin + mQPtBins;
1328 const int multBin = std::clamp(offsMult +
static_cast<int>(mMultBins * localMult / mMultMax),
1329 offsMult, offsMult + mMultBins - 1);
1330 const int nBins = getNBins();
1336 auto it = indicesITSTPC.find(iTrk);
1337 const auto idxITSTPC = (it != indicesITSTPC.end()) ? (it->second) : std::array<int, 2>{-1, -1};
1340 const auto vertex = (idxITSTPC.back() != -1) ? vertices[idxITSTPC.back()] : ((mNearestVtxTPC[iTrk] != -1) ? vertices[mNearestVtxTPC[iTrk]] :
o2::dataformats::PrimaryVertex{});
1342 const int vtxID = (idxITSTPC.back() != -1) ? idxITSTPC.back() : mNearestVtxTPC[iTrk];
1343 const int nContribITS = (vtxID >= 0 && vtxID < static_cast<int>(mNContributorsITS.size())) ? mNContributorsITS[vtxID] : -1;
1344 const int nContribITSTPC = (vtxID >= 0 && vtxID < static_cast<int>(mNContributorsITSTPC.size())) ? mNContributorsITSTPC[vtxID] : -1;
1345 const int nContribTRD = (vtxID >= 0 && vtxID < static_cast<int>(mNContributorsTRD.size())) ? mNContributorsTRD[vtxID] : -1;
1348 const float signSide = trackFull.hasCSideClustersOnly() ? -1 : 1;
1349 const float dcaZFromDeltaTime = (
vertex.getTimeStamp().getTimeStamp() == 0) ? 0 : (
o2::tpc::ParameterElectronics::Instance().ZbinWidth * trackFull.getTime0() -
vertex.
getTimeStamp().
getTimeStamp()) * mVDrift + signSide *
vertex.getZ();
1354 const float div = (resCl *
track.getPt());
1359 const float fB = 0.2 /
div;
1360 const float fA = 0.15 + 0.15;
1361 const float dcarW = 1. / std::sqrt(fA * fA + fB * fB);
1364 const bool hasITSTPC = idxITSTPC.front() != -1;
1367 const float chi2 = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getChi2Match() : -1;
1371 const auto src = tracksITSTPC[idxITSTPC.front()].getRefITS().getSource();
1379 const float chi2Match = (
chi2 > 0) ? std::sqrt(
chi2) : -1;
1380 const float sqrtChi2TPC = (trackFull.getChi2() > 0) ? std::sqrt(trackFull.getChi2()) : 0;
1381 const float nClTPC = trackFull.getNClusters();
1384 const float dedxRatioqTot = (trackFull.getdEdx().dEdxTotTPC > 0) ? (mMIPdEdx / trackFull.getdEdx().dEdxTotTPC) : -1;
1385 const float dedxRatioqMax = (trackFull.getdEdx().dEdxMaxTPC > 0) ? (mMIPdEdx / trackFull.getdEdx().dEdxMaxTPC) : -1;
1387 const auto dedxQTotVars = getdEdxVars(0, trackFull);
1388 const auto dedxQMaxVars = getdEdxVars(1, trackFull);
1392 const bool idxITSCheck = (idxITSTrack != -1);
1394 const int nClITS = idxITSCheck ? tracksITS[idxITSTrack].getNClusters() : -1;
1395 float chi2ITS = idxITSCheck ? tracksITS[idxITSTrack].getChi2() : -1;
1396 if ((chi2ITS > 0) && (nClITS > 0)) {
1397 chi2ITS = std::sqrt(chi2ITS / nClITS);
1399 sigmaY2 =
track.getSigmaY2();
1400 sigmaZ2 =
track.getSigmaZ2();
1402 if (trackFull.hasCSideClustersOnly()) {
1403 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);
1404 }
else if (trackFull.hasASideClustersOnly()) {
1405 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);
1411 std::array<float, 2> dcaITSTPC{0, 0};
1412 float deltaP0 = -999;
1413 float deltaP1 = -999;
1414 float deltaP2 = -999;
1415 float deltaP3 = -999;
1416 float deltaP4 = -999;
1417 float phiITSTPCAtVertex = -999;
1418 float dcaTPCAtVertex = -999;
1421 auto trackITSTPCTmp = tracksITSTPC[idxITSTPC.front()];
1423 if (propagator->propagateToDCA(refPoint, trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPC)) {
1425 if ((std::abs(dcaITSTPC[0]) < maxITSTPCDCAr) && (std::abs(dcaITSTPC[1]) < maxITSTPCDCAz)) {
1428 const bool contributeToVertex = (idxITSTPC.back() != -1);
1429 std::array<float, 2> dcaITSTPCTmp{-1, -1};
1431 if (contributeToVertex) {
1432 if (propagator->propagateToDCA(
vertex.getXYZ(), trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPCTmp)) {
1433 phiITSTPCAtVertex = trackITSTPCTmp.getPhi();
1434 dcaITSTPC = dcaITSTPCTmp;
1438 std::array<float, 2> dcaTPCTmp{-1, -1};
1439 if (propagator->propagateToDCA(
vertex.getXYZ(), track, propagator->getNominalBz(), mFineStep, mMatType, &dcaTPCTmp)) {
1440 dcaTPCAtVertex = dcaTPCTmp[0];
1445 if ((std::abs(dcaITSTPCTmp[0]) < maxITSTPCDCAr_comb) && (std::abs(dcaITSTPCTmp[1]) < maxITSTPCDCAz_comb)) {
1447 if (idxITSTrack >= 0 &&
track.rotate(tracksITS[idxITSTrack].getAlpha()) && propagator->propagateTo(track, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1449 const bool propITSOk = propagator->propagateTo(trackITS, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType);
1451 deltaP0 =
track.getParam(0) - trackITS.getParam(0);
1452 deltaP1 =
track.getParam(1) - trackITS.getParam(1);
1453 deltaP2 =
track.getParam(2) - trackITS.getParam(2);
1454 deltaP3 =
track.getParam(3) - trackITS.getParam(3);
1455 deltaP4 =
track.getParam(4) - trackITS.getParam(4);
1456 mBufferVals[iThread].front().setDeltaParam(deltaP2, deltaP3, deltaP4);
1460 dcaITSTPCTmp[0] = -1;
1461 dcaITSTPCTmp[1] = -1;
1465 if (trackFull.hasCSideClustersOnly()) {
1466 mBufferVals[iThread].back().emplace_back_ITSTPC(
Side::C, tglBin, phiBin, qPtBin, multBin, dcaTPCAtVertex, dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, dcaITSTPCTmp[0], dcaITSTPCTmp[1]);
1467 }
else if (trackFull.hasASideClustersOnly()) {
1468 mBufferVals[iThread].back().emplace_back_ITSTPC(
Side::A, tglBin, phiBin, qPtBin, multBin, dcaTPCAtVertex, dcaZFromDeltaTime, dcarW, dedxRatioqTot, dedxRatioqMax, sqrtChi2TPC, nClTPC, dcaITSTPCTmp[0], dcaITSTPCTmp[1]);
1475 if (mUnbinnedWriter && mStreamer[iThread]) {
1476 const float factorPt = mSamplingFactor;
1477 bool writeData =
true;
1478 bool writeDataITSTPC =
false;
1480 float weightITSTPC = 0;
1481 if (mSampleTsallis) {
1482 std::uniform_real_distribution<>
distr(0., 1.);
1488 if (writeData || writeDataITSTPC || minBiasOk) {
1489 auto clusterMask = makeClusterBitMask(trackFull);
1490 const auto& trkOrig = tracksTPC[iTrk];
1491 const bool isNearestVtx = (idxITSTPC.back() == -1);
1492 const float mx_ITS = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getX() : -1;
1493 const float pt_ITS = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getQ2Pt() : -1;
1494 const float chi2match_ITSTPC = hasITSTPC ? tracksITSTPC[idxITSTPC.front()].getChi2Match() : -1;
1495 const int nClITS = idxITSCheck ? tracksITS[idxITSTrack].getNClusters() : -1;
1496 const int chi2ITS = idxITSCheck ? tracksITS[idxITSTrack].getChi2() : -1;
1498 const uint32_t itsClusterSizes = idxITSCheck ? (
static_cast<uint32_t
>(tracksITS[idxITSTrack].getClusterSizes()) & 0x0FFFFFFFu) : 0u;
1499 const bool itsHasSharedClusters = idxITSCheck ? tracksITS[idxITSTrack].hasSharedClusters() :
false;
1500 const uint32_t itsPattern = idxITSCheck ? (tracksITS[idxITSTrack].getPattern() & 0x7Fu) : 0u;
1505 std::vector<o2::trd::Tracklet64> trdTrackletVec(6);
1506 std::vector<o2::trd::CalibratedTracklet> trdCalibVec(6);
1507 auto itTRD = tpcToTRDMap.find(iTrk);
1508 if (itTRD != tpcToTRDMap.end()) {
1509 const auto& trdData = itTRD->second;
1510 trdPattern = trdData.trdPattern;
1511 nTRDTracklets = trdData.nTRDTracklets;
1512 for (
int iLay = 0; iLay < 6; ++iLay) {
1513 if (trdData.trackletIndices[iLay] >= 0) {
1514 trdTrackletVec[iLay] = trdTracklets[trdData.trackletIndices[iLay]];
1515 if (trdData.trackletIndices[iLay] <
static_cast<int>(trdCalibTracklets.size())) {
1516 trdCalibVec[iLay] = trdCalibTracklets[trdData.trackletIndices[iLay]];
1527 static constexpr float kTPCTRDMiddle = 275.f;
1528 static constexpr uint32_t kDeltaTRDTPCMask = 0xFFFFE000;
1533 float chi2PhiTPCTRD = -1.f;
1534 float chi2ZTPCTRD = -1.f;
1545 float sn = std::sin(tpcOutCov.getAlpha());
1546 float cs = std::cos(tpcOutCov.getAlpha());
1547 float gy = tpcOutCov.getX() * sn + tpcOutCov.getY() * cs;
1548 float gx = tpcOutCov.getX() * cs - tpcOutCov.getY() * sn;
1549 if (tpcOutCov.rotate(std::atan2(gy, gx)) &&
1550 propagator->propagateTo(tpcOutCov, kTPCTRDMiddle,
false, mMaxSnp, mCoarseStep, mMatType)) {
1556 if (itTRD != tpcToTRDMap.end() && itTRD->second.hasTRDTrackPar && tpcOutOK == 0) {
1559 if (trdInCov.rotate(tpcOutCov.getAlpha()) &&
1560 propagator->propagateTo(trdInCov, kTPCTRDMiddle,
false, mMaxSnp, mCoarseStep, mMatType)) {
1564 deltaTRDTPC = tpcOutCov;
1565 for (
int iPar = 0; iPar < 5; ++iPar) {
1566 deltaTRDTPC.setParam(o2::math_utils::truncateFloatFraction(trdInCov.getParam(iPar) - tpcOutCov.getParam(iPar), kDeltaTRDTPCMask), iPar);
1577 int trdTrigDBCBefore = -999999;
1578 int trdTrigDBCAfter = 999999;
1579 if (vtxID >= 0 && !
vertex.getIRMin().isDummy() && !
vertex.getIRMax().isDummy()) {
1580 const auto& irMin =
vertex.getIRMin();
1581 const auto& irMax =
vertex.getIRMax();
1582 const auto itTrig = std::lower_bound(mTRDTrigBCs.begin(), mTRDTrigBCs.end(), irMin);
1583 if (itTrig != mTRDTrigBCs.end() && *itTrig <= irMax) {
1584 trdTrigDBCBefore = 0;
1585 trdTrigDBCAfter = 0;
1587 if (itTrig != mTRDTrigBCs.end()) {
1588 trdTrigDBCAfter =
static_cast<int>(itTrig->differenceInBC(irMax));
1590 if (itTrig != mTRDTrigBCs.begin()) {
1591 trdTrigDBCBefore =
static_cast<int>((itTrig - 1)->differenceInBC(irMin));
1600 int vertexBC = -999999;
1601 int trdTrigDBCVtxBefore = -999999;
1602 int trdTrigDBCVtxAfter = 999999;
1604 vertexBC =
static_cast<int>(std::lround(
vertex.getTimeStamp().getTimeStamp() / o2::constants::lhc::LHCBunchSpacingMUS));
1605 const auto itBC = std::lower_bound(mTRDTrigBCsInTF.begin(), mTRDTrigBCsInTF.end(), vertexBC);
1606 if (itBC != mTRDTrigBCsInTF.end()) {
1607 trdTrigDBCVtxAfter = *itBC - vertexBC;
1609 if (itBC != mTRDTrigBCsInTF.end() && *itBC == vertexBC) {
1610 trdTrigDBCVtxBefore = 0;
1611 }
else if (itBC != mTRDTrigBCsInTF.begin()) {
1612 trdTrigDBCVtxBefore = *(itBC - 1) - vertexBC;
1617 if (trackFull.hasASideClustersOnly()) {
1619 }
else if (trackFull.hasCSideClustersOnly()) {
1624 bool hasTOFCluster = (std::get<0>(idxTPCTrackToTOFCluster[iTrk]) != -1);
1625 auto tofCl = hasTOFCluster ? tofClusters[std::get<0>(idxTPCTrackToTOFCluster[iTrk])] :
o2::tof::Cluster();
1627 float tpcYDeltaAtTOF = -999;
1628 float tpcZDeltaAtTOF = -999;
1629 if (hasTOFCluster) {
1631 if (trackTmpOut.rotate(
o2::math_utils::sector2Angle(tofCl.getSector())) && propagator->propagateTo(trackTmpOut, tofCl.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1632 tpcYDeltaAtTOF = trackTmpOut.getY() - tofCl.getY();
1638 float deltaTPCParamInOutTgl = trackFull.getTgl() - trackFull.getParamOut().getTgl();
1639 float deltaTPCParamInOutQPt = trackFull.getQ2Pt() - trackFull.getParamOut().getQ2Pt();
1642 float deltaP0OuterITS = -999;
1643 float deltaP1OuterITS = -999;
1644 float deltaP2OuterITS = -999;
1645 float deltaP3OuterITS = -999;
1646 float deltaP4OuterITS = -999;
1649 const bool propITSOk = propagator->propagateTo(trackTmpOut, mXOuterMatching,
false, mMaxSnp, mCoarseStep, mMatType);
1650 if (propITSOk && trackTmp.rotate(trackTmpOut.getAlpha())) {
1651 const bool propTPCOk = propagator->propagateTo(trackTmp, mXOuterMatching,
false, mMaxSnp, mCoarseStep, mMatType);
1654 deltaP0OuterITS = trackTmp.getParam(0) - trackTmpOut.getParam(0);
1655 deltaP1OuterITS = trackTmp.getParam(1) - trackTmpOut.getParam(1);
1656 deltaP2OuterITS = trackTmp.getParam(2) - trackTmpOut.getParam(2);
1657 deltaP3OuterITS = trackTmp.getParam(3) - trackTmpOut.getParam(3);
1658 deltaP4OuterITS = trackTmp.getParam(4) - trackTmpOut.getParam(4);
1666 const int triggerMask = 0x1 * minBiasOk + 0x2 * writeData + 0x4 * writeDataITSTPC;
1668 float deltaP2ConstrVtx = -999;
1669 float deltaP3ConstrVtx = -999;
1670 float deltaP4ConstrVtx = -999;
1673 float covTPCConstrVtxP2 = -999;
1674 float covTPCConstrVtxP3 = -999;
1675 float covTPCConstrVtxP4 = -999;
1678 float covITSTPCConstrVtxP2 = -999;
1679 float covITSTPCConstrVtxP3 = -999;
1680 float covITSTPCConstrVtxP4 = -999;
1682 float covTPCAtVertex0 = -999;
1683 float covTPCAtVertex1 = -999;
1685 const bool contributeToVertex = (idxITSTPC.back() != -1);
1686 if (hasITSTPC && contributeToVertex) {
1688 std::array<float, 2> dcaITSTPCTmp{-1, -1};
1689 if (propagator->propagateToDCA(
vertex.getXYZ(), trackITSTPCTmp, propagator->getNominalBz(), mFineStep, mMatType, &dcaITSTPCTmp)) {
1691 if (trackTPC.rotate(trackITSTPCTmp.getAlpha()) && propagator->propagateTo(trackTPC, trackITSTPCTmp.getX(),
false, mMaxSnp, mFineStep, mMatType)) {
1693 covTPCAtVertex0 = trackTPC.getCovarElem(0, 0);
1694 covTPCAtVertex1 = trackTPC.getCovarElem(1, 1);
1697 deltaP2ConstrVtx = trackTPC.getParam(2) - trackITSTPCTmp.getParam(2);
1698 deltaP3ConstrVtx = trackTPC.getParam(3) - trackITSTPCTmp.getParam(3);
1699 deltaP4ConstrVtx = trackTPC.getParam(4) - trackITSTPCTmp.getParam(4);
1700 covTPCConstrVtxP2 = trackTPC.getCovarElem(2, 2);
1701 covTPCConstrVtxP3 = trackTPC.getCovarElem(3, 3);
1702 covTPCConstrVtxP4 = trackTPC.getCovarElem(4, 4);
1703 covITSTPCConstrVtxP2 = trackITSTPCTmp.getCovarElem(2, 2);
1704 covITSTPCConstrVtxP3 = trackITSTPCTmp.getCovarElem(3, 3);
1705 covITSTPCConstrVtxP4 = trackITSTPCTmp.getCovarElem(4, 4);
1709 double vertexTime =
vertex.getTimeStamp().getTimeStamp();
1710 double trackTime0 = trackFull.getTime0();
1725 if (mStoreFullTrackPar) {
1726 tpcOutPar = tpcOutCov;
1727 trdInPar = trdInCov;
1728 tpcAtVtxPar =
track;
1729 *mStreamer[iThread] <<
"treeTimeSeries"
1730 <<
"tpcOut=" << tpcOutPar
1731 <<
"trdIn=" << trdInPar
1732 <<
"tpcAtVtx=" << tpcAtVtxPar;
1734 *mStreamer[iThread] <<
"treeTimeSeries"
1736 <<
"triggerMask=" << triggerMask
1737 <<
"factorMinBias=" << factorMinBias
1738 <<
"factorPt=" << factorPt
1740 <<
"weight_ITSTPC=" << weightITSTPC
1741 <<
"dcar_tpc_vertex=" << dcaTPCAtVertex
1742 <<
"dcar_tpc=" << dca[0]
1743 <<
"dcaz_tpc=" << dca[1]
1744 <<
"dcar_itstpc=" << dcaITSTPC[0]
1745 <<
"dcaz_itstpc=" << dcaITSTPC[1]
1746 <<
"dcarW=" << dcarW
1747 <<
"dcaZFromDeltaTime=" << dcaZFromDeltaTime
1748 <<
"hasITSTPC=" << hasITSTPC
1750 <<
"vertex_x=" <<
vertex.getX()
1751 <<
"vertex_y=" <<
vertex.getY()
1752 <<
"vertex_z=" <<
vertex.getZ()
1753 <<
"vertex_time=" <<
vertex.getTimeStamp().getTimeStamp()
1754 <<
"vertex_nContributors=" <<
vertex.getNContributors()
1756 <<
"vertex_nContributorsITS=" << nContribITS
1757 <<
"vertex_nContributorsITSTPC=" << nContribITSTPC
1758 <<
"vertex_nContributorsTRD=" << nContribTRD
1759 <<
"trdTrigDBCBefore=" << trdTrigDBCBefore
1760 <<
"trdTrigDBCAfter=" << trdTrigDBCAfter
1762 <<
"vertex_bc=" << vertexBC
1763 <<
"trdTrigDBCVtxBefore=" << trdTrigDBCVtxBefore
1764 <<
"trdTrigDBCVtxAfter=" << trdTrigDBCVtxAfter
1765 <<
"isNearestVertex=" << isNearestVtx
1767 <<
"pt=" << trkOrig.getPt()
1768 <<
"qpt_ITSTPC=" << pt_ITS
1769 <<
"tpc_timebin=" << trkOrig.getTime0()
1770 <<
"qpt=" << trkOrig.getParam(4)
1771 <<
"ncl=" << trkOrig.getNClusters()
1772 <<
"ncl_shared=" << trkOrig.getNClusters()
1773 <<
"tgl=" << trkOrig.getTgl()
1774 <<
"side_type=" << typeSide
1775 <<
"phi=" << trkOrig.getPhi()
1776 <<
"clusterMask=" << clusterMask
1777 <<
"dedxTPC=" << trkOrig.getdEdx()
1778 <<
"chi2=" << trkOrig.getChi2()
1779 <<
"mX=" << trkOrig.getX()
1780 <<
"mX_ITS=" << mx_ITS
1781 <<
"nClITS=" << nClITS
1782 <<
"chi2ITS=" << chi2ITS
1783 <<
"itsClusterSizes=" << itsClusterSizes
1784 <<
"itsHasSharedClusters=" << itsHasSharedClusters
1785 <<
"itsPattern=" << itsPattern
1787 <<
"trdPattern=" << trdPattern
1788 <<
"nTRDTracklets=" << nTRDTracklets
1789 <<
"trdTracklets=" << trdTrackletVec
1790 <<
"trdCalibTracklets=" << trdCalibVec
1793 <<
"tpcOutOK=" << tpcOutOK
1794 <<
"trdInOK=" << trdInOK
1795 <<
"chi2PhiTPCTRD=" << chi2PhiTPCTRD
1796 <<
"chi2ZTPCTRD=" << chi2ZTPCTRD
1797 <<
"deltaTRDTPC=" << deltaTRDTPC
1799 <<
"trdInReadout=" << mTRDInReadout
1800 <<
"chi2match_ITSTPC=" << chi2match_ITSTPC
1801 <<
"PID=" << trkOrig.getPID().getID()
1803 <<
"covTPCAtVertex0=" << covTPCAtVertex0
1804 <<
"covTPCAtVertex1=" << covTPCAtVertex1
1806 <<
"covTPCConstrVtxP2=" << covTPCConstrVtxP2
1807 <<
"covTPCConstrVtxP3=" << covTPCConstrVtxP3
1808 <<
"covTPCConstrVtxP4=" << covTPCConstrVtxP4
1810 <<
"covITSTPCConstrVtxP2=" << covITSTPCConstrVtxP2
1811 <<
"covITSTPCConstrVtxP3=" << covITSTPCConstrVtxP3
1812 <<
"covITSTPCConstrVtxP4=" << covITSTPCConstrVtxP4
1814 <<
"deltaP2ConstrVtx=" << deltaP2ConstrVtx
1815 <<
"deltaP3ConstrVtx=" << deltaP3ConstrVtx
1816 <<
"deltaP4ConstrVtx=" << deltaP4ConstrVtx
1818 <<
"deltaPar0=" << deltaP0
1819 <<
"deltaPar1=" << deltaP1
1820 <<
"deltaPar2=" << deltaP2
1821 <<
"deltaPar3=" << deltaP3
1822 <<
"deltaPar4=" << deltaP4
1823 <<
"sigmaY2=" << sigmaY2
1824 <<
"sigmaZ2=" << sigmaZ2
1826 <<
"mult=" << mNTracksWindow[iTrk]
1827 <<
"time_window_mult=" << mTimeWindowMUS
1828 <<
"firstTFOrbit=" << mFirstTFOrbit
1829 <<
"timeMS=" << mTimeMS
1831 <<
"mVDrift=" << mVDrift
1832 <<
"its_flag=" <<
int(gID)
1833 <<
"sqrtChi2Match=" << chi2Match
1835 <<
"tpcYDeltaAtTOF=" << tpcYDeltaAtTOF
1836 <<
"tpcZDeltaAtTOF=" << tpcZDeltaAtTOF
1837 <<
"mDXatTOF=" << std::get<1>(idxTPCTrackToTOFCluster[iTrk])
1838 <<
"mDZatTOF=" << std::get<2>(idxTPCTrackToTOFCluster[iTrk])
1839 <<
"mTOFLength=" << std::get<3>(idxTPCTrackToTOFCluster[iTrk])
1840 <<
"mTOFSignal=" << std::get<4>(idxTPCTrackToTOFCluster[iTrk])
1841 <<
"mDeltaTTOFTPC=" << std::get<5>(idxTPCTrackToTOFCluster[iTrk])
1842 <<
"vertexTime=" << vertexTime
1843 <<
"trackTime0=" << trackTime0
1844 <<
"TOFmask=" << std::get<6>(idxTPCTrackToTOFCluster[iTrk])
1845 <<
"TOFchannel=" << std::get<7>(idxTPCTrackToTOFCluster[iTrk])
1847 <<
"deltaTPCParamInOutTgl=" << deltaTPCParamInOutTgl
1848 <<
"deltaTPCParamInOutQPt=" << deltaTPCParamInOutQPt
1850 <<
"deltaP0OuterITS=" << deltaP0OuterITS
1851 <<
"deltaP1OuterITS=" << deltaP1OuterITS
1852 <<
"deltaP2OuterITS=" << deltaP2OuterITS
1853 <<
"deltaP3OuterITS=" << deltaP3OuterITS
1854 <<
"deltaP4OuterITS=" << deltaP4OuterITS
1855 <<
"mXOuterMatching=" << mXOuterMatching
1857 <<
"phiITSTPCAtVertex=" << phiITSTPCAtVertex
1865 mBufferDCA.mTSTPC.setStartTime(mTimeMS);
1866 mBufferDCA.mTSITSTPC.setStartTime(mTimeMS);
1869 if (!mDisableWriter) {
1877 void findNearesVertex(
const gsl::span<const TrackTPC> tracksTPC,
const gsl::span<const o2::dataformats::PrimaryVertex> vertices)
1880 const int nVertices = vertices.size();
1882 const int nTracks = tracksTPC.size();
1883 mNearestVtxTPC.clear();
1884 mNearestVtxTPC.resize(nTracks);
1888 std::fill(mNearestVtxTPC.begin(), mNearestVtxTPC.end(), -1);
1893 std::vector<float> times_vtx;
1894 times_vtx.reserve(nVertices);
1895 for (
const auto& vtx : vertices) {
1896 times_vtx.emplace_back(vtx.getTimeStamp().getTimeStamp());
1900 auto myThread = [&](
int iThread) {
1901 for (
int i = iThread;
i < nTracks;
i += mNThreads) {
1903 const auto lower = std::lower_bound(times_vtx.begin(), times_vtx.end(), timeTrack);
1904 int closestVtx = std::distance(times_vtx.begin(),
lower);
1906 if (closestVtx == nVertices) {
1908 }
else if (closestVtx > 0) {
1910 double diff1 = std::abs(timeTrack - *
lower);
1911 double diff2 = std::abs(timeTrack - *(
lower - 1));
1912 if (diff2 < diff1) {
1916 mNearestVtxTPC[
i] = closestVtx;
1920 std::vector<std::thread> threads(mNThreads);
1921 for (
int i = 0;
i < mNThreads;
i++) {
1922 threads[
i] = std::thread(myThread,
i);
1926 for (
auto& th : threads) {
1932 std::vector<bool> makeClusterBitMask(
const TrackTPC& track)
const
1935 const int nCl =
track.getNClusterReferences();
1936 for (
int j = 0;
j <
nCl; ++
j) {
1938 uint32_t clusterIndexInRow;
1939 track.getClusterReference(mTPCTrackClIdx,
j, sector,
padrow, clusterIndexInRow);
1940 tpcClusterMask[
padrow] =
true;
1942 return tpcClusterMask;
1946 void findNNeighbourTracks(
const gsl::span<const TrackTPC> tracksTPC)
1949 const float windowTimeBins = mTimeWindowMUS / tpcTBinMUS;
1952 std::vector<float>
times;
1953 const int nTracks = tracksTPC.size();
1954 times.reserve(nTracks);
1955 for (
const auto& trk : tracksTPC) {
1956 times.emplace_back(trk.getTime0());
1960 mNTracksWindow.clear();
1961 mNTracksWindow.resize(nTracks);
1964 auto myThread = [&](
int iThread) {
1965 for (
int i = iThread;
i < nTracks;
i += mNThreads) {
1966 const float t0 = tracksTPC[
i].getTime0();
1967 const auto upperV0 = std::upper_bound(
times.begin(),
times.end(),
t0 + windowTimeBins);
1968 const auto lowerV0 = std::lower_bound(
times.begin(),
times.end(),
t0 - windowTimeBins);
1969 const int nMult = std::distance(
times.begin(), upperV0) - std::distance(
times.begin(), lowerV0);
1970 mNTracksWindow[
i] = nMult;
1974 std::vector<std::thread> threads(mNThreads);
1975 for (
int i = 0;
i < mNThreads;
i++) {
1976 threads[
i] = std::thread(myThread,
i);
1980 for (
auto& th : threads) {
1985 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)
1988 std::unordered_map<unsigned int, int> indicesITSTPC_vtx;
1990 std::unordered_map<int, int> nContributors_ITS;
1991 std::unordered_map<int, int> nContributors_ITSTPC;
1992 std::unordered_map<int, int> nContributors_TRD;
1995 if (!vertices.empty()) {
1996 for (
const auto&
ref : primMatchedTracksRef) {
1998 const std::array<TrkSrc, 5>
sources = {TrkSrc::ITSTPC, TrkSrc::ITSTPCTRD, TrkSrc::ITSTPCTOF, TrkSrc::ITSTPCTRDTOF, TrkSrc::ITS};
2000 const int vID =
ref.getVtxID();
2001 const int firstEntry =
ref.getFirstEntryOfSource(
source);
2005 const auto& matchedTrk = primMatchedTracks[
i + firstEntry];
2006 bool pvCont = matchedTrk.isPVContributor();
2010 if (refITSTPC.isIndexSet()) {
2011 indicesITSTPC_vtx[refITSTPC] = vID;
2012 ++nContributors_ITSTPC[vID];
2014 if (
source == TrkSrc::ITSTPCTRD ||
source == TrkSrc::ITSTPCTRDTOF) {
2015 ++nContributors_TRD[vID];
2018 ++nContributors_ITS[vID];
2027 mNContributorsITS.assign(vertices.size(), 0);
2028 mNContributorsITSTPC.assign(vertices.size(), 0);
2029 mNContributorsTRD.assign(vertices.size(), 0);
2030 const int nVertices = vertices.size();
2031 for (
const auto& [vID,
n] : nContributors_ITS) {
2032 if (vID >= 0 && vID < nVertices) {
2033 mNContributorsITS[vID] =
n;
2036 for (
const auto& [vID,
n] : nContributors_ITSTPC) {
2037 if (vID >= 0 && vID < nVertices) {
2038 mNContributorsITSTPC[vID] =
n;
2041 for (
const auto& [vID,
n] : nContributors_TRD) {
2042 if (vID >= 0 && vID < nVertices) {
2043 mNContributorsTRD[vID] =
n;
2048 std::array<RobustAverage, 4> avgVtxITS;
2049 std::array<RobustAverage, 4> avgVtxITSTPC;
2050 for (
int i = 0;
i < avgVtxITS.size(); ++
i) {
2051 avgVtxITS[
i].reserve(vertices.size());
2052 avgVtxITSTPC[
i].reserve(vertices.size());
2054 for (
int ivtx = 0; ivtx < vertices.size(); ++ivtx) {
2055 const auto& vtx = vertices[ivtx];
2056 const float itsFrac = nContributors_ITS[ivtx] /
static_cast<float>(vtx.getNContributors());
2057 const float itstpcFrac = (nContributors_ITS[ivtx] + nContributors_ITSTPC[ivtx]) /
static_cast<float>(vtx.getNContributors());
2059 const float itsMin = 0.2;
2060 const float itsMax = 0.8;
2061 if ((itsFrac > itsMin) && (itsFrac < itsMax)) {
2062 avgVtxITS[0].addValue(vtx.getX());
2063 avgVtxITS[1].addValue(vtx.getY());
2064 avgVtxITS[2].addValue(vtx.getZ());
2065 avgVtxITS[3].addValue(vtx.getNContributors());
2068 const float itstpcMax = 0.95;
2069 if (itstpcFrac < itstpcMax) {
2070 avgVtxITSTPC[0].addValue(vtx.getX());
2071 avgVtxITSTPC[1].addValue(vtx.getY());
2072 avgVtxITSTPC[2].addValue(vtx.getZ());
2073 avgVtxITSTPC[3].addValue(vtx.getNContributors());
2078 mBufferDCA.nPrimVertices_ITS.front() = avgVtxITS[3].getValues().size();
2079 mBufferDCA.nVertexContributors_ITS_Median.front() = avgVtxITS[3].getMedian();
2080 mBufferDCA.nVertexContributors_ITS_RMS.front() = avgVtxITS[3].getStdDev();
2081 mBufferDCA.vertexX_ITS_Median.front() = avgVtxITS[0].getMedian();
2082 mBufferDCA.vertexY_ITS_Median.front() = avgVtxITS[1].getMedian();
2083 mBufferDCA.vertexZ_ITS_Median.front() = avgVtxITS[2].getMedian();
2084 mBufferDCA.vertexX_ITS_RMS.front() = avgVtxITS[0].getStdDev();
2085 mBufferDCA.vertexY_ITS_RMS.front() = avgVtxITS[1].getStdDev();
2086 mBufferDCA.vertexZ_ITS_RMS.front() = avgVtxITS[2].getStdDev();
2089 mBufferDCA.nPrimVertices_ITSTPC.front() = avgVtxITSTPC[3].getValues().size();
2090 mBufferDCA.nVertexContributors_ITSTPC_Median.front() = avgVtxITSTPC[3].getMedian();
2091 mBufferDCA.nVertexContributors_ITSTPC_RMS.front() = avgVtxITSTPC[3].getStdDev();
2092 mBufferDCA.vertexX_ITSTPC_Median.front() = avgVtxITSTPC[0].getMedian();
2093 mBufferDCA.vertexY_ITSTPC_Median.front() = avgVtxITSTPC[1].getMedian();
2094 mBufferDCA.vertexZ_ITSTPC_Median.front() = avgVtxITSTPC[2].getMedian();
2095 mBufferDCA.vertexX_ITSTPC_RMS.front() = avgVtxITSTPC[0].getStdDev();
2096 mBufferDCA.vertexY_ITSTPC_RMS.front() = avgVtxITSTPC[1].getStdDev();
2097 mBufferDCA.vertexZ_ITSTPC_RMS.front() = avgVtxITSTPC[2].getStdDev();
2100 int sumITSTPCBased = 0;
2102 for (
int ivtx = 0; ivtx < vertices.size(); ++ivtx) {
2103 sumITSTPCBased += nContributors_ITSTPC[ivtx];
2104 sumWithTRD += nContributors_TRD[ivtx];
2106 mBufferDCA.nITSTPCBasedPVContributors.front() = sumITSTPCBased;
2107 mBufferDCA.nITSTPCWithTRDPVContributors.front() = sumWithTRD;
2108 mBufferDCA.fracTRD.front() = (sumITSTPCBased > 0) ?
static_cast<float>(sumWithTRD) / sumITSTPCBased : std::nanf(
"");
2111 RobustAverage avg(vertices.size(),
false);
2112 for (
const auto& vtx : vertices) {
2113 if (vtx.getNContributors() > mMinTracksPerVertex) {
2115 avg.addValue(std::sqrt(vtx.getNContributors()));
2120 int sizeQ = mBufferDCA.nVertexContributors_Quantiles.size();
2121 const int nBinsQ = 20;
2122 if (sizeQ >= (nBinsQ + 3)) {
2123 for (
int iq = 0; iq < nBinsQ; ++iq) {
2124 const float quantile = (iq + 1) /
static_cast<float>(nBinsQ);
2125 const float val = avg.getQuantile(quantile, 1);
2126 mBufferDCA.nVertexContributors_Quantiles[iq] =
val *
val;
2128 const float tr0 = avg.getTrunctedMean(0.05, 0.95);
2129 const float tr1 = avg.getTrunctedMean(0.1, 0.9);
2130 const float tr2 = avg.getTrunctedMean(0.2, 0.8);
2131 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 3] = tr0 * tr0;
2132 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 2] = tr1 * tr1;
2133 mBufferDCA.nVertexContributors_Quantiles[sizeQ - 1] = tr2 * tr2;
2135 mBufferDCA.nPrimVertices.front() = vertices.size();
2137 return indicesITSTPC_vtx;
2141 int getNBins()
const {
return mBufferDCA.mTSTPC.getNBins(); }
2143 ValsdEdx getdEdxVars(
bool useQMax,
const TrackTPC& track)
const
2145 const float dedx = useQMax ?
track.getdEdx().dEdxMaxTPC :
track.getdEdx().dEdxTotTPC;
2146 const float dedxRatioNorm = mPID.getExpectedSignal(track,
o2::track::PID::ID(o2::track::PID::Pion)) /
dedx;
2147 float dedxNorm = (dedxRatioNorm > 0) ? std::log(mPID.getExpectedSignal(track,
o2::track::PID::ID(o2::track::PID::Pion)) /
dedx) : -1;
2149 if (std::abs(dedxNorm) > mMaxdEdxRatio) {
2154 float dedxIROC = -1;
2155 float dedxOROC1 = -1;
2156 float dedxOROC2 = -1;
2157 float dedxOROC3 = -1;
2159 dedxIROC = useQMax ?
track.getdEdx().dEdxMaxIROC :
track.getdEdx().dEdxTotIROC;
2160 dedxOROC1 = useQMax ?
track.getdEdx().dEdxMaxOROC1 :
track.getdEdx().dEdxTotOROC1;
2161 dedxOROC2 = useQMax ?
track.getdEdx().dEdxMaxOROC2 :
track.getdEdx().dEdxTotOROC2;
2162 dedxOROC3 = useQMax ?
track.getdEdx().dEdxMaxOROC3 :
track.getdEdx().dEdxTotOROC3;
2167 dedxIROC = (dedxIROC > 0) ? std::log(dedxIROC) : -1;
2168 dedxOROC1 = (dedxOROC1 > 0) ? std::log(dedxOROC1) : -1;
2169 dedxOROC2 = (dedxOROC2 > 0) ? std::log(dedxOROC2) : -1;
2170 dedxOROC3 = (dedxOROC3 > 0) ? std::log(dedxOROC3) : -1;
2173 if (std::abs(dedxIROC) > mMaxdEdxRegionRatio) {
2176 if (std::abs(dedxOROC1) > mMaxdEdxRegionRatio) {
2179 if (std::abs(dedxOROC2) > mMaxdEdxRegionRatio) {
2182 if (std::abs(dedxOROC3) > mMaxdEdxRegionRatio) {
2186 return ValsdEdx{dedxNorm, dedxIROC, dedxOROC1, dedxOROC2, dedxOROC3};