87#include "Math/SMatrix.h"
93#include <unordered_map>
98#include "TLorentzVector.h"
125 uint64_t classMaskEMCAL = 0, classMaskTRD = 0, classMaskPHOSCPV = 0;
126 for (
const auto& trgclass : ctpcfg->getCTPClasses()) {
127 if (trgclass.cluster->getClusterDetNames().find(
"EMC") != std::string::npos) {
128 classMaskEMCAL = trgclass.classMask;
130 if (trgclass.cluster->getClusterDetNames().find(
"PHS") != std::string::npos) {
131 classMaskPHOSCPV = trgclass.classMask;
133 if (trgclass.cluster->getClusterDetNames().find(
"TRD") != std::string::npos) {
134 classMaskTRD = trgclass.classMask;
137 LOG(info) <<
"createCTPReadout: Class Mask EMCAL -> " << classMaskEMCAL;
138 LOG(info) <<
"createCTPReadout: Class Mask PHOS/CPV -> " << classMaskPHOSCPV;
139 LOG(info) <<
"createCTPReadout: Class Mask TRD -> " << classMaskTRD;
147 std::vector<o2::emcal::TriggerRecord> triggerRecordEMCALPhys;
148 for (
const auto& trg : triggerrecordEMCAL) {
152 triggerRecordEMCALPhys.push_back(trg);
158 std::set<uint64_t> bcsMapT0triggers;
160 for (
auto& ft0RecPoint : ft0RecPoints) {
161 auto t0triggers = ft0RecPoint.getTrigger();
162 if (t0triggers.getVertex()) {
163 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
164 bcsMapT0triggers.insert(globalBC);
168 auto genericCTPDigitizer = [&bcsMapT0triggers, &ctpDigits](
auto triggerrecords, uint64_t classmask) ->
int {
172 uint32_t orbitPrev = 0;
174 for (
auto& trigger : triggerrecords) {
175 auto orbitPrevT = orbitPrev;
176 auto bcPrevT = bcPrev;
177 bcPrev = trigger.getBCData().bc;
178 orbitPrev = trigger.getBCData().orbit;
184 uint64_t globalBC = trigger.getBCData().toLong();
185 auto t0entry = bcsMapT0triggers.find(globalBC);
186 if (t0entry != bcsMapT0triggers.end()) {
187 auto ctpdig = std::find_if(ctpDigits.begin(), ctpDigits.end(), [globalBC](
const o2::ctp::CTPDigit& dig) { return static_cast<uint64_t>(dig.intRecord.toLong()) == globalBC; });
188 if (ctpdig != ctpDigits.end()) {
190 ctpdig->CTPClassMask |= std::bitset<64>(classmask);
191 LOG(
debug) <<
"createCTPReadout: Merging " << classmask <<
" CTP digits with existing digit, CTP mask " << ctpdig->CTPClassMask;
194 LOG(
debug) <<
"createCTPReadout: New CTP digit needed for class " << classmask << std::endl;
195 auto& ctpdigNew = ctpDigits.emplace_back();
196 ctpdigNew.intRecord.setFromLong(globalBC);
197 ctpdigNew.CTPClassMask = classmask;
200 LOG(warning) <<
"createCTPReadout: Found " << classmask <<
" and no MTVX:" << globalBC;
207 auto warningsTRD = genericCTPDigitizer(triggerrecordTRD, classMaskTRD);
208 auto warningsEMCAL = genericCTPDigitizer(triggerRecordEMCALPhys, classMaskEMCAL);
209 auto warningsPHOSCPV = genericCTPDigitizer(triggerrecordPHOSCPV, classMaskPHOSCPV);
211 LOG(info) <<
"createCTPReadout:# of TRD bogus triggers:" << warningsTRD;
212 LOG(info) <<
"createCTPReadout:# of EMCAL bogus triggers:" << warningsEMCAL;
213 LOG(info) <<
"createCTPReadout:# of PHOS/CPV bogus triggers:" << warningsPHOSCPV;
217 const std::vector<o2::InteractionTimeRecord>& mcRecords,
218 std::map<uint64_t, int>& bcsMap)
220 const auto& primVertices =
data.getPrimaryVertices();
221 const auto& fddRecPoints =
data.getFDDRecPoints();
222 const auto& ft0RecPoints =
data.getFT0RecPoints();
223 const auto& fv0RecPoints =
data.getFV0RecPoints();
224 const auto& caloEMCCellsTRGR =
data.getEMCALTriggers();
225 const auto& caloPHOSCellsTRGR =
data.getPHOSTriggers();
226 const auto& cpvTRGR =
data.getCPVTriggers();
227 const auto& ctpDigits =
data.getCTPDigits();
228 const auto& zdcBCRecData =
data.getZDCBCRecData();
230 bcsMap[mStartIR.
toLong()] = 1;
233 for (
auto&
rec : mcRecords) {
234 uint64_t globalBC =
rec.toLong();
235 bcsMap[globalBC] = 1;
238 for (
auto& fddRecPoint : fddRecPoints) {
239 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
240 bcsMap[globalBC] = 1;
243 for (
auto& ft0RecPoint : ft0RecPoints) {
244 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
245 bcsMap[globalBC] = 1;
248 for (
auto& fv0RecPoint : fv0RecPoints) {
249 uint64_t globalBC = fv0RecPoint.getInteractionRecord().toLong();
250 bcsMap[globalBC] = 1;
253 for (
auto& zdcRecData : zdcBCRecData) {
254 uint64_t globalBC = zdcRecData.ir.toLong();
255 bcsMap[globalBC] = 1;
258 for (
auto&
vertex : primVertices) {
259 auto& timeStamp =
vertex.getTimeStamp();
260 double tsTimeStamp = timeStamp.getTimeStamp() * 1E3;
261 uint64_t globalBC = relativeTime_to_GlobalBC(tsTimeStamp);
262 bcsMap[globalBC] = 1;
265 for (
auto& emcaltrg : caloEMCCellsTRGR) {
266 uint64_t globalBC = emcaltrg.getBCData().toLong();
267 bcsMap[globalBC] = 1;
270 for (
auto& phostrg : caloPHOSCellsTRGR) {
271 uint64_t globalBC = phostrg.getBCData().toLong();
272 bcsMap[globalBC] = 1;
275 for (
auto& cpvtrg : cpvTRGR) {
276 uint64_t globalBC = cpvtrg.getBCData().toLong();
277 bcsMap[globalBC] = 1;
280 for (
auto& ctpDigit : ctpDigits) {
281 uint64_t globalBC = ctpDigit.intRecord.toLong();
282 bcsMap[globalBC] = 1;
286 for (
auto& item : bcsMap) {
292template <
typename TracksCursorType,
typename TracksCovCursorType>
293void AODProducerWorkflowDPL::addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor,
296 tracksCursor(collisionID,
298 truncateFloatFraction(track.getX(), mTrackX),
299 truncateFloatFraction(track.getAlpha(), mTrackAlpha),
302 truncateFloatFraction(track.getSnp(), mTrackSnp),
303 truncateFloatFraction(track.getTgl(), mTrackTgl),
304 truncateFloatFraction(track.getQ2Pt(), mTrack1Pt));
306 float sY = TMath::Sqrt(track.getSigmaY2()), sZ = TMath::Sqrt(track.getSigmaZ2()), sSnp = TMath::Sqrt(track.getSigmaSnp2()),
307 sTgl = TMath::Sqrt(track.getSigmaTgl2()), sQ2Pt = TMath::Sqrt(track.getSigma1Pt2());
308 tracksCovCursor(truncateFloatFraction(sY, mTrackCovDiag),
309 truncateFloatFraction(sZ, mTrackCovDiag),
310 truncateFloatFraction(sSnp, mTrackCovDiag),
311 truncateFloatFraction(sTgl, mTrackCovDiag),
312 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
313 (Char_t)(128. * track.getSigmaZY() / (sZ * sY)),
314 (Char_t)(128. * track.getSigmaSnpY() / (sSnp * sY)),
315 (Char_t)(128. * track.getSigmaSnpZ() / (sSnp * sZ)),
316 (Char_t)(128. * track.getSigmaTglY() / (sTgl * sY)),
317 (Char_t)(128. * track.getSigmaTglZ() / (sTgl * sZ)),
318 (Char_t)(128. * track.getSigmaTglSnp() / (sTgl * sSnp)),
319 (Char_t)(128. * track.getSigma1PtY() / (sQ2Pt * sY)),
320 (Char_t)(128. * track.getSigma1PtZ() / (sQ2Pt * sZ)),
321 (Char_t)(128. * track.getSigma1PtSnp() / (sQ2Pt * sSnp)),
322 (Char_t)(128. * track.getSigma1PtTgl() / (sQ2Pt * sTgl)));
325template <
typename TracksExtraCursorType>
326void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder)
330 auto trackTimeRes = extraInfoHolder.trackTimeRes;
331 if (!extraInfoHolder.isTPConly) {
332 trackTimeRes = truncateFloatFraction(trackTimeRes, mTrackTimeError);
336 tracksExtraCursor(truncateFloatFraction(extraInfoHolder.tpcInnerParam, mTrack1Pt),
337 extraInfoHolder.flags,
338 extraInfoHolder.itsClusterSizes,
339 extraInfoHolder.tpcNClsFindable,
340 extraInfoHolder.tpcNClsFindableMinusFound,
341 extraInfoHolder.tpcNClsFindableMinusPID,
342 extraInfoHolder.tpcNClsFindableMinusCrossedRows,
343 extraInfoHolder.tpcNClsShared,
344 extraInfoHolder.trdPattern,
345 truncateFloatFraction(extraInfoHolder.itsChi2NCl, mTrackChi2),
346 truncateFloatFraction(extraInfoHolder.tpcChi2NCl, mTrackChi2),
347 truncateFloatFraction(extraInfoHolder.trdChi2, mTrackChi2),
348 truncateFloatFraction(extraInfoHolder.tofChi2, mTrackChi2),
349 truncateFloatFraction(extraInfoHolder.tpcSignal, mTrackSignal),
350 truncateFloatFraction(extraInfoHolder.trdSignal, mTrackSignal),
351 truncateFloatFraction(extraInfoHolder.length, mTrackSignal),
352 truncateFloatFraction(extraInfoHolder.tofExpMom, mTrack1Pt),
353 truncateFloatFraction(extraInfoHolder.trackEtaEMCAL, mTrackPosEMCAL),
354 truncateFloatFraction(extraInfoHolder.trackPhiEMCAL, mTrackPosEMCAL),
355 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime),
359template <
typename TracksQACursorType>
360void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor,
TrackQA& trackQAInfoHolder)
363 trackQAInfoHolder.trackID,
364 truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
365 trackQAInfoHolder.tpcdcaR,
366 trackQAInfoHolder.tpcdcaZ,
367 trackQAInfoHolder.tpcClusterByteMask,
368 trackQAInfoHolder.tpcdEdxMax0R,
369 trackQAInfoHolder.tpcdEdxMax1R,
370 trackQAInfoHolder.tpcdEdxMax2R,
371 trackQAInfoHolder.tpcdEdxMax3R,
372 trackQAInfoHolder.tpcdEdxTot0R,
373 trackQAInfoHolder.tpcdEdxTot1R,
374 trackQAInfoHolder.tpcdEdxTot2R,
375 trackQAInfoHolder.tpcdEdxTot3R,
376 trackQAInfoHolder.dRefContY,
377 trackQAInfoHolder.dRefContZ,
378 trackQAInfoHolder.dRefContSnp,
379 trackQAInfoHolder.dRefContTgl,
380 trackQAInfoHolder.dRefContQ2Pt,
381 trackQAInfoHolder.dRefGloY,
382 trackQAInfoHolder.dRefGloZ,
383 trackQAInfoHolder.dRefGloSnp,
384 trackQAInfoHolder.dRefGloTgl,
385 trackQAInfoHolder.dRefGloQ2Pt,
386 trackQAInfoHolder.dTofdX,
387 trackQAInfoHolder.dTofdZ);
390template <
typename mftTracksCursorType,
typename AmbigMFTTracksCursorType>
391void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
393 std::uint64_t collisionBC,
const std::map<uint64_t, int>& bcsMap)
396 int bcSlice[2] = {-1, -1};
397 const auto& track =
data.getMFTTrack(trackID);
398 const auto& rof =
data.getMFTTracksROFRecords()[mMFTROFs[trackID.getIndex()]];
400 float trackTimeRes = mMFTROFrameHalfLengthNS;
401 bool needBCSlice = collisionID < 0;
402 std::uint64_t bcOfTimeRef;
404 double error = mTimeMarginTrackTime + trackTimeRes;
405 bcOfTimeRef = fillBCSlice(bcSlice, trackTime - error, trackTime + error, bcsMap);
407 bcOfTimeRef = collisionBC - mStartIR.
toLong();
412 uint64_t mftClusterSizesAndTrackFlags = track.getClusterSizes();
413 mftClusterSizesAndTrackFlags |= (track.isCA()) ? (1ULL << (60)) : 0;
415 mftTracksCursor(collisionID,
418 truncateFloatFraction(track.getZ(), mTrackX),
419 truncateFloatFraction(track.getPhi(), mTrackAlpha),
420 truncateFloatFraction(track.getTanl(), mTrackTgl),
421 truncateFloatFraction(track.getInvQPt(), mTrack1Pt),
422 mftClusterSizesAndTrackFlags,
423 truncateFloatFraction(track.getTrackChi2(), mTrackChi2),
424 truncateFloatFraction(trackTime, mTrackTime),
425 truncateFloatFraction(trackTimeRes, mTrackTimeError));
427 ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
431template <
typename TracksCursorType,
typename TracksCovCursorType,
typename TracksExtraCursorType,
typename TracksQACursorType,
typename AmbigTracksCursorType,
432 typename MFTTracksCursorType,
typename MFTTracksCovCursorType,
typename AmbigMFTTracksCursorType,
433 typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename FwdTrkClsCursorType>
434void AODProducerWorkflowDPL::fillTrackTablesPerCollision(
int collisionID,
435 std::uint64_t collisionBC,
437 const gsl::span<const GIndex>& GIndices,
439 TracksCursorType& tracksCursor,
440 TracksCovCursorType& tracksCovCursor,
441 TracksExtraCursorType& tracksExtraCursor,
442 TracksQACursorType& tracksQACursor,
443 AmbigTracksCursorType& ambigTracksCursor,
444 MFTTracksCursorType& mftTracksCursor,
445 MFTTracksCovCursorType& mftTracksCovCursor,
446 AmbigMFTTracksCursorType& ambigMFTTracksCursor,
447 FwdTracksCursorType& fwdTracksCursor,
448 FwdTracksCovCursorType& fwdTracksCovCursor,
449 AmbigFwdTracksCursorType& ambigFwdTracksCursor,
450 FwdTrkClsCursorType& fwdTrkClsCursor,
451 const std::map<uint64_t, int>& bcsMap)
454 if (!GIndex::isTrackSource(
src)) {
461 mftTracksCursor.reserve(nToReserve + mftTracksCursor.lastIndex());
463 fwdTracksCursor.reserve(nToReserve + fwdTracksCursor.lastIndex());
464 fwdTracksCovCursor.reserve(nToReserve + fwdTracksCovCursor.lastIndex());
466 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex());
469 tracksCursor.reserve(nToReserve + tracksCursor.lastIndex());
470 tracksCovCursor.reserve(nToReserve + tracksCovCursor.lastIndex());
471 tracksExtraCursor.reserve(nToReserve + tracksExtraCursor.lastIndex());
473 for (
int ti =
start; ti <
end; ti++) {
474 const auto& trackIndex = GIndices[ti];
475 if (GIndex::includesSource(
src, mInputSources)) {
477 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
480 addToMFTTracksTable(mftTracksCursor, ambigMFTTracksCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
481 mGIDToTableMFTID.emplace(trackIndex, mTableTrMFTID);
484 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
487 addToFwdTracksTable(fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, mftTracksCovCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
488 mGIDToTableFwdID.emplace(trackIndex, mTableTrFwdID);
489 addClustersToFwdTrkClsTable(
data, fwdTrkClsCursor, trackIndex, mTableTrFwdID);
493 if (trackIndex.isAmbiguous() && mGIDToTableID.find(trackIndex) != mGIDToTableID.end()) {
498 static std::uniform_real_distribution<>
distr(0., 1.);
500 auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex,
data, bcsMap);
503 auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex,
data, bcsMap);
504 if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) {
505 trackQAInfoHolder.trackID = mTableTrID;
509 addToTracksQATable(tracksQACursor, trackQAInfoHolder);
515 if (mThinTracks &&
src ==
GIndex::Source::TPC && mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() && mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end() && !writeQAData) {
516 mGIDToTableID.emplace(trackIndex, -1);
520 if (!extraInfoHolder.isTPConly && extraInfoHolder.trackTimeRes < 0.f) {
521 LOG(warning) <<
"Barrel track " << trackIndex <<
" has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime
522 <<
" timeErr=" << extraInfoHolder.trackTimeRes <<
" BCSlice: " << extraInfoHolder.bcSlice[0] <<
":" << extraInfoHolder.bcSlice[1];
525 const auto& trOrig =
data.getTrackParam(trackIndex);
527 if (mPropTracks && trOrig.getX() < mMinPropR &&
528 mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() &&
529 mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end()) {
530 auto trackPar(trOrig);
531 isProp = propagateTrackToPV(trackPar,
data, collisionID);
533 addToTracksTable(tracksCursor, tracksCovCursor, trackPar, collisionID,
aod::track::Track);
539 addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
542 if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
543 ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
545 mGIDToTableID.emplace(trackIndex, mTableTrID);
551 if (collisionID < 0) {
555 auto sTracks =
data.getStrangeTracks();
556 tracksCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCursor.lastIndex());
557 tracksCovCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCovCursor.lastIndex());
558 tracksExtraCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksExtraCursor.lastIndex());
559 for (
int iS{mVertexStrLUT[collisionID]}; iS < mVertexStrLUT[collisionID + 1]; ++iS) {
560 auto& collStrTrk = mCollisionStrTrk[iS];
561 auto& sTrk = sTracks[collStrTrk.second];
562 TrackExtraInfo extraInfo;
563 extraInfo.itsChi2NCl = sTrk.mTopoChi2;
564 extraInfo.itsClusterSizes = sTrk.getClusterSizes();
566 addToTracksExtraTable(tracksExtraCursor, extraInfo);
567 mStrTrkIndices[collStrTrk.second] = mTableTrID;
574 const auto& mchmidMatches =
data.getMCHMIDMatches();
579 for (
int ti =
start; ti <
end; ti++) {
580 auto& trackIndex = GIndices[ti];
581 if (GIndex::includesSource(
src, mInputSources)) {
583 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
586 mGIDToTableMFTID.emplace(trackIndex, mIndexMFTID);
587 mIndexTableMFT[trackIndex.getIndex()] = mIndexMFTID;
590 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
593 mGIDToTableFwdID.emplace(trackIndex, mIndexFwdID);
595 mIndexTableFwd[trackIndex.getIndex()] = mIndexFwdID;
597 const auto& mchmidMatch = mchmidMatches[trackIndex.getIndex()];
598 const auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
599 mIndexTableFwd[mchTrackID] = mIndexFwdID;
608template <
typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename mftTracksCovCursorType>
609void AODProducerWorkflowDPL::addToFwdTracksTable(FwdTracksCursorType& fwdTracksCursor, FwdTracksCovCursorType& fwdTracksCovCursor,
610 AmbigFwdTracksCursorType& ambigFwdTracksCursor, mftTracksCovCursorType& mftTracksCovCursor,
GIndex trackID,
612 const std::map<uint64_t, int>& bcsMap)
614 const auto& mchTracks =
data.getMCHTracks();
615 const auto& midTracks =
data.getMIDTracks();
616 const auto& mchmidMatches =
data.getMCHMIDMatches();
617 const auto& mchClusters =
data.getMCHTrackClusters();
619 FwdTrackInfo fwdInfo;
620 FwdTrackCovInfo fwdCovInfo;
621 int bcSlice[2] = {-1, -1};
624 auto getMCHBitMap = [&](
int mchTrackID) {
625 if (mchTrackID != -1) {
626 const auto& mchTrack = mchTracks[mchTrackID];
627 int first = mchTrack.getFirstClusterIdx();
628 int last = mchTrack.getLastClusterIdx();
629 for (
int i =
first;
i <= last;
i++) {
630 const auto& cluster = mchClusters[
i];
631 int chamberId = cluster.getChamberId();
632 fwdInfo.mchBitMap |= 1 << chamberId;
637 auto getMIDBitMapBoards = [&](
int midTrackID) {
638 if (midTrackID != -1) {
639 const auto& midTrack = midTracks[midTrackID];
640 fwdInfo.midBitMap = midTrack.getHitMap();
641 fwdInfo.midBoards = midTrack.getEfficiencyWord();
645 auto extrapMCHTrack = [&](
int mchTrackID) {
646 const auto& track = mchTracks[mchTrackID];
654 float vx = 0, vy = 0, vz = 0;
655 if (collisionID >= 0) {
656 const auto&
v =
data.getPrimaryVertex(collisionID);
662 o2::mch::TrackParam trackParamAtVertex(track.getZ(), track.getParameters(), track.getCovariances());
685 double dca = std::sqrt(dcaX * dcaX + dcaY * dcaY);
690 double dpdca = track.getP() * dca;
691 double dchi2 = track.getChi2OverNDF();
693 auto fwdmuon = mMatching.
MCHtoFwd(trackParamAtVertex);
695 fwdInfo.x = fwdmuon.
getX();
696 fwdInfo.y = fwdmuon.getY();
697 fwdInfo.z = fwdmuon.getZ();
698 fwdInfo.phi = fwdmuon.getPhi();
699 fwdInfo.tanl = fwdmuon.getTgl();
700 fwdInfo.invqpt = fwdmuon.getInvQPt();
701 fwdInfo.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs);
702 fwdInfo.chi2 = dchi2;
703 fwdInfo.pdca = dpdca;
704 fwdInfo.nClusters = track.getNClusters();
706 fwdCovInfo.sigX = TMath::Sqrt(fwdmuon.getCovariances()(0, 0));
707 fwdCovInfo.sigY = TMath::Sqrt(fwdmuon.getCovariances()(1, 1));
708 fwdCovInfo.sigPhi = TMath::Sqrt(fwdmuon.getCovariances()(2, 2));
709 fwdCovInfo.sigTgl = TMath::Sqrt(fwdmuon.getCovariances()(3, 3));
710 fwdCovInfo.sig1Pt = TMath::Sqrt(fwdmuon.getCovariances()(4, 4));
711 fwdCovInfo.rhoXY = (Char_t)(128. * fwdmuon.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
712 fwdCovInfo.rhoPhiX = (Char_t)(128. * fwdmuon.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
713 fwdCovInfo.rhoPhiY = (Char_t)(128. * fwdmuon.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
714 fwdCovInfo.rhoTglX = (Char_t)(128. * fwdmuon.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
715 fwdCovInfo.rhoTglY = (Char_t)(128. * fwdmuon.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
716 fwdCovInfo.rhoTglPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
717 fwdCovInfo.rho1PtX = (Char_t)(128. * fwdmuon.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
718 fwdCovInfo.rho1PtY = (Char_t)(128. * fwdmuon.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
719 fwdCovInfo.rho1PtPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
720 fwdCovInfo.rho1PtTgl = (Char_t)(128. * fwdmuon.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
726 int mchTrackID = trackID.getIndex();
727 getMCHBitMap(mchTrackID);
728 if (!extrapMCHTrack(mchTrackID)) {
729 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
732 const auto& rof =
data.getMCHTracksROFRecords()[mMCHROFs[mchTrackID]];
733 auto time = rof.getTimeMUS(mStartIR).first;
734 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
735 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
738 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
739 auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
740 if (!extrapMCHTrack(mchTrackID)) {
741 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
743 auto midTrackID = mchmidMatch.getMIDRef().getIndex();
744 fwdInfo.chi2matchmchmid = mchmidMatch.getMatchChi2OverNDF();
745 getMCHBitMap(mchTrackID);
746 getMIDBitMapBoards(midTrackID);
747 auto time = mchmidMatch.getTimeMUS(mStartIR).first;
748 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
749 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
751 const auto& track =
data.getGlobalFwdTrack(trackID);
752 const auto& mftTracks =
data.getMFTTracks();
753 const auto& mfttrack = mftTracks[track.getMFTTrackID()];
754 if (!extrapMCHTrack(track.getMCHTrackID())) {
755 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", track.getMCHTrackID());
757 fwdInfo.x = track.getX();
758 fwdInfo.y = track.getY();
759 fwdInfo.z = track.getZ();
760 fwdInfo.phi = track.getPhi();
761 fwdInfo.tanl = track.getTanl();
762 fwdInfo.invqpt = track.getInvQPt();
763 fwdInfo.chi2 = track.getTrackChi2();
765 fwdInfo.chi2matchmchmid = track.getMIDMatchingChi2();
766 fwdInfo.chi2matchmchmft = track.getMFTMCHMatchingChi2();
767 fwdInfo.matchscoremchmft = track.getMFTMCHMatchingScore();
768 fwdInfo.matchmfttrackid = mIndexTableMFT[track.getMFTTrackID()];
769 fwdInfo.matchmchtrackid = mIndexTableFwd[track.getMCHTrackID()];
770 fwdInfo.trackTime = track.getTimeMUS().getTimeStamp() * 1.e3;
771 fwdInfo.trackTimeRes = track.getTimeMUS().getTimeStampError() * 1.e3;
773 getMCHBitMap(track.getMCHTrackID());
774 getMIDBitMapBoards(track.getMIDTrackID());
776 fwdCovInfo.sigX = TMath::Sqrt(track.getCovariances()(0, 0));
777 fwdCovInfo.sigY = TMath::Sqrt(track.getCovariances()(1, 1));
778 fwdCovInfo.sigPhi = TMath::Sqrt(track.getCovariances()(2, 2));
779 fwdCovInfo.sigTgl = TMath::Sqrt(track.getCovariances()(3, 3));
780 fwdCovInfo.sig1Pt = TMath::Sqrt(track.getCovariances()(4, 4));
781 fwdCovInfo.rhoXY = (Char_t)(128. * track.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
782 fwdCovInfo.rhoPhiX = (Char_t)(128. * track.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
783 fwdCovInfo.rhoPhiY = (Char_t)(128. * track.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
784 fwdCovInfo.rhoTglX = (Char_t)(128. * track.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
785 fwdCovInfo.rhoTglY = (Char_t)(128. * track.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
786 fwdCovInfo.rhoTglPhi = (Char_t)(128. * track.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
787 fwdCovInfo.rho1PtX = (Char_t)(128. * track.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
788 fwdCovInfo.rho1PtY = (Char_t)(128. * track.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
789 fwdCovInfo.rho1PtPhi = (Char_t)(128. * track.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
790 fwdCovInfo.rho1PtTgl = (Char_t)(128. * track.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
794 float sX = TMath::Sqrt(mfttrack.getSigma2X()), sY = TMath::Sqrt(mfttrack.getSigma2Y()), sPhi = TMath::Sqrt(mfttrack.getSigma2Phi()),
795 sTgl = TMath::Sqrt(mfttrack.getSigma2Tanl()), sQ2Pt = TMath::Sqrt(mfttrack.getSigma2InvQPt());
797 mftTracksCovCursor(fwdInfo.matchmfttrackid,
798 truncateFloatFraction(sX, mTrackCovDiag),
799 truncateFloatFraction(sY, mTrackCovDiag),
800 truncateFloatFraction(sPhi, mTrackCovDiag),
801 truncateFloatFraction(sTgl, mTrackCovDiag),
802 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
803 (Char_t)(128. * mfttrack.getCovariances()(0, 1) / (sX * sY)),
804 (Char_t)(128. * mfttrack.getCovariances()(0, 2) / (sPhi * sX)),
805 (Char_t)(128. * mfttrack.getCovariances()(1, 2) / (sPhi * sY)),
806 (Char_t)(128. * mfttrack.getCovariances()(0, 3) / (sTgl * sX)),
807 (Char_t)(128. * mfttrack.getCovariances()(1, 3) / (sTgl * sY)),
808 (Char_t)(128. * mfttrack.getCovariances()(2, 3) / (sTgl * sPhi)),
809 (Char_t)(128. * mfttrack.getCovariances()(0, 4) / (sQ2Pt * sX)),
810 (Char_t)(128. * mfttrack.getCovariances()(1, 4) / (sQ2Pt * sY)),
811 (Char_t)(128. * mfttrack.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
812 (Char_t)(128. * mfttrack.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
815 std::uint64_t bcOfTimeRef;
816 bool needBCSlice = collisionID < 0;
818 float err = mTimeMarginTrackTime + fwdInfo.trackTimeRes;
819 bcOfTimeRef = fillBCSlice(bcSlice, fwdInfo.trackTime - err, fwdInfo.trackTime + err, bcsMap);
821 bcOfTimeRef = collisionBC - mStartIR.
toLong();
825 fwdTracksCursor(collisionID,
829 truncateFloatFraction(fwdInfo.z, mTrackX),
830 truncateFloatFraction(fwdInfo.phi, mTrackAlpha),
831 truncateFloatFraction(fwdInfo.tanl, mTrackTgl),
832 truncateFloatFraction(fwdInfo.invqpt, mTrack1Pt),
834 truncateFloatFraction(fwdInfo.pdca, mTrackX),
835 truncateFloatFraction(fwdInfo.rabs, mTrackX),
836 truncateFloatFraction(fwdInfo.chi2, mTrackChi2),
837 truncateFloatFraction(fwdInfo.chi2matchmchmid, mTrackChi2),
838 truncateFloatFraction(fwdInfo.chi2matchmchmft, mTrackChi2),
839 truncateFloatFraction(fwdInfo.matchscoremchmft, mTrackChi2),
840 fwdInfo.matchmfttrackid,
841 fwdInfo.matchmchtrackid,
845 truncateFloatFraction(fwdInfo.trackTime, mTrackTime),
846 truncateFloatFraction(fwdInfo.trackTimeRes, mTrackTimeError));
848 fwdTracksCovCursor(truncateFloatFraction(fwdCovInfo.sigX, mTrackCovDiag),
849 truncateFloatFraction(fwdCovInfo.sigY, mTrackCovDiag),
850 truncateFloatFraction(fwdCovInfo.sigPhi, mTrackCovDiag),
851 truncateFloatFraction(fwdCovInfo.sigTgl, mTrackCovDiag),
852 truncateFloatFraction(fwdCovInfo.sig1Pt, mTrackCovDiag),
858 fwdCovInfo.rhoTglPhi,
861 fwdCovInfo.rho1PtPhi,
862 fwdCovInfo.rho1PtTgl);
865 ambigFwdTracksCursor(mTableTrFwdID, bcSlice);
870void AODProducerWorkflowDPL::updateMCHeader(MCCollisionCursor& collisionCursor,
871 XSectionCursor& xSectionCursor,
872 PdfInfoCursor& pdfInfoCursor,
873 HeavyIonCursor& heavyIonCursor,
874 const MCEventHeader& header,
886 auto genID = updateMCCollisions(collisionCursor,
893 mXSectionUpdate = (updateHepMCXSection(xSectionCursor,
898 ? HepMCUpdate::always
899 : HepMCUpdate::never);
900 mPdfInfoUpdate = (updateHepMCPdfInfo(pdfInfoCursor,
905 ? HepMCUpdate::always
906 : HepMCUpdate::never);
907 mHeavyIonUpdate = (updateHepMCHeavyIon(heavyIonCursor,
912 ? HepMCUpdate::always
913 : HepMCUpdate::never);
916void dimensionMCKeepStore(std::vector<std::vector<std::unordered_map<int, int>>>& store,
int Nsources,
int NEvents)
918 store.resize(Nsources);
919 for (
int s = 0;
s < Nsources; ++
s) {
920 store[
s].resize(NEvents);
926 for (
auto s = 0U;
s < store.size(); ++
s) {
927 for (
auto e = 0U; e < store[
s].size(); ++e) {
937 LOG(warn) <<
"trackID is smaller than 0. Neglecting";
944 MCParticlesCursor& mcParticlesCursor,
945 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
946 const gsl::span<const GIndex>& GIndices,
948 const std::vector<std::vector<int>>& mcColToEvSrc)
952 for (
auto& p : mcColToEvSrc) {
953 NSources = std::max(p[1], NSources);
954 NEvents = std::max(p[2], NEvents);
958 LOG(info) <<
" number of events " << NEvents;
959 LOG(info) <<
" number of sources " << NSources;
962 std::vector<int> particleIDsToKeep;
964 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
965 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
966 if (!mcLabel.isValid()) {
969 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
973 for (
auto& trackRef : primVer2TRefs) {
977 for (
int ti =
start; ti <
end; ti++) {
978 auto& trackIndex = GIndices[ti];
979 if (GIndex::includesSource(
src, mInputSources)) {
980 auto mcTruth =
data.getTrackMCLabel(trackIndex);
981 if (!mcTruth.isValid()) {
984 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
986 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
995 for (
auto& mcLabel : labelsTOF) {
996 if (!mcLabel.isValid()) {
999 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
1008 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1009 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1010 if (!mcTruth.isValid()) {
1013 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1017 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1018 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1019 if (!mcTruth.isValid()) {
1022 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1025 using namespace aodmchelpers;
1029 for (
auto& colInfo : mcColToEvSrc) {
1030 int event = colInfo[2];
1032 int mcColId = colInfo[0];
1034 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1052template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1053void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1054 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1055 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1057 const gsl::span<const GIndex>& primVerGIs,
1070 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1071 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1072 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1073 for (
int ti =
start; ti <
end; ti++) {
1074 const auto trackIndex = primVerGIs[ti];
1077 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1078 auto entry = mp.find(trackIndex);
1079 if (
entry == mp.end() ||
entry->second == -1) {
1086 if (GIndex::includesSource(
src, mInputSources)) {
1087 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1088 MCLabels labelHolder{};
1093 if (mcTruth.isValid()) {
1094 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1096 if (mcTruth.isFake()) {
1097 labelHolder.fwdLabelMask |= (0x1 << 7);
1099 if (mcTruth.isNoise()) {
1100 labelHolder.fwdLabelMask |= (0x1 << 6);
1103 mcMFTTrackLabelCursor(labelHolder.labelID,
1104 labelHolder.fwdLabelMask);
1106 mcFwdTrackLabelCursor(labelHolder.labelID,
1107 labelHolder.fwdLabelMask);
1110 if (!needToStore(mGIDToTableID)) {
1113 if (mcTruth.isValid()) {
1114 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1115 if (mcTruth.isFake()) {
1116 labelHolder.labelMask |= (0x1 << 15);
1119 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1122 labelHolder.labelMask |= (0x1 << 13);
1126 }
else if (mcTruth.isNoise()) {
1127 labelHolder.labelMask |= (0x1 << 14);
1129 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1136 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1138 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1139 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1140 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1141 auto& collStrTrk = mCollisionStrTrk[iS];
1142 auto&
label = sTrackLabels[collStrTrk.second];
1143 MCLabels labelHolder;
1144 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1145 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1146 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1151template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1152void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1159 v0Cursor.reserve(v0s.size());
1161 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1162 const auto&
v0 = v0s[iv0];
1163 auto trPosID =
v0.getProngID(0);
1164 auto trNegID =
v0.getProngID(1);
1165 uint8_t v0flags =
v0.getBits();
1166 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1167 auto item = mGIDToTableID.find(trPosID);
1168 if (item != mGIDToTableID.end()) {
1169 posTableIdx = item->second;
1171 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1173 item = mGIDToTableID.find(trNegID);
1174 if (item != mGIDToTableID.end()) {
1175 negTableIdx = item->second;
1177 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1179 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1180 if (itemV == mVtxToTableCollID.end()) {
1181 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1183 collID = itemV->second;
1185 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1186 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1187 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1192 cascadeCursor.reserve(cascades.size());
1193 for (
auto& cascade : cascades) {
1194 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1195 if (itemV0 == mV0ToTableID.end()) {
1198 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1199 auto bachelorID = cascade.getBachelorID();
1200 auto item = mGIDToTableID.find(bachelorID);
1201 if (item != mGIDToTableID.end()) {
1202 bachTableIdx = item->second;
1204 LOG(warn) <<
"Could not find a bachelor track index";
1207 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1208 if (itemV != mVtxToTableCollID.end()) {
1209 collID = itemV->second;
1211 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1214 cascadeCursor(collID, v0tableID, bachTableIdx);
1218 decay3BodyCursor.reserve(decays3Body.size());
1219 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1220 const auto& decay3Body = decays3Body[i3Body];
1222 decay3Body.getProngID(0),
1223 decay3Body.getProngID(1),
1224 decay3Body.getProngID(2)};
1225 int tableIdx[3]{-1, -1, -1}, collID = -1;
1226 bool missing{
false};
1227 for (
int i{0};
i < 3; ++
i) {
1228 auto item = mGIDToTableID.find(trIDs[
i]);
1229 if (item != mGIDToTableID.end()) {
1230 tableIdx[
i] = item->second;
1232 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1236 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1237 if (itemV == mVtxToTableCollID.end()) {
1238 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1241 collID = itemV->second;
1246 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1250template <
typename FwdTrkClsCursorType>
1257 int mchTrackID = -1;
1259 mchTrackID = trackID.getIndex();
1261 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1262 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1265 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1266 const auto& mchTrack = mchTracks[mchTrackID];
1267 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1268 int first = mchTrack.getFirstClusterIdx();
1269 int last = mchTrack.getLastClusterIdx();
1270 for (
int i =
first;
i <= last;
i++) {
1271 const auto& cluster = mchClusters[
i];
1272 fwdTrkClsCursor(fwdTrackId,
1273 truncateFloatFraction(cluster.x, mMuonCl),
1274 truncateFloatFraction(cluster.y, mMuonCl),
1275 truncateFloatFraction(cluster.z, mMuonCl),
1276 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1281template <
typename HMPCursorType>
1286 hmpCursor.reserve(hmpMatches.size());
1289 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1291 const auto&
match = hmpMatches[iHmp];
1293 float xTrk, yTrk, theta,
phi;
1297 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1300 auto photChargeVec =
match.getPhotCharge();
1302 float photChargeVec2[10];
1304 for (Int_t
i = 0;
i < 10;
i++) {
1305 photChargeVec2[
i] = photChargeVec[
i];
1307 auto tref = mGIDToTableID.find(
match.getTrackRef());
1308 if (tref != mGIDToTableID.end()) {
1309 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1311 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1323 mCollisionStrTrk.clear();
1325 mVertexStrLUT.clear();
1327 for (
auto& sTrk : recoData.getStrangeTracks()) {
1331 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1333 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1335 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1337 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1338 mVertexStrLUT[vtxId]++;
1340 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1343 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1344 mStrTrkIndices.clear();
1345 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1348template <
typename V0C,
typename CC,
typename D3BC>
1351 int itsTableIdx = -1;
1357 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1367 v0Curs.reserve(nV0);
1368 cascCurs.reserve(nCasc);
1369 d3BodyCurs.reserve(nD3Body);
1371 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1373 auto item = mGIDToTableID.find(ITSIndex);
1374 if (item != mGIDToTableID.end()) {
1375 itsTableIdx = item->second;
1377 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1381 v0Curs(mStrTrkIndices[sTrkID++],
1391 sTrk.getAverageClusterSize());
1393 cascCurs(mStrTrkIndices[sTrkID++],
1403 sTrk.getAverageClusterSize());
1405 d3BodyCurs(mStrTrkIndices[sTrkID++],
1415 sTrk.getAverageClusterSize());
1422 const auto& tpcTracks =
data.getTPCTracks();
1423 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1424 const auto& tpcClusShMap =
data.clusterShMapTPC;
1425 const auto& tpcClusAcc =
data.getTPCClusters();
1426 constexpr int maxRows = 152;
1427 constexpr int neighbour = 2;
1428 int ntr = tpcTracks.size();
1429 mTPCCounters.clear();
1430 mTPCCounters.resize(ntr);
1432 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1433#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1435 for (
int itr = 0; itr < ntr; itr++) {
1436 std::array<bool, maxRows> clMap{}, shMap{};
1437 uint8_t sectorIndex, rowIndex;
1438 uint32_t clusterIndex;
1439 auto&
counters = mTPCCounters[itr];
1440 const auto& track = tpcTracks[itr];
1441 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1442 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1443 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1444 clMap[rowIndex] =
true;
1446 if (!shMap[rowIndex]) {
1449 shMap[rowIndex] =
true;
1453 for (
int i = 0;
i < maxRows;
i++) {
1458 }
else if ((
i - last) <= neighbour) {
1461 int lim = std::min(
i + 1 + neighbour, maxRows);
1462 for (
int j =
i + 1;
j < lim;
j++) {
1477 if (track.getTrackletIndex(il) != -1) {
1481 if (track.getHasNeighbor()) {
1484 if (track.getHasPadrowCrossing()) {
1490template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1491void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1492 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1494 auto inputEvent = caloHandler.buildEvent(eventID);
1495 auto cellsInEvent = inputEvent.mCells;
1496 auto cellMClabels = inputEvent.mMCCellLabels;
1497 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1498 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1500 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1502 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1503 caloCellCursor(bcID,
1507 cellsInEvent[iCell].
getType(),
1521 std::vector<int32_t> particleIds;
1522 std::vector<float> amplitudeFraction;
1523 if (!mEMCselectLeading) {
1524 particleIds.reserve(cellMClabels.size());
1525 amplitudeFraction.reserve(cellMClabels.size());
1527 float tmpMaxAmplitude = 0;
1528 int32_t tmpindex = 0;
1529 for (
auto& mclabel : cellMClabels[iCell]) {
1531 if (mclabel.isValid()) {
1532 if (mEMCselectLeading) {
1533 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1535 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1536 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1537 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1538 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1542 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1543 auto iter = trackStore.find(mclabel.getTrackID());
1544 if (iter != trackStore.end()) {
1545 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1546 particleIds.emplace_back(iter->second);
1548 particleIds.emplace_back(-1);
1549 amplitudeFraction.emplace_back(0.f);
1550 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1551 if (mMCKineReader) {
1552 auto mctrack = mMCKineReader->
getTrack(mclabel);
1555 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1561 if (mEMCselectLeading) {
1562 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1563 particleIds.emplace_back(tmpindex);
1565 if (particleIds.size() == 0) {
1566 particleIds.emplace_back(-1);
1567 amplitudeFraction.emplace_back(0.f);
1569 mcCaloCellLabelCursor(particleIds,
1576template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1577void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1578 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1582 auto caloEMCCells =
data.getEMCALCells();
1583 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1584 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1586 auto caloPHOSCells =
data.getPHOSCells();
1587 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1588 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1592 caloPHOSCellsTRGR = {};
1593 mcCaloPHOSCellLabels = {};
1598 caloEMCCellsTRGR = {};
1599 mcCaloEMCCellLabels = {};
1606 emcEventHandler.
reset();
1607 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1610 phsEventHandler.
reset();
1611 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1617 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1619 caloEvents.reserve(emcNEvents + phsNEvents);
1621 for (
int iev = 0; iev < emcNEvents; ++iev) {
1623 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1626 for (
int iev = 0; iev < phsNEvents; ++iev) {
1628 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1631 std::sort(caloEvents.begin(), caloEvents.end(),
1632 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1635 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1636 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1637 int8_t caloType = std::get<1>(caloEvents[
i]);
1638 int eventID = std::get<2>(caloEvents[
i]);
1639 auto item = bcsMap.find(globalBC);
1641 if (item != bcsMap.end()) {
1642 bcID = item->second;
1644 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1646 if (caloType == 0) {
1647 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1649 if (caloType == 1) {
1650 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1661 mLPMProdTag = ic.
options().
get<
string>(
"lpmp-prod-tag");
1662 mAnchorPass = ic.
options().
get<
string>(
"anchor-pass");
1663 mAnchorProd = ic.
options().
get<
string>(
"anchor-prod");
1664 mRecoPass = ic.
options().
get<
string>(
"reco-pass");
1665 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1666 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1667 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1668 mRunNumber = ic.
options().
get<
int>(
"run-number");
1669 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1670 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1671 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1672 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1673 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1674 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1675 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1676 mStreamerFlags.
set(
s);
1677 if (mStreamerFlags) {
1678 LOGP(info,
"Writing streamer data with mask:");
1679 LOG(info) << mStreamerFlags;
1681 LOGP(warn,
"Specified non-default empty streamer mask!");
1684 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1685 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1686 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1687 LOGP(info,
"Using random device for seeding");
1688 std::random_device
rd;
1689 std::array<int, std::mt19937::state_size> seed_data{};
1690 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1691 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1692 mGenerator = std::mt19937(seq);
1694 LOGP(info,
"Using seed {} for sampling", seed);
1695 mGenerator.seed(seed);
1698 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1701 LOG(info) <<
"OpenMP is disabled";
1703 if (mTFNumber == -1L) {
1704 LOG(info) <<
"TFNumber will be obtained from CCDB";
1706 if (mRunNumber == -1L) {
1707 LOG(info) <<
"The Run number will be obtained from DPL headers";
1711 if (mTruncate != 1) {
1712 LOG(info) <<
"Truncation is not used!";
1713 mCollisionPosition = 0xFFFFFFFF;
1714 mCollisionPositionCov = 0xFFFFFFFF;
1715 mTrackX = 0xFFFFFFFF;
1716 mTrackAlpha = 0xFFFFFFFF;
1717 mTrackSnp = 0xFFFFFFFF;
1718 mTrackTgl = 0xFFFFFFFF;
1719 mTrack1Pt = 0xFFFFFFFF;
1720 mTrackChi2 = 0xFFFFFFFF;
1721 mTrackCovDiag = 0xFFFFFFFF;
1722 mTrackCovOffDiag = 0xFFFFFFFF;
1723 mTrackSignal = 0xFFFFFFFF;
1724 mTrackTime = 0xFFFFFFFF;
1725 mTPCTime0 = 0xFFFFFFFF;
1726 mTrackTimeError = 0xFFFFFFFF;
1727 mTrackPosEMCAL = 0xFFFFFFFF;
1728 mTracklets = 0xFFFFFFFF;
1729 mMcParticleW = 0xFFFFFFFF;
1730 mMcParticlePos = 0xFFFFFFFF;
1731 mMcParticleMom = 0xFFFFFFFF;
1732 mCaloAmp = 0xFFFFFFFF;
1733 mCaloTime = 0xFFFFFFFF;
1734 mCPVPos = 0xFFFFFFFF;
1735 mCPVAmpl = 0xFFFFFFFF;
1736 mMuonTr1P = 0xFFFFFFFF;
1737 mMuonTrThetaX = 0xFFFFFFFF;
1738 mMuonTrThetaY = 0xFFFFFFFF;
1739 mMuonTrZmu = 0xFFFFFFFF;
1740 mMuonTrBend = 0xFFFFFFFF;
1741 mMuonTrNonBend = 0xFFFFFFFF;
1742 mMuonTrCov = 0xFFFFFFFF;
1743 mMuonCl = 0xFFFFFFFF;
1744 mMuonClErr = 0xFFFFFFFF;
1745 mV0Time = 0xFFFFFFFF;
1746 mV0ChannelTime = 0xFFFFFFFF;
1747 mFDDTime = 0xFFFFFFFF;
1748 mFDDChannelTime = 0xFFFFFFFF;
1749 mT0Time = 0xFFFFFFFF;
1750 mT0ChannelTime = 0xFFFFFFFF;
1751 mV0Amplitude = 0xFFFFFFFF;
1752 mFDDAmplitude = 0xFFFFFFFF;
1753 mT0Amplitude = 0xFFFFFFFF;
1757 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1760 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1763 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1764 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1765 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1766 : HepMCUpdate::anyKey);
1767 mXSectionUpdate = when;
1768 mPdfInfoUpdate = when;
1769 mHeavyIonUpdate = when;
1773 if (mStreamerFlags) {
1774 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1780 mTimer.Start(
false);
1783 updateTimeDependentParams(pc);
1808 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
1809 if (mCTPReadout == 1) {
1810 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
1811 createCTPReadout(recoData, ctpDigitsCreated, pc);
1812 LOG(info) <<
"CTP : ctpreadout created from AOD";
1813 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
1815 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1816 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
1817 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
1818 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
1819 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
1820 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
1822 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1826 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
1827 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
1828 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
1829 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
1830 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
1831 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
1832 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
1833 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
1834 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
1835 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
1836 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
1837 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
1838 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
1839 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
1840 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
1841 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
1842 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
1843 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
1844 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
1845 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
1846 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
1847 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1848 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
1849 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
1850 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
1851 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
1852 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
1853 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
1854 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
1855 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
1856 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
1857 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
1858 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
1872 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
1873 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
1874 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
1875 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
1876 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
1877 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
1878 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
1879 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
1880 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
1881 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
1884 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
1886 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
1888 mMCKineReader = mcReader.get();
1889 std::map<uint64_t, int> bcsMap;
1890 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
1891 if (!primVer2TRefs.empty()) {
1892 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
1895 mBCLookup.
init(bcsMap);
1898 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
1899 if (mTFNumber == -1L) {
1901 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
1903 tfNumber = mTFNumber;
1906 std::vector<float> aAmplitudes, aTimes;
1907 std::vector<uint8_t> aChannels;
1908 fv0aCursor.reserve(fv0RecPoints.size());
1909 for (
auto& fv0RecPoint : fv0RecPoints) {
1910 aAmplitudes.clear();
1913 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
1914 for (
auto& channel : channelData) {
1915 if (channel.charge > 0) {
1916 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
1917 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
1918 aChannels.push_back(channel.channel);
1921 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
1922 auto item = bcsMap.find(
bc);
1924 if (item != bcsMap.end()) {
1925 bcID = item->second;
1927 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
1932 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
1933 fv0RecPoint.getTrigger().getTriggersignals());
1935 if (mEnableFITextra) {
1936 fv0aExtraCursor(bcID,
1941 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
1942 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
1943 zdcCursor.reserve(zdcBCRecData.size());
1944 for (
auto zdcRecData : zdcBCRecData) {
1945 uint64_t
bc = zdcRecData.ir.toLong();
1946 auto item = bcsMap.find(
bc);
1948 if (item != bcsMap.end()) {
1949 bcID = item->second;
1951 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
1953 int fe, ne, ft, nt, fi, ni;
1954 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
1956 zdcChannelsE.clear();
1957 zdcAmplitudes.clear();
1959 zdcChannelsT.clear();
1960 for (
int ie = 0; ie < ne; ie++) {
1961 auto& zdcEnergyData = zdcEnergies[fe + ie];
1962 zdcEnergy.emplace_back(zdcEnergyData.energy());
1963 zdcChannelsE.emplace_back(zdcEnergyData.ch());
1965 for (
int it = 0; it < nt; it++) {
1966 auto& tdc = zdcTDCData[ft + it];
1967 zdcAmplitudes.emplace_back(tdc.amplitude());
1968 zdcTime.emplace_back(tdc.value());
1982 std::vector<std::vector<int>> mcColToEvSrc;
1988 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
1989 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
1990 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
1993 int totalNParts = 0;
1994 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
1995 totalNParts += mcParts[iCol].size();
1997 mcCollisionsCursor.
reserve(totalNParts);
1999 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2000 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2001 auto globalBC = mcRecords[iCol].toLong();
2002 auto item = bcsMap.find(globalBC);
2004 if (item != bcsMap.end()) {
2005 bcID = item->second;
2007 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2008 <<
"for MC collision; BC = " << globalBC
2009 <<
", mc collision = " << iCol;
2011 auto& colParts = mcParts[iCol];
2012 auto nParts = colParts.size();
2013 for (
auto colPart : colParts) {
2014 auto eventID = colPart.entryID;
2015 auto sourceID = colPart.sourceID;
2018 if (nParts == 1 || sourceID == 0) {
2021 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2022 updateMCHeader(mcCollisionsCursor.
cursor,
2023 hepmcXSectionsCursor.
cursor,
2024 hepmcPdfInfosCursor.
cursor,
2025 hepmcHeavyIonsCursor.
cursor,
2033 mcColToEvSrc.emplace_back(std::vector<int>{iCol, sourceID, eventID});
2038 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2039 [](
const std::vector<int>&
left,
const std::vector<int>&
right) { return (left[0] < right[0]); });
2042 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2043 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2045 fddCursor.reserve(fddRecPoints.size());
2046 for (
const auto& fddRecPoint : fddRecPoints) {
2047 for (
int i = 0;
i < 8;
i++) {
2048 aFDDAmplitudesA[
i] = 0;
2049 aFDDAmplitudesC[
i] = 0;
2050 aFDDTimesA[
i] = 0.f;
2051 aFDDTimesC[
i] = 0.f;
2053 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2054 uint64_t
bc = globalBC;
2055 auto item = bcsMap.find(
bc);
2057 if (item != bcsMap.end()) {
2058 bcID = item->second;
2060 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2062 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2063 for (
const auto& channel : channelData) {
2064 if (channel.mPMNumber < 8) {
2065 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2066 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2068 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2069 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2076 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2077 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2078 fddRecPoint.getTrigger().getTriggersignals());
2079 if (mEnableFITextra) {
2080 fddExtraCursor(bcID,
2087 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2088 std::vector<uint8_t> aChannelsA, aChannelsC;
2089 ft0Cursor.reserve(ft0RecPoints.size());
2090 for (
auto& ft0RecPoint : ft0RecPoints) {
2091 aAmplitudesA.clear();
2092 aAmplitudesC.clear();
2097 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2098 for (
auto& channel : channelData) {
2100 if (channel.QTCAmpl > 0) {
2102 if (channel.ChId < nFT0ChannelsAside) {
2103 aChannelsA.push_back(channel.ChId);
2104 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2105 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2107 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2108 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2109 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2113 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2114 uint64_t
bc = globalBC;
2115 auto item = bcsMap.find(
bc);
2117 if (item != bcsMap.end()) {
2118 bcID = item->second;
2120 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2127 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2128 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2129 ft0RecPoint.getTrigger().getTriggersignals());
2130 if (mEnableFITextra) {
2131 ft0ExtraCursor(bcID,
2139 mcColLabelsCursor.
reserve(primVerLabels.size());
2140 for (
auto&
label : primVerLabels) {
2141 auto it = std::find_if(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2142 [&
label](
const auto& mcColInfo) { return mcColInfo[1] == label.getSourceID() && mcColInfo[2] == label.getEventID(); });
2143 int32_t mcCollisionID = -1;
2144 if (it != mcColToEvSrc.end()) {
2145 mcCollisionID = it->at(0);
2147 uint16_t mcMask = 0;
2148 mcColLabelsCursor(mcCollisionID, mcMask);
2152 cacheTriggers(recoData);
2153 countTPCClusters(recoData);
2155 int collisionID = 0;
2159 auto& trackReffwd = primVer2TRefs.back();
2160 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2162 for (
auto&
vertex : primVertices) {
2163 auto& trackReffwd = primVer2TRefs[collisionID];
2164 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2169 prepareStrangenessTracking(recoData);
2171 mGIDToTableFwdID.clear();
2172 mGIDToTableMFTID.clear();
2174 if (mPropTracks || mThinTracks) {
2178 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2179 for (
const auto&
v0 : v0s) {
2180 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2181 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2183 for (
const auto& cascade : cascades) {
2184 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2186 for (
const auto& id3Body : decays3Body) {
2187 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2188 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2189 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2200 auto& trackRef = primVer2TRefs.back();
2202 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2203 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2204 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2208 collisionsCursor.reserve(primVertices.size());
2209 for (
auto&
vertex : primVertices) {
2210 auto& cov =
vertex.getCov();
2211 auto& timeStamp =
vertex.getTimeStamp();
2212 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2213 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2214 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2215 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2218 auto item = bcsMap.find(globalBC);
2220 if (item != bcsMap.end()) {
2221 bcID = item->second;
2223 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2225 collisionsCursor(bcID,
2226 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2227 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2228 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2229 truncateFloatFraction(cov[0], mCollisionPositionCov),
2230 truncateFloatFraction(cov[1], mCollisionPositionCov),
2231 truncateFloatFraction(cov[2], mCollisionPositionCov),
2232 truncateFloatFraction(cov[3], mCollisionPositionCov),
2233 truncateFloatFraction(cov[4], mCollisionPositionCov),
2234 truncateFloatFraction(cov[5], mCollisionPositionCov),
2236 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2237 vertex.getNContributors(),
2238 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2239 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2240 mVtxToTableCollID[collisionID] = mTableCollID++;
2242 auto& trackRef = primVer2TRefs[collisionID];
2244 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2245 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2246 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2250 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2251 fillHMPID(recoData, hmpCursor);
2252 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2256 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2258 LOG(
debug) <<
"CTP input available";
2259 for (
auto& ctpDigit : ctpDigits) {
2260 uint64_t
bc = ctpDigit.intRecord.toLong();
2261 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2262 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2263 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2265 auto classMaskOrig = classMask;
2266 classMask = classMask & ~mEMCALTrgClassMask;
2267 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2269 bcToClassMask[
bc] = {classMask, inputMask};
2275 bcCursor.reserve(bcsMap.size());
2276 for (
auto& item : bcsMap) {
2277 uint64_t
bc = item.first;
2278 std::pair<uint64_t, uint64_t> masks{0, 0};
2280 auto bcClassPair = bcToClassMask.find(
bc);
2281 if (bcClassPair != bcToClassMask.end()) {
2282 masks = bcClassPair->second;
2291 bcToClassMask.clear();
2294 auto bcFlags = fillBCFlags(recoData, bcsMap);
2295 bcFlagsCursor.reserve(bcFlags.size());
2296 for (
auto f : bcFlags) {
2303 cpvClustersCursor.reserve(cpvTrigRecs.size());
2304 for (
auto& cpvEvent : cpvTrigRecs) {
2305 uint64_t
bc = cpvEvent.getBCData().toLong();
2306 auto item = bcsMap.find(
bc);
2308 if (item != bcsMap.end()) {
2309 bcID = item->second;
2311 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2313 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2314 auto&
clu = cpvClusters[iClu];
2315 clu.getLocalPosition(posX, posZ);
2316 cpvClustersCursor(bcID,
2317 truncateFloatFraction(posX, mCPVPos),
2318 truncateFloatFraction(posZ, mCPVPos),
2319 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2320 clu.getPackedClusterStatus());
2329 fillMCParticlesTable(*mcReader,
2330 mcParticlesCursor.
cursor,
2336 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2337 mcColToEvSrc.clear();
2343 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2344 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2345 auto& trackRef = primVer2TRefs[iref];
2346 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2352 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2357 mGIDToTableID.clear();
2359 mGIDToTableFwdID.clear();
2361 mGIDToTableMFTID.clear();
2363 mVtxToTableCollID.clear();
2365 mV0ToTableID.clear();
2368 mIndexTableFwd.clear();
2370 mIndexTableMFT.clear();
2375 mGIDUsedBySVtx.clear();
2376 mGIDUsedByStr.clear();
2378 originCursor(tfNumber);
2381 TString dataType = mUseMC ?
"MC" :
"RAW";
2383 TString ROOTVersion = ROOT_RELEASE;
2384 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag"};
2385 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag};
2402 for (
const auto& rof : rofs) {
2403 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2404 for (
int i =
first;
i < last;
i++) {
2405 mITSROFs.push_back(
count);
2415 for (
const auto& rof : rofs) {
2416 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2418 mMFTROFs.push_back(
count);
2425 mITSTPCTRDTriggers.clear();
2428 for (
const auto& trig : itstpctrigs) {
2429 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2431 mITSTPCTRDTriggers.push_back(
count);
2438 mTPCTRDTriggers.clear();
2441 for (
const auto& trig : tpctrigs) {
2442 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2444 mTPCTRDTriggers.push_back(
count);
2454 for (
const auto& rof : rofs) {
2457 mMCHROFs.push_back(
count);
2464AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2467 TrackExtraInfo extraInfoHolder;
2468 if (collisionID < 0) {
2471 bool needBCSlice = collisionID < 0;
2472 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2474 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2480 extraInfoHolder.trackTimeRes = terr;
2482 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2483 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2486 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2488 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2491 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2492 const auto& trackPar =
data.getTrackParam(trackIndex);
2493 extraInfoHolder.flags |= trackPar.getPID() << 28;
2494 auto src = trackIndex.getSource();
2496 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2497 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2498 const auto& tofInt = tofMatch.getLTIntegralOut();
2499 float intLen = tofInt.getL();
2500 extraInfoHolder.length = intLen;
2507 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2510 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2511 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2512 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2513 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2514 setTrackTime(tofSignal, 0.2,
true);
2518 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2519 extraInfoHolder.trdSignal = trdOrig.getSignal();
2520 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2521 if (extraInfoHolder.trackTimeRes < 0.) {
2523 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2525 setTrackTime(ttrig, 1.,
true);
2529 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2530 int nClusters = itsTrack.getNClusters();
2531 float chi2 = itsTrack.getChi2();
2533 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2535 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2537 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2540 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2544 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2545 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2546 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2547 extraInfoHolder.tpcSignal = tpcOrig.getdEdx().dEdxTotTPC;
2548 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2549 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2550 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2551 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2552 uint32_t clsUsedForPID = tpcOrig.getdEdx().NHitsIROC + tpcOrig.getdEdx().NHitsOROC1 + tpcOrig.getdEdx().NHitsOROC2 + tpcOrig.getdEdx().NHitsOROC3;
2553 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2556 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2557 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2558 double err = mTimeMarginTrackTime + terr;
2559 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2564 extraInfoHolder.trackTimeRes = p.
getTimeErr();
2566 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2567 extraInfoHolder.isTPConly =
true;
2570 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2571 auto ts = trITSTPC.getTimeMUS();
2572 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2576 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2581 return extraInfoHolder;
2584AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2588 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2589 const auto& trackPar =
data.getTrackParam(trackIndex);
2590 if (contributorsGID.isIndexSet()) {
2592 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2598 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2599 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2600 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2604 auto safeInt8Clamp = [](
auto value) -> int8_t {
2605 using ValType =
decltype(
value);
2606 return static_cast<int8_t
>(TMath::Nint(std::clamp(
value,
static_cast<ValType
>(std::numeric_limits<int8_t>::min()),
static_cast<ValType
>(std::numeric_limits<int8_t>::max()))));
2609 uint8_t clusterCounters[8] = {0};
2611 uint8_t sectorIndex, rowIndex;
2612 uint32_t clusterIndex;
2613 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2614 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2615 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2616 char indexTracklet = (rowIndex % 152) / 19;
2617 clusterCounters[indexTracklet]++;
2621 for (
int i = 0;
i < 8;
i++) {
2622 if (clusterCounters[
i] > 5) {
2623 byteMask |= (1 <<
i);
2626 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2627 trackQAHolder.tpcClusterByteMask = byteMask;
2628 const float dEdxNorm = (tpcOrig.getdEdx().dEdxTotTPC > 0) ? 100. / tpcOrig.getdEdx().dEdxTotTPC : 0;
2629 trackQAHolder.tpcdEdxMax0R =
uint8_t(tpcOrig.getdEdx().dEdxMaxIROC * dEdxNorm);
2630 trackQAHolder.tpcdEdxMax1R =
uint8_t(tpcOrig.getdEdx().dEdxMaxOROC1 * dEdxNorm);
2631 trackQAHolder.tpcdEdxMax2R =
uint8_t(tpcOrig.getdEdx().dEdxMaxOROC2 * dEdxNorm);
2632 trackQAHolder.tpcdEdxMax3R =
uint8_t(tpcOrig.getdEdx().dEdxMaxOROC3 * dEdxNorm);
2634 trackQAHolder.tpcdEdxTot0R =
uint8_t(tpcOrig.getdEdx().dEdxTotIROC * dEdxNorm);
2635 trackQAHolder.tpcdEdxTot1R =
uint8_t(tpcOrig.getdEdx().dEdxTotOROC1 * dEdxNorm);
2636 trackQAHolder.tpcdEdxTot2R =
uint8_t(tpcOrig.getdEdx().dEdxTotOROC2 * dEdxNorm);
2637 trackQAHolder.tpcdEdxTot3R =
uint8_t(tpcOrig.getdEdx().dEdxTotOROC3 * dEdxNorm);
2640 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2642 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2643 const float qpt = trackPar.getQ2Pt();
2645 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2646 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2652 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2653 const auto& itsOrig =
data.getITSTrack(itsContGID);
2662 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2663 const float qpt = gloCopy.getQ2Pt();
2664 const float x = qpt / beta0;
2666 auto scaleCont = [&
x](
int i) ->
float {
2669 auto scaleGlo = [&
x](
int i) ->
float {
2674 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2675 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2676 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2677 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2678 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2680 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2681 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2682 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2683 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2684 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2688 (*mStreamer) <<
"trackQA"
2689 <<
"trackITSOrig=" << itsOrig
2690 <<
"trackTPCOrig=" << tpcOrig
2691 <<
"trackITSTPCOrig=" << trackPar
2692 <<
"trackITSProp=" << itsCopy
2693 <<
"trackTPCProp=" << tpcCopy
2694 <<
"trackITSTPCProp=" << gloCopy
2697 <<
"scaleCont0=" << scaleCont(0)
2698 <<
"scaleCont1=" << scaleCont(1)
2699 <<
"scaleCont2=" << scaleCont(2)
2700 <<
"scaleCont3=" << scaleCont(3)
2701 <<
"scaleCont4=" << scaleCont(4)
2702 <<
"scaleGlo0=" << scaleGlo(0)
2703 <<
"scaleGlo1=" << scaleGlo(1)
2704 <<
"scaleGlo2=" << scaleGlo(2)
2705 <<
"scaleGlo3=" << scaleGlo(3)
2706 <<
"scaleGlo4=" << scaleGlo(4)
2707 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
2708 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
2709 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
2710 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
2711 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
2712 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
2713 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
2714 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
2715 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
2716 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
2717 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
2718 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
2719 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
2720 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
2721 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
2722 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
2723 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
2724 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
2725 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
2726 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
2727 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
2728 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
2729 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
2730 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
2731 <<
"scaleTOF=" << scaleTOF
2738 return trackQAHolder;
2746 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
2751void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
2753 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
2754 constexpr float ETAEMCAL = 0.75;
2755 constexpr float ZEMCALFastCheck = 460.;
2756 constexpr float ETADCALINNER = 0.22;
2757 constexpr float ETAPHOS = 0.13653194;
2758 constexpr float ETAPHOSMARGIN = 0.17946979;
2759 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
2760 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
2761 constexpr short SECTORTYPE[18] = {
2762 SNONE, SNONE, SNONE, SNONE,
2763 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
2766 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
2777 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
2778 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2779 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
2783 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
2784 (!outTr.rotateParam(outTr.getPhi()) ||
2786 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
2787 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
2793 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
2796 auto outTrTmp = outTr;
2798 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
2799 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2800 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
2805 if (sectorTmp == sector) {
2813 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
2820 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
2825 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
2826 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
2827 if (etaAbs > ETAEMCAL) {
2828 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
2832 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
2833 if (!propExactSector(XPHOS)) {
2836 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
2837 tg = std::atan2(
r, outTr.getZ());
2838 eta = -std::log(std::tan(0.5f * tg));
2839 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
2842 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
2843 extraInfoHolder.trackEtaEMCAL = eta;
2844 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
2848std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
2850 std::set<uint64_t> emcalIncompletes;
2851 for (
const auto& trg : triggers) {
2852 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
2854 emcalIncompletes.insert(trg.getBCData().toLong());
2857 return emcalIncompletes;
2863 static bool initOnceDone =
false;
2864 if (!initOnceDone) {
2865 initOnceDone =
true;
2872 for (
auto i = 0U;
i < bs.size();
i++) {
2887 mTPCBinNS = elParam.ZbinWidth * 1.e3;
2890 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
2891 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
2912 LOG(info) <<
"ITS Alpide param updated";
2914 par.printKeyValues();
2918 LOG(info) <<
"MFT Alpide param updated";
2920 par.printKeyValues();
2931 mEMCALTrgClassMask = 0;
2932 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
2934 mEMCALTrgClassMask |= trgclass.classMask;
2937 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
2941void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
2952 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
2953 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
2954 assert(nbitsFrac > 1);
2955 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
2957 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
2958 << TOFTimePrecPS <<
" ps";
2961 if (!trackRef.getEntries()) {
2965 std::uint64_t maxBC = mStartIR.
toLong();
2966 const auto& tofClus =
data.getTOFClusters();
2973 for (
int ti =
start; ti <
end; ti++) {
2974 auto& trackIndex = GIndices[ti];
2975 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2976 const auto& tofInt = tofMatch.getLTIntegralOut();
2977 float intLen = tofInt.getL();
2978 float tofExpMom = 0.;
2988 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
2989 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
2990 double exp = intLen * energy / (cSpeed * tofExpMom);
2991 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2992 auto bc = relativeTime_to_GlobalBC(tofSignal);
2994 auto it = bcsMap.lower_bound(
bc);
2995 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
2996 bcsMap.emplace_hint(it,
bc, 1);
3005 if ((--bcsMap.end())->first <= maxBC) {
3006 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3010 for (
auto& item : bcsMap) {
3016std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3028 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3051 auto upperindex = p.first;
3052 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3055 if (upperindex != p.first) {
3059 slice[1] = upperindex;
3061 auto bcOfTimeRef = p.second - this->mStartIR.
toLong();
3062 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3063 <<
" t: " << tmax <<
" " << slice[1]
3064 <<
" bcref: " << bcOfTimeRef;
3070 std::vector<uint8_t>
flags(bcsMap.size());
3073 auto bcIt = bcsMap.begin();
3074 auto itsrofs =
data.getITSTracksROFRecords();
3077 for (
auto& rof : itsrofs) {
3078 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3081 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3083 while (bcIt != bcsMap.end()) {
3084 if (bcIt->first < globalBC0) {
3088 if (bcIt->first > globalBC1) {
3100 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3101 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3108 auto dataRequest = std::make_shared<DataRequest>();
3109 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3111 dataRequest->requestTracks(
src, useMC);
3112 dataRequest->requestPrimaryVertices(useMC);
3114 dataRequest->requestCTPDigits(useMC);
3117 dataRequest->requestSecondaryVertices(useMC);
3119 if (enableStrangenessTracking) {
3120 dataRequest->requestStrangeTracks(useMC);
3121 LOGF(info,
"requestStrangeTracks Finish");
3130 dataRequest->requestTOFClusters(useMC);
3133 dataRequest->requestPHOSCells(useMC);
3136 dataRequest->requestTRDTracklets(
false);
3139 dataRequest->requestEMCALCells(useMC);
3142 dataRequest->requestCPVClusters(useMC);
3145 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3151 dataRequest->inputs,
3154 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3159 std::vector<OutputSpec> outputs{
3199 outputs.insert(outputs.end(),
3200 {OutputForTable<McCollisions>::spec(),
3201 OutputForTable<HepMCXSections>::spec(),
3202 OutputForTable<HepMCPdfInfos>::spec(),
3203 OutputForTable<HepMCHeavyIons>::spec(),
3204 OutputForTable<McMFTTrackLabels>::spec(),
3205 OutputForTable<McFwdTrackLabels>::spec(),
3206 OutputForTable<StoredMcParticles_001>::spec(),
3207 OutputForTable<McTrackLabels>::spec(),
3208 OutputForTable<McCaloLabels_001>::spec(),
3213 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3217 "aod-producer-workflow",
3220 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3222 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3223 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3224 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3225 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3226 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3227 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3228 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3229 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3230 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3231 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3232 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3233 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3234 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3235 ConfigParamSpec{
"hepmc-update", VariantType::String,
"always", {
"When to update HepMC Aux tables: always - force update, never - never update, all - if all keys are present, any - when any key is present (not valid yet)"}},
3236 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3237 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3238 ConfigParamSpec{
"trackqc-fraction", VariantType::Float,
float(0.1), {
"Fraction of tracks to QC"}},
3239 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3240 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3241 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
Class to refer to the reconstructed information.
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
General auxilliary methods.
uint64_t exp(uint64_t base, uint8_t exp) noexcept
definition of CTPDigit, CTPInputDigit
Header of the AggregatedRunInfo struct.
Global Forward Muon tracks.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the MCTrack class.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Utility functions for MC particles.
Class to perform MFT MCH (and MID) matching.
Class to store the output of the matching to HMPID.
Class to perform TOF matching to global tracks.
Definition of the parameter class for the detector electronics.
Header to collect physics constants.
Definition of the FDD RecPoint class.
Definition of the ITS track.
Definition of the MUON track.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
Result of refitting TPC-ITS matched track.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
Container class to store energy released in the ZDC.
Container class to store a TDC hit in a ZDC channel.
const auto & getBCPattern() const
void GetStartVertex(TVector3 &vertex) const
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void run(ProcessingContext &pc) final
void init(InitContext &ic) final
std::pair< size_t, uint64_t > lower_bound(uint64_t timestamp) const
void init(std::map< uint64_t, int > const &bcs)
initialize this container (to be ready for lookup/search queries)
void clear()
clear/reset this container
std::vector< uint64_t > const & getBCTimeVector() const
return the sorted vector of increaing BC times
static float getAmplitude(const o2::emcal::Cell &cell)
static int16_t getLnAmplitude(const o2::emcal::Cell &)
static int8_t getTriggerBits(const o2::emcal::Cell &)
static int16_t getCellNumber(const o2::emcal::Cell &cell)
static int16_t getFastOrAbsID(const o2::emcal::Cell &)
static bool isTRU(const o2::emcal::Cell &cell)
static float getTimeStamp(const o2::emcal::Cell &cell)
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static constexpr float MAX_SIN_PHI
static constexpr float MAX_STEP
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const DPLAlpideParam< N > & Instance()
void printStream(std::ostream &stream) const
Static class with identifiers, bitmasks and names for ALICE detectors.
Handler for EMCAL event data.
void reset()
Reset containers with empty ranges.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::emcal::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
InteractionRecord getInteractionRecordForEvent(int eventID) const
Get the interaction record for the given event.
int getNumberOfEvents() const
Get the number of events handled by the event handler.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static constexpr int NCellsA
o2::dataformats::GlobalFwdTrack MCHtoFwd(const o2::mch::TrackParam &mchTrack)
Converts mchTrack parameters to Forward coordinate system.
track parameters for internal use
Double_t getNonBendingCoor() const
return non bending coordinate (cm)
Double_t getBendingCoor() const
return bending coordinate (cm)
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::phos::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void reset()
Reset containers with empty ranges.
InteractionRecord getInteractionRecordForEvent(int eventID) const
int getNumberOfEvents() const
MCTrack const * getTrack(o2::MCCompLabel const &) const
void releaseTracksForSourceAndEvent(int source, int event)
API to ask releasing tracks (freeing memory) for source + event.
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
static void addInteractionBC(int bc, bool fromCollisonCotext=false)
void set(const std::string &s, int base=2)
bool match(const std::vector< std::string > &queries, const char *pattern)
GLfloat GLfloat GLfloat alpha
GLint GLint GLsizei GLuint * counters
GLuint GLuint GLfloat weight
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
constexpr std::array< float, 2 > trackQAScaledTOF
constexpr std::array< float, 5 > trackQAScaleContP1
uint8_t itsSharedClusterMap uint8_t
constexpr std::array< float, 5 > trackQAScaleContP0
constexpr std::array< float, 5 > trackQAScaleGloP0
constexpr std::array< float, 5 > trackQAScaleGloP1
constexpr float trackQAScaleBins
constexpr float trackQARefRadius
bool updateHepMCHeavyIon(const HeavyIonCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
short updateMCCollisions(const CollisionCursor &cursor, int bcId, float time, o2::dataformats::MCEventHeader const &header, short generatorId=0, int sourceId=0, unsigned int mask=0xFFFFFFF0)
bool updateHepMCPdfInfo(const PdfInfoCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
uint32_t updateParticles(const ParticleCursor &cursor, int collisionID, std::vector< MCTrack > const &tracks, TrackToIndex &preselect, uint32_t offset=0, bool filter=false, bool background=false, uint32_t weightMask=0xFFFFFFF0, uint32_t momentumMask=0xFFFFFFF0, uint32_t positionMask=0xFFFFFFF0)
bool updateHepMCXSection(const XSectionCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
void keepMCParticle(std::vector< std::vector< std::unordered_map< int, int > > > &store, int source, int event, int track, int value=1)
framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra)
create a processor spec
void dimensionMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store, int Nsources, int NEvents)
void clearMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store)
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
constexpr double MassPionCharged
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
int angle2Sector(float phi)
float sector2Angle(int sect)
const int TDCSignal[NTDCChannels]
constexpr int NTDCChannels
std::string fullVersion()
get full version information (official O2 release and git commit)
void setDeltaTFwd(float fwd)
void setDeltaTBwd(float bwd)
static OutputSpec const spec()
decltype(FFL(std::declval< cursor_t >())) cursor
void reserve(int64_t size)
auto getZDCTDCData() const
auto getStrangeTracks() const
auto getFDDRecPoints() const
auto getMCHMIDMatches() const
o2::InteractionRecord startIR
auto getDecays3BodyIdx() const
auto getTPCTRDTriggers() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
auto getMCHTrackClusters() const
auto getMCHTracksROFRecords() const
auto getCTPDigits() const
auto getCascadesIdx() const
auto getPrimaryVertexMatchedTrackRefs() const
gsl::span< const o2::trd::TriggerRecord > getTRDTriggerRecords() const
auto getCPVClusters() const
auto getFV0ChannelsData() const
auto getMFTTracksROFRecords() const
auto getCPVTriggers() const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
auto getPrimaryVertexMCLabels() const
auto getZDCEnergy() const
auto getFT0RecPoints() const
auto getITSTracksROFRecords() const
auto getMCHTracks() const
auto getFV0RecPoints() const
auto getHMPMatches() const
auto getITSTPCTRDTriggers() const
auto getFT0ChannelsData() const
auto getFDDChannelsData() const
auto getZDCBCRecData() const
auto getEMCALTriggers() const
auto getMFTTracks() const
auto getPHOSTriggers() const
static bool downsampleTsallisCharged(float pt, float factorPt, float sqrts, float &weight, float rnd, float mass=0.13957)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::uniform_int_distribution< unsigned long long > distr
std::array< uint16_t, 5 > pattern