87#include "Math/SMatrix.h"
93#include <unordered_map>
98#include "TLorentzVector.h"
125 uint64_t classMaskEMCAL = 0, classMaskTRD = 0, classMaskPHOSCPV = 0;
126 for (
const auto& trgclass : ctpcfg->getCTPClasses()) {
127 if (trgclass.cluster->getClusterDetNames().find(
"EMC") != std::string::npos) {
128 classMaskEMCAL = trgclass.classMask;
130 if (trgclass.cluster->getClusterDetNames().find(
"PHS") != std::string::npos) {
131 classMaskPHOSCPV = trgclass.classMask;
133 if (trgclass.cluster->getClusterDetNames().find(
"TRD") != std::string::npos) {
134 classMaskTRD = trgclass.classMask;
137 LOG(info) <<
"createCTPReadout: Class Mask EMCAL -> " << classMaskEMCAL;
138 LOG(info) <<
"createCTPReadout: Class Mask PHOS/CPV -> " << classMaskPHOSCPV;
139 LOG(info) <<
"createCTPReadout: Class Mask TRD -> " << classMaskTRD;
147 std::vector<o2::emcal::TriggerRecord> triggerRecordEMCALPhys;
148 for (
const auto& trg : triggerrecordEMCAL) {
152 triggerRecordEMCALPhys.push_back(trg);
158 std::set<uint64_t> bcsMapT0triggers;
160 for (
auto& ft0RecPoint : ft0RecPoints) {
161 auto t0triggers = ft0RecPoint.getTrigger();
162 if (t0triggers.getVertex()) {
163 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
164 bcsMapT0triggers.insert(globalBC);
168 auto genericCTPDigitizer = [&bcsMapT0triggers, &ctpDigits](
auto triggerrecords, uint64_t classmask) ->
int {
172 uint32_t orbitPrev = 0;
174 for (
auto& trigger : triggerrecords) {
175 auto orbitPrevT = orbitPrev;
176 auto bcPrevT = bcPrev;
177 bcPrev = trigger.getBCData().bc;
178 orbitPrev = trigger.getBCData().orbit;
184 uint64_t globalBC = trigger.getBCData().toLong();
185 auto t0entry = bcsMapT0triggers.find(globalBC);
186 if (t0entry != bcsMapT0triggers.end()) {
187 auto ctpdig = std::find_if(ctpDigits.begin(), ctpDigits.end(), [globalBC](
const o2::ctp::CTPDigit& dig) { return static_cast<uint64_t>(dig.intRecord.toLong()) == globalBC; });
188 if (ctpdig != ctpDigits.end()) {
190 ctpdig->CTPClassMask |= std::bitset<64>(classmask);
191 LOG(
debug) <<
"createCTPReadout: Merging " << classmask <<
" CTP digits with existing digit, CTP mask " << ctpdig->CTPClassMask;
194 LOG(
debug) <<
"createCTPReadout: New CTP digit needed for class " << classmask << std::endl;
195 auto& ctpdigNew = ctpDigits.emplace_back();
196 ctpdigNew.intRecord.setFromLong(globalBC);
197 ctpdigNew.CTPClassMask = classmask;
200 LOG(warning) <<
"createCTPReadout: Found " << classmask <<
" and no MTVX:" << globalBC;
207 auto warningsTRD = genericCTPDigitizer(triggerrecordTRD, classMaskTRD);
208 auto warningsEMCAL = genericCTPDigitizer(triggerRecordEMCALPhys, classMaskEMCAL);
209 auto warningsPHOSCPV = genericCTPDigitizer(triggerrecordPHOSCPV, classMaskPHOSCPV);
211 LOG(info) <<
"createCTPReadout:# of TRD bogus triggers:" << warningsTRD;
212 LOG(info) <<
"createCTPReadout:# of EMCAL bogus triggers:" << warningsEMCAL;
213 LOG(info) <<
"createCTPReadout:# of PHOS/CPV bogus triggers:" << warningsPHOSCPV;
217 const std::vector<o2::InteractionTimeRecord>& mcRecords,
218 std::map<uint64_t, int>& bcsMap)
220 const auto& primVertices =
data.getPrimaryVertices();
221 const auto& fddRecPoints =
data.getFDDRecPoints();
222 const auto& ft0RecPoints =
data.getFT0RecPoints();
223 const auto& fv0RecPoints =
data.getFV0RecPoints();
224 const auto& caloEMCCellsTRGR =
data.getEMCALTriggers();
225 const auto& caloPHOSCellsTRGR =
data.getPHOSTriggers();
226 const auto& cpvTRGR =
data.getCPVTriggers();
227 const auto& ctpDigits =
data.getCTPDigits();
228 const auto& zdcBCRecData =
data.getZDCBCRecData();
230 bcsMap[mStartIR.
toLong()] = 1;
233 for (
auto&
rec : mcRecords) {
234 uint64_t globalBC =
rec.toLong();
235 bcsMap[globalBC] = 1;
238 for (
auto& fddRecPoint : fddRecPoints) {
239 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
240 bcsMap[globalBC] = 1;
243 for (
auto& ft0RecPoint : ft0RecPoints) {
244 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
245 bcsMap[globalBC] = 1;
248 for (
auto& fv0RecPoint : fv0RecPoints) {
249 uint64_t globalBC = fv0RecPoint.getInteractionRecord().toLong();
250 bcsMap[globalBC] = 1;
253 for (
auto& zdcRecData : zdcBCRecData) {
254 uint64_t globalBC = zdcRecData.ir.toLong();
255 bcsMap[globalBC] = 1;
258 for (
auto&
vertex : primVertices) {
259 auto& timeStamp =
vertex.getTimeStamp();
260 double tsTimeStamp = timeStamp.getTimeStamp() * 1E3;
261 uint64_t globalBC = relativeTime_to_GlobalBC(tsTimeStamp);
262 bcsMap[globalBC] = 1;
265 for (
auto& emcaltrg : caloEMCCellsTRGR) {
266 uint64_t globalBC = emcaltrg.getBCData().toLong();
267 bcsMap[globalBC] = 1;
270 for (
auto& phostrg : caloPHOSCellsTRGR) {
271 uint64_t globalBC = phostrg.getBCData().toLong();
272 bcsMap[globalBC] = 1;
275 for (
auto& cpvtrg : cpvTRGR) {
276 uint64_t globalBC = cpvtrg.getBCData().toLong();
277 bcsMap[globalBC] = 1;
280 for (
auto& ctpDigit : ctpDigits) {
281 uint64_t globalBC = ctpDigit.intRecord.toLong();
282 bcsMap[globalBC] = 1;
286 for (
auto& item : bcsMap) {
292template <
typename TracksCursorType,
typename TracksCovCursorType>
293void AODProducerWorkflowDPL::addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor,
296 tracksCursor(collisionID,
298 truncateFloatFraction(track.getX(), mTrackX),
299 truncateFloatFraction(track.getAlpha(), mTrackAlpha),
302 truncateFloatFraction(track.getSnp(), mTrackSnp),
303 truncateFloatFraction(track.getTgl(), mTrackTgl),
304 truncateFloatFraction(track.getQ2Pt(), mTrack1Pt));
306 float sY = TMath::Sqrt(track.getSigmaY2()), sZ = TMath::Sqrt(track.getSigmaZ2()), sSnp = TMath::Sqrt(track.getSigmaSnp2()),
307 sTgl = TMath::Sqrt(track.getSigmaTgl2()), sQ2Pt = TMath::Sqrt(track.getSigma1Pt2());
308 tracksCovCursor(truncateFloatFraction(sY, mTrackCovDiag),
309 truncateFloatFraction(sZ, mTrackCovDiag),
310 truncateFloatFraction(sSnp, mTrackCovDiag),
311 truncateFloatFraction(sTgl, mTrackCovDiag),
312 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
313 (Char_t)(128. * track.getSigmaZY() / (sZ * sY)),
314 (Char_t)(128. * track.getSigmaSnpY() / (sSnp * sY)),
315 (Char_t)(128. * track.getSigmaSnpZ() / (sSnp * sZ)),
316 (Char_t)(128. * track.getSigmaTglY() / (sTgl * sY)),
317 (Char_t)(128. * track.getSigmaTglZ() / (sTgl * sZ)),
318 (Char_t)(128. * track.getSigmaTglSnp() / (sTgl * sSnp)),
319 (Char_t)(128. * track.getSigma1PtY() / (sQ2Pt * sY)),
320 (Char_t)(128. * track.getSigma1PtZ() / (sQ2Pt * sZ)),
321 (Char_t)(128. * track.getSigma1PtSnp() / (sQ2Pt * sSnp)),
322 (Char_t)(128. * track.getSigma1PtTgl() / (sQ2Pt * sTgl)));
325template <
typename TracksExtraCursorType>
326void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder)
330 auto trackTimeRes = extraInfoHolder.trackTimeRes;
331 if (!extraInfoHolder.isTPConly) {
332 trackTimeRes = truncateFloatFraction(trackTimeRes, mTrackTimeError);
336 tracksExtraCursor(truncateFloatFraction(extraInfoHolder.tpcInnerParam, mTrack1Pt),
337 extraInfoHolder.flags,
338 extraInfoHolder.itsClusterSizes,
339 extraInfoHolder.tpcNClsFindable,
340 extraInfoHolder.tpcNClsFindableMinusFound,
341 extraInfoHolder.tpcNClsFindableMinusPID,
342 extraInfoHolder.tpcNClsFindableMinusCrossedRows,
343 extraInfoHolder.tpcNClsShared,
344 extraInfoHolder.trdPattern,
345 truncateFloatFraction(extraInfoHolder.itsChi2NCl, mTrackChi2),
346 truncateFloatFraction(extraInfoHolder.tpcChi2NCl, mTrackChi2),
347 truncateFloatFraction(extraInfoHolder.trdChi2, mTrackChi2),
348 truncateFloatFraction(extraInfoHolder.tofChi2, mTrackChi2),
349 truncateFloatFraction(extraInfoHolder.tpcSignal, mTrackSignal),
350 truncateFloatFraction(extraInfoHolder.trdSignal, mTrackSignal),
351 truncateFloatFraction(extraInfoHolder.length, mTrackSignal),
352 truncateFloatFraction(extraInfoHolder.tofExpMom, mTrack1Pt),
353 truncateFloatFraction(extraInfoHolder.trackEtaEMCAL, mTrackPosEMCAL),
354 truncateFloatFraction(extraInfoHolder.trackPhiEMCAL, mTrackPosEMCAL),
355 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime),
359template <
typename TracksQACursorType>
360void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor,
TrackQA& trackQAInfoHolder)
363 trackQAInfoHolder.trackID,
364 truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
365 truncateFloatFraction(trackQAInfoHolder.tpcdEdxNorm, mTrackSignal),
366 trackQAInfoHolder.tpcdcaR,
367 trackQAInfoHolder.tpcdcaZ,
368 trackQAInfoHolder.tpcClusterByteMask,
369 trackQAInfoHolder.tpcdEdxMax0R,
370 trackQAInfoHolder.tpcdEdxMax1R,
371 trackQAInfoHolder.tpcdEdxMax2R,
372 trackQAInfoHolder.tpcdEdxMax3R,
373 trackQAInfoHolder.tpcdEdxTot0R,
374 trackQAInfoHolder.tpcdEdxTot1R,
375 trackQAInfoHolder.tpcdEdxTot2R,
376 trackQAInfoHolder.tpcdEdxTot3R,
377 trackQAInfoHolder.dRefContY,
378 trackQAInfoHolder.dRefContZ,
379 trackQAInfoHolder.dRefContSnp,
380 trackQAInfoHolder.dRefContTgl,
381 trackQAInfoHolder.dRefContQ2Pt,
382 trackQAInfoHolder.dRefGloY,
383 trackQAInfoHolder.dRefGloZ,
384 trackQAInfoHolder.dRefGloSnp,
385 trackQAInfoHolder.dRefGloTgl,
386 trackQAInfoHolder.dRefGloQ2Pt,
387 trackQAInfoHolder.dTofdX,
388 trackQAInfoHolder.dTofdZ);
391template <
typename mftTracksCursorType,
typename AmbigMFTTracksCursorType>
392void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
394 std::uint64_t collisionBC,
const std::map<uint64_t, int>& bcsMap)
397 int bcSlice[2] = {-1, -1};
398 const auto& track =
data.getMFTTrack(trackID);
399 const auto& rof =
data.getMFTTracksROFRecords()[mMFTROFs[trackID.getIndex()]];
401 float trackTimeRes = mMFTROFrameHalfLengthNS;
402 bool needBCSlice = collisionID < 0;
403 std::uint64_t bcOfTimeRef;
405 double error = mTimeMarginTrackTime + trackTimeRes;
406 bcOfTimeRef = fillBCSlice(bcSlice, trackTime - error, trackTime + error, bcsMap);
408 bcOfTimeRef = collisionBC - mStartIR.
toLong();
413 uint64_t mftClusterSizesAndTrackFlags = track.getClusterSizes();
414 mftClusterSizesAndTrackFlags |= (track.isCA()) ? (1ULL << (60)) : 0;
416 mftTracksCursor(collisionID,
419 truncateFloatFraction(track.getZ(), mTrackX),
420 truncateFloatFraction(track.getPhi(), mTrackAlpha),
421 truncateFloatFraction(track.getTanl(), mTrackTgl),
422 truncateFloatFraction(track.getInvQPt(), mTrack1Pt),
423 mftClusterSizesAndTrackFlags,
424 truncateFloatFraction(track.getTrackChi2(), mTrackChi2),
425 truncateFloatFraction(trackTime, mTrackTime),
426 truncateFloatFraction(trackTimeRes, mTrackTimeError));
428 ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
432template <
typename TracksCursorType,
typename TracksCovCursorType,
typename TracksExtraCursorType,
typename TracksQACursorType,
typename AmbigTracksCursorType,
433 typename MFTTracksCursorType,
typename MFTTracksCovCursorType,
typename AmbigMFTTracksCursorType,
434 typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename FwdTrkClsCursorType>
435void AODProducerWorkflowDPL::fillTrackTablesPerCollision(
int collisionID,
436 std::uint64_t collisionBC,
438 const gsl::span<const GIndex>& GIndices,
440 TracksCursorType& tracksCursor,
441 TracksCovCursorType& tracksCovCursor,
442 TracksExtraCursorType& tracksExtraCursor,
443 TracksQACursorType& tracksQACursor,
444 AmbigTracksCursorType& ambigTracksCursor,
445 MFTTracksCursorType& mftTracksCursor,
446 MFTTracksCovCursorType& mftTracksCovCursor,
447 AmbigMFTTracksCursorType& ambigMFTTracksCursor,
448 FwdTracksCursorType& fwdTracksCursor,
449 FwdTracksCovCursorType& fwdTracksCovCursor,
450 AmbigFwdTracksCursorType& ambigFwdTracksCursor,
451 FwdTrkClsCursorType& fwdTrkClsCursor,
452 const std::map<uint64_t, int>& bcsMap)
455 if (!GIndex::isTrackSource(
src)) {
462 mftTracksCursor.reserve(nToReserve + mftTracksCursor.lastIndex());
464 fwdTracksCursor.reserve(nToReserve + fwdTracksCursor.lastIndex());
465 fwdTracksCovCursor.reserve(nToReserve + fwdTracksCovCursor.lastIndex());
467 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex());
470 tracksCursor.reserve(nToReserve + tracksCursor.lastIndex());
471 tracksCovCursor.reserve(nToReserve + tracksCovCursor.lastIndex());
472 tracksExtraCursor.reserve(nToReserve + tracksExtraCursor.lastIndex());
474 for (
int ti =
start; ti <
end; ti++) {
475 const auto& trackIndex = GIndices[ti];
476 if (GIndex::includesSource(
src, mInputSources)) {
478 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
481 addToMFTTracksTable(mftTracksCursor, ambigMFTTracksCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
482 mGIDToTableMFTID.emplace(trackIndex, mTableTrMFTID);
485 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
488 addToFwdTracksTable(fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, mftTracksCovCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
489 mGIDToTableFwdID.emplace(trackIndex, mTableTrFwdID);
490 addClustersToFwdTrkClsTable(
data, fwdTrkClsCursor, trackIndex, mTableTrFwdID);
494 if (trackIndex.isAmbiguous() && mGIDToTableID.find(trackIndex) != mGIDToTableID.end()) {
499 static std::uniform_real_distribution<>
distr(0., 1.);
501 auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex,
data, bcsMap);
504 auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex,
data, bcsMap);
505 if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) {
506 trackQAInfoHolder.trackID = mTableTrID;
510 addToTracksQATable(tracksQACursor, trackQAInfoHolder);
517 if (mThinTracks && extraInfoHolder.isTPConly && !writeQAData) {
518 auto trk =
data.getTPCTrack(trackIndex);
519 if (trk.getNClusters() >= mTrackQCNCls && trk.getPt() >= mTrackQCPt) {
529 if (mThinTracks &&
src ==
GIndex::Source::TPC && mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() && mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end() && !writeQAData) {
530 mGIDToTableID.emplace(trackIndex, -1);
534 if (!extraInfoHolder.isTPConly && extraInfoHolder.trackTimeRes < 0.f) {
535 LOG(warning) <<
"Barrel track " << trackIndex <<
" has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime
536 <<
" timeErr=" << extraInfoHolder.trackTimeRes <<
" BCSlice: " << extraInfoHolder.bcSlice[0] <<
":" << extraInfoHolder.bcSlice[1];
539 const auto& trOrig =
data.getTrackParam(trackIndex);
541 if (mPropTracks && trOrig.getX() < mMinPropR &&
542 mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() &&
543 mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end()) {
544 auto trackPar(trOrig);
545 isProp = propagateTrackToPV(trackPar,
data, collisionID);
547 addToTracksTable(tracksCursor, tracksCovCursor, trackPar, collisionID,
aod::track::Track);
553 addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
556 if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
557 ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
559 mGIDToTableID.emplace(trackIndex, mTableTrID);
565 if (collisionID < 0) {
569 auto sTracks =
data.getStrangeTracks();
570 tracksCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCursor.lastIndex());
571 tracksCovCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCovCursor.lastIndex());
572 tracksExtraCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksExtraCursor.lastIndex());
573 for (
int iS{mVertexStrLUT[collisionID]}; iS < mVertexStrLUT[collisionID + 1]; ++iS) {
574 auto& collStrTrk = mCollisionStrTrk[iS];
575 auto& sTrk = sTracks[collStrTrk.second];
576 TrackExtraInfo extraInfo;
577 extraInfo.itsChi2NCl = sTrk.mTopoChi2;
578 extraInfo.itsClusterSizes = sTrk.getClusterSizes();
580 addToTracksExtraTable(tracksExtraCursor, extraInfo);
581 mStrTrkIndices[collStrTrk.second] = mTableTrID;
588 const auto& mchmidMatches =
data.getMCHMIDMatches();
593 for (
int ti =
start; ti <
end; ti++) {
594 auto& trackIndex = GIndices[ti];
595 if (GIndex::includesSource(
src, mInputSources)) {
597 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
600 mGIDToTableMFTID.emplace(trackIndex, mIndexMFTID);
601 mIndexTableMFT[trackIndex.getIndex()] = mIndexMFTID;
604 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
607 mGIDToTableFwdID.emplace(trackIndex, mIndexFwdID);
609 mIndexTableFwd[trackIndex.getIndex()] = mIndexFwdID;
611 const auto& mchmidMatch = mchmidMatches[trackIndex.getIndex()];
612 const auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
613 mIndexTableFwd[mchTrackID] = mIndexFwdID;
622template <
typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename mftTracksCovCursorType>
623void AODProducerWorkflowDPL::addToFwdTracksTable(FwdTracksCursorType& fwdTracksCursor, FwdTracksCovCursorType& fwdTracksCovCursor,
624 AmbigFwdTracksCursorType& ambigFwdTracksCursor, mftTracksCovCursorType& mftTracksCovCursor,
GIndex trackID,
626 const std::map<uint64_t, int>& bcsMap)
628 const auto& mchTracks =
data.getMCHTracks();
629 const auto& midTracks =
data.getMIDTracks();
630 const auto& mchmidMatches =
data.getMCHMIDMatches();
631 const auto& mchClusters =
data.getMCHTrackClusters();
633 FwdTrackInfo fwdInfo;
634 FwdTrackCovInfo fwdCovInfo;
635 int bcSlice[2] = {-1, -1};
638 auto getMCHBitMap = [&](
int mchTrackID) {
639 if (mchTrackID != -1) {
640 const auto& mchTrack = mchTracks[mchTrackID];
641 int first = mchTrack.getFirstClusterIdx();
642 int last = mchTrack.getLastClusterIdx();
643 for (
int i =
first;
i <= last;
i++) {
644 const auto& cluster = mchClusters[
i];
645 int chamberId = cluster.getChamberId();
646 fwdInfo.mchBitMap |= 1 << chamberId;
651 auto getMIDBitMapBoards = [&](
int midTrackID) {
652 if (midTrackID != -1) {
653 const auto& midTrack = midTracks[midTrackID];
654 fwdInfo.midBitMap = midTrack.getHitMap();
655 fwdInfo.midBoards = midTrack.getEfficiencyWord();
659 auto extrapMCHTrack = [&](
int mchTrackID) {
660 const auto& track = mchTracks[mchTrackID];
668 float vx = 0, vy = 0, vz = 0;
669 if (collisionID >= 0) {
670 const auto&
v =
data.getPrimaryVertex(collisionID);
676 o2::mch::TrackParam trackParamAtVertex(track.getZ(), track.getParameters(), track.getCovariances());
699 double dca = std::sqrt(dcaX * dcaX + dcaY * dcaY);
704 double dpdca = track.getP() * dca;
705 double dchi2 = track.getChi2OverNDF();
707 auto fwdmuon = mMatching.
MCHtoFwd(trackParamAtVertex);
709 fwdInfo.x = fwdmuon.
getX();
710 fwdInfo.y = fwdmuon.getY();
711 fwdInfo.z = fwdmuon.getZ();
712 fwdInfo.phi = fwdmuon.getPhi();
713 fwdInfo.tanl = fwdmuon.getTgl();
714 fwdInfo.invqpt = fwdmuon.getInvQPt();
715 fwdInfo.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs);
716 fwdInfo.chi2 = dchi2;
717 fwdInfo.pdca = dpdca;
718 fwdInfo.nClusters = track.getNClusters();
720 fwdCovInfo.sigX = TMath::Sqrt(fwdmuon.getCovariances()(0, 0));
721 fwdCovInfo.sigY = TMath::Sqrt(fwdmuon.getCovariances()(1, 1));
722 fwdCovInfo.sigPhi = TMath::Sqrt(fwdmuon.getCovariances()(2, 2));
723 fwdCovInfo.sigTgl = TMath::Sqrt(fwdmuon.getCovariances()(3, 3));
724 fwdCovInfo.sig1Pt = TMath::Sqrt(fwdmuon.getCovariances()(4, 4));
725 fwdCovInfo.rhoXY = (Char_t)(128. * fwdmuon.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
726 fwdCovInfo.rhoPhiX = (Char_t)(128. * fwdmuon.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
727 fwdCovInfo.rhoPhiY = (Char_t)(128. * fwdmuon.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
728 fwdCovInfo.rhoTglX = (Char_t)(128. * fwdmuon.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
729 fwdCovInfo.rhoTglY = (Char_t)(128. * fwdmuon.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
730 fwdCovInfo.rhoTglPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
731 fwdCovInfo.rho1PtX = (Char_t)(128. * fwdmuon.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
732 fwdCovInfo.rho1PtY = (Char_t)(128. * fwdmuon.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
733 fwdCovInfo.rho1PtPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
734 fwdCovInfo.rho1PtTgl = (Char_t)(128. * fwdmuon.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
740 int mchTrackID = trackID.getIndex();
741 getMCHBitMap(mchTrackID);
742 if (!extrapMCHTrack(mchTrackID)) {
743 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
746 const auto& rof =
data.getMCHTracksROFRecords()[mMCHROFs[mchTrackID]];
747 auto time = rof.getTimeMUS(mStartIR).first;
748 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
749 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
752 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
753 auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
754 if (!extrapMCHTrack(mchTrackID)) {
755 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
757 auto midTrackID = mchmidMatch.getMIDRef().getIndex();
758 fwdInfo.chi2matchmchmid = mchmidMatch.getMatchChi2OverNDF();
759 getMCHBitMap(mchTrackID);
760 getMIDBitMapBoards(midTrackID);
761 auto time = mchmidMatch.getTimeMUS(mStartIR).first;
762 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
763 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
765 const auto& track =
data.getGlobalFwdTrack(trackID);
766 const auto& mftTracks =
data.getMFTTracks();
767 const auto& mfttrack = mftTracks[track.getMFTTrackID()];
768 if (!extrapMCHTrack(track.getMCHTrackID())) {
769 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", track.getMCHTrackID());
771 fwdInfo.x = track.getX();
772 fwdInfo.y = track.getY();
773 fwdInfo.z = track.getZ();
774 fwdInfo.phi = track.getPhi();
775 fwdInfo.tanl = track.getTanl();
776 fwdInfo.invqpt = track.getInvQPt();
777 fwdInfo.chi2 = track.getTrackChi2();
779 fwdInfo.chi2matchmchmid = track.getMIDMatchingChi2();
780 fwdInfo.chi2matchmchmft = track.getMFTMCHMatchingChi2();
781 fwdInfo.matchscoremchmft = track.getMFTMCHMatchingScore();
782 fwdInfo.matchmfttrackid = mIndexTableMFT[track.getMFTTrackID()];
783 fwdInfo.matchmchtrackid = mIndexTableFwd[track.getMCHTrackID()];
784 fwdInfo.trackTime = track.getTimeMUS().getTimeStamp() * 1.e3;
785 fwdInfo.trackTimeRes = track.getTimeMUS().getTimeStampError() * 1.e3;
787 getMCHBitMap(track.getMCHTrackID());
788 getMIDBitMapBoards(track.getMIDTrackID());
790 fwdCovInfo.sigX = TMath::Sqrt(track.getCovariances()(0, 0));
791 fwdCovInfo.sigY = TMath::Sqrt(track.getCovariances()(1, 1));
792 fwdCovInfo.sigPhi = TMath::Sqrt(track.getCovariances()(2, 2));
793 fwdCovInfo.sigTgl = TMath::Sqrt(track.getCovariances()(3, 3));
794 fwdCovInfo.sig1Pt = TMath::Sqrt(track.getCovariances()(4, 4));
795 fwdCovInfo.rhoXY = (Char_t)(128. * track.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
796 fwdCovInfo.rhoPhiX = (Char_t)(128. * track.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
797 fwdCovInfo.rhoPhiY = (Char_t)(128. * track.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
798 fwdCovInfo.rhoTglX = (Char_t)(128. * track.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
799 fwdCovInfo.rhoTglY = (Char_t)(128. * track.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
800 fwdCovInfo.rhoTglPhi = (Char_t)(128. * track.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
801 fwdCovInfo.rho1PtX = (Char_t)(128. * track.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
802 fwdCovInfo.rho1PtY = (Char_t)(128. * track.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
803 fwdCovInfo.rho1PtPhi = (Char_t)(128. * track.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
804 fwdCovInfo.rho1PtTgl = (Char_t)(128. * track.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
808 float sX = TMath::Sqrt(mfttrack.getSigma2X()), sY = TMath::Sqrt(mfttrack.getSigma2Y()), sPhi = TMath::Sqrt(mfttrack.getSigma2Phi()),
809 sTgl = TMath::Sqrt(mfttrack.getSigma2Tanl()), sQ2Pt = TMath::Sqrt(mfttrack.getSigma2InvQPt());
811 mftTracksCovCursor(fwdInfo.matchmfttrackid,
812 truncateFloatFraction(sX, mTrackCovDiag),
813 truncateFloatFraction(sY, mTrackCovDiag),
814 truncateFloatFraction(sPhi, mTrackCovDiag),
815 truncateFloatFraction(sTgl, mTrackCovDiag),
816 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
817 (Char_t)(128. * mfttrack.getCovariances()(0, 1) / (sX * sY)),
818 (Char_t)(128. * mfttrack.getCovariances()(0, 2) / (sPhi * sX)),
819 (Char_t)(128. * mfttrack.getCovariances()(1, 2) / (sPhi * sY)),
820 (Char_t)(128. * mfttrack.getCovariances()(0, 3) / (sTgl * sX)),
821 (Char_t)(128. * mfttrack.getCovariances()(1, 3) / (sTgl * sY)),
822 (Char_t)(128. * mfttrack.getCovariances()(2, 3) / (sTgl * sPhi)),
823 (Char_t)(128. * mfttrack.getCovariances()(0, 4) / (sQ2Pt * sX)),
824 (Char_t)(128. * mfttrack.getCovariances()(1, 4) / (sQ2Pt * sY)),
825 (Char_t)(128. * mfttrack.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
826 (Char_t)(128. * mfttrack.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
829 std::uint64_t bcOfTimeRef;
830 bool needBCSlice = collisionID < 0;
832 float err = mTimeMarginTrackTime + fwdInfo.trackTimeRes;
833 bcOfTimeRef = fillBCSlice(bcSlice, fwdInfo.trackTime - err, fwdInfo.trackTime + err, bcsMap);
835 bcOfTimeRef = collisionBC - mStartIR.
toLong();
839 fwdTracksCursor(collisionID,
843 truncateFloatFraction(fwdInfo.z, mTrackX),
844 truncateFloatFraction(fwdInfo.phi, mTrackAlpha),
845 truncateFloatFraction(fwdInfo.tanl, mTrackTgl),
846 truncateFloatFraction(fwdInfo.invqpt, mTrack1Pt),
848 truncateFloatFraction(fwdInfo.pdca, mTrackX),
849 truncateFloatFraction(fwdInfo.rabs, mTrackX),
850 truncateFloatFraction(fwdInfo.chi2, mTrackChi2),
851 truncateFloatFraction(fwdInfo.chi2matchmchmid, mTrackChi2),
852 truncateFloatFraction(fwdInfo.chi2matchmchmft, mTrackChi2),
853 truncateFloatFraction(fwdInfo.matchscoremchmft, mTrackChi2),
854 fwdInfo.matchmfttrackid,
855 fwdInfo.matchmchtrackid,
859 truncateFloatFraction(fwdInfo.trackTime, mTrackTime),
860 truncateFloatFraction(fwdInfo.trackTimeRes, mTrackTimeError));
862 fwdTracksCovCursor(truncateFloatFraction(fwdCovInfo.sigX, mTrackCovDiag),
863 truncateFloatFraction(fwdCovInfo.sigY, mTrackCovDiag),
864 truncateFloatFraction(fwdCovInfo.sigPhi, mTrackCovDiag),
865 truncateFloatFraction(fwdCovInfo.sigTgl, mTrackCovDiag),
866 truncateFloatFraction(fwdCovInfo.sig1Pt, mTrackCovDiag),
872 fwdCovInfo.rhoTglPhi,
875 fwdCovInfo.rho1PtPhi,
876 fwdCovInfo.rho1PtTgl);
879 ambigFwdTracksCursor(mTableTrFwdID, bcSlice);
884void AODProducerWorkflowDPL::updateMCHeader(MCCollisionCursor& collisionCursor,
885 XSectionCursor& xSectionCursor,
886 PdfInfoCursor& pdfInfoCursor,
887 HeavyIonCursor& heavyIonCursor,
888 const MCEventHeader& header,
900 auto genID = updateMCCollisions(collisionCursor,
907 mXSectionUpdate = (updateHepMCXSection(xSectionCursor,
912 ? HepMCUpdate::always
913 : HepMCUpdate::never);
914 mPdfInfoUpdate = (updateHepMCPdfInfo(pdfInfoCursor,
919 ? HepMCUpdate::always
920 : HepMCUpdate::never);
921 mHeavyIonUpdate = (updateHepMCHeavyIon(heavyIonCursor,
926 ? HepMCUpdate::always
927 : HepMCUpdate::never);
930void dimensionMCKeepStore(std::vector<std::vector<std::unordered_map<int, int>>>& store,
int Nsources,
int NEvents)
932 store.resize(Nsources);
933 for (
int s = 0;
s < Nsources; ++
s) {
934 store[
s].resize(NEvents);
940 for (
auto s = 0U;
s < store.size(); ++
s) {
941 for (
auto e = 0U; e < store[
s].size(); ++e) {
951 LOG(warn) <<
"trackID is smaller than 0. Neglecting";
958 MCParticlesCursor& mcParticlesCursor,
959 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
960 const gsl::span<const GIndex>& GIndices,
962 const std::vector<std::vector<int>>& mcColToEvSrc)
966 for (
auto& p : mcColToEvSrc) {
967 NSources = std::max(p[1], NSources);
968 NEvents = std::max(p[2], NEvents);
972 LOG(info) <<
" number of events " << NEvents;
973 LOG(info) <<
" number of sources " << NSources;
976 std::vector<int> particleIDsToKeep;
978 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
979 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
980 if (!mcLabel.isValid()) {
983 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
987 for (
auto& trackRef : primVer2TRefs) {
991 for (
int ti =
start; ti <
end; ti++) {
992 auto& trackIndex = GIndices[ti];
993 if (GIndex::includesSource(
src, mInputSources)) {
994 auto mcTruth =
data.getTrackMCLabel(trackIndex);
995 if (!mcTruth.isValid()) {
998 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1000 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1009 for (
auto& mcLabel : labelsTOF) {
1010 if (!mcLabel.isValid()) {
1013 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
1022 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1023 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1024 if (!mcTruth.isValid()) {
1027 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1031 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1032 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1033 if (!mcTruth.isValid()) {
1036 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1039 using namespace aodmchelpers;
1043 for (
auto& colInfo : mcColToEvSrc) {
1044 int event = colInfo[2];
1046 int mcColId = colInfo[0];
1048 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1066template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1067void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1068 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1069 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1071 const gsl::span<const GIndex>& primVerGIs,
1084 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1085 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1086 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1087 for (
int ti =
start; ti <
end; ti++) {
1088 const auto trackIndex = primVerGIs[ti];
1091 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1092 auto entry = mp.find(trackIndex);
1093 if (
entry == mp.end() ||
entry->second == -1) {
1100 if (GIndex::includesSource(
src, mInputSources)) {
1101 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1102 MCLabels labelHolder{};
1107 if (mcTruth.isValid()) {
1108 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1110 if (mcTruth.isFake()) {
1111 labelHolder.fwdLabelMask |= (0x1 << 7);
1113 if (mcTruth.isNoise()) {
1114 labelHolder.fwdLabelMask |= (0x1 << 6);
1117 mcMFTTrackLabelCursor(labelHolder.labelID,
1118 labelHolder.fwdLabelMask);
1120 mcFwdTrackLabelCursor(labelHolder.labelID,
1121 labelHolder.fwdLabelMask);
1124 if (!needToStore(mGIDToTableID)) {
1127 if (mcTruth.isValid()) {
1128 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1129 if (mcTruth.isFake()) {
1130 labelHolder.labelMask |= (0x1 << 15);
1133 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1136 labelHolder.labelMask |= (0x1 << 13);
1140 }
else if (mcTruth.isNoise()) {
1141 labelHolder.labelMask |= (0x1 << 14);
1143 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1150 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1152 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1153 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1154 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1155 auto& collStrTrk = mCollisionStrTrk[iS];
1156 auto&
label = sTrackLabels[collStrTrk.second];
1157 MCLabels labelHolder;
1158 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1159 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1160 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1165template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1166void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1173 v0Cursor.reserve(v0s.size());
1175 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1176 const auto&
v0 = v0s[iv0];
1177 auto trPosID =
v0.getProngID(0);
1178 auto trNegID =
v0.getProngID(1);
1179 uint8_t v0flags =
v0.getBits();
1180 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1181 auto item = mGIDToTableID.find(trPosID);
1182 if (item != mGIDToTableID.end()) {
1183 posTableIdx = item->second;
1185 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1187 item = mGIDToTableID.find(trNegID);
1188 if (item != mGIDToTableID.end()) {
1189 negTableIdx = item->second;
1191 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1193 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1194 if (itemV == mVtxToTableCollID.end()) {
1195 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1197 collID = itemV->second;
1199 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1200 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1201 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1206 cascadeCursor.reserve(cascades.size());
1207 for (
auto& cascade : cascades) {
1208 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1209 if (itemV0 == mV0ToTableID.end()) {
1212 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1213 auto bachelorID = cascade.getBachelorID();
1214 auto item = mGIDToTableID.find(bachelorID);
1215 if (item != mGIDToTableID.end()) {
1216 bachTableIdx = item->second;
1218 LOG(warn) <<
"Could not find a bachelor track index";
1221 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1222 if (itemV != mVtxToTableCollID.end()) {
1223 collID = itemV->second;
1225 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1228 cascadeCursor(collID, v0tableID, bachTableIdx);
1232 decay3BodyCursor.reserve(decays3Body.size());
1233 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1234 const auto& decay3Body = decays3Body[i3Body];
1236 decay3Body.getProngID(0),
1237 decay3Body.getProngID(1),
1238 decay3Body.getProngID(2)};
1239 int tableIdx[3]{-1, -1, -1}, collID = -1;
1240 bool missing{
false};
1241 for (
int i{0};
i < 3; ++
i) {
1242 auto item = mGIDToTableID.find(trIDs[
i]);
1243 if (item != mGIDToTableID.end()) {
1244 tableIdx[
i] = item->second;
1246 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1250 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1251 if (itemV == mVtxToTableCollID.end()) {
1252 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1255 collID = itemV->second;
1260 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1264template <
typename FwdTrkClsCursorType>
1271 int mchTrackID = -1;
1273 mchTrackID = trackID.getIndex();
1275 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1276 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1279 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1280 const auto& mchTrack = mchTracks[mchTrackID];
1281 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1282 int first = mchTrack.getFirstClusterIdx();
1283 int last = mchTrack.getLastClusterIdx();
1284 for (
int i =
first;
i <= last;
i++) {
1285 const auto& cluster = mchClusters[
i];
1286 fwdTrkClsCursor(fwdTrackId,
1287 truncateFloatFraction(cluster.x, mMuonCl),
1288 truncateFloatFraction(cluster.y, mMuonCl),
1289 truncateFloatFraction(cluster.z, mMuonCl),
1290 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1295template <
typename HMPCursorType>
1300 hmpCursor.reserve(hmpMatches.size());
1303 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1305 const auto&
match = hmpMatches[iHmp];
1307 float xTrk, yTrk, theta,
phi;
1311 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1314 auto photChargeVec =
match.getPhotCharge();
1316 float photChargeVec2[10];
1318 for (Int_t
i = 0;
i < 10;
i++) {
1319 photChargeVec2[
i] = photChargeVec[
i];
1321 auto tref = mGIDToTableID.find(
match.getTrackRef());
1322 if (tref != mGIDToTableID.end()) {
1323 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1325 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1337 mCollisionStrTrk.clear();
1339 mVertexStrLUT.clear();
1341 for (
auto& sTrk : recoData.getStrangeTracks()) {
1345 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1347 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1349 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1351 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1352 mVertexStrLUT[vtxId]++;
1354 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1357 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1358 mStrTrkIndices.clear();
1359 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1362template <
typename V0C,
typename CC,
typename D3BC>
1365 int itsTableIdx = -1;
1371 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1381 v0Curs.reserve(nV0);
1382 cascCurs.reserve(nCasc);
1383 d3BodyCurs.reserve(nD3Body);
1385 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1387 auto item = mGIDToTableID.find(ITSIndex);
1388 if (item != mGIDToTableID.end()) {
1389 itsTableIdx = item->second;
1391 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1395 v0Curs(mStrTrkIndices[sTrkID++],
1405 sTrk.getAverageClusterSize());
1407 cascCurs(mStrTrkIndices[sTrkID++],
1417 sTrk.getAverageClusterSize());
1419 d3BodyCurs(mStrTrkIndices[sTrkID++],
1429 sTrk.getAverageClusterSize());
1436 const auto& tpcTracks =
data.getTPCTracks();
1437 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1438 const auto& tpcClusShMap =
data.clusterShMapTPC;
1439 const auto& tpcClusAcc =
data.getTPCClusters();
1440 constexpr int maxRows = 152;
1441 constexpr int neighbour = 2;
1442 int ntr = tpcTracks.size();
1443 mTPCCounters.clear();
1444 mTPCCounters.resize(ntr);
1446 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1447#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1449 for (
int itr = 0; itr < ntr; itr++) {
1450 std::array<bool, maxRows> clMap{}, shMap{};
1451 uint8_t sectorIndex, rowIndex;
1452 uint32_t clusterIndex;
1453 auto&
counters = mTPCCounters[itr];
1454 const auto& track = tpcTracks[itr];
1455 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1456 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1457 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1458 clMap[rowIndex] =
true;
1460 if (!shMap[rowIndex]) {
1463 shMap[rowIndex] =
true;
1467 for (
int i = 0;
i < maxRows;
i++) {
1472 }
else if ((
i - last) <= neighbour) {
1475 int lim = std::min(
i + 1 + neighbour, maxRows);
1476 for (
int j =
i + 1;
j < lim;
j++) {
1491 if (track.getTrackletIndex(il) != -1) {
1495 if (track.getHasNeighbor()) {
1498 if (track.getHasPadrowCrossing()) {
1504template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1505void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1506 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1508 auto inputEvent = caloHandler.buildEvent(eventID);
1509 auto cellsInEvent = inputEvent.mCells;
1510 auto cellMClabels = inputEvent.mMCCellLabels;
1511 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1512 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1514 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1516 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1517 caloCellCursor(bcID,
1521 cellsInEvent[iCell].
getType(),
1535 std::vector<int32_t> particleIds;
1536 std::vector<float> amplitudeFraction;
1537 if (!mEMCselectLeading) {
1538 particleIds.reserve(cellMClabels.size());
1539 amplitudeFraction.reserve(cellMClabels.size());
1541 float tmpMaxAmplitude = 0;
1542 int32_t tmpindex = 0;
1543 for (
auto& mclabel : cellMClabels[iCell]) {
1545 if (mclabel.isValid()) {
1546 if (mEMCselectLeading) {
1547 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1549 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1550 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1551 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1552 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1556 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1557 auto iter = trackStore.find(mclabel.getTrackID());
1558 if (iter != trackStore.end()) {
1559 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1560 particleIds.emplace_back(iter->second);
1562 particleIds.emplace_back(-1);
1563 amplitudeFraction.emplace_back(0.f);
1564 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1565 if (mMCKineReader) {
1566 auto mctrack = mMCKineReader->
getTrack(mclabel);
1569 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1575 if (mEMCselectLeading) {
1576 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1577 particleIds.emplace_back(tmpindex);
1579 if (particleIds.size() == 0) {
1580 particleIds.emplace_back(-1);
1581 amplitudeFraction.emplace_back(0.f);
1583 mcCaloCellLabelCursor(particleIds,
1590template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1591void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1592 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1596 auto caloEMCCells =
data.getEMCALCells();
1597 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1598 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1600 auto caloPHOSCells =
data.getPHOSCells();
1601 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1602 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1606 caloPHOSCellsTRGR = {};
1607 mcCaloPHOSCellLabels = {};
1612 caloEMCCellsTRGR = {};
1613 mcCaloEMCCellLabels = {};
1620 emcEventHandler.
reset();
1621 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1624 phsEventHandler.
reset();
1625 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1631 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1633 caloEvents.reserve(emcNEvents + phsNEvents);
1635 for (
int iev = 0; iev < emcNEvents; ++iev) {
1637 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1640 for (
int iev = 0; iev < phsNEvents; ++iev) {
1642 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1645 std::sort(caloEvents.begin(), caloEvents.end(),
1646 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1649 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1650 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1651 int8_t caloType = std::get<1>(caloEvents[
i]);
1652 int eventID = std::get<2>(caloEvents[
i]);
1653 auto item = bcsMap.find(globalBC);
1655 if (item != bcsMap.end()) {
1656 bcID = item->second;
1658 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1660 if (caloType == 0) {
1661 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1663 if (caloType == 1) {
1664 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1675 mLPMProdTag = ic.
options().
get<
string>(
"lpmp-prod-tag");
1676 mAnchorPass = ic.
options().
get<
string>(
"anchor-pass");
1677 mAnchorProd = ic.
options().
get<
string>(
"anchor-prod");
1678 mRecoPass = ic.
options().
get<
string>(
"reco-pass");
1679 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1680 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1681 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1682 mRunNumber = ic.
options().
get<
int>(
"run-number");
1683 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1684 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1685 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1686 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1687 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1688 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1689 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1690 mStreamerFlags.
set(
s);
1691 if (mStreamerFlags) {
1692 LOGP(info,
"Writing streamer data with mask:");
1693 LOG(info) << mStreamerFlags;
1695 LOGP(warn,
"Specified non-default empty streamer mask!");
1698 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1699 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1700 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1701 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1702 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1703 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1704 LOGP(info,
"Using random device for seeding");
1705 std::random_device
rd;
1706 std::array<int, std::mt19937::state_size> seed_data{};
1707 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1708 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1709 mGenerator = std::mt19937(seq);
1711 LOGP(info,
"Using seed {} for sampling", seed);
1712 mGenerator.seed(seed);
1715 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1718 LOG(info) <<
"OpenMP is disabled";
1720 if (mTFNumber == -1L) {
1721 LOG(info) <<
"TFNumber will be obtained from CCDB";
1723 if (mRunNumber == -1L) {
1724 LOG(info) <<
"The Run number will be obtained from DPL headers";
1728 if (mTruncate != 1) {
1729 LOG(info) <<
"Truncation is not used!";
1730 mCollisionPosition = 0xFFFFFFFF;
1731 mCollisionPositionCov = 0xFFFFFFFF;
1732 mTrackX = 0xFFFFFFFF;
1733 mTrackAlpha = 0xFFFFFFFF;
1734 mTrackSnp = 0xFFFFFFFF;
1735 mTrackTgl = 0xFFFFFFFF;
1736 mTrack1Pt = 0xFFFFFFFF;
1737 mTrackChi2 = 0xFFFFFFFF;
1738 mTrackCovDiag = 0xFFFFFFFF;
1739 mTrackCovOffDiag = 0xFFFFFFFF;
1740 mTrackSignal = 0xFFFFFFFF;
1741 mTrackTime = 0xFFFFFFFF;
1742 mTPCTime0 = 0xFFFFFFFF;
1743 mTrackTimeError = 0xFFFFFFFF;
1744 mTrackPosEMCAL = 0xFFFFFFFF;
1745 mTracklets = 0xFFFFFFFF;
1746 mMcParticleW = 0xFFFFFFFF;
1747 mMcParticlePos = 0xFFFFFFFF;
1748 mMcParticleMom = 0xFFFFFFFF;
1749 mCaloAmp = 0xFFFFFFFF;
1750 mCaloTime = 0xFFFFFFFF;
1751 mCPVPos = 0xFFFFFFFF;
1752 mCPVAmpl = 0xFFFFFFFF;
1753 mMuonTr1P = 0xFFFFFFFF;
1754 mMuonTrThetaX = 0xFFFFFFFF;
1755 mMuonTrThetaY = 0xFFFFFFFF;
1756 mMuonTrZmu = 0xFFFFFFFF;
1757 mMuonTrBend = 0xFFFFFFFF;
1758 mMuonTrNonBend = 0xFFFFFFFF;
1759 mMuonTrCov = 0xFFFFFFFF;
1760 mMuonCl = 0xFFFFFFFF;
1761 mMuonClErr = 0xFFFFFFFF;
1762 mV0Time = 0xFFFFFFFF;
1763 mV0ChannelTime = 0xFFFFFFFF;
1764 mFDDTime = 0xFFFFFFFF;
1765 mFDDChannelTime = 0xFFFFFFFF;
1766 mT0Time = 0xFFFFFFFF;
1767 mT0ChannelTime = 0xFFFFFFFF;
1768 mV0Amplitude = 0xFFFFFFFF;
1769 mFDDAmplitude = 0xFFFFFFFF;
1770 mT0Amplitude = 0xFFFFFFFF;
1774 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1777 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1780 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1781 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1782 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1783 : HepMCUpdate::anyKey);
1784 mXSectionUpdate = when;
1785 mPdfInfoUpdate = when;
1786 mHeavyIonUpdate = when;
1790 if (mStreamerFlags) {
1791 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1797 mTimer.Start(
false);
1800 updateTimeDependentParams(pc);
1825 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
1826 if (mCTPReadout == 1) {
1827 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
1828 createCTPReadout(recoData, ctpDigitsCreated, pc);
1829 LOG(info) <<
"CTP : ctpreadout created from AOD";
1830 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
1832 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1833 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
1834 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
1835 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
1836 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
1837 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
1839 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1843 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
1844 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
1845 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
1846 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
1847 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
1848 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
1849 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
1850 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
1851 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
1852 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
1853 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
1854 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
1855 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
1856 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
1857 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
1858 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
1859 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
1860 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
1861 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
1862 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
1863 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
1864 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1865 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
1866 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
1867 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
1868 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
1869 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
1870 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
1871 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
1872 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
1873 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
1874 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
1875 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
1889 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
1890 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
1891 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
1892 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
1893 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
1894 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
1895 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
1896 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
1897 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
1898 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
1901 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
1903 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
1905 mMCKineReader = mcReader.get();
1906 std::map<uint64_t, int> bcsMap;
1907 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
1908 if (!primVer2TRefs.empty()) {
1909 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
1912 mBCLookup.
init(bcsMap);
1915 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
1916 if (mTFNumber == -1L) {
1918 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
1920 tfNumber = mTFNumber;
1923 std::vector<float> aAmplitudes, aTimes;
1924 std::vector<uint8_t> aChannels;
1925 fv0aCursor.reserve(fv0RecPoints.size());
1926 for (
auto& fv0RecPoint : fv0RecPoints) {
1927 aAmplitudes.clear();
1930 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
1931 for (
auto& channel : channelData) {
1932 if (channel.charge > 0) {
1933 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
1934 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
1935 aChannels.push_back(channel.channel);
1938 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
1939 auto item = bcsMap.find(
bc);
1941 if (item != bcsMap.end()) {
1942 bcID = item->second;
1944 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
1949 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
1950 fv0RecPoint.getTrigger().getTriggersignals());
1952 if (mEnableFITextra) {
1953 fv0aExtraCursor(bcID,
1958 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
1959 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
1960 zdcCursor.reserve(zdcBCRecData.size());
1961 for (
auto zdcRecData : zdcBCRecData) {
1962 uint64_t
bc = zdcRecData.ir.toLong();
1963 auto item = bcsMap.find(
bc);
1965 if (item != bcsMap.end()) {
1966 bcID = item->second;
1968 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
1970 int fe, ne, ft, nt, fi, ni;
1971 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
1973 zdcChannelsE.clear();
1974 zdcAmplitudes.clear();
1976 zdcChannelsT.clear();
1977 for (
int ie = 0; ie < ne; ie++) {
1978 auto& zdcEnergyData = zdcEnergies[fe + ie];
1979 zdcEnergy.emplace_back(zdcEnergyData.energy());
1980 zdcChannelsE.emplace_back(zdcEnergyData.ch());
1982 for (
int it = 0; it < nt; it++) {
1983 auto& tdc = zdcTDCData[ft + it];
1984 zdcAmplitudes.emplace_back(tdc.amplitude());
1985 zdcTime.emplace_back(tdc.value());
1999 std::vector<std::vector<int>> mcColToEvSrc;
2005 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2006 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2007 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2010 int totalNParts = 0;
2011 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2012 totalNParts += mcParts[iCol].size();
2014 mcCollisionsCursor.
reserve(totalNParts);
2016 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2017 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2018 auto globalBC = mcRecords[iCol].toLong();
2019 auto item = bcsMap.find(globalBC);
2021 if (item != bcsMap.end()) {
2022 bcID = item->second;
2024 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2025 <<
"for MC collision; BC = " << globalBC
2026 <<
", mc collision = " << iCol;
2028 auto& colParts = mcParts[iCol];
2029 auto nParts = colParts.size();
2030 for (
auto colPart : colParts) {
2031 auto eventID = colPart.entryID;
2032 auto sourceID = colPart.sourceID;
2035 if (nParts == 1 || sourceID == 0) {
2038 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2039 updateMCHeader(mcCollisionsCursor.
cursor,
2040 hepmcXSectionsCursor.
cursor,
2041 hepmcPdfInfosCursor.
cursor,
2042 hepmcHeavyIonsCursor.
cursor,
2050 mcColToEvSrc.emplace_back(std::vector<int>{iCol, sourceID, eventID});
2055 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2056 [](
const std::vector<int>&
left,
const std::vector<int>&
right) { return (left[0] < right[0]); });
2059 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2060 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2062 fddCursor.reserve(fddRecPoints.size());
2063 for (
const auto& fddRecPoint : fddRecPoints) {
2064 for (
int i = 0;
i < 8;
i++) {
2065 aFDDAmplitudesA[
i] = 0;
2066 aFDDAmplitudesC[
i] = 0;
2067 aFDDTimesA[
i] = 0.f;
2068 aFDDTimesC[
i] = 0.f;
2070 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2071 uint64_t
bc = globalBC;
2072 auto item = bcsMap.find(
bc);
2074 if (item != bcsMap.end()) {
2075 bcID = item->second;
2077 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2079 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2080 for (
const auto& channel : channelData) {
2081 if (channel.mPMNumber < 8) {
2082 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2083 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2085 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2086 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2093 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2094 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2095 fddRecPoint.getTrigger().getTriggersignals());
2096 if (mEnableFITextra) {
2097 fddExtraCursor(bcID,
2104 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2105 std::vector<uint8_t> aChannelsA, aChannelsC;
2106 ft0Cursor.reserve(ft0RecPoints.size());
2107 for (
auto& ft0RecPoint : ft0RecPoints) {
2108 aAmplitudesA.clear();
2109 aAmplitudesC.clear();
2114 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2115 for (
auto& channel : channelData) {
2117 if (channel.QTCAmpl > 0) {
2119 if (channel.ChId < nFT0ChannelsAside) {
2120 aChannelsA.push_back(channel.ChId);
2121 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2122 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2124 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2125 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2126 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2130 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2131 uint64_t
bc = globalBC;
2132 auto item = bcsMap.find(
bc);
2134 if (item != bcsMap.end()) {
2135 bcID = item->second;
2137 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2144 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2145 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2146 ft0RecPoint.getTrigger().getTriggersignals());
2147 if (mEnableFITextra) {
2148 ft0ExtraCursor(bcID,
2156 mcColLabelsCursor.
reserve(primVerLabels.size());
2157 for (
auto&
label : primVerLabels) {
2158 auto it = std::find_if(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2159 [&
label](
const auto& mcColInfo) { return mcColInfo[1] == label.getSourceID() && mcColInfo[2] == label.getEventID(); });
2160 int32_t mcCollisionID = -1;
2161 if (it != mcColToEvSrc.end()) {
2162 mcCollisionID = it->at(0);
2164 uint16_t mcMask = 0;
2165 mcColLabelsCursor(mcCollisionID, mcMask);
2169 cacheTriggers(recoData);
2170 countTPCClusters(recoData);
2172 int collisionID = 0;
2176 auto& trackReffwd = primVer2TRefs.back();
2177 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2179 for (
auto&
vertex : primVertices) {
2180 auto& trackReffwd = primVer2TRefs[collisionID];
2181 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2186 prepareStrangenessTracking(recoData);
2188 mGIDToTableFwdID.clear();
2189 mGIDToTableMFTID.clear();
2191 if (mPropTracks || mThinTracks) {
2195 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2196 for (
const auto&
v0 : v0s) {
2197 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2198 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2200 for (
const auto& cascade : cascades) {
2201 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2203 for (
const auto& id3Body : decays3Body) {
2204 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2205 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2206 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2217 auto& trackRef = primVer2TRefs.back();
2219 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2220 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2221 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2225 collisionsCursor.reserve(primVertices.size());
2226 for (
auto&
vertex : primVertices) {
2227 auto& cov =
vertex.getCov();
2228 auto& timeStamp =
vertex.getTimeStamp();
2229 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2230 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2231 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2232 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2235 auto item = bcsMap.find(globalBC);
2237 if (item != bcsMap.end()) {
2238 bcID = item->second;
2240 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2242 collisionsCursor(bcID,
2243 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2244 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2245 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2246 truncateFloatFraction(cov[0], mCollisionPositionCov),
2247 truncateFloatFraction(cov[1], mCollisionPositionCov),
2248 truncateFloatFraction(cov[2], mCollisionPositionCov),
2249 truncateFloatFraction(cov[3], mCollisionPositionCov),
2250 truncateFloatFraction(cov[4], mCollisionPositionCov),
2251 truncateFloatFraction(cov[5], mCollisionPositionCov),
2253 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2254 vertex.getNContributors(),
2255 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2256 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2257 mVtxToTableCollID[collisionID] = mTableCollID++;
2259 auto& trackRef = primVer2TRefs[collisionID];
2261 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2262 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2263 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2267 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2268 fillHMPID(recoData, hmpCursor);
2269 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2273 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2275 LOG(
debug) <<
"CTP input available";
2276 for (
auto& ctpDigit : ctpDigits) {
2277 uint64_t
bc = ctpDigit.intRecord.toLong();
2278 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2279 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2280 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2282 auto classMaskOrig = classMask;
2283 classMask = classMask & ~mEMCALTrgClassMask;
2284 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2286 bcToClassMask[
bc] = {classMask, inputMask};
2292 bcCursor.reserve(bcsMap.size());
2293 for (
auto& item : bcsMap) {
2294 uint64_t
bc = item.first;
2295 std::pair<uint64_t, uint64_t> masks{0, 0};
2297 auto bcClassPair = bcToClassMask.find(
bc);
2298 if (bcClassPair != bcToClassMask.end()) {
2299 masks = bcClassPair->second;
2308 bcToClassMask.clear();
2311 auto bcFlags = fillBCFlags(recoData, bcsMap);
2312 bcFlagsCursor.reserve(bcFlags.size());
2313 for (
auto f : bcFlags) {
2320 cpvClustersCursor.reserve(cpvTrigRecs.size());
2321 for (
auto& cpvEvent : cpvTrigRecs) {
2322 uint64_t
bc = cpvEvent.getBCData().toLong();
2323 auto item = bcsMap.find(
bc);
2325 if (item != bcsMap.end()) {
2326 bcID = item->second;
2328 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2330 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2331 auto&
clu = cpvClusters[iClu];
2332 clu.getLocalPosition(posX, posZ);
2333 cpvClustersCursor(bcID,
2334 truncateFloatFraction(posX, mCPVPos),
2335 truncateFloatFraction(posZ, mCPVPos),
2336 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2337 clu.getPackedClusterStatus());
2346 fillMCParticlesTable(*mcReader,
2347 mcParticlesCursor.
cursor,
2353 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2354 mcColToEvSrc.clear();
2360 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2361 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2362 auto& trackRef = primVer2TRefs[iref];
2363 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2369 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2374 mGIDToTableID.clear();
2376 mGIDToTableFwdID.clear();
2378 mGIDToTableMFTID.clear();
2380 mVtxToTableCollID.clear();
2382 mV0ToTableID.clear();
2385 mIndexTableFwd.clear();
2387 mIndexTableMFT.clear();
2392 mGIDUsedBySVtx.clear();
2393 mGIDUsedByStr.clear();
2395 originCursor(tfNumber);
2398 TString dataType = mUseMC ?
"MC" :
"RAW";
2400 TString ROOTVersion = ROOT_RELEASE;
2401 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag"};
2402 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag};
2419 for (
const auto& rof : rofs) {
2420 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2421 for (
int i =
first;
i < last;
i++) {
2422 mITSROFs.push_back(
count);
2432 for (
const auto& rof : rofs) {
2433 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2435 mMFTROFs.push_back(
count);
2442 mITSTPCTRDTriggers.clear();
2445 for (
const auto& trig : itstpctrigs) {
2446 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2448 mITSTPCTRDTriggers.push_back(
count);
2455 mTPCTRDTriggers.clear();
2458 for (
const auto& trig : tpctrigs) {
2459 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2461 mTPCTRDTriggers.push_back(
count);
2471 for (
const auto& rof : rofs) {
2474 mMCHROFs.push_back(
count);
2481AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2484 TrackExtraInfo extraInfoHolder;
2485 if (collisionID < 0) {
2488 bool needBCSlice = collisionID < 0;
2489 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2491 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2497 extraInfoHolder.trackTimeRes = terr;
2499 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2500 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2503 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2505 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2508 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2509 const auto& trackPar =
data.getTrackParam(trackIndex);
2510 extraInfoHolder.flags |= trackPar.getPID() << 28;
2511 auto src = trackIndex.getSource();
2513 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2514 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2515 const auto& tofInt = tofMatch.getLTIntegralOut();
2516 float intLen = tofInt.getL();
2517 extraInfoHolder.length = intLen;
2524 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2527 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2528 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2529 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2530 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2531 setTrackTime(tofSignal, 0.2,
true);
2535 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2536 extraInfoHolder.trdSignal = trdOrig.getSignal();
2537 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2538 if (extraInfoHolder.trackTimeRes < 0.) {
2540 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2542 setTrackTime(ttrig, 1.,
true);
2546 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2547 int nClusters = itsTrack.getNClusters();
2548 float chi2 = itsTrack.getChi2();
2550 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2552 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2554 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2557 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2561 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2562 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2563 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2566 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2567 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2568 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2569 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2570 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2571 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2572 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2573 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2574 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2577 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2578 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2579 double err = mTimeMarginTrackTime + terr;
2580 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2585 extraInfoHolder.trackTimeRes = p.
getTimeErr();
2587 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2588 extraInfoHolder.isTPConly =
true;
2591 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2592 auto ts = trITSTPC.getTimeMUS();
2593 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2597 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2602 return extraInfoHolder;
2605AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2609 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2610 const auto& trackPar =
data.getTrackParam(trackIndex);
2611 if (contributorsGID.isIndexSet()) {
2613 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2619 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2620 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2621 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2625 auto safeInt8Clamp = [](
auto value) -> int8_t {
2626 using ValType =
decltype(
value);
2627 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()))));
2629 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2630 using ValType =
decltype(
value);
2631 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()))));
2635 uint8_t clusterCounters[8] = {0};
2637 uint8_t sectorIndex, rowIndex;
2638 uint32_t clusterIndex;
2639 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2640 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2641 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2642 char indexTracklet = (rowIndex % 152) / 19;
2643 clusterCounters[indexTracklet]++;
2647 for (
int i = 0;
i < 8;
i++) {
2648 if (clusterCounters[
i] > 5) {
2649 byteMask |= (1 <<
i);
2652 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2653 trackQAHolder.tpcClusterByteMask = byteMask;
2654 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2655 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2656 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2657 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2658 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2659 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2660 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2662 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2663 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2664 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2665 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2668 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2670 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2671 const float qpt = trackPar.getQ2Pt();
2673 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2674 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2680 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2681 const auto& itsOrig =
data.getITSTrack(itsContGID);
2690 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2691 const float qpt = gloCopy.getQ2Pt();
2692 const float x = qpt / beta0;
2694 auto scaleCont = [&
x](
int i) ->
float {
2697 auto scaleGlo = [&
x](
int i) ->
float {
2702 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2703 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2704 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2705 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2706 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2708 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2709 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2710 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2711 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2712 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2716 (*mStreamer) <<
"trackQA"
2717 <<
"trackITSOrig=" << itsOrig
2718 <<
"trackTPCOrig=" << tpcOrig
2719 <<
"trackITSTPCOrig=" << trackPar
2720 <<
"trackITSProp=" << itsCopy
2721 <<
"trackTPCProp=" << tpcCopy
2722 <<
"trackITSTPCProp=" << gloCopy
2725 <<
"scaleCont0=" << scaleCont(0)
2726 <<
"scaleCont1=" << scaleCont(1)
2727 <<
"scaleCont2=" << scaleCont(2)
2728 <<
"scaleCont3=" << scaleCont(3)
2729 <<
"scaleCont4=" << scaleCont(4)
2730 <<
"scaleGlo0=" << scaleGlo(0)
2731 <<
"scaleGlo1=" << scaleGlo(1)
2732 <<
"scaleGlo2=" << scaleGlo(2)
2733 <<
"scaleGlo3=" << scaleGlo(3)
2734 <<
"scaleGlo4=" << scaleGlo(4)
2735 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
2736 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
2737 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
2738 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
2739 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
2740 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
2741 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
2742 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
2743 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
2744 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
2745 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
2746 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
2747 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
2748 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
2749 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
2750 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
2751 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
2752 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
2753 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
2754 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
2755 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
2756 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
2757 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
2758 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
2759 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
2760 <<
"scaleTOF=" << scaleTOF
2767 return trackQAHolder;
2775 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
2780void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
2782 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
2783 constexpr float ETAEMCAL = 0.75;
2784 constexpr float ZEMCALFastCheck = 460.;
2785 constexpr float ETADCALINNER = 0.22;
2786 constexpr float ETAPHOS = 0.13653194;
2787 constexpr float ETAPHOSMARGIN = 0.17946979;
2788 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
2789 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
2790 constexpr short SECTORTYPE[18] = {
2791 SNONE, SNONE, SNONE, SNONE,
2792 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
2795 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
2806 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
2807 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2808 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
2812 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
2813 (!outTr.rotateParam(outTr.getPhi()) ||
2815 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
2816 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
2822 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
2825 auto outTrTmp = outTr;
2827 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
2828 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2829 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
2834 if (sectorTmp == sector) {
2842 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
2849 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
2854 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
2855 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
2856 if (etaAbs > ETAEMCAL) {
2857 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
2861 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
2862 if (!propExactSector(XPHOS)) {
2865 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
2866 tg = std::atan2(
r, outTr.getZ());
2867 eta = -std::log(std::tan(0.5f * tg));
2868 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
2871 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
2872 extraInfoHolder.trackEtaEMCAL = eta;
2873 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
2877std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
2879 std::set<uint64_t> emcalIncompletes;
2880 for (
const auto& trg : triggers) {
2881 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
2883 emcalIncompletes.insert(trg.getBCData().toLong());
2886 return emcalIncompletes;
2892 static bool initOnceDone =
false;
2893 if (!initOnceDone) {
2894 initOnceDone =
true;
2901 for (
auto i = 0U;
i < bs.size();
i++) {
2916 mTPCBinNS = elParam.ZbinWidth * 1.e3;
2919 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
2920 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
2941 LOG(info) <<
"ITS Alpide param updated";
2943 par.printKeyValues();
2947 LOG(info) <<
"MFT Alpide param updated";
2949 par.printKeyValues();
2960 mEMCALTrgClassMask = 0;
2961 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
2963 mEMCALTrgClassMask |= trgclass.classMask;
2966 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
2970void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
2981 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
2982 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
2983 assert(nbitsFrac > 1);
2984 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
2986 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
2987 << TOFTimePrecPS <<
" ps";
2990 if (!trackRef.getEntries()) {
2994 std::uint64_t maxBC = mStartIR.
toLong();
2995 const auto& tofClus =
data.getTOFClusters();
3002 for (
int ti =
start; ti <
end; ti++) {
3003 auto& trackIndex = GIndices[ti];
3004 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3005 const auto& tofInt = tofMatch.getLTIntegralOut();
3006 float intLen = tofInt.getL();
3007 float tofExpMom = 0.;
3017 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3018 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3019 double exp = intLen * energy / (cSpeed * tofExpMom);
3020 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3021 auto bc = relativeTime_to_GlobalBC(tofSignal);
3023 auto it = bcsMap.lower_bound(
bc);
3024 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3025 bcsMap.emplace_hint(it,
bc, 1);
3034 if ((--bcsMap.end())->first <= maxBC) {
3035 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3039 for (
auto& item : bcsMap) {
3045std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3057 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3080 auto upperindex = p.first;
3081 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3084 if (upperindex != p.first) {
3088 slice[1] = upperindex;
3090 auto bcOfTimeRef = p.second - this->mStartIR.
toLong();
3091 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3092 <<
" t: " << tmax <<
" " << slice[1]
3093 <<
" bcref: " << bcOfTimeRef;
3099 std::vector<uint8_t>
flags(bcsMap.size());
3102 auto bcIt = bcsMap.begin();
3103 auto itsrofs =
data.getITSTracksROFRecords();
3106 for (
auto& rof : itsrofs) {
3107 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3110 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3112 while (bcIt != bcsMap.end()) {
3113 if (bcIt->first < globalBC0) {
3117 if (bcIt->first > globalBC1) {
3129 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3130 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3137 auto dataRequest = std::make_shared<DataRequest>();
3138 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3140 dataRequest->requestTracks(
src, useMC);
3141 dataRequest->requestPrimaryVertices(useMC);
3143 dataRequest->requestCTPDigits(useMC);
3146 dataRequest->requestSecondaryVertices(useMC);
3148 if (enableStrangenessTracking) {
3149 dataRequest->requestStrangeTracks(useMC);
3150 LOGF(info,
"requestStrangeTracks Finish");
3159 dataRequest->requestTOFClusters(useMC);
3162 dataRequest->requestPHOSCells(useMC);
3165 dataRequest->requestTRDTracklets(
false);
3168 dataRequest->requestEMCALCells(useMC);
3171 dataRequest->requestCPVClusters(useMC);
3174 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3180 dataRequest->inputs,
3183 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3188 std::vector<OutputSpec> outputs{
3228 outputs.insert(outputs.end(),
3229 {OutputForTable<McCollisions>::spec(),
3230 OutputForTable<HepMCXSections>::spec(),
3231 OutputForTable<HepMCPdfInfos>::spec(),
3232 OutputForTable<HepMCHeavyIons>::spec(),
3233 OutputForTable<McMFTTrackLabels>::spec(),
3234 OutputForTable<McFwdTrackLabels>::spec(),
3235 OutputForTable<StoredMcParticles_001>::spec(),
3236 OutputForTable<McTrackLabels>::spec(),
3237 OutputForTable<McCaloLabels_001>::spec(),
3242 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3246 "aod-producer-workflow",
3249 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3251 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3252 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3253 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3254 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3255 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3256 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3257 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3258 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3259 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3260 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3261 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3262 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3263 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3264 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)"}},
3265 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3266 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3267 ConfigParamSpec{
"trackqc-fraction", VariantType::Float,
float(0.1), {
"Fraction of tracks to QC"}},
3268 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3269 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3270 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3271 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3272 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3273 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
Class to refer to the reconstructed information.
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
General auxilliary methods.
uint64_t exp(uint64_t base, uint8_t exp) noexcept
definition of CTPDigit, CTPInputDigit
Header of the AggregatedRunInfo struct.
Global Forward Muon tracks.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the MCTrack class.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Utility functions for MC particles.
Class to perform MFT MCH (and MID) matching.
Class to store the output of the matching to HMPID.
Class to perform TOF matching to global tracks.
Definition of the parameter class for the detector electronics.
Header to collect physics constants.
Definition of the FDD RecPoint class.
Definition of the ITS track.
Definition of the MUON track.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
Result of refitting TPC-ITS matched track.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
Container class to store energy released in the ZDC.
Container class to store a TDC hit in a ZDC channel.
const auto & getBCPattern() const
void GetStartVertex(TVector3 &vertex) const
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void run(ProcessingContext &pc) final
void init(InitContext &ic) final
std::pair< size_t, uint64_t > lower_bound(uint64_t timestamp) const
void init(std::map< uint64_t, int > const &bcs)
initialize this container (to be ready for lookup/search queries)
void clear()
clear/reset this container
std::vector< uint64_t > const & getBCTimeVector() const
return the sorted vector of increaing BC times
static float getAmplitude(const o2::emcal::Cell &cell)
static int16_t getLnAmplitude(const o2::emcal::Cell &)
static int8_t getTriggerBits(const o2::emcal::Cell &)
static int16_t getCellNumber(const o2::emcal::Cell &cell)
static int16_t getFastOrAbsID(const o2::emcal::Cell &)
static bool isTRU(const o2::emcal::Cell &cell)
static float getTimeStamp(const o2::emcal::Cell &cell)
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static constexpr float MAX_SIN_PHI
static constexpr float MAX_STEP
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const DPLAlpideParam< N > & Instance()
void printStream(std::ostream &stream) const
Static class with identifiers, bitmasks and names for ALICE detectors.
Handler for EMCAL event data.
void reset()
Reset containers with empty ranges.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::emcal::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
InteractionRecord getInteractionRecordForEvent(int eventID) const
Get the interaction record for the given event.
int getNumberOfEvents() const
Get the number of events handled by the event handler.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static constexpr int NCellsA
o2::dataformats::GlobalFwdTrack MCHtoFwd(const o2::mch::TrackParam &mchTrack)
Converts mchTrack parameters to Forward coordinate system.
track parameters for internal use
Double_t getNonBendingCoor() const
return non bending coordinate (cm)
Double_t getBendingCoor() const
return bending coordinate (cm)
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::phos::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void reset()
Reset containers with empty ranges.
InteractionRecord getInteractionRecordForEvent(int eventID) const
int getNumberOfEvents() const
MCTrack const * getTrack(o2::MCCompLabel const &) const
void releaseTracksForSourceAndEvent(int source, int event)
API to ask releasing tracks (freeing memory) for source + event.
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
static void addInteractionBC(int bc, bool fromCollisonCotext=false)
void set(const std::string &s="", int base=2)
bool match(const std::vector< std::string > &queries, const char *pattern)
GLfloat GLfloat GLfloat alpha
GLint GLint GLsizei GLuint * counters
GLuint GLuint GLfloat weight
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
constexpr std::array< float, 2 > trackQAScaledTOF
constexpr std::array< float, 5 > trackQAScaleContP1
uint8_t itsSharedClusterMap uint8_t
constexpr std::array< float, 5 > trackQAScaleContP0
constexpr std::array< float, 5 > trackQAScaleGloP0
constexpr std::array< float, 5 > trackQAScaleGloP1
constexpr float trackQAScaleBins
constexpr float trackQARefRadius
bool updateHepMCHeavyIon(const HeavyIonCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
short updateMCCollisions(const CollisionCursor &cursor, int bcId, float time, o2::dataformats::MCEventHeader const &header, short generatorId=0, int sourceId=0, unsigned int mask=0xFFFFFFF0)
bool updateHepMCPdfInfo(const PdfInfoCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
uint32_t updateParticles(const ParticleCursor &cursor, int collisionID, std::vector< MCTrack > const &tracks, TrackToIndex &preselect, uint32_t offset=0, bool filter=false, bool background=false, uint32_t weightMask=0xFFFFFFF0, uint32_t momentumMask=0xFFFFFFF0, uint32_t positionMask=0xFFFFFFF0)
bool updateHepMCXSection(const XSectionCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
void keepMCParticle(std::vector< std::vector< std::unordered_map< int, int > > > &store, int source, int event, int track, int value=1)
framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra)
create a processor spec
void dimensionMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store, int Nsources, int NEvents)
void clearMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store)
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
constexpr double MassPionCharged
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
int angle2Sector(float phi)
float sector2Angle(int sect)
const int TDCSignal[NTDCChannels]
constexpr int NTDCChannels
std::string fullVersion()
get full version information (official O2 release and git commit)
void setDeltaTFwd(float fwd)
void setDeltaTBwd(float bwd)
static OutputSpec const spec()
decltype(FFL(std::declval< cursor_t >())) cursor
void reserve(int64_t size)
auto getZDCTDCData() const
auto getStrangeTracks() const
auto getFDDRecPoints() const
auto getMCHMIDMatches() const
o2::InteractionRecord startIR
auto getDecays3BodyIdx() const
auto getTPCTRDTriggers() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
auto getMCHTrackClusters() const
auto getMCHTracksROFRecords() const
auto getCTPDigits() const
auto getCascadesIdx() const
auto getPrimaryVertexMatchedTrackRefs() const
gsl::span< const o2::trd::TriggerRecord > getTRDTriggerRecords() const
auto getCPVClusters() const
auto getFV0ChannelsData() const
auto getMFTTracksROFRecords() const
auto getCPVTriggers() const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
auto getPrimaryVertexMCLabels() const
auto getZDCEnergy() const
auto getFT0RecPoints() const
auto getITSTracksROFRecords() const
auto getMCHTracks() const
auto getFV0RecPoints() const
auto getHMPMatches() const
auto getITSTPCTRDTriggers() const
auto getFT0ChannelsData() const
auto getFDDChannelsData() const
auto getZDCBCRecData() const
auto getEMCALTriggers() const
auto getMFTTracks() const
auto getPHOSTriggers() const
static bool downsampleTsallisCharged(float pt, float factorPt, float sqrts, float &weight, float rnd, float mass=0.13957)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::uniform_int_distribution< unsigned long long > distr
std::array< uint16_t, 5 > pattern