87#include "Math/SMatrix.h"
93#include <unordered_map>
98#include "TLorentzVector.h"
106#include <nlohmann/json.hpp>
127 uint64_t classMaskEMCAL = 0, classMaskTRD = 0, classMaskPHOSCPV = 0;
128 for (
const auto& trgclass : ctpcfg->getCTPClasses()) {
129 if (trgclass.cluster->getClusterDetNames().find(
"EMC") != std::string::npos) {
130 classMaskEMCAL = trgclass.classMask;
132 if (trgclass.cluster->getClusterDetNames().find(
"PHS") != std::string::npos) {
133 classMaskPHOSCPV = trgclass.classMask;
135 if (trgclass.cluster->getClusterDetNames().find(
"TRD") != std::string::npos) {
136 classMaskTRD = trgclass.classMask;
139 LOG(info) <<
"createCTPReadout: Class Mask EMCAL -> " << classMaskEMCAL;
140 LOG(info) <<
"createCTPReadout: Class Mask PHOS/CPV -> " << classMaskPHOSCPV;
141 LOG(info) <<
"createCTPReadout: Class Mask TRD -> " << classMaskTRD;
149 std::vector<o2::emcal::TriggerRecord> triggerRecordEMCALPhys;
150 for (
const auto& trg : triggerrecordEMCAL) {
154 triggerRecordEMCALPhys.push_back(trg);
160 std::set<uint64_t> bcsMapT0triggers;
162 for (
auto& ft0RecPoint : ft0RecPoints) {
163 auto t0triggers = ft0RecPoint.getTrigger();
164 if (t0triggers.getVertex()) {
165 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
166 bcsMapT0triggers.insert(globalBC);
170 auto genericCTPDigitizer = [&bcsMapT0triggers, &ctpDigits](
auto triggerrecords, uint64_t classmask) ->
int {
174 uint32_t orbitPrev = 0;
176 for (
auto& trigger : triggerrecords) {
177 auto orbitPrevT = orbitPrev;
178 auto bcPrevT = bcPrev;
179 bcPrev = trigger.getBCData().bc;
180 orbitPrev = trigger.getBCData().orbit;
186 uint64_t globalBC = trigger.getBCData().toLong();
187 auto t0entry = bcsMapT0triggers.find(globalBC);
188 if (t0entry != bcsMapT0triggers.end()) {
189 auto ctpdig = std::find_if(ctpDigits.begin(), ctpDigits.end(), [globalBC](
const o2::ctp::CTPDigit& dig) { return static_cast<uint64_t>(dig.intRecord.toLong()) == globalBC; });
190 if (ctpdig != ctpDigits.end()) {
192 ctpdig->CTPClassMask |= std::bitset<64>(classmask);
193 LOG(
debug) <<
"createCTPReadout: Merging " << classmask <<
" CTP digits with existing digit, CTP mask " << ctpdig->CTPClassMask;
196 LOG(
debug) <<
"createCTPReadout: New CTP digit needed for class " << classmask << std::endl;
197 auto& ctpdigNew = ctpDigits.emplace_back();
198 ctpdigNew.intRecord.setFromLong(globalBC);
199 ctpdigNew.CTPClassMask = classmask;
202 LOG(warning) <<
"createCTPReadout: Found " << classmask <<
" and no MTVX:" << globalBC;
209 auto warningsTRD = genericCTPDigitizer(triggerrecordTRD, classMaskTRD);
210 auto warningsEMCAL = genericCTPDigitizer(triggerRecordEMCALPhys, classMaskEMCAL);
211 auto warningsPHOSCPV = genericCTPDigitizer(triggerrecordPHOSCPV, classMaskPHOSCPV);
213 LOG(info) <<
"createCTPReadout:# of TRD bogus triggers:" << warningsTRD;
214 LOG(info) <<
"createCTPReadout:# of EMCAL bogus triggers:" << warningsEMCAL;
215 LOG(info) <<
"createCTPReadout:# of PHOS/CPV bogus triggers:" << warningsPHOSCPV;
219 const std::vector<o2::InteractionTimeRecord>& mcRecords,
220 std::map<uint64_t, int>& bcsMap)
222 const auto& primVertices =
data.getPrimaryVertices();
223 const auto& fddRecPoints =
data.getFDDRecPoints();
224 const auto& ft0RecPoints =
data.getFT0RecPoints();
225 const auto& fv0RecPoints =
data.getFV0RecPoints();
226 const auto& caloEMCCellsTRGR =
data.getEMCALTriggers();
227 const auto& caloPHOSCellsTRGR =
data.getPHOSTriggers();
228 const auto& cpvTRGR =
data.getCPVTriggers();
229 const auto& ctpDigits =
data.getCTPDigits();
230 const auto& zdcBCRecData =
data.getZDCBCRecData();
232 bcsMap[mStartIR.
toLong()] = 1;
235 for (
auto&
rec : mcRecords) {
236 uint64_t globalBC =
rec.toLong();
237 bcsMap[globalBC] = 1;
240 for (
auto& fddRecPoint : fddRecPoints) {
241 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
242 bcsMap[globalBC] = 1;
245 for (
auto& ft0RecPoint : ft0RecPoints) {
246 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
247 bcsMap[globalBC] = 1;
250 for (
auto& fv0RecPoint : fv0RecPoints) {
251 uint64_t globalBC = fv0RecPoint.getInteractionRecord().toLong();
252 bcsMap[globalBC] = 1;
255 for (
auto& zdcRecData : zdcBCRecData) {
256 uint64_t globalBC = zdcRecData.ir.toLong();
257 bcsMap[globalBC] = 1;
260 for (
auto&
vertex : primVertices) {
261 auto& timeStamp =
vertex.getTimeStamp();
262 double tsTimeStamp = timeStamp.getTimeStamp() * 1E3;
263 uint64_t globalBC = relativeTime_to_GlobalBC(tsTimeStamp);
264 bcsMap[globalBC] = 1;
267 for (
auto& emcaltrg : caloEMCCellsTRGR) {
268 uint64_t globalBC = emcaltrg.getBCData().toLong();
269 bcsMap[globalBC] = 1;
272 for (
auto& phostrg : caloPHOSCellsTRGR) {
273 uint64_t globalBC = phostrg.getBCData().toLong();
274 bcsMap[globalBC] = 1;
277 for (
auto& cpvtrg : cpvTRGR) {
278 uint64_t globalBC = cpvtrg.getBCData().toLong();
279 bcsMap[globalBC] = 1;
282 for (
auto& ctpDigit : ctpDigits) {
283 uint64_t globalBC = ctpDigit.intRecord.toLong();
284 bcsMap[globalBC] = 1;
288 for (
auto& item : bcsMap) {
294template <
typename TracksCursorType,
typename TracksCovCursorType>
295void AODProducerWorkflowDPL::addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor,
298 tracksCursor(collisionID,
300 truncateFloatFraction(track.getX(), mTrackX),
301 truncateFloatFraction(track.getAlpha(), mTrackAlpha),
304 truncateFloatFraction(track.getSnp(), mTrackSnp),
305 truncateFloatFraction(track.getTgl(), mTrackTgl),
306 truncateFloatFraction(track.getQ2Pt(), mTrack1Pt));
308 float sY = TMath::Sqrt(track.getSigmaY2()), sZ = TMath::Sqrt(track.getSigmaZ2()), sSnp = TMath::Sqrt(track.getSigmaSnp2()),
309 sTgl = TMath::Sqrt(track.getSigmaTgl2()), sQ2Pt = TMath::Sqrt(track.getSigma1Pt2());
310 tracksCovCursor(truncateFloatFraction(sY, mTrackCovDiag),
311 truncateFloatFraction(sZ, mTrackCovDiag),
312 truncateFloatFraction(sSnp, mTrackCovDiag),
313 truncateFloatFraction(sTgl, mTrackCovDiag),
314 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
315 (Char_t)(128. * track.getSigmaZY() / (sZ * sY)),
316 (Char_t)(128. * track.getSigmaSnpY() / (sSnp * sY)),
317 (Char_t)(128. * track.getSigmaSnpZ() / (sSnp * sZ)),
318 (Char_t)(128. * track.getSigmaTglY() / (sTgl * sY)),
319 (Char_t)(128. * track.getSigmaTglZ() / (sTgl * sZ)),
320 (Char_t)(128. * track.getSigmaTglSnp() / (sTgl * sSnp)),
321 (Char_t)(128. * track.getSigma1PtY() / (sQ2Pt * sY)),
322 (Char_t)(128. * track.getSigma1PtZ() / (sQ2Pt * sZ)),
323 (Char_t)(128. * track.getSigma1PtSnp() / (sQ2Pt * sSnp)),
324 (Char_t)(128. * track.getSigma1PtTgl() / (sQ2Pt * sTgl)));
327template <
typename TracksExtraCursorType>
328void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder)
332 auto trackTimeRes = extraInfoHolder.trackTimeRes;
333 if (!extraInfoHolder.isTPConly) {
334 trackTimeRes = truncateFloatFraction(trackTimeRes, mTrackTimeError);
338 tracksExtraCursor(truncateFloatFraction(extraInfoHolder.tpcInnerParam, mTrack1Pt),
339 extraInfoHolder.flags,
340 extraInfoHolder.itsClusterSizes,
341 extraInfoHolder.tpcNClsFindable,
342 extraInfoHolder.tpcNClsFindableMinusFound,
343 extraInfoHolder.tpcNClsFindableMinusPID,
344 extraInfoHolder.tpcNClsFindableMinusCrossedRows,
345 extraInfoHolder.tpcNClsShared,
346 extraInfoHolder.trdPattern,
347 truncateFloatFraction(extraInfoHolder.itsChi2NCl, mTrackChi2),
348 truncateFloatFraction(extraInfoHolder.tpcChi2NCl, mTrackChi2),
349 truncateFloatFraction(extraInfoHolder.trdChi2, mTrackChi2),
350 truncateFloatFraction(extraInfoHolder.tofChi2, mTrackChi2),
351 truncateFloatFraction(extraInfoHolder.tpcSignal, mTrackSignal),
352 truncateFloatFraction(extraInfoHolder.trdSignal, mTrackSignal),
353 truncateFloatFraction(extraInfoHolder.length, mTrackSignal),
354 truncateFloatFraction(extraInfoHolder.tofExpMom, mTrack1Pt),
355 truncateFloatFraction(extraInfoHolder.trackEtaEMCAL, mTrackPosEMCAL),
356 truncateFloatFraction(extraInfoHolder.trackPhiEMCAL, mTrackPosEMCAL),
357 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime),
361template <
typename TracksQACursorType>
362void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor,
TrackQA& trackQAInfoHolder)
365 trackQAInfoHolder.trackID,
366 truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
367 truncateFloatFraction(trackQAInfoHolder.tpcdEdxNorm, mTrackSignal),
368 trackQAInfoHolder.tpcdcaR,
369 trackQAInfoHolder.tpcdcaZ,
370 trackQAInfoHolder.tpcClusterByteMask,
371 trackQAInfoHolder.tpcdEdxMax0R,
372 trackQAInfoHolder.tpcdEdxMax1R,
373 trackQAInfoHolder.tpcdEdxMax2R,
374 trackQAInfoHolder.tpcdEdxMax3R,
375 trackQAInfoHolder.tpcdEdxTot0R,
376 trackQAInfoHolder.tpcdEdxTot1R,
377 trackQAInfoHolder.tpcdEdxTot2R,
378 trackQAInfoHolder.tpcdEdxTot3R,
379 trackQAInfoHolder.dRefContY,
380 trackQAInfoHolder.dRefContZ,
381 trackQAInfoHolder.dRefContSnp,
382 trackQAInfoHolder.dRefContTgl,
383 trackQAInfoHolder.dRefContQ2Pt,
384 trackQAInfoHolder.dRefGloY,
385 trackQAInfoHolder.dRefGloZ,
386 trackQAInfoHolder.dRefGloSnp,
387 trackQAInfoHolder.dRefGloTgl,
388 trackQAInfoHolder.dRefGloQ2Pt,
389 trackQAInfoHolder.dTofdX,
390 trackQAInfoHolder.dTofdZ);
393template <
typename mftTracksCursorType,
typename AmbigMFTTracksCursorType>
394void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
396 std::uint64_t collisionBC,
const std::map<uint64_t, int>& bcsMap)
399 int bcSlice[2] = {-1, -1};
400 const auto& track =
data.getMFTTrack(trackID);
401 const auto& rof =
data.getMFTTracksROFRecords()[mMFTROFs[trackID.getIndex()]];
403 float trackTimeRes = mMFTROFrameHalfLengthNS;
404 bool needBCSlice = collisionID < 0;
405 std::uint64_t bcOfTimeRef;
407 double error = mTimeMarginTrackTime + trackTimeRes;
408 bcOfTimeRef = fillBCSlice(bcSlice, trackTime - error, trackTime + error, bcsMap);
410 bcOfTimeRef = collisionBC - mStartIR.
toLong();
415 uint64_t mftClusterSizesAndTrackFlags = track.getClusterSizes();
416 mftClusterSizesAndTrackFlags |= (track.isCA()) ? (1ULL << (60)) : 0;
418 mftTracksCursor(collisionID,
421 truncateFloatFraction(track.getZ(), mTrackX),
422 truncateFloatFraction(track.getPhi(), mTrackAlpha),
423 truncateFloatFraction(track.getTanl(), mTrackTgl),
424 truncateFloatFraction(track.getInvQPt(), mTrack1Pt),
425 mftClusterSizesAndTrackFlags,
426 truncateFloatFraction(track.getTrackChi2(), mTrackChi2),
427 truncateFloatFraction(trackTime, mTrackTime),
428 truncateFloatFraction(trackTimeRes, mTrackTimeError));
430 ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
434template <
typename TracksCursorType,
typename TracksCovCursorType,
typename TracksExtraCursorType,
typename TracksQACursorType,
typename AmbigTracksCursorType,
435 typename MFTTracksCursorType,
typename MFTTracksCovCursorType,
typename AmbigMFTTracksCursorType,
436 typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename FwdTrkClsCursorType>
437void AODProducerWorkflowDPL::fillTrackTablesPerCollision(
int collisionID,
438 std::uint64_t collisionBC,
440 const gsl::span<const GIndex>& GIndices,
442 TracksCursorType& tracksCursor,
443 TracksCovCursorType& tracksCovCursor,
444 TracksExtraCursorType& tracksExtraCursor,
445 TracksQACursorType& tracksQACursor,
446 AmbigTracksCursorType& ambigTracksCursor,
447 MFTTracksCursorType& mftTracksCursor,
448 MFTTracksCovCursorType& mftTracksCovCursor,
449 AmbigMFTTracksCursorType& ambigMFTTracksCursor,
450 FwdTracksCursorType& fwdTracksCursor,
451 FwdTracksCovCursorType& fwdTracksCovCursor,
452 AmbigFwdTracksCursorType& ambigFwdTracksCursor,
453 FwdTrkClsCursorType& fwdTrkClsCursor,
454 const std::map<uint64_t, int>& bcsMap)
457 if (!GIndex::isTrackSource(
src)) {
464 mftTracksCursor.reserve(nToReserve + mftTracksCursor.lastIndex());
466 fwdTracksCursor.reserve(nToReserve + fwdTracksCursor.lastIndex());
467 fwdTracksCovCursor.reserve(nToReserve + fwdTracksCovCursor.lastIndex());
469 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex());
472 tracksCursor.reserve(nToReserve + tracksCursor.lastIndex());
473 tracksCovCursor.reserve(nToReserve + tracksCovCursor.lastIndex());
474 tracksExtraCursor.reserve(nToReserve + tracksExtraCursor.lastIndex());
476 for (
int ti =
start; ti <
end; ti++) {
477 const auto& trackIndex = GIndices[ti];
478 if (GIndex::includesSource(
src, mInputSources)) {
480 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
483 addToMFTTracksTable(mftTracksCursor, ambigMFTTracksCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
484 mGIDToTableMFTID.emplace(trackIndex, mTableTrMFTID);
487 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
490 addToFwdTracksTable(fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, mftTracksCovCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
491 mGIDToTableFwdID.emplace(trackIndex, mTableTrFwdID);
492 addClustersToFwdTrkClsTable(
data, fwdTrkClsCursor, trackIndex, mTableTrFwdID);
496 if (trackIndex.isAmbiguous() && mGIDToTableID.find(trackIndex) != mGIDToTableID.end()) {
501 static std::uniform_real_distribution<>
distr(0., 1.);
503 auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex,
data, bcsMap);
506 auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex,
data, bcsMap);
507 if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) {
508 trackQAInfoHolder.trackID = mTableTrID;
512 addToTracksQATable(tracksQACursor, trackQAInfoHolder);
519 if (mThinTracks && extraInfoHolder.isTPConly && !writeQAData) {
520 auto trk =
data.getTPCTrack(trackIndex);
521 if (trk.getNClusters() >= mTrackQCNCls && trk.getPt() >= mTrackQCPt) {
531 if (mThinTracks &&
src ==
GIndex::Source::TPC && mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() && mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end() && !writeQAData) {
532 mGIDToTableID.emplace(trackIndex, -1);
536 if (!extraInfoHolder.isTPConly && extraInfoHolder.trackTimeRes < 0.f) {
537 LOG(warning) <<
"Barrel track " << trackIndex <<
" has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime
538 <<
" timeErr=" << extraInfoHolder.trackTimeRes <<
" BCSlice: " << extraInfoHolder.bcSlice[0] <<
":" << extraInfoHolder.bcSlice[1];
541 const auto& trOrig =
data.getTrackParam(trackIndex);
543 if (mPropTracks && trOrig.getX() < mMinPropR &&
544 mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() &&
545 mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end()) {
546 auto trackPar(trOrig);
547 isProp = propagateTrackToPV(trackPar,
data, collisionID);
549 addToTracksTable(tracksCursor, tracksCovCursor, trackPar, collisionID,
aod::track::Track);
555 addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
558 if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
559 ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
561 mGIDToTableID.emplace(trackIndex, mTableTrID);
567 if (collisionID < 0) {
571 auto sTracks =
data.getStrangeTracks();
572 tracksCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCursor.lastIndex());
573 tracksCovCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCovCursor.lastIndex());
574 tracksExtraCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksExtraCursor.lastIndex());
575 for (
int iS{mVertexStrLUT[collisionID]}; iS < mVertexStrLUT[collisionID + 1]; ++iS) {
576 auto& collStrTrk = mCollisionStrTrk[iS];
577 auto& sTrk = sTracks[collStrTrk.second];
578 TrackExtraInfo extraInfo;
579 extraInfo.itsChi2NCl = sTrk.mTopoChi2;
580 extraInfo.itsClusterSizes = sTrk.getClusterSizes();
582 addToTracksExtraTable(tracksExtraCursor, extraInfo);
583 mStrTrkIndices[collStrTrk.second] = mTableTrID;
590 const auto& mchmidMatches =
data.getMCHMIDMatches();
595 for (
int ti =
start; ti <
end; ti++) {
596 auto& trackIndex = GIndices[ti];
597 if (GIndex::includesSource(
src, mInputSources)) {
599 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
602 mGIDToTableMFTID.emplace(trackIndex, mIndexMFTID);
603 mIndexTableMFT[trackIndex.getIndex()] = mIndexMFTID;
606 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
609 mGIDToTableFwdID.emplace(trackIndex, mIndexFwdID);
611 mIndexTableFwd[trackIndex.getIndex()] = mIndexFwdID;
613 const auto& mchmidMatch = mchmidMatches[trackIndex.getIndex()];
614 const auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
615 mIndexTableFwd[mchTrackID] = mIndexFwdID;
624template <
typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename mftTracksCovCursorType>
625void AODProducerWorkflowDPL::addToFwdTracksTable(FwdTracksCursorType& fwdTracksCursor, FwdTracksCovCursorType& fwdTracksCovCursor,
626 AmbigFwdTracksCursorType& ambigFwdTracksCursor, mftTracksCovCursorType& mftTracksCovCursor,
GIndex trackID,
628 const std::map<uint64_t, int>& bcsMap)
630 const auto& mchTracks =
data.getMCHTracks();
631 const auto& midTracks =
data.getMIDTracks();
632 const auto& mchmidMatches =
data.getMCHMIDMatches();
633 const auto& mchClusters =
data.getMCHTrackClusters();
635 FwdTrackInfo fwdInfo;
636 FwdTrackCovInfo fwdCovInfo;
637 int bcSlice[2] = {-1, -1};
640 auto getMCHBitMap = [&](
int mchTrackID) {
641 if (mchTrackID != -1) {
642 const auto& mchTrack = mchTracks[mchTrackID];
643 int first = mchTrack.getFirstClusterIdx();
644 int last = mchTrack.getLastClusterIdx();
645 for (
int i =
first;
i <= last;
i++) {
646 const auto& cluster = mchClusters[
i];
647 int chamberId = cluster.getChamberId();
648 fwdInfo.mchBitMap |= 1 << chamberId;
653 auto getMIDBitMapBoards = [&](
int midTrackID) {
654 if (midTrackID != -1) {
655 const auto& midTrack = midTracks[midTrackID];
656 fwdInfo.midBitMap = midTrack.getHitMap();
657 fwdInfo.midBoards = midTrack.getEfficiencyWord();
661 auto extrapMCHTrack = [&](
int mchTrackID) {
662 const auto& track = mchTracks[mchTrackID];
670 float vx = 0, vy = 0, vz = 0;
671 if (collisionID >= 0) {
672 const auto&
v =
data.getPrimaryVertex(collisionID);
678 o2::mch::TrackParam trackParamAtVertex(track.getZ(), track.getParameters(), track.getCovariances());
701 double dca = std::sqrt(dcaX * dcaX + dcaY * dcaY);
706 double dpdca = track.getP() * dca;
707 double dchi2 = track.getChi2OverNDF();
709 auto fwdmuon = mMatching.
MCHtoFwd(trackParamAtVertex);
711 fwdInfo.x = fwdmuon.
getX();
712 fwdInfo.y = fwdmuon.getY();
713 fwdInfo.z = fwdmuon.getZ();
714 fwdInfo.phi = fwdmuon.getPhi();
715 fwdInfo.tanl = fwdmuon.getTgl();
716 fwdInfo.invqpt = fwdmuon.getInvQPt();
717 fwdInfo.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs);
718 fwdInfo.chi2 = dchi2;
719 fwdInfo.pdca = dpdca;
720 fwdInfo.nClusters = track.getNClusters();
722 fwdCovInfo.sigX = TMath::Sqrt(fwdmuon.getCovariances()(0, 0));
723 fwdCovInfo.sigY = TMath::Sqrt(fwdmuon.getCovariances()(1, 1));
724 fwdCovInfo.sigPhi = TMath::Sqrt(fwdmuon.getCovariances()(2, 2));
725 fwdCovInfo.sigTgl = TMath::Sqrt(fwdmuon.getCovariances()(3, 3));
726 fwdCovInfo.sig1Pt = TMath::Sqrt(fwdmuon.getCovariances()(4, 4));
727 fwdCovInfo.rhoXY = (Char_t)(128. * fwdmuon.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
728 fwdCovInfo.rhoPhiX = (Char_t)(128. * fwdmuon.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
729 fwdCovInfo.rhoPhiY = (Char_t)(128. * fwdmuon.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
730 fwdCovInfo.rhoTglX = (Char_t)(128. * fwdmuon.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
731 fwdCovInfo.rhoTglY = (Char_t)(128. * fwdmuon.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
732 fwdCovInfo.rhoTglPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
733 fwdCovInfo.rho1PtX = (Char_t)(128. * fwdmuon.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
734 fwdCovInfo.rho1PtY = (Char_t)(128. * fwdmuon.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
735 fwdCovInfo.rho1PtPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
736 fwdCovInfo.rho1PtTgl = (Char_t)(128. * fwdmuon.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
742 int mchTrackID = trackID.getIndex();
743 getMCHBitMap(mchTrackID);
744 if (!extrapMCHTrack(mchTrackID)) {
745 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
748 const auto& rof =
data.getMCHTracksROFRecords()[mMCHROFs[mchTrackID]];
749 auto time = rof.getTimeMUS(mStartIR).first;
750 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
751 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
754 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
755 auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
756 if (!extrapMCHTrack(mchTrackID)) {
757 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
759 auto midTrackID = mchmidMatch.getMIDRef().getIndex();
760 fwdInfo.chi2matchmchmid = mchmidMatch.getMatchChi2OverNDF();
761 getMCHBitMap(mchTrackID);
762 getMIDBitMapBoards(midTrackID);
763 auto time = mchmidMatch.getTimeMUS(mStartIR).first;
764 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
765 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
767 const auto& track =
data.getGlobalFwdTrack(trackID);
768 const auto& mftTracks =
data.getMFTTracks();
769 const auto& mfttrack = mftTracks[track.getMFTTrackID()];
770 if (!extrapMCHTrack(track.getMCHTrackID())) {
771 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", track.getMCHTrackID());
773 fwdInfo.x = track.getX();
774 fwdInfo.y = track.getY();
775 fwdInfo.z = track.getZ();
776 fwdInfo.phi = track.getPhi();
777 fwdInfo.tanl = track.getTanl();
778 fwdInfo.invqpt = track.getInvQPt();
779 fwdInfo.chi2 = track.getTrackChi2();
781 fwdInfo.chi2matchmchmid = track.getMIDMatchingChi2();
782 fwdInfo.chi2matchmchmft = track.getMFTMCHMatchingChi2();
783 fwdInfo.matchscoremchmft = track.getMFTMCHMatchingScore();
784 fwdInfo.matchmfttrackid = mIndexTableMFT[track.getMFTTrackID()];
785 fwdInfo.matchmchtrackid = mIndexTableFwd[track.getMCHTrackID()];
786 fwdInfo.trackTime = track.getTimeMUS().getTimeStamp() * 1.e3;
787 fwdInfo.trackTimeRes = track.getTimeMUS().getTimeStampError() * 1.e3;
789 getMCHBitMap(track.getMCHTrackID());
790 getMIDBitMapBoards(track.getMIDTrackID());
792 fwdCovInfo.sigX = TMath::Sqrt(track.getCovariances()(0, 0));
793 fwdCovInfo.sigY = TMath::Sqrt(track.getCovariances()(1, 1));
794 fwdCovInfo.sigPhi = TMath::Sqrt(track.getCovariances()(2, 2));
795 fwdCovInfo.sigTgl = TMath::Sqrt(track.getCovariances()(3, 3));
796 fwdCovInfo.sig1Pt = TMath::Sqrt(track.getCovariances()(4, 4));
797 fwdCovInfo.rhoXY = (Char_t)(128. * track.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
798 fwdCovInfo.rhoPhiX = (Char_t)(128. * track.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
799 fwdCovInfo.rhoPhiY = (Char_t)(128. * track.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
800 fwdCovInfo.rhoTglX = (Char_t)(128. * track.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
801 fwdCovInfo.rhoTglY = (Char_t)(128. * track.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
802 fwdCovInfo.rhoTglPhi = (Char_t)(128. * track.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
803 fwdCovInfo.rho1PtX = (Char_t)(128. * track.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
804 fwdCovInfo.rho1PtY = (Char_t)(128. * track.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
805 fwdCovInfo.rho1PtPhi = (Char_t)(128. * track.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
806 fwdCovInfo.rho1PtTgl = (Char_t)(128. * track.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
810 float sX = TMath::Sqrt(mfttrack.getSigma2X()), sY = TMath::Sqrt(mfttrack.getSigma2Y()), sPhi = TMath::Sqrt(mfttrack.getSigma2Phi()),
811 sTgl = TMath::Sqrt(mfttrack.getSigma2Tanl()), sQ2Pt = TMath::Sqrt(mfttrack.getSigma2InvQPt());
813 mftTracksCovCursor(fwdInfo.matchmfttrackid,
814 truncateFloatFraction(sX, mTrackCovDiag),
815 truncateFloatFraction(sY, mTrackCovDiag),
816 truncateFloatFraction(sPhi, mTrackCovDiag),
817 truncateFloatFraction(sTgl, mTrackCovDiag),
818 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
819 (Char_t)(128. * mfttrack.getCovariances()(0, 1) / (sX * sY)),
820 (Char_t)(128. * mfttrack.getCovariances()(0, 2) / (sPhi * sX)),
821 (Char_t)(128. * mfttrack.getCovariances()(1, 2) / (sPhi * sY)),
822 (Char_t)(128. * mfttrack.getCovariances()(0, 3) / (sTgl * sX)),
823 (Char_t)(128. * mfttrack.getCovariances()(1, 3) / (sTgl * sY)),
824 (Char_t)(128. * mfttrack.getCovariances()(2, 3) / (sTgl * sPhi)),
825 (Char_t)(128. * mfttrack.getCovariances()(0, 4) / (sQ2Pt * sX)),
826 (Char_t)(128. * mfttrack.getCovariances()(1, 4) / (sQ2Pt * sY)),
827 (Char_t)(128. * mfttrack.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
828 (Char_t)(128. * mfttrack.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
831 std::uint64_t bcOfTimeRef;
832 bool needBCSlice = collisionID < 0;
834 float err = mTimeMarginTrackTime + fwdInfo.trackTimeRes;
835 bcOfTimeRef = fillBCSlice(bcSlice, fwdInfo.trackTime - err, fwdInfo.trackTime + err, bcsMap);
837 bcOfTimeRef = collisionBC - mStartIR.
toLong();
841 fwdTracksCursor(collisionID,
845 truncateFloatFraction(fwdInfo.z, mTrackX),
846 truncateFloatFraction(fwdInfo.phi, mTrackAlpha),
847 truncateFloatFraction(fwdInfo.tanl, mTrackTgl),
848 truncateFloatFraction(fwdInfo.invqpt, mTrack1Pt),
850 truncateFloatFraction(fwdInfo.pdca, mTrackX),
851 truncateFloatFraction(fwdInfo.rabs, mTrackX),
852 truncateFloatFraction(fwdInfo.chi2, mTrackChi2),
853 truncateFloatFraction(fwdInfo.chi2matchmchmid, mTrackChi2),
854 truncateFloatFraction(fwdInfo.chi2matchmchmft, mTrackChi2),
855 truncateFloatFraction(fwdInfo.matchscoremchmft, mTrackChi2),
856 fwdInfo.matchmfttrackid,
857 fwdInfo.matchmchtrackid,
861 truncateFloatFraction(fwdInfo.trackTime, mTrackTime),
862 truncateFloatFraction(fwdInfo.trackTimeRes, mTrackTimeError));
864 fwdTracksCovCursor(truncateFloatFraction(fwdCovInfo.sigX, mTrackCovDiag),
865 truncateFloatFraction(fwdCovInfo.sigY, mTrackCovDiag),
866 truncateFloatFraction(fwdCovInfo.sigPhi, mTrackCovDiag),
867 truncateFloatFraction(fwdCovInfo.sigTgl, mTrackCovDiag),
868 truncateFloatFraction(fwdCovInfo.sig1Pt, mTrackCovDiag),
874 fwdCovInfo.rhoTglPhi,
877 fwdCovInfo.rho1PtPhi,
878 fwdCovInfo.rho1PtTgl);
881 ambigFwdTracksCursor(mTableTrFwdID, bcSlice);
886void AODProducerWorkflowDPL::updateMCHeader(MCCollisionCursor& collisionCursor,
887 XSectionCursor& xSectionCursor,
888 PdfInfoCursor& pdfInfoCursor,
889 HeavyIonCursor& heavyIonCursor,
890 const MCEventHeader& header,
902 auto genID = updateMCCollisions(collisionCursor,
909 mXSectionUpdate = (updateHepMCXSection(xSectionCursor,
914 ? HepMCUpdate::always
915 : HepMCUpdate::never);
916 mPdfInfoUpdate = (updateHepMCPdfInfo(pdfInfoCursor,
921 ? HepMCUpdate::always
922 : HepMCUpdate::never);
923 mHeavyIonUpdate = (updateHepMCHeavyIon(heavyIonCursor,
928 ? HepMCUpdate::always
929 : HepMCUpdate::never);
932void dimensionMCKeepStore(std::vector<std::vector<std::unordered_map<int, int>>>& store,
int Nsources,
int NEvents)
934 store.resize(Nsources);
935 for (
int s = 0;
s < Nsources; ++
s) {
936 store[
s].resize(NEvents);
942 for (
auto s = 0U;
s < store.size(); ++
s) {
943 for (
auto e = 0U; e < store[
s].size(); ++e) {
953 LOG(warn) <<
"trackID is smaller than 0. Neglecting";
960 MCParticlesCursor& mcParticlesCursor,
961 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
962 const gsl::span<const GIndex>& GIndices,
964 const std::vector<std::vector<int>>& mcColToEvSrc)
968 for (
auto& p : mcColToEvSrc) {
969 NSources = std::max(p[1], NSources);
970 NEvents = std::max(p[2], NEvents);
974 LOG(info) <<
" number of events " << NEvents;
975 LOG(info) <<
" number of sources " << NSources;
978 std::vector<int> particleIDsToKeep;
980 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
981 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
982 if (!mcLabel.isValid()) {
985 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
989 for (
auto& trackRef : primVer2TRefs) {
993 for (
int ti =
start; ti <
end; ti++) {
994 auto& trackIndex = GIndices[ti];
995 if (GIndex::includesSource(
src, mInputSources)) {
996 auto mcTruth =
data.getTrackMCLabel(trackIndex);
997 if (!mcTruth.isValid()) {
1000 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1002 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1011 for (
auto& mcLabel : labelsTOF) {
1012 if (!mcLabel.isValid()) {
1015 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
1024 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1025 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1026 if (!mcTruth.isValid()) {
1029 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1033 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1034 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1035 if (!mcTruth.isValid()) {
1038 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1041 using namespace aodmchelpers;
1045 for (
auto& colInfo : mcColToEvSrc) {
1046 int event = colInfo[2];
1048 int mcColId = colInfo[0];
1050 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1068template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1069void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1070 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1071 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1073 const gsl::span<const GIndex>& primVerGIs,
1086 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1087 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1088 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1089 for (
int ti =
start; ti <
end; ti++) {
1090 const auto trackIndex = primVerGIs[ti];
1093 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1094 auto entry = mp.find(trackIndex);
1095 if (
entry == mp.end() ||
entry->second == -1) {
1102 if (GIndex::includesSource(
src, mInputSources)) {
1103 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1104 MCLabels labelHolder{};
1109 if (mcTruth.isValid()) {
1110 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1112 if (mcTruth.isFake()) {
1113 labelHolder.fwdLabelMask |= (0x1 << 7);
1115 if (mcTruth.isNoise()) {
1116 labelHolder.fwdLabelMask |= (0x1 << 6);
1119 mcMFTTrackLabelCursor(labelHolder.labelID,
1120 labelHolder.fwdLabelMask);
1122 mcFwdTrackLabelCursor(labelHolder.labelID,
1123 labelHolder.fwdLabelMask);
1126 if (!needToStore(mGIDToTableID)) {
1129 if (mcTruth.isValid()) {
1130 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1131 if (mcTruth.isFake()) {
1132 labelHolder.labelMask |= (0x1 << 15);
1135 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1138 labelHolder.labelMask |= (0x1 << 13);
1142 }
else if (mcTruth.isNoise()) {
1143 labelHolder.labelMask |= (0x1 << 14);
1145 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1152 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1154 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1155 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1156 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1157 auto& collStrTrk = mCollisionStrTrk[iS];
1158 auto&
label = sTrackLabels[collStrTrk.second];
1159 MCLabels labelHolder;
1160 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1161 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1162 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1167template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1168void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1175 v0Cursor.reserve(v0s.size());
1177 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1178 const auto&
v0 = v0s[iv0];
1179 auto trPosID =
v0.getProngID(0);
1180 auto trNegID =
v0.getProngID(1);
1181 uint8_t v0flags =
v0.getBits();
1182 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1183 auto item = mGIDToTableID.find(trPosID);
1184 if (item != mGIDToTableID.end()) {
1185 posTableIdx = item->second;
1187 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1189 item = mGIDToTableID.find(trNegID);
1190 if (item != mGIDToTableID.end()) {
1191 negTableIdx = item->second;
1193 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1195 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1196 if (itemV == mVtxToTableCollID.end()) {
1197 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1199 collID = itemV->second;
1201 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1202 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1203 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1208 cascadeCursor.reserve(cascades.size());
1209 for (
auto& cascade : cascades) {
1210 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1211 if (itemV0 == mV0ToTableID.end()) {
1214 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1215 auto bachelorID = cascade.getBachelorID();
1216 auto item = mGIDToTableID.find(bachelorID);
1217 if (item != mGIDToTableID.end()) {
1218 bachTableIdx = item->second;
1220 LOG(warn) <<
"Could not find a bachelor track index";
1223 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1224 if (itemV != mVtxToTableCollID.end()) {
1225 collID = itemV->second;
1227 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1230 cascadeCursor(collID, v0tableID, bachTableIdx);
1234 decay3BodyCursor.reserve(decays3Body.size());
1235 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1236 const auto& decay3Body = decays3Body[i3Body];
1238 decay3Body.getProngID(0),
1239 decay3Body.getProngID(1),
1240 decay3Body.getProngID(2)};
1241 int tableIdx[3]{-1, -1, -1}, collID = -1;
1242 bool missing{
false};
1243 for (
int i{0};
i < 3; ++
i) {
1244 auto item = mGIDToTableID.find(trIDs[
i]);
1245 if (item != mGIDToTableID.end()) {
1246 tableIdx[
i] = item->second;
1248 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1252 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1253 if (itemV == mVtxToTableCollID.end()) {
1254 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1257 collID = itemV->second;
1262 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1266template <
typename FwdTrkClsCursorType>
1273 int mchTrackID = -1;
1275 mchTrackID = trackID.getIndex();
1277 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1278 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1281 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1282 const auto& mchTrack = mchTracks[mchTrackID];
1283 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1284 int first = mchTrack.getFirstClusterIdx();
1285 int last = mchTrack.getLastClusterIdx();
1286 for (
int i =
first;
i <= last;
i++) {
1287 const auto& cluster = mchClusters[
i];
1288 fwdTrkClsCursor(fwdTrackId,
1289 truncateFloatFraction(cluster.x, mMuonCl),
1290 truncateFloatFraction(cluster.y, mMuonCl),
1291 truncateFloatFraction(cluster.z, mMuonCl),
1292 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1297template <
typename HMPCursorType>
1302 hmpCursor.reserve(hmpMatches.size());
1305 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1307 const auto&
match = hmpMatches[iHmp];
1309 float xTrk, yTrk, theta,
phi;
1313 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1316 auto photChargeVec =
match.getPhotCharge();
1318 float photChargeVec2[10];
1320 for (Int_t
i = 0;
i < 10;
i++) {
1321 photChargeVec2[
i] = photChargeVec[
i];
1323 auto tref = mGIDToTableID.find(
match.getTrackRef());
1324 if (tref != mGIDToTableID.end()) {
1325 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1327 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1339 mCollisionStrTrk.clear();
1341 mVertexStrLUT.clear();
1343 for (
auto& sTrk : recoData.getStrangeTracks()) {
1347 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1349 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1351 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1353 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1354 mVertexStrLUT[vtxId]++;
1356 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1359 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1360 mStrTrkIndices.clear();
1361 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1364template <
typename V0C,
typename CC,
typename D3BC>
1367 int itsTableIdx = -1;
1373 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1383 v0Curs.reserve(nV0);
1384 cascCurs.reserve(nCasc);
1385 d3BodyCurs.reserve(nD3Body);
1387 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1389 auto item = mGIDToTableID.find(ITSIndex);
1390 if (item != mGIDToTableID.end()) {
1391 itsTableIdx = item->second;
1393 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1397 v0Curs(mStrTrkIndices[sTrkID++],
1407 sTrk.getAverageClusterSize());
1409 cascCurs(mStrTrkIndices[sTrkID++],
1419 sTrk.getAverageClusterSize());
1421 d3BodyCurs(mStrTrkIndices[sTrkID++],
1431 sTrk.getAverageClusterSize());
1438 const auto& tpcTracks =
data.getTPCTracks();
1439 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1440 const auto& tpcClusShMap =
data.clusterShMapTPC;
1441 const auto& tpcClusAcc =
data.getTPCClusters();
1442 constexpr int maxRows = 152;
1443 constexpr int neighbour = 2;
1444 int ntr = tpcTracks.size();
1445 mTPCCounters.clear();
1446 mTPCCounters.resize(ntr);
1448 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1449#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1451 for (
int itr = 0; itr < ntr; itr++) {
1452 std::array<bool, maxRows> clMap{}, shMap{};
1453 uint8_t sectorIndex, rowIndex;
1454 uint32_t clusterIndex;
1455 auto&
counters = mTPCCounters[itr];
1456 const auto& track = tpcTracks[itr];
1457 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1458 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1459 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1460 clMap[rowIndex] =
true;
1462 if (!shMap[rowIndex]) {
1465 shMap[rowIndex] =
true;
1469 for (
int i = 0;
i < maxRows;
i++) {
1474 }
else if ((
i - last) <= neighbour) {
1477 int lim = std::min(
i + 1 + neighbour, maxRows);
1478 for (
int j =
i + 1;
j < lim;
j++) {
1493 if (track.getTrackletIndex(il) != -1) {
1497 if (track.getHasNeighbor()) {
1500 if (track.getHasPadrowCrossing()) {
1506template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1507void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1508 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1510 auto inputEvent = caloHandler.buildEvent(eventID);
1511 auto cellsInEvent = inputEvent.mCells;
1512 auto cellMClabels = inputEvent.mMCCellLabels;
1513 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1514 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1516 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1518 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1519 caloCellCursor(bcID,
1523 cellsInEvent[iCell].
getType(),
1537 std::vector<int32_t> particleIds;
1538 std::vector<float> amplitudeFraction;
1539 if (!mEMCselectLeading) {
1540 particleIds.reserve(cellMClabels.size());
1541 amplitudeFraction.reserve(cellMClabels.size());
1543 float tmpMaxAmplitude = 0;
1544 int32_t tmpindex = 0;
1545 for (
auto& mclabel : cellMClabels[iCell]) {
1547 if (mclabel.isValid()) {
1548 if (mEMCselectLeading) {
1549 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1551 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1552 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1553 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1554 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1558 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1559 auto iter = trackStore.find(mclabel.getTrackID());
1560 if (iter != trackStore.end()) {
1561 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1562 particleIds.emplace_back(iter->second);
1564 particleIds.emplace_back(-1);
1565 amplitudeFraction.emplace_back(0.f);
1566 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1567 if (mMCKineReader) {
1568 auto mctrack = mMCKineReader->
getTrack(mclabel);
1571 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1577 if (mEMCselectLeading) {
1578 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1579 particleIds.emplace_back(tmpindex);
1581 if (particleIds.size() == 0) {
1582 particleIds.emplace_back(-1);
1583 amplitudeFraction.emplace_back(0.f);
1585 mcCaloCellLabelCursor(particleIds,
1592template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1593void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1594 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1598 auto caloEMCCells =
data.getEMCALCells();
1599 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1600 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1602 auto caloPHOSCells =
data.getPHOSCells();
1603 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1604 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1608 caloPHOSCellsTRGR = {};
1609 mcCaloPHOSCellLabels = {};
1614 caloEMCCellsTRGR = {};
1615 mcCaloEMCCellLabels = {};
1622 emcEventHandler.
reset();
1623 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1626 phsEventHandler.
reset();
1627 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1633 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1635 caloEvents.reserve(emcNEvents + phsNEvents);
1637 for (
int iev = 0; iev < emcNEvents; ++iev) {
1639 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1642 for (
int iev = 0; iev < phsNEvents; ++iev) {
1644 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1647 std::sort(caloEvents.begin(), caloEvents.end(),
1648 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1651 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1652 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1653 int8_t caloType = std::get<1>(caloEvents[
i]);
1654 int eventID = std::get<2>(caloEvents[
i]);
1655 auto item = bcsMap.find(globalBC);
1657 if (item != bcsMap.end()) {
1658 bcID = item->second;
1660 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1662 if (caloType == 0) {
1663 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1665 if (caloType == 1) {
1666 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1677 mLPMProdTag = ic.
options().
get<
string>(
"lpmp-prod-tag");
1678 mAnchorPass = ic.
options().
get<
string>(
"anchor-pass");
1679 mAnchorProd = ic.
options().
get<
string>(
"anchor-prod");
1680 mUser = ic.
options().
get<
string>(
"created-by");
1681 mRecoPass = ic.
options().
get<
string>(
"reco-pass");
1682 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1683 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1684 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1685 mRunNumber = ic.
options().
get<
int>(
"run-number");
1686 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1687 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1688 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1689 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1690 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1691 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1692 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1693 mStreamerFlags.
set(
s);
1694 if (mStreamerFlags) {
1695 LOGP(info,
"Writing streamer data with mask:");
1696 LOG(info) << mStreamerFlags;
1698 LOGP(warn,
"Specified non-default empty streamer mask!");
1701 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1702 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1703 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1704 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1705 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1706 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1707 LOGP(info,
"Using random device for seeding");
1708 std::random_device
rd;
1709 std::array<int, std::mt19937::state_size> seed_data{};
1710 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1711 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1712 mGenerator = std::mt19937(seq);
1714 LOGP(info,
"Using seed {} for sampling", seed);
1715 mGenerator.seed(seed);
1718 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1721 LOG(info) <<
"OpenMP is disabled";
1723 if (mTFNumber == -1L) {
1724 LOG(info) <<
"TFNumber will be obtained from CCDB";
1726 if (mRunNumber == -1L) {
1727 LOG(info) <<
"The Run number will be obtained from DPL headers";
1731 if (mTruncate != 1) {
1732 LOG(info) <<
"Truncation is not used!";
1733 mCollisionPosition = 0xFFFFFFFF;
1734 mCollisionPositionCov = 0xFFFFFFFF;
1735 mTrackX = 0xFFFFFFFF;
1736 mTrackAlpha = 0xFFFFFFFF;
1737 mTrackSnp = 0xFFFFFFFF;
1738 mTrackTgl = 0xFFFFFFFF;
1739 mTrack1Pt = 0xFFFFFFFF;
1740 mTrackChi2 = 0xFFFFFFFF;
1741 mTrackCovDiag = 0xFFFFFFFF;
1742 mTrackCovOffDiag = 0xFFFFFFFF;
1743 mTrackSignal = 0xFFFFFFFF;
1744 mTrackTime = 0xFFFFFFFF;
1745 mTPCTime0 = 0xFFFFFFFF;
1746 mTrackTimeError = 0xFFFFFFFF;
1747 mTrackPosEMCAL = 0xFFFFFFFF;
1748 mTracklets = 0xFFFFFFFF;
1749 mMcParticleW = 0xFFFFFFFF;
1750 mMcParticlePos = 0xFFFFFFFF;
1751 mMcParticleMom = 0xFFFFFFFF;
1752 mCaloAmp = 0xFFFFFFFF;
1753 mCaloTime = 0xFFFFFFFF;
1754 mCPVPos = 0xFFFFFFFF;
1755 mCPVAmpl = 0xFFFFFFFF;
1756 mMuonTr1P = 0xFFFFFFFF;
1757 mMuonTrThetaX = 0xFFFFFFFF;
1758 mMuonTrThetaY = 0xFFFFFFFF;
1759 mMuonTrZmu = 0xFFFFFFFF;
1760 mMuonTrBend = 0xFFFFFFFF;
1761 mMuonTrNonBend = 0xFFFFFFFF;
1762 mMuonTrCov = 0xFFFFFFFF;
1763 mMuonCl = 0xFFFFFFFF;
1764 mMuonClErr = 0xFFFFFFFF;
1765 mV0Time = 0xFFFFFFFF;
1766 mV0ChannelTime = 0xFFFFFFFF;
1767 mFDDTime = 0xFFFFFFFF;
1768 mFDDChannelTime = 0xFFFFFFFF;
1769 mT0Time = 0xFFFFFFFF;
1770 mT0ChannelTime = 0xFFFFFFFF;
1771 mV0Amplitude = 0xFFFFFFFF;
1772 mFDDAmplitude = 0xFFFFFFFF;
1773 mT0Amplitude = 0xFFFFFFFF;
1777 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1780 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1783 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1784 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1785 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1786 : HepMCUpdate::anyKey);
1787 mXSectionUpdate = when;
1788 mPdfInfoUpdate = when;
1789 mHeavyIonUpdate = when;
1793 if (mStreamerFlags) {
1794 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1800void add_additional_meta_info(std::vector<TString>& keys, std::vector<TString>&
values)
1803 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1804 if (aod_external_meta_info_file !=
nullptr) {
1805 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1806 if (std::filesystem::exists(aod_external_meta_info_file)) {
1807 std::ifstream input_file(aod_external_meta_info_file);
1809 nlohmann::json json_data;
1811 input_file >> json_data;
1812 }
catch (nlohmann::json::parse_error& e) {
1813 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1814 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1815 std::cerr <<
"Byte position: " << e.byte <<
"\n";
1819 for (
const auto& [
key,
value] : json_data.items()) {
1820 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
1821 keys.push_back(
key.c_str());
1832 mTimer.Start(
false);
1835 updateTimeDependentParams(pc);
1860 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
1861 if (mCTPReadout == 1) {
1862 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
1863 createCTPReadout(recoData, ctpDigitsCreated, pc);
1864 LOG(info) <<
"CTP : ctpreadout created from AOD";
1865 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
1867 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1868 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
1869 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
1870 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
1871 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
1872 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
1874 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1878 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
1879 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
1880 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
1881 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
1882 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
1883 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
1884 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
1885 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
1886 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
1887 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
1888 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
1889 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
1890 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
1891 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
1892 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
1893 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
1894 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
1895 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
1896 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
1897 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
1898 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
1899 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1900 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
1901 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
1902 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
1903 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
1904 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
1905 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
1906 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
1907 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
1908 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
1909 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
1910 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
1924 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
1925 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
1926 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
1927 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
1928 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
1929 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
1930 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
1931 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
1932 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
1933 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
1936 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
1938 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
1940 mMCKineReader = mcReader.get();
1941 std::map<uint64_t, int> bcsMap;
1942 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
1943 if (!primVer2TRefs.empty()) {
1944 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
1947 mBCLookup.
init(bcsMap);
1950 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
1951 if (mTFNumber == -1L) {
1953 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
1955 tfNumber = mTFNumber;
1958 std::vector<float> aAmplitudes, aTimes;
1959 std::vector<uint8_t> aChannels;
1960 fv0aCursor.reserve(fv0RecPoints.size());
1961 for (
auto& fv0RecPoint : fv0RecPoints) {
1962 aAmplitudes.clear();
1965 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
1966 for (
auto& channel : channelData) {
1967 if (channel.charge > 0) {
1968 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
1969 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
1970 aChannels.push_back(channel.channel);
1973 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
1974 auto item = bcsMap.find(
bc);
1976 if (item != bcsMap.end()) {
1977 bcID = item->second;
1979 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
1984 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
1985 fv0RecPoint.getTrigger().getTriggersignals());
1987 if (mEnableFITextra) {
1988 fv0aExtraCursor(bcID,
1993 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
1994 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
1995 zdcCursor.reserve(zdcBCRecData.size());
1996 for (
auto zdcRecData : zdcBCRecData) {
1997 uint64_t
bc = zdcRecData.ir.toLong();
1998 auto item = bcsMap.find(
bc);
2000 if (item != bcsMap.end()) {
2001 bcID = item->second;
2003 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2005 int fe, ne, ft, nt, fi, ni;
2006 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2008 zdcChannelsE.clear();
2009 zdcAmplitudes.clear();
2011 zdcChannelsT.clear();
2012 for (
int ie = 0; ie < ne; ie++) {
2013 auto& zdcEnergyData = zdcEnergies[fe + ie];
2014 zdcEnergy.emplace_back(zdcEnergyData.energy());
2015 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2017 for (
int it = 0; it < nt; it++) {
2018 auto& tdc = zdcTDCData[ft + it];
2019 zdcAmplitudes.emplace_back(tdc.amplitude());
2020 zdcTime.emplace_back(tdc.value());
2034 std::vector<std::vector<int>> mcColToEvSrc;
2040 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2041 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2042 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2045 int totalNParts = 0;
2046 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2047 totalNParts += mcParts[iCol].size();
2049 mcCollisionsCursor.
reserve(totalNParts);
2051 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2052 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2053 auto globalBC = mcRecords[iCol].toLong();
2054 auto item = bcsMap.find(globalBC);
2056 if (item != bcsMap.end()) {
2057 bcID = item->second;
2059 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2060 <<
"for MC collision; BC = " << globalBC
2061 <<
", mc collision = " << iCol;
2063 auto& colParts = mcParts[iCol];
2064 auto nParts = colParts.size();
2065 for (
auto colPart : colParts) {
2066 auto eventID = colPart.entryID;
2067 auto sourceID = colPart.sourceID;
2070 if (nParts == 1 || sourceID == 0) {
2073 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2074 updateMCHeader(mcCollisionsCursor.
cursor,
2075 hepmcXSectionsCursor.
cursor,
2076 hepmcPdfInfosCursor.
cursor,
2077 hepmcHeavyIonsCursor.
cursor,
2085 mcColToEvSrc.emplace_back(std::vector<int>{iCol, sourceID, eventID});
2090 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2091 [](
const std::vector<int>&
left,
const std::vector<int>&
right) { return (left[0] < right[0]); });
2094 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2095 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2097 fddCursor.reserve(fddRecPoints.size());
2098 for (
const auto& fddRecPoint : fddRecPoints) {
2099 for (
int i = 0;
i < 8;
i++) {
2100 aFDDAmplitudesA[
i] = 0;
2101 aFDDAmplitudesC[
i] = 0;
2102 aFDDTimesA[
i] = 0.f;
2103 aFDDTimesC[
i] = 0.f;
2105 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2106 uint64_t
bc = globalBC;
2107 auto item = bcsMap.find(
bc);
2109 if (item != bcsMap.end()) {
2110 bcID = item->second;
2112 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2114 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2115 for (
const auto& channel : channelData) {
2116 if (channel.mPMNumber < 8) {
2117 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2118 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2120 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2121 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2128 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2129 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2130 fddRecPoint.getTrigger().getTriggersignals());
2131 if (mEnableFITextra) {
2132 fddExtraCursor(bcID,
2139 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2140 std::vector<uint8_t> aChannelsA, aChannelsC;
2141 ft0Cursor.reserve(ft0RecPoints.size());
2142 for (
auto& ft0RecPoint : ft0RecPoints) {
2143 aAmplitudesA.clear();
2144 aAmplitudesC.clear();
2149 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2150 for (
auto& channel : channelData) {
2152 if (channel.QTCAmpl > 0) {
2154 if (channel.ChId < nFT0ChannelsAside) {
2155 aChannelsA.push_back(channel.ChId);
2156 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2157 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2159 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2160 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2161 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2165 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2166 uint64_t
bc = globalBC;
2167 auto item = bcsMap.find(
bc);
2169 if (item != bcsMap.end()) {
2170 bcID = item->second;
2172 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2179 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2180 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2181 ft0RecPoint.getTrigger().getTriggersignals());
2182 if (mEnableFITextra) {
2183 ft0ExtraCursor(bcID,
2191 mcColLabelsCursor.
reserve(primVerLabels.size());
2192 for (
auto&
label : primVerLabels) {
2193 auto it = std::find_if(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2194 [&
label](
const auto& mcColInfo) { return mcColInfo[1] == label.getSourceID() && mcColInfo[2] == label.getEventID(); });
2195 int32_t mcCollisionID = -1;
2196 if (it != mcColToEvSrc.end()) {
2197 mcCollisionID = it->at(0);
2199 uint16_t mcMask = 0;
2200 mcColLabelsCursor(mcCollisionID, mcMask);
2204 cacheTriggers(recoData);
2205 countTPCClusters(recoData);
2207 int collisionID = 0;
2211 auto& trackReffwd = primVer2TRefs.back();
2212 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2214 for (
auto&
vertex : primVertices) {
2215 auto& trackReffwd = primVer2TRefs[collisionID];
2216 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2221 prepareStrangenessTracking(recoData);
2223 mGIDToTableFwdID.clear();
2224 mGIDToTableMFTID.clear();
2226 if (mPropTracks || mThinTracks) {
2230 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2231 for (
const auto&
v0 : v0s) {
2232 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2233 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2235 for (
const auto& cascade : cascades) {
2236 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2238 for (
const auto& id3Body : decays3Body) {
2239 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2240 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2241 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2252 auto& trackRef = primVer2TRefs.back();
2254 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2255 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2256 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2260 collisionsCursor.reserve(primVertices.size());
2261 for (
auto&
vertex : primVertices) {
2262 auto& cov =
vertex.getCov();
2263 auto& timeStamp =
vertex.getTimeStamp();
2264 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2265 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2266 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2267 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2270 auto item = bcsMap.find(globalBC);
2272 if (item != bcsMap.end()) {
2273 bcID = item->second;
2275 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2277 collisionsCursor(bcID,
2278 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2279 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2280 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2281 truncateFloatFraction(cov[0], mCollisionPositionCov),
2282 truncateFloatFraction(cov[1], mCollisionPositionCov),
2283 truncateFloatFraction(cov[2], mCollisionPositionCov),
2284 truncateFloatFraction(cov[3], mCollisionPositionCov),
2285 truncateFloatFraction(cov[4], mCollisionPositionCov),
2286 truncateFloatFraction(cov[5], mCollisionPositionCov),
2288 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2289 vertex.getNContributors(),
2290 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2291 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2292 mVtxToTableCollID[collisionID] = mTableCollID++;
2294 auto& trackRef = primVer2TRefs[collisionID];
2296 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2297 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2298 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2302 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2303 fillHMPID(recoData, hmpCursor);
2304 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2308 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2310 LOG(
debug) <<
"CTP input available";
2311 for (
auto& ctpDigit : ctpDigits) {
2312 uint64_t
bc = ctpDigit.intRecord.toLong();
2313 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2314 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2315 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2317 auto classMaskOrig = classMask;
2318 classMask = classMask & ~mEMCALTrgClassMask;
2319 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2321 bcToClassMask[
bc] = {classMask, inputMask};
2327 bcCursor.reserve(bcsMap.size());
2328 for (
auto& item : bcsMap) {
2329 uint64_t
bc = item.first;
2330 std::pair<uint64_t, uint64_t> masks{0, 0};
2332 auto bcClassPair = bcToClassMask.find(
bc);
2333 if (bcClassPair != bcToClassMask.end()) {
2334 masks = bcClassPair->second;
2343 bcToClassMask.clear();
2346 auto bcFlags = fillBCFlags(recoData, bcsMap);
2347 bcFlagsCursor.reserve(bcFlags.size());
2348 for (
auto f : bcFlags) {
2355 cpvClustersCursor.reserve(cpvTrigRecs.size());
2356 for (
auto& cpvEvent : cpvTrigRecs) {
2357 uint64_t
bc = cpvEvent.getBCData().toLong();
2358 auto item = bcsMap.find(
bc);
2360 if (item != bcsMap.end()) {
2361 bcID = item->second;
2363 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2365 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2366 auto&
clu = cpvClusters[iClu];
2367 clu.getLocalPosition(posX, posZ);
2368 cpvClustersCursor(bcID,
2369 truncateFloatFraction(posX, mCPVPos),
2370 truncateFloatFraction(posZ, mCPVPos),
2371 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2372 clu.getPackedClusterStatus());
2381 fillMCParticlesTable(*mcReader,
2382 mcParticlesCursor.
cursor,
2388 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2389 mcColToEvSrc.clear();
2395 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2396 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2397 auto& trackRef = primVer2TRefs[iref];
2398 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2404 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2409 mGIDToTableID.clear();
2411 mGIDToTableFwdID.clear();
2413 mGIDToTableMFTID.clear();
2415 mVtxToTableCollID.clear();
2417 mV0ToTableID.clear();
2420 mIndexTableFwd.clear();
2422 mIndexTableMFT.clear();
2427 mGIDUsedBySVtx.clear();
2428 mGIDUsedByStr.clear();
2430 originCursor(tfNumber);
2433 TString dataType = mUseMC ?
"MC" :
"RAW";
2435 TString ROOTVersion = ROOT_RELEASE;
2436 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2437 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2438 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2456 for (
const auto& rof : rofs) {
2457 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2458 for (
int i =
first;
i < last;
i++) {
2459 mITSROFs.push_back(
count);
2469 for (
const auto& rof : rofs) {
2470 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2472 mMFTROFs.push_back(
count);
2479 mITSTPCTRDTriggers.clear();
2482 for (
const auto& trig : itstpctrigs) {
2483 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2485 mITSTPCTRDTriggers.push_back(
count);
2492 mTPCTRDTriggers.clear();
2495 for (
const auto& trig : tpctrigs) {
2496 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2498 mTPCTRDTriggers.push_back(
count);
2508 for (
const auto& rof : rofs) {
2511 mMCHROFs.push_back(
count);
2518AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2521 TrackExtraInfo extraInfoHolder;
2522 if (collisionID < 0) {
2525 bool needBCSlice = collisionID < 0;
2526 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2528 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2534 extraInfoHolder.trackTimeRes = terr;
2536 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2537 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2540 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2542 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2545 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2546 const auto& trackPar =
data.getTrackParam(trackIndex);
2547 extraInfoHolder.flags |= trackPar.getPID() << 28;
2548 auto src = trackIndex.getSource();
2550 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2551 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2552 const auto& tofInt = tofMatch.getLTIntegralOut();
2553 float intLen = tofInt.getL();
2554 extraInfoHolder.length = intLen;
2561 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2564 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2565 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2566 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2567 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2568 setTrackTime(tofSignal, 0.2,
true);
2572 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2573 extraInfoHolder.trdSignal = trdOrig.getSignal();
2574 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2575 if (extraInfoHolder.trackTimeRes < 0.) {
2577 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2579 setTrackTime(ttrig, 1.,
true);
2583 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2584 int nClusters = itsTrack.getNClusters();
2585 float chi2 = itsTrack.getChi2();
2587 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2589 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2591 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2594 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2598 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2599 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2600 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2603 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2604 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2605 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2606 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2607 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2608 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2609 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2610 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2611 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2614 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2615 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2616 double err = mTimeMarginTrackTime + terr;
2617 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2622 extraInfoHolder.trackTimeRes = p.
getTimeErr();
2624 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2625 extraInfoHolder.isTPConly =
true;
2628 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2629 auto ts = trITSTPC.getTimeMUS();
2630 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2634 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2639 return extraInfoHolder;
2642AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2646 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2647 const auto& trackPar =
data.getTrackParam(trackIndex);
2648 if (contributorsGID.isIndexSet()) {
2650 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2655 std::array<float, 2> dcaInfo{-999., -999.};
2656 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2657 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2658 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2662 auto safeInt8Clamp = [](
auto value) -> int8_t {
2663 using ValType =
decltype(
value);
2664 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()))));
2666 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2667 using ValType =
decltype(
value);
2668 return static_cast<uint8_t>(TMath::Nint(std::clamp(
value,
static_cast<ValType
>(std::numeric_limits<uint8_t>::min()),
static_cast<ValType
>(std::numeric_limits<uint8_t>::max()))));
2672 uint8_t clusterCounters[8] = {0};
2674 uint8_t sectorIndex, rowIndex;
2675 uint32_t clusterIndex;
2676 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2677 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2678 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2679 char indexTracklet = (rowIndex % 152) / 19;
2680 clusterCounters[indexTracklet]++;
2684 for (
int i = 0;
i < 8;
i++) {
2685 if (clusterCounters[
i] > 5) {
2686 byteMask |= (1 <<
i);
2689 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2690 trackQAHolder.tpcClusterByteMask = byteMask;
2691 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2692 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2693 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2694 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2695 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2696 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2697 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2699 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2700 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2701 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2702 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2705 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2707 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2708 const float qpt = trackPar.getQ2Pt();
2710 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2711 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2717 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2718 const auto& itsOrig =
data.getITSTrack(itsContGID);
2727 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2728 const float qpt = gloCopy.getQ2Pt();
2729 const float x = qpt / beta0;
2731 auto scaleCont = [&
x](
int i) ->
float {
2734 auto scaleGlo = [&
x](
int i) ->
float {
2739 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2740 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2741 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2742 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2743 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2745 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2746 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2747 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2748 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2749 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2753 (*mStreamer) <<
"trackQA"
2754 <<
"trackITSOrig=" << itsOrig
2755 <<
"trackTPCOrig=" << tpcOrig
2756 <<
"trackITSTPCOrig=" << trackPar
2757 <<
"trackITSProp=" << itsCopy
2758 <<
"trackTPCProp=" << tpcCopy
2759 <<
"trackITSTPCProp=" << gloCopy
2762 <<
"scaleCont0=" << scaleCont(0)
2763 <<
"scaleCont1=" << scaleCont(1)
2764 <<
"scaleCont2=" << scaleCont(2)
2765 <<
"scaleCont3=" << scaleCont(3)
2766 <<
"scaleCont4=" << scaleCont(4)
2767 <<
"scaleGlo0=" << scaleGlo(0)
2768 <<
"scaleGlo1=" << scaleGlo(1)
2769 <<
"scaleGlo2=" << scaleGlo(2)
2770 <<
"scaleGlo3=" << scaleGlo(3)
2771 <<
"scaleGlo4=" << scaleGlo(4)
2772 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
2773 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
2774 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
2775 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
2776 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
2777 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
2778 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
2779 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
2780 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
2781 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
2782 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
2783 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
2784 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
2785 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
2786 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
2787 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
2788 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
2789 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
2790 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
2791 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
2792 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
2793 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
2794 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
2795 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
2796 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
2797 <<
"scaleTOF=" << scaleTOF
2804 return trackQAHolder;
2812 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
2817void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
2819 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
2820 constexpr float ETAEMCAL = 0.75;
2821 constexpr float ZEMCALFastCheck = 460.;
2822 constexpr float ETADCALINNER = 0.22;
2823 constexpr float ETAPHOS = 0.13653194;
2824 constexpr float ETAPHOSMARGIN = 0.17946979;
2825 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
2826 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
2827 constexpr short SECTORTYPE[18] = {
2828 SNONE, SNONE, SNONE, SNONE,
2829 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
2832 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
2843 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
2844 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2845 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
2849 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
2850 (!outTr.rotateParam(outTr.getPhi()) ||
2852 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
2853 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
2859 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
2862 auto outTrTmp = outTr;
2864 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
2865 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2866 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
2871 if (sectorTmp == sector) {
2879 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
2886 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
2891 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
2892 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
2893 if (etaAbs > ETAEMCAL) {
2894 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
2898 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
2899 if (!propExactSector(XPHOS)) {
2902 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
2903 tg = std::atan2(
r, outTr.getZ());
2904 eta = -std::log(std::tan(0.5f * tg));
2905 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
2908 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
2909 extraInfoHolder.trackEtaEMCAL = eta;
2910 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
2914std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
2916 std::set<uint64_t> emcalIncompletes;
2917 for (
const auto& trg : triggers) {
2918 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
2920 emcalIncompletes.insert(trg.getBCData().toLong());
2923 return emcalIncompletes;
2929 static bool initOnceDone =
false;
2930 if (!initOnceDone) {
2931 initOnceDone =
true;
2938 for (
auto i = 0U;
i < bs.size();
i++) {
2953 mTPCBinNS = elParam.ZbinWidth * 1.e3;
2956 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
2957 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
2978 LOG(info) <<
"ITS Alpide param updated";
2980 par.printKeyValues();
2984 LOG(info) <<
"MFT Alpide param updated";
2986 par.printKeyValues();
2997 mEMCALTrgClassMask = 0;
2998 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3000 mEMCALTrgClassMask |= trgclass.classMask;
3003 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3007void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3018 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3019 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3020 assert(nbitsFrac > 1);
3021 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3023 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3024 << TOFTimePrecPS <<
" ps";
3027 if (!trackRef.getEntries()) {
3031 std::uint64_t maxBC = mStartIR.
toLong();
3032 const auto& tofClus =
data.getTOFClusters();
3039 for (
int ti =
start; ti <
end; ti++) {
3040 auto& trackIndex = GIndices[ti];
3041 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3042 const auto& tofInt = tofMatch.getLTIntegralOut();
3043 float intLen = tofInt.getL();
3044 float tofExpMom = 0.;
3054 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3055 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3056 double exp = intLen * energy / (cSpeed * tofExpMom);
3057 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3058 auto bc = relativeTime_to_GlobalBC(tofSignal);
3060 auto it = bcsMap.lower_bound(
bc);
3061 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3062 bcsMap.emplace_hint(it,
bc, 1);
3071 if ((--bcsMap.end())->first <= maxBC) {
3072 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3076 for (
auto& item : bcsMap) {
3082std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3094 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3117 auto upperindex = p.first;
3118 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3121 if (upperindex != p.first) {
3125 slice[1] = upperindex;
3127 auto bcOfTimeRef = p.second - this->mStartIR.
toLong();
3128 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3129 <<
" t: " << tmax <<
" " << slice[1]
3130 <<
" bcref: " << bcOfTimeRef;
3136 std::vector<uint8_t>
flags(bcsMap.size());
3139 auto bcIt = bcsMap.begin();
3140 auto itsrofs =
data.getITSTracksROFRecords();
3143 for (
auto& rof : itsrofs) {
3144 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3147 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3149 while (bcIt != bcsMap.end()) {
3150 if (bcIt->first < globalBC0) {
3154 if (bcIt->first > globalBC1) {
3166 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3167 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3174 auto dataRequest = std::make_shared<DataRequest>();
3175 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3177 dataRequest->requestTracks(
src, useMC);
3178 dataRequest->requestPrimaryVertices(useMC);
3180 dataRequest->requestCTPDigits(useMC);
3183 dataRequest->requestSecondaryVertices(useMC);
3185 if (enableStrangenessTracking) {
3186 dataRequest->requestStrangeTracks(useMC);
3187 LOGF(info,
"requestStrangeTracks Finish");
3196 dataRequest->requestTOFClusters(useMC);
3199 dataRequest->requestPHOSCells(useMC);
3202 dataRequest->requestTRDTracklets(
false);
3205 dataRequest->requestEMCALCells(useMC);
3208 dataRequest->requestCPVClusters(useMC);
3211 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3217 dataRequest->inputs,
3220 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3225 std::vector<OutputSpec> outputs{
3265 outputs.insert(outputs.end(),
3266 {OutputForTable<McCollisions>::spec(),
3267 OutputForTable<HepMCXSections>::spec(),
3268 OutputForTable<HepMCPdfInfos>::spec(),
3269 OutputForTable<HepMCHeavyIons>::spec(),
3270 OutputForTable<McMFTTrackLabels>::spec(),
3271 OutputForTable<McFwdTrackLabels>::spec(),
3272 OutputForTable<StoredMcParticles_001>::spec(),
3273 OutputForTable<McTrackLabels>::spec(),
3274 OutputForTable<McCaloLabels_001>::spec(),
3279 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3283 "aod-producer-workflow",
3286 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3288 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3289 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3290 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3291 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3292 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3293 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3294 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3295 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3296 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3297 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3298 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3299 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3300 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3301 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3302 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)"}},
3303 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3304 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3305 ConfigParamSpec{
"trackqc-fraction", VariantType::Float,
float(0.1), {
"Fraction of tracks to QC"}},
3306 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3307 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3308 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3309 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3310 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3311 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
GLenum GLsizei GLsizei GLint * values
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