91#include "Math/SMatrix.h"
98#include <unordered_map>
103#include "TLorentzVector.h"
111#include <nlohmann/json.hpp>
132 uint64_t classMaskEMCAL = 0, classMaskTRD = 0, classMaskPHOSCPV = 0;
133 for (
const auto& trgclass : ctpcfg->getCTPClasses()) {
134 if (trgclass.cluster->getClusterDetNames().find(
"EMC") != std::string::npos) {
135 classMaskEMCAL = trgclass.classMask;
137 if (trgclass.cluster->getClusterDetNames().find(
"PHS") != std::string::npos) {
138 classMaskPHOSCPV = trgclass.classMask;
140 if (trgclass.cluster->getClusterDetNames().find(
"TRD") != std::string::npos) {
141 classMaskTRD = trgclass.classMask;
144 LOG(info) <<
"createCTPReadout: Class Mask EMCAL -> " << classMaskEMCAL;
145 LOG(info) <<
"createCTPReadout: Class Mask PHOS/CPV -> " << classMaskPHOSCPV;
146 LOG(info) <<
"createCTPReadout: Class Mask TRD -> " << classMaskTRD;
154 std::vector<o2::emcal::TriggerRecord> triggerRecordEMCALPhys;
155 for (
const auto& trg : triggerrecordEMCAL) {
159 triggerRecordEMCALPhys.push_back(trg);
165 std::set<uint64_t> bcsMapT0triggers;
167 for (
auto& ft0RecPoint : ft0RecPoints) {
168 auto t0triggers = ft0RecPoint.getTrigger();
169 if (t0triggers.getVertex()) {
170 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
171 bcsMapT0triggers.insert(globalBC);
175 auto genericCTPDigitizer = [&bcsMapT0triggers, &ctpDigits](
auto triggerrecords, uint64_t classmask) ->
int {
179 uint32_t orbitPrev = 0;
181 for (
auto& trigger : triggerrecords) {
182 auto orbitPrevT = orbitPrev;
183 auto bcPrevT = bcPrev;
184 bcPrev = trigger.getBCData().bc;
185 orbitPrev = trigger.getBCData().orbit;
191 uint64_t globalBC = trigger.getBCData().toLong();
192 auto t0entry = bcsMapT0triggers.find(globalBC);
193 if (t0entry != bcsMapT0triggers.end()) {
194 auto ctpdig = std::find_if(ctpDigits.begin(), ctpDigits.end(), [globalBC](
const o2::ctp::CTPDigit& dig) { return static_cast<uint64_t>(dig.intRecord.toLong()) == globalBC; });
195 if (ctpdig != ctpDigits.end()) {
197 ctpdig->CTPClassMask |= std::bitset<64>(classmask);
198 LOG(
debug) <<
"createCTPReadout: Merging " << classmask <<
" CTP digits with existing digit, CTP mask " << ctpdig->CTPClassMask;
201 LOG(
debug) <<
"createCTPReadout: New CTP digit needed for class " << classmask << std::endl;
202 auto& ctpdigNew = ctpDigits.emplace_back();
203 ctpdigNew.intRecord.setFromLong(globalBC);
204 ctpdigNew.CTPClassMask = classmask;
207 LOG(warning) <<
"createCTPReadout: Found " << classmask <<
" and no MTVX:" << globalBC;
214 auto warningsTRD = genericCTPDigitizer(triggerrecordTRD, classMaskTRD);
215 auto warningsEMCAL = genericCTPDigitizer(triggerRecordEMCALPhys, classMaskEMCAL);
216 auto warningsPHOSCPV = genericCTPDigitizer(triggerrecordPHOSCPV, classMaskPHOSCPV);
218 LOG(info) <<
"createCTPReadout:# of TRD bogus triggers:" << warningsTRD;
219 LOG(info) <<
"createCTPReadout:# of EMCAL bogus triggers:" << warningsEMCAL;
220 LOG(info) <<
"createCTPReadout:# of PHOS/CPV bogus triggers:" << warningsPHOSCPV;
224 const std::vector<o2::InteractionTimeRecord>& mcRecords,
225 std::map<uint64_t, int>& bcsMap)
227 const auto& primVertices =
data.getPrimaryVertices();
228 const auto& fddRecPoints =
data.getFDDRecPoints();
229 const auto& ft0RecPoints =
data.getFT0RecPoints();
230 const auto& fv0RecPoints =
data.getFV0RecPoints();
231 const auto& caloEMCCellsTRGR =
data.getEMCALTriggers();
232 const auto& caloPHOSCellsTRGR =
data.getPHOSTriggers();
233 const auto& cpvTRGR =
data.getCPVTriggers();
234 const auto& ctpDigits =
data.getCTPDigits();
235 const auto& zdcBCRecData =
data.getZDCBCRecData();
237 bcsMap[mStartIR.
toLong()] = 1;
240 for (
auto&
rec : mcRecords) {
241 uint64_t globalBC =
rec.toLong();
242 bcsMap[globalBC] = 1;
245 for (
auto& fddRecPoint : fddRecPoints) {
246 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
247 bcsMap[globalBC] = 1;
250 for (
auto& ft0RecPoint : ft0RecPoints) {
251 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
252 bcsMap[globalBC] = 1;
255 for (
auto& fv0RecPoint : fv0RecPoints) {
256 uint64_t globalBC = fv0RecPoint.getInteractionRecord().toLong();
257 bcsMap[globalBC] = 1;
260 for (
auto& zdcRecData : zdcBCRecData) {
261 uint64_t globalBC = zdcRecData.ir.toLong();
262 bcsMap[globalBC] = 1;
265 for (
auto&
vertex : primVertices) {
266 auto& timeStamp =
vertex.getTimeStamp();
267 double tsTimeStamp = timeStamp.getTimeStamp() * 1E3;
268 uint64_t globalBC = relativeTime_to_GlobalBC(tsTimeStamp);
269 bcsMap[globalBC] = 1;
272 for (
auto& emcaltrg : caloEMCCellsTRGR) {
273 uint64_t globalBC = emcaltrg.getBCData().toLong();
274 bcsMap[globalBC] = 1;
277 for (
auto& phostrg : caloPHOSCellsTRGR) {
278 uint64_t globalBC = phostrg.getBCData().toLong();
279 bcsMap[globalBC] = 1;
282 for (
auto& cpvtrg : cpvTRGR) {
283 uint64_t globalBC = cpvtrg.getBCData().toLong();
284 bcsMap[globalBC] = 1;
287 for (
auto& ctpDigit : ctpDigits) {
288 uint64_t globalBC = ctpDigit.intRecord.toLong();
289 bcsMap[globalBC] = 1;
293 for (
auto& item : bcsMap) {
299template <
typename TracksCursorType,
typename TracksCovCursorType>
300void AODProducerWorkflowDPL::addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor,
303 tracksCursor(collisionID,
305 truncateFloatFraction(track.getX(), mTrackX),
306 truncateFloatFraction(track.getAlpha(), mTrackAlpha),
309 truncateFloatFraction(track.getSnp(), mTrackSnp),
310 truncateFloatFraction(track.getTgl(), mTrackTgl),
311 truncateFloatFraction(track.getQ2Pt(), mTrack1Pt));
313 float sY = TMath::Sqrt(track.getSigmaY2()), sZ = TMath::Sqrt(track.getSigmaZ2()), sSnp = TMath::Sqrt(track.getSigmaSnp2()),
314 sTgl = TMath::Sqrt(track.getSigmaTgl2()), sQ2Pt = TMath::Sqrt(track.getSigma1Pt2());
315 tracksCovCursor(truncateFloatFraction(sY, mTrackCovDiag),
316 truncateFloatFraction(sZ, mTrackCovDiag),
317 truncateFloatFraction(sSnp, mTrackCovDiag),
318 truncateFloatFraction(sTgl, mTrackCovDiag),
319 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
320 (Char_t)(128. * track.getSigmaZY() / (sZ * sY)),
321 (Char_t)(128. * track.getSigmaSnpY() / (sSnp * sY)),
322 (Char_t)(128. * track.getSigmaSnpZ() / (sSnp * sZ)),
323 (Char_t)(128. * track.getSigmaTglY() / (sTgl * sY)),
324 (Char_t)(128. * track.getSigmaTglZ() / (sTgl * sZ)),
325 (Char_t)(128. * track.getSigmaTglSnp() / (sTgl * sSnp)),
326 (Char_t)(128. * track.getSigma1PtY() / (sQ2Pt * sY)),
327 (Char_t)(128. * track.getSigma1PtZ() / (sQ2Pt * sZ)),
328 (Char_t)(128. * track.getSigma1PtSnp() / (sQ2Pt * sSnp)),
329 (Char_t)(128. * track.getSigma1PtTgl() / (sQ2Pt * sTgl)));
332template <
typename TracksExtraCursorType>
333void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder)
337 auto trackTimeRes = extraInfoHolder.trackTimeRes;
338 if (!extraInfoHolder.isTPConly) {
339 trackTimeRes = truncateFloatFraction(trackTimeRes, mTrackTimeError);
343 tracksExtraCursor(truncateFloatFraction(extraInfoHolder.tpcInnerParam, mTrack1Pt),
344 extraInfoHolder.flags,
345 extraInfoHolder.itsClusterSizes,
346 extraInfoHolder.tpcNClsFindable,
347 extraInfoHolder.tpcNClsFindableMinusFound,
348 extraInfoHolder.tpcNClsFindableMinusPID,
349 extraInfoHolder.tpcNClsFindableMinusCrossedRows,
350 extraInfoHolder.tpcNClsShared,
351 extraInfoHolder.trdPattern,
352 truncateFloatFraction(extraInfoHolder.itsChi2NCl, mTrackChi2),
353 truncateFloatFraction(extraInfoHolder.tpcChi2NCl, mTrackChi2),
354 truncateFloatFraction(extraInfoHolder.trdChi2, mTrackChi2),
355 truncateFloatFraction(extraInfoHolder.tofChi2, mTrackChi2),
356 truncateFloatFraction(extraInfoHolder.tpcSignal, mTrackSignal),
357 truncateFloatFraction(extraInfoHolder.trdSignal, mTrackSignal),
358 truncateFloatFraction(extraInfoHolder.length, mTrackSignal),
359 truncateFloatFraction(extraInfoHolder.tofExpMom, mTrack1Pt),
360 truncateFloatFraction(extraInfoHolder.trackEtaEMCAL, mTrackPosEMCAL),
361 truncateFloatFraction(extraInfoHolder.trackPhiEMCAL, mTrackPosEMCAL),
362 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime),
366template <
typename TracksQACursorType>
367void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor,
TrackQA& trackQAInfoHolder)
370 trackQAInfoHolder.trackID,
371 mTrackQCRetainOnlydEdx ? 0.0f : truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
372 truncateFloatFraction(trackQAInfoHolder.tpcdEdxNorm, mTrackSignal),
373 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaR,
374 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaZ,
375 trackQAInfoHolder.tpcClusterByteMask,
376 trackQAInfoHolder.tpcdEdxMax0R,
377 trackQAInfoHolder.tpcdEdxMax1R,
378 trackQAInfoHolder.tpcdEdxMax2R,
379 trackQAInfoHolder.tpcdEdxMax3R,
380 trackQAInfoHolder.tpcdEdxTot0R,
381 trackQAInfoHolder.tpcdEdxTot1R,
382 trackQAInfoHolder.tpcdEdxTot2R,
383 trackQAInfoHolder.tpcdEdxTot3R,
384 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContY,
385 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContZ,
386 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContSnp,
387 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContTgl,
388 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContQ2Pt,
389 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloY,
390 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloZ,
391 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloSnp,
392 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloTgl,
393 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloQ2Pt,
394 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdX,
395 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdZ);
398template <
typename TRDsExtraCursorType>
401 int q0s[6] = {-1}, q1s[6] = {-1}, q2s[6] = {-1};
402 float q0sCor[6] = {-1}, q1sCor[6] = {-1}, q2sCor[6] = {-1};
403 float ttgls[6] = {-999}, tphis[6] = {-999};
413 for (
int iLay{0}; iLay < 6; ++iLay) {
414 q0s[iLay] = q1s[iLay] = q2s[iLay] = -1;
415 q0sCor[iLay] = q1sCor[iLay] = q2sCor[iLay] = -1;
416 tphis[iLay] = ttgls[iLay] = -999;
417 auto trkltId = trk.getTrackletIndex(iLay);
421 const auto& tracklet = trklets[trkltId];
426 int trkltDet = tracklet.getDetector();
427 int trkltSec = trkltDet / 30;
437 auto tphi = trkC.getSnp() / std::sqrt((1.f - trkC.getSnp()) * (1.f + trkC.getSnp()));
438 auto trackletLength = std::sqrt(1.f + tphi * tphi + trkC.getTgl() * trkC.getTgl());
440 q0s[iLay] = tracklet.getQ0();
441 q1s[iLay] = tracklet.getQ1();
442 q2s[iLay] = tracklet.getQ2();
443 q0sCor[iLay] = (float)tracklet.getQ0() / cor;
444 q1sCor[iLay] = (float)tracklet.getQ1() / cor;
445 q2sCor[iLay] = (float)tracklet.getQ2() / cor;
446 ttgls[iLay] = trkC.getTgl();
450 if (trk.getIsCrossingNeighbor(iLay) && trk.getHasNeighbor()) {
453 size_t trdSelID = -1;
455 const auto& trig = trigsTRD[mCurrentTRDTrigID];
456 bool foundTRDTrigger =
false;
458 if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) {
459 trdSelID = mCurrentTRDTrigID;
460 foundTRDTrigger =
true;
463 if (mCurrentTRDTrigID < trigsTRD.size() - 1) {
464 const auto& trig = trigsTRD[mCurrentTRDTrigID + 1];
465 if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) {
466 trdSelID = mCurrentTRDTrigID + 1;
467 foundTRDTrigger =
true;
472 size_t low = 0, up = trigsTRD.size() - 1;
475 while (low <= up && !foundTRDTrigger) {
476 trdSelID = low + std::floor((up - low) / 2);
477 const auto& trig = trigsTRD[trdSelID];
478 if (trig.getFirstTracklet() > trkltId) {
481 if (trig.getFirstTracklet() + trig.getNumberOfTracklets() <= trkltId) {
484 foundTRDTrigger =
true;
489 mCurrentTRDTrigID = trdSelID;
490 const auto& trigSel = trigsTRD[trdSelID];
493 for (
const auto& trklt : trklets.subspan(trigSel.getFirstTracklet(), trigSel.getNumberOfTracklets())) {
494 if (tracklet.getTrackletWord() == trklt.getTrackletWord() || tracklet.getDetector() != trklt.getDetector()) {
497 if (std::abs(tracklet.getPadCol() - trklt.getPadCol()) <= 1 && std::abs(tracklet.getPadRow() - trklt.getPadRow()) == 1) {
499 q0s[iLay] += trklt.getQ0();
500 q1s[iLay] += trklt.getQ1();
501 q2s[iLay] += trklt.getQ2();
502 q0sCor[iLay] += (float)trklt.getQ0() / cor;
503 q1sCor[iLay] += (float)trklt.getQ1() / cor;
504 q2sCor[iLay] += (float)trklt.getQ2() / cor;
510 trdExtraCursor(trkTableIdx, q0s, q1s, q2s, q0sCor, q1sCor, q2sCor, ttgls, tphis);
513template <
typename mftTracksCursorType,
typename mftTracksCovCursorType,
typename AmbigMFTTracksCursorType>
514void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, mftTracksCovCursorType& mftTracksCovCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
516 std::uint64_t collisionBC,
const std::map<uint64_t, int>& bcsMap)
519 int bcSlice[2] = {-1, -1};
520 const auto& track =
data.getMFTTrack(trackID);
521 const auto& rof =
data.getMFTTracksROFRecords()[mMFTROFs[trackID.getIndex()]];
523 float trackTimeRes = mMFTROFrameHalfLengthNS;
524 bool needBCSlice = collisionID < 0;
525 std::uint64_t bcOfTimeRef;
527 double error = mTimeMarginTrackTime + trackTimeRes;
528 bcOfTimeRef = fillBCSlice(bcSlice, trackTime - error, trackTime + error, bcsMap);
530 bcOfTimeRef = collisionBC - mStartIR.
toLong();
535 uint64_t mftClusterSizesAndTrackFlags = track.getClusterSizes();
536 mftClusterSizesAndTrackFlags |= (track.isCA()) ? (1ULL << (60)) : 0;
538 mftTracksCursor(collisionID,
541 truncateFloatFraction(track.getZ(), mTrackX),
542 truncateFloatFraction(track.getPhi(), mTrackAlpha),
543 truncateFloatFraction(track.getTanl(), mTrackTgl),
544 truncateFloatFraction(track.getInvQPt(), mTrack1Pt),
545 mftClusterSizesAndTrackFlags,
546 truncateFloatFraction(track.getTrackChi2(), mTrackChi2),
547 truncateFloatFraction(trackTime, mTrackTime),
548 truncateFloatFraction(trackTimeRes, mTrackTimeError));
549 if (mStoreAllMFTCov) {
550 float sX = TMath::Sqrt(track.getSigma2X());
551 float sY = TMath::Sqrt(track.getSigma2Y());
552 float sPhi = TMath::Sqrt(track.getSigma2Phi());
553 float sTgl = TMath::Sqrt(track.getSigma2Tanl());
554 float sQ2Pt = TMath::Sqrt(track.getSigma2InvQPt());
556 mftTracksCovCursor(mTableTrMFTID,
557 truncateFloatFraction(sX, mTrackCovDiag),
558 truncateFloatFraction(sY, mTrackCovDiag),
559 truncateFloatFraction(sPhi, mTrackCovDiag),
560 truncateFloatFraction(sTgl, mTrackCovDiag),
561 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
562 (Char_t)(128. * track.getCovariances()(0, 1) / (sX * sY)),
563 (Char_t)(128. * track.getCovariances()(0, 2) / (sPhi * sX)),
564 (Char_t)(128. * track.getCovariances()(1, 2) / (sPhi * sY)),
565 (Char_t)(128. * track.getCovariances()(0, 3) / (sTgl * sX)),
566 (Char_t)(128. * track.getCovariances()(1, 3) / (sTgl * sY)),
567 (Char_t)(128. * track.getCovariances()(2, 3) / (sTgl * sPhi)),
568 (Char_t)(128. * track.getCovariances()(0, 4) / (sQ2Pt * sX)),
569 (Char_t)(128. * track.getCovariances()(1, 4) / (sQ2Pt * sY)),
570 (Char_t)(128. * track.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
571 (Char_t)(128. * track.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
574 ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
577template <
typename TracksCursorType,
typename TracksCovCursorType,
typename TracksExtraCursorType,
typename TracksQACursorType,
typename TRDsExtraCursor,
typename AmbigTracksCursorType,
578 typename MFTTracksCursorType,
typename MFTTracksCovCursorType,
typename AmbigMFTTracksCursorType,
579 typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename FwdTrkClsCursorType>
580void AODProducerWorkflowDPL::fillTrackTablesPerCollision(
int collisionID,
581 std::uint64_t collisionBC,
583 const gsl::span<const GIndex>& GIndices,
585 TracksCursorType& tracksCursor,
586 TracksCovCursorType& tracksCovCursor,
587 TracksExtraCursorType& tracksExtraCursor,
588 TracksQACursorType& tracksQACursor,
589 TRDsExtraCursor& trdsExtraCursor,
590 AmbigTracksCursorType& ambigTracksCursor,
591 MFTTracksCursorType& mftTracksCursor,
592 MFTTracksCovCursorType& mftTracksCovCursor,
593 AmbigMFTTracksCursorType& ambigMFTTracksCursor,
594 FwdTracksCursorType& fwdTracksCursor,
595 FwdTracksCovCursorType& fwdTracksCovCursor,
596 AmbigFwdTracksCursorType& ambigFwdTracksCursor,
597 FwdTrkClsCursorType& fwdTrkClsCursor,
598 const std::map<uint64_t, int>& bcsMap)
601 if (!GIndex::isTrackSource(
src)) {
608 mftTracksCursor.reserve(nToReserve + mftTracksCursor.lastIndex() + 1);
609 if (mStoreAllMFTCov) {
610 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex() + 1);
613 fwdTracksCursor.reserve(nToReserve + fwdTracksCursor.lastIndex() + 1);
614 fwdTracksCovCursor.reserve(nToReserve + fwdTracksCovCursor.lastIndex() + 1);
616 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex() + 1);
619 tracksCursor.reserve(nToReserve + tracksCursor.lastIndex() + 1);
620 tracksCovCursor.reserve(nToReserve + tracksCovCursor.lastIndex() + 1);
621 tracksExtraCursor.reserve(nToReserve + tracksExtraCursor.lastIndex() + 1);
623 for (
int ti =
start; ti <
end; ti++) {
624 const auto& trackIndex = GIndices[ti];
625 if (GIndex::includesSource(
src, mInputSources)) {
627 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
630 addToMFTTracksTable(mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
631 mGIDToTableMFTID.emplace(trackIndex, mTableTrMFTID);
634 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
637 addToFwdTracksTable(fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, mftTracksCovCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
638 mGIDToTableFwdID.emplace(trackIndex, mTableTrFwdID);
639 addClustersToFwdTrkClsTable(
data, fwdTrkClsCursor, trackIndex, mTableTrFwdID);
643 if (trackIndex.isAmbiguous() && mGIDToTableID.find(trackIndex) != mGIDToTableID.end()) {
648 static std::uniform_real_distribution<>
distr(0., 1.);
650 auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex,
data, bcsMap);
653 auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex,
data, bcsMap);
654 if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) {
655 trackQAInfoHolder.trackID = mTableTrID;
659 addToTracksQATable(tracksQACursor, trackQAInfoHolder);
666 if (mThinTracks && extraInfoHolder.isTPConly && !writeQAData) {
667 auto trk =
data.getTPCTrack(trackIndex);
668 if (trk.getNClusters() >= mTrackQCNCls && trk.getPt() >= mTrackQCPt) {
678 if (mThinTracks &&
src ==
GIndex::Source::TPC && mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() && mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end() && !writeQAData) {
679 mGIDToTableID.emplace(trackIndex, -1);
683 if (!extraInfoHolder.isTPConly && extraInfoHolder.trackTimeRes < 0.f) {
684 LOG(warning) <<
"Barrel track " << trackIndex <<
" has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime
685 <<
" timeErr=" << extraInfoHolder.trackTimeRes <<
" BCSlice: " << extraInfoHolder.bcSlice[0] <<
":" << extraInfoHolder.bcSlice[1];
688 const auto& trOrig =
data.getTrackParam(trackIndex);
690 if (mPropTracks && trOrig.getX() < mMaxPropXiu &&
691 mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() &&
692 mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end()) {
693 auto trackPar(trOrig);
694 isProp = propagateTrackToPV(trackPar,
data, collisionID);
696 addToTracksTable(tracksCursor, tracksCovCursor, trackPar, collisionID,
aod::track::Track);
702 addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
704 addToTRDsExtra(
data, trdsExtraCursor, trackIndex, mTableTrID);
707 if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
708 ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
710 mGIDToTableID.emplace(trackIndex, mTableTrID);
716 if (collisionID < 0) {
720 auto sTracks =
data.getStrangeTracks();
721 tracksCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCursor.lastIndex() + 1);
722 tracksCovCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCovCursor.lastIndex() + 1);
723 tracksExtraCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksExtraCursor.lastIndex() + 1);
724 for (
int iS{mVertexStrLUT[collisionID]}; iS < mVertexStrLUT[collisionID + 1]; ++iS) {
725 auto& collStrTrk = mCollisionStrTrk[iS];
726 auto& sTrk = sTracks[collStrTrk.second];
727 TrackExtraInfo extraInfo;
728 extraInfo.itsChi2NCl = sTrk.mTopoChi2;
729 extraInfo.itsClusterSizes = sTrk.getClusterSizes();
731 addToTracksExtraTable(tracksExtraCursor, extraInfo);
732 mStrTrkIndices[collStrTrk.second] = mTableTrID;
739 const auto& mchmidMatches =
data.getMCHMIDMatches();
744 for (
int ti =
start; ti <
end; ti++) {
745 auto& trackIndex = GIndices[ti];
746 if (GIndex::includesSource(
src, mInputSources)) {
748 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
751 mGIDToTableMFTID.emplace(trackIndex, mIndexMFTID);
752 mIndexTableMFT[trackIndex.getIndex()] = mIndexMFTID;
755 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
758 mGIDToTableFwdID.emplace(trackIndex, mIndexFwdID);
760 mIndexTableFwd[trackIndex.getIndex()] = mIndexFwdID;
762 const auto& mchmidMatch = mchmidMatches[trackIndex.getIndex()];
763 const auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
764 mIndexTableFwd[mchTrackID] = mIndexFwdID;
773template <
typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename mftTracksCovCursorType>
774void AODProducerWorkflowDPL::addToFwdTracksTable(FwdTracksCursorType& fwdTracksCursor, FwdTracksCovCursorType& fwdTracksCovCursor,
775 AmbigFwdTracksCursorType& ambigFwdTracksCursor, mftTracksCovCursorType& mftTracksCovCursor,
GIndex trackID,
777 const std::map<uint64_t, int>& bcsMap)
779 const auto& mchTracks =
data.getMCHTracks();
780 const auto& midTracks =
data.getMIDTracks();
781 const auto& mchmidMatches =
data.getMCHMIDMatches();
782 const auto& mchClusters =
data.getMCHTrackClusters();
784 FwdTrackInfo fwdInfo;
785 FwdTrackCovInfo fwdCovInfo;
786 int bcSlice[2] = {-1, -1};
789 auto getMCHBitMap = [&](
int mchTrackID) {
790 if (mchTrackID != -1) {
791 const auto& mchTrack = mchTracks[mchTrackID];
792 int first = mchTrack.getFirstClusterIdx();
793 int last = mchTrack.getLastClusterIdx();
794 for (
int i =
first;
i <= last;
i++) {
795 const auto& cluster = mchClusters[
i];
796 int chamberId = cluster.getChamberId();
797 fwdInfo.mchBitMap |= 1 << chamberId;
802 auto getMIDBitMapBoards = [&](
int midTrackID) {
803 if (midTrackID != -1) {
804 const auto& midTrack = midTracks[midTrackID];
805 fwdInfo.midBitMap = midTrack.getHitMap();
806 fwdInfo.midBoards = midTrack.getEfficiencyWord();
810 auto extrapMCHTrack = [&](
int mchTrackID) {
811 const auto& track = mchTracks[mchTrackID];
819 float vx = 0, vy = 0, vz = 0;
820 if (collisionID >= 0) {
821 const auto&
v =
data.getPrimaryVertex(collisionID);
827 o2::mch::TrackParam trackParamAtVertex(track.getZ(), track.getParameters(), track.getCovariances());
850 double dca = std::sqrt(dcaX * dcaX + dcaY * dcaY);
855 double dpdca = track.getP() * dca;
856 double dchi2 = track.getChi2OverNDF();
858 auto fwdmuon = mMatching.
MCHtoFwd(trackParamAtVertex);
860 fwdInfo.x = fwdmuon.
getX();
861 fwdInfo.y = fwdmuon.getY();
862 fwdInfo.z = fwdmuon.getZ();
863 fwdInfo.phi = fwdmuon.getPhi();
864 fwdInfo.tanl = fwdmuon.getTgl();
865 fwdInfo.invqpt = fwdmuon.getInvQPt();
866 fwdInfo.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs);
867 fwdInfo.chi2 = dchi2;
868 fwdInfo.pdca = dpdca;
869 fwdInfo.nClusters = track.getNClusters();
871 fwdCovInfo.sigX = TMath::Sqrt(fwdmuon.getCovariances()(0, 0));
872 fwdCovInfo.sigY = TMath::Sqrt(fwdmuon.getCovariances()(1, 1));
873 fwdCovInfo.sigPhi = TMath::Sqrt(fwdmuon.getCovariances()(2, 2));
874 fwdCovInfo.sigTgl = TMath::Sqrt(fwdmuon.getCovariances()(3, 3));
875 fwdCovInfo.sig1Pt = TMath::Sqrt(fwdmuon.getCovariances()(4, 4));
876 fwdCovInfo.rhoXY = (Char_t)(128. * fwdmuon.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
877 fwdCovInfo.rhoPhiX = (Char_t)(128. * fwdmuon.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
878 fwdCovInfo.rhoPhiY = (Char_t)(128. * fwdmuon.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
879 fwdCovInfo.rhoTglX = (Char_t)(128. * fwdmuon.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
880 fwdCovInfo.rhoTglY = (Char_t)(128. * fwdmuon.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
881 fwdCovInfo.rhoTglPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
882 fwdCovInfo.rho1PtX = (Char_t)(128. * fwdmuon.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
883 fwdCovInfo.rho1PtY = (Char_t)(128. * fwdmuon.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
884 fwdCovInfo.rho1PtPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
885 fwdCovInfo.rho1PtTgl = (Char_t)(128. * fwdmuon.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
891 int mchTrackID = trackID.getIndex();
892 getMCHBitMap(mchTrackID);
893 if (!extrapMCHTrack(mchTrackID)) {
894 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
897 const auto& rof =
data.getMCHTracksROFRecords()[mMCHROFs[mchTrackID]];
898 auto time = rof.getTimeMUS(mStartIR).first;
899 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
900 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
903 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
904 auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
905 if (!extrapMCHTrack(mchTrackID)) {
906 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
908 auto midTrackID = mchmidMatch.getMIDRef().getIndex();
909 fwdInfo.chi2matchmchmid = mchmidMatch.getMatchChi2OverNDF();
910 getMCHBitMap(mchTrackID);
911 getMIDBitMapBoards(midTrackID);
912 auto time = mchmidMatch.getTimeMUS(mStartIR).first;
913 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
914 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
916 const auto& track =
data.getGlobalFwdTrack(trackID);
917 const auto& mftTracks =
data.getMFTTracks();
918 const auto& mfttrack = mftTracks[track.getMFTTrackID()];
919 if (!extrapMCHTrack(track.getMCHTrackID())) {
920 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", track.getMCHTrackID());
922 fwdInfo.x = track.getX();
923 fwdInfo.y = track.getY();
924 fwdInfo.z = track.getZ();
925 fwdInfo.phi = track.getPhi();
926 fwdInfo.tanl = track.getTanl();
927 fwdInfo.invqpt = track.getInvQPt();
928 fwdInfo.chi2 = track.getTrackChi2();
930 fwdInfo.chi2matchmchmid = track.getMIDMatchingChi2();
931 fwdInfo.chi2matchmchmft = track.getMFTMCHMatchingChi2();
932 fwdInfo.matchscoremchmft = track.getMFTMCHMatchingScore();
933 fwdInfo.matchmfttrackid = mIndexTableMFT[track.getMFTTrackID()];
934 fwdInfo.matchmchtrackid = mIndexTableFwd[track.getMCHTrackID()];
935 fwdInfo.trackTime = track.getTimeMUS().getTimeStamp() * 1.e3;
936 fwdInfo.trackTimeRes = track.getTimeMUS().getTimeStampError() * 1.e3;
938 getMCHBitMap(track.getMCHTrackID());
939 getMIDBitMapBoards(track.getMIDTrackID());
941 fwdCovInfo.sigX = TMath::Sqrt(track.getCovariances()(0, 0));
942 fwdCovInfo.sigY = TMath::Sqrt(track.getCovariances()(1, 1));
943 fwdCovInfo.sigPhi = TMath::Sqrt(track.getCovariances()(2, 2));
944 fwdCovInfo.sigTgl = TMath::Sqrt(track.getCovariances()(3, 3));
945 fwdCovInfo.sig1Pt = TMath::Sqrt(track.getCovariances()(4, 4));
946 fwdCovInfo.rhoXY = (Char_t)(128. * track.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
947 fwdCovInfo.rhoPhiX = (Char_t)(128. * track.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
948 fwdCovInfo.rhoPhiY = (Char_t)(128. * track.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
949 fwdCovInfo.rhoTglX = (Char_t)(128. * track.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
950 fwdCovInfo.rhoTglY = (Char_t)(128. * track.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
951 fwdCovInfo.rhoTglPhi = (Char_t)(128. * track.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
952 fwdCovInfo.rho1PtX = (Char_t)(128. * track.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
953 fwdCovInfo.rho1PtY = (Char_t)(128. * track.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
954 fwdCovInfo.rho1PtPhi = (Char_t)(128. * track.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
955 fwdCovInfo.rho1PtTgl = (Char_t)(128. * track.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
959 float sX = TMath::Sqrt(mfttrack.getSigma2X()), sY = TMath::Sqrt(mfttrack.getSigma2Y()), sPhi = TMath::Sqrt(mfttrack.getSigma2Phi()),
960 sTgl = TMath::Sqrt(mfttrack.getSigma2Tanl()), sQ2Pt = TMath::Sqrt(mfttrack.getSigma2InvQPt());
962 if (!mStoreAllMFTCov) {
963 mftTracksCovCursor(fwdInfo.matchmfttrackid,
964 truncateFloatFraction(sX, mTrackCovDiag),
965 truncateFloatFraction(sY, mTrackCovDiag),
966 truncateFloatFraction(sPhi, mTrackCovDiag),
967 truncateFloatFraction(sTgl, mTrackCovDiag),
968 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
969 (Char_t)(128. * mfttrack.getCovariances()(0, 1) / (sX * sY)),
970 (Char_t)(128. * mfttrack.getCovariances()(0, 2) / (sPhi * sX)),
971 (Char_t)(128. * mfttrack.getCovariances()(1, 2) / (sPhi * sY)),
972 (Char_t)(128. * mfttrack.getCovariances()(0, 3) / (sTgl * sX)),
973 (Char_t)(128. * mfttrack.getCovariances()(1, 3) / (sTgl * sY)),
974 (Char_t)(128. * mfttrack.getCovariances()(2, 3) / (sTgl * sPhi)),
975 (Char_t)(128. * mfttrack.getCovariances()(0, 4) / (sQ2Pt * sX)),
976 (Char_t)(128. * mfttrack.getCovariances()(1, 4) / (sQ2Pt * sY)),
977 (Char_t)(128. * mfttrack.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
978 (Char_t)(128. * mfttrack.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
982 std::uint64_t bcOfTimeRef;
983 bool needBCSlice = collisionID < 0;
985 float err = mTimeMarginTrackTime + fwdInfo.trackTimeRes;
986 bcOfTimeRef = fillBCSlice(bcSlice, fwdInfo.trackTime - err, fwdInfo.trackTime + err, bcsMap);
988 bcOfTimeRef = collisionBC - mStartIR.
toLong();
992 fwdTracksCursor(collisionID,
996 truncateFloatFraction(fwdInfo.z, mTrackX),
997 truncateFloatFraction(fwdInfo.phi, mTrackAlpha),
998 truncateFloatFraction(fwdInfo.tanl, mTrackTgl),
999 truncateFloatFraction(fwdInfo.invqpt, mTrack1Pt),
1001 truncateFloatFraction(fwdInfo.pdca, mTrackX),
1002 truncateFloatFraction(fwdInfo.rabs, mTrackX),
1003 truncateFloatFraction(fwdInfo.chi2, mTrackChi2),
1004 truncateFloatFraction(fwdInfo.chi2matchmchmid, mTrackChi2),
1005 truncateFloatFraction(fwdInfo.chi2matchmchmft, mTrackChi2),
1006 truncateFloatFraction(fwdInfo.matchscoremchmft, mTrackChi2),
1007 fwdInfo.matchmfttrackid,
1008 fwdInfo.matchmchtrackid,
1012 truncateFloatFraction(fwdInfo.trackTime, mTrackTime),
1013 truncateFloatFraction(fwdInfo.trackTimeRes, mTrackTimeError));
1015 fwdTracksCovCursor(truncateFloatFraction(fwdCovInfo.sigX, mTrackCovDiag),
1016 truncateFloatFraction(fwdCovInfo.sigY, mTrackCovDiag),
1017 truncateFloatFraction(fwdCovInfo.sigPhi, mTrackCovDiag),
1018 truncateFloatFraction(fwdCovInfo.sigTgl, mTrackCovDiag),
1019 truncateFloatFraction(fwdCovInfo.sig1Pt, mTrackCovDiag),
1025 fwdCovInfo.rhoTglPhi,
1028 fwdCovInfo.rho1PtPhi,
1029 fwdCovInfo.rho1PtTgl);
1032 ambigFwdTracksCursor(mTableTrFwdID, bcSlice);
1037void AODProducerWorkflowDPL::updateMCHeader(MCCollisionCursor& collisionCursor,
1038 XSectionCursor& xSectionCursor,
1039 PdfInfoCursor& pdfInfoCursor,
1040 HeavyIonCursor& heavyIonCursor,
1041 const MCEventHeader& header,
1053 auto genID = updateMCCollisions(collisionCursor,
1059 mCollisionPosition);
1060 mXSectionUpdate = (updateHepMCXSection(xSectionCursor,
1065 ? HepMCUpdate::always
1066 : HepMCUpdate::never);
1067 mPdfInfoUpdate = (updateHepMCPdfInfo(pdfInfoCursor,
1072 ? HepMCUpdate::always
1073 : HepMCUpdate::never);
1074 mHeavyIonUpdate = (updateHepMCHeavyIon(heavyIonCursor,
1079 ? HepMCUpdate::always
1080 : HepMCUpdate::never);
1085 store.resize(Nsources);
1086 for (
int s = 0;
s < Nsources; ++
s) {
1087 store[
s].resize(NEvents);
1093 for (
auto s = 0U;
s < store.size(); ++
s) {
1094 for (
auto e = 0U; e < store[
s].size(); ++e) {
1095 store[
s][e].clear();
1104 LOG(warn) <<
"trackID is smaller than 0. Neglecting";
1107 if (useSigFilt &&
source == 0) {
1115 MCParticlesCursor& mcParticlesCursor,
1116 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
1117 const gsl::span<const GIndex>& GIndices,
1119 const std::vector<MCColInfo>& mcColToEvSrc)
1123 for (
auto& p : mcColToEvSrc) {
1124 NSources = std::max(p.sourceID, NSources);
1125 NEvents = std::max(p.eventID, NEvents);
1129 LOG(info) <<
" number of events " << NEvents;
1130 LOG(info) <<
" number of sources " << NSources;
1133 std::vector<int> particleIDsToKeep;
1135 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
1136 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
1137 if (!mcLabel.isValid()) {
1140 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
1144 for (
auto& trackRef : primVer2TRefs) {
1148 for (
int ti =
start; ti <
end; ti++) {
1149 auto& trackIndex = GIndices[ti];
1150 if (GIndex::includesSource(
src, mInputSources)) {
1151 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1152 if (!mcTruth.isValid()) {
1155 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1157 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1166 for (
auto& mcLabel : labelsTOF) {
1167 if (!mcLabel.isValid()) {
1170 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
1179 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1180 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1181 if (!mcTruth.isValid()) {
1184 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1188 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1189 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1190 if (!mcTruth.isValid()) {
1193 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1196 using namespace aodmchelpers;
1200 for (
auto& colInfo : mcColToEvSrc) {
1201 int event = colInfo.eventID;
1202 int source = colInfo.sourceID;
1203 int mcColId = colInfo.colIndex;
1205 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1224template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1225void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1226 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1227 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1229 const gsl::span<const GIndex>& primVerGIs,
1242 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex() + 1);
1243 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex() + 1);
1244 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex() + 1);
1245 for (
int ti =
start; ti <
end; ti++) {
1246 const auto trackIndex = primVerGIs[ti];
1249 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1250 auto entry = mp.find(trackIndex);
1251 if (
entry == mp.end() ||
entry->second == -1) {
1258 if (GIndex::includesSource(
src, mInputSources)) {
1259 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1260 MCLabels labelHolder{};
1265 if (mcTruth.isValid()) {
1266 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1268 if (mcTruth.isFake()) {
1269 labelHolder.fwdLabelMask |= (0x1 << 7);
1271 if (mcTruth.isNoise()) {
1272 labelHolder.fwdLabelMask |= (0x1 << 6);
1275 mcMFTTrackLabelCursor(labelHolder.labelID,
1276 labelHolder.fwdLabelMask);
1278 mcFwdTrackLabelCursor(labelHolder.labelID,
1279 labelHolder.fwdLabelMask);
1282 if (!needToStore(mGIDToTableID)) {
1285 if (mcTruth.isValid()) {
1286 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1287 if (mcTruth.isFake()) {
1288 labelHolder.labelMask |= (0x1 << 15);
1291 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1294 labelHolder.labelMask |= (0x1 << 13);
1299 auto itsGID =
data.getITSContributorGID(trackIndex);
1300 auto itsSource = itsGID.getSource();
1302 auto& itsTrack =
data.getITSTrack(itsGID);
1303 for (
unsigned int iL = 0; iL < 7; ++iL) {
1304 if (itsTrack.isFakeOnLayer(iL)) {
1305 labelHolder.labelMask |= (0x1 << iL);
1309 labelHolder.labelMask |= (
data.getTrackMCLabel(itsGID).isFake() << 12);
1313 }
else if (mcTruth.isNoise()) {
1314 labelHolder.labelMask |= (0x1 << 14);
1316 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1323 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1325 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1326 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex() + 1);
1327 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1328 auto& collStrTrk = mCollisionStrTrk[iS];
1329 auto&
label = sTrackLabels[collStrTrk.second];
1330 MCLabels labelHolder;
1331 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1332 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1333 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1338template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1339void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1346 v0Cursor.reserve(v0s.size());
1348 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1349 const auto&
v0 = v0s[iv0];
1350 auto trPosID =
v0.getProngID(0);
1351 auto trNegID =
v0.getProngID(1);
1352 uint8_t v0flags =
v0.getBits();
1353 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1354 auto item = mGIDToTableID.find(trPosID);
1355 if (item != mGIDToTableID.end()) {
1356 posTableIdx = item->second;
1358 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1360 item = mGIDToTableID.find(trNegID);
1361 if (item != mGIDToTableID.end()) {
1362 negTableIdx = item->second;
1364 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1366 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1367 if (itemV == mVtxToTableCollID.end()) {
1368 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1370 collID = itemV->second;
1372 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1373 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1374 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1379 cascadeCursor.reserve(cascades.size());
1380 for (
auto& cascade : cascades) {
1381 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1382 if (itemV0 == mV0ToTableID.end()) {
1385 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1386 auto bachelorID = cascade.getBachelorID();
1387 auto item = mGIDToTableID.find(bachelorID);
1388 if (item != mGIDToTableID.end()) {
1389 bachTableIdx = item->second;
1391 LOG(warn) <<
"Could not find a bachelor track index";
1394 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1395 if (itemV != mVtxToTableCollID.end()) {
1396 collID = itemV->second;
1398 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1401 cascadeCursor(collID, v0tableID, bachTableIdx);
1405 decay3BodyCursor.reserve(decays3Body.size());
1406 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1407 const auto& decay3Body = decays3Body[i3Body];
1409 decay3Body.getProngID(0),
1410 decay3Body.getProngID(1),
1411 decay3Body.getProngID(2)};
1412 int tableIdx[3]{-1, -1, -1}, collID = -1;
1413 bool missing{
false};
1414 for (
int i{0};
i < 3; ++
i) {
1415 auto item = mGIDToTableID.find(trIDs[
i]);
1416 if (item != mGIDToTableID.end()) {
1417 tableIdx[
i] = item->second;
1419 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1423 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1424 if (itemV == mVtxToTableCollID.end()) {
1425 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1428 collID = itemV->second;
1433 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1437template <
typename FwdTrkClsCursorType>
1444 int mchTrackID = -1;
1446 mchTrackID = trackID.getIndex();
1448 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1449 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1452 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1453 const auto& mchTrack = mchTracks[mchTrackID];
1454 int first = mchTrack.getFirstClusterIdx();
1455 int last = mchTrack.getLastClusterIdx();
1456 fwdTrkClsCursor.reserve(last -
first + 1 + fwdTrkClsCursor.lastIndex() + 1);
1457 for (
int i =
first;
i <= last;
i++) {
1458 const auto& cluster = mchClusters[
i];
1459 fwdTrkClsCursor(fwdTrackId,
1460 truncateFloatFraction(cluster.x, mMuonCl),
1461 truncateFloatFraction(cluster.y, mMuonCl),
1462 truncateFloatFraction(cluster.z, mMuonCl),
1463 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1468template <
typename HMPCursorType>
1473 hmpCursor.reserve(hmpMatches.size());
1476 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1478 const auto&
match = hmpMatches[iHmp];
1480 float xTrk, yTrk, theta,
phi;
1484 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1487 auto photChargeVec =
match.getPhotCharge();
1489 float photChargeVec2[10];
1491 for (Int_t
i = 0;
i < 10;
i++) {
1492 photChargeVec2[
i] = photChargeVec[
i];
1494 auto tref = mGIDToTableID.find(
match.getTrackRef());
1495 if (tref != mGIDToTableID.end()) {
1496 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1498 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1510 mCollisionStrTrk.clear();
1512 mVertexStrLUT.clear();
1514 for (
auto& sTrk : recoData.getStrangeTracks()) {
1518 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1520 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1522 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1524 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1525 mVertexStrLUT[vtxId]++;
1527 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1530 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1531 mStrTrkIndices.clear();
1532 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1535template <
typename V0C,
typename CC,
typename D3BC>
1538 int itsTableIdx = -1;
1544 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1554 v0Curs.reserve(nV0);
1555 cascCurs.reserve(nCasc);
1556 d3BodyCurs.reserve(nD3Body);
1558 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1560 auto item = mGIDToTableID.find(ITSIndex);
1561 if (item != mGIDToTableID.end()) {
1562 itsTableIdx = item->second;
1564 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1568 v0Curs(mStrTrkIndices[sTrkID++],
1578 sTrk.getAverageClusterSize());
1580 cascCurs(mStrTrkIndices[sTrkID++],
1590 sTrk.getAverageClusterSize());
1592 d3BodyCurs(mStrTrkIndices[sTrkID++],
1602 sTrk.getAverageClusterSize());
1609 const auto& tpcTracks =
data.getTPCTracks();
1610 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1611 const auto& tpcClusShMap =
data.clusterShMapTPC;
1612 const auto& tpcClusAcc =
data.getTPCClusters();
1613 constexpr int maxRows = 152;
1614 constexpr int neighbour = 2;
1615 int ntr = tpcTracks.size();
1616 mTPCCounters.clear();
1617 mTPCCounters.resize(ntr);
1619 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1620#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1622 for (
int itr = 0; itr < ntr; itr++) {
1623 std::array<bool, maxRows> clMap{}, shMap{};
1624 uint8_t sectorIndex, rowIndex;
1625 uint32_t clusterIndex;
1626 auto&
counters = mTPCCounters[itr];
1627 const auto&
track = tpcTracks[itr];
1628 for (
int i = 0;
i <
track.getNClusterReferences();
i++) {
1629 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex,
track.getClusterRef());
1630 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1631 clMap[rowIndex] =
true;
1633 if (!shMap[rowIndex]) {
1636 shMap[rowIndex] =
true;
1640 for (
int i = 0;
i < maxRows;
i++) {
1645 }
else if ((
i - last) <= neighbour) {
1648 int lim = std::min(
i + 1 + neighbour, maxRows);
1649 for (
int j =
i + 1;
j < lim;
j++) {
1664 if (
track.getTrackletIndex(il) != -1) {
1668 if (
track.getHasNeighbor()) {
1671 if (
track.getHasPadrowCrossing()) {
1677template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1678void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1679 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1681 auto inputEvent = caloHandler.buildEvent(eventID);
1682 auto cellsInEvent = inputEvent.mCells;
1683 auto cellMClabels = inputEvent.mMCCellLabels;
1684 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex() + 1);
1685 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex() + 1);
1687 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex() + 1);
1689 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1690 caloCellCursor(bcID,
1694 cellsInEvent[iCell].
getType(),
1708 std::vector<int32_t> particleIds;
1709 std::vector<float> amplitudeFraction;
1710 if (!mEMCselectLeading) {
1711 particleIds.reserve(cellMClabels.size());
1712 amplitudeFraction.reserve(cellMClabels.size());
1714 float tmpMaxAmplitude = 0;
1715 int32_t tmpindex = 0;
1716 for (
auto& mclabel : cellMClabels[iCell]) {
1718 if (mclabel.isValid()) {
1719 if (mEMCselectLeading) {
1720 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1722 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1723 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1724 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1725 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1729 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1730 auto iter = trackStore.find(mclabel.getTrackID());
1731 if (iter != trackStore.end()) {
1732 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1733 particleIds.emplace_back(iter->second);
1735 particleIds.emplace_back(-1);
1736 amplitudeFraction.emplace_back(0.f);
1737 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1738 if (mMCKineReader) {
1739 auto mctrack = mMCKineReader->
getTrack(mclabel);
1742 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1748 if (mEMCselectLeading) {
1749 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1750 particleIds.emplace_back(tmpindex);
1752 if (particleIds.size() == 0) {
1753 particleIds.emplace_back(-1);
1754 amplitudeFraction.emplace_back(0.f);
1756 mcCaloCellLabelCursor(particleIds,
1763template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1764void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1765 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1769 auto caloEMCCells =
data.getEMCALCells();
1770 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1771 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1773 auto caloPHOSCells =
data.getPHOSCells();
1774 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1775 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1779 caloPHOSCellsTRGR = {};
1780 mcCaloPHOSCellLabels = {};
1785 caloEMCCellsTRGR = {};
1786 mcCaloEMCCellLabels = {};
1793 emcEventHandler.
reset();
1794 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1797 phsEventHandler.
reset();
1798 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1804 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1806 caloEvents.reserve(emcNEvents + phsNEvents);
1808 for (
int iev = 0; iev < emcNEvents; ++iev) {
1810 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1813 for (
int iev = 0; iev < phsNEvents; ++iev) {
1815 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1818 std::sort(caloEvents.begin(), caloEvents.end(),
1819 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1822 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1823 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1824 int8_t caloType = std::get<1>(caloEvents[
i]);
1825 int eventID = std::get<2>(caloEvents[
i]);
1826 auto item = bcsMap.find(globalBC);
1828 if (item != bcsMap.end()) {
1829 bcID = item->second;
1831 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1833 if (caloType == 0) {
1834 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1836 if (caloType == 1) {
1837 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1848 mLPMProdTag = ic.
options().
get<std::string>(
"lpmp-prod-tag");
1849 mAnchorPass = ic.
options().
get<std::string>(
"anchor-pass");
1850 mAnchorProd = ic.
options().
get<std::string>(
"anchor-prod");
1851 mUser = ic.
options().
get<std::string>(
"created-by");
1852 mRecoPass = ic.
options().
get<std::string>(
"reco-pass");
1853 mAODParent = ic.
options().
get<std::string>(
"aod-parent");
1854 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1855 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1856 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1857 mRunNumber = ic.
options().
get<
int>(
"run-number");
1858 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1859 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1860 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1861 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1862 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1863 mMaxPropXiu = ic.
options().
get<
float>(
"propagate-tracks-max-xiu");
1864 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1865 mStoreAllMFTCov = ic.
options().
get<
bool>(
"store-all-mft-cov");
1866 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1867 mStreamerFlags.
set(
s);
1868 if (mStreamerFlags) {
1869 LOGP(info,
"Writing streamer data with mask:");
1870 LOG(info) << mStreamerFlags;
1872 LOGP(warn,
"Specified non-default empty streamer mask!");
1875 mTrackQCKeepGlobalTracks = ic.
options().
get<
bool>(
"trackqc-keepglobaltracks");
1876 mTrackQCRetainOnlydEdx = ic.
options().
get<
bool>(
"trackqc-retainonlydedx");
1877 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1878 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1879 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1880 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1881 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1882 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1883 LOGP(info,
"Using random device for seeding");
1884 std::random_device
rd;
1885 std::array<int, std::mt19937::state_size> seed_data{};
1886 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1887 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1888 mGenerator = std::mt19937(seq);
1890 LOGP(info,
"Using seed {} for sampling", seed);
1891 mGenerator.seed(seed);
1894 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1897 LOG(info) <<
"OpenMP is disabled";
1899 if (mTFNumber == -1L) {
1900 LOG(info) <<
"TFNumber will be obtained from CCDB";
1902 if (mRunNumber == -1L) {
1903 LOG(info) <<
"The Run number will be obtained from DPL headers";
1906 mUseSigFiltMC = ic.
options().
get<
bool>(
"mc-signal-filt");
1908 mCollectConfigFiles = ic.
options().
get<
bool>(
"collect-config-files");
1911 if (mTruncate != 1) {
1912 LOG(info) <<
"Truncation is not used!";
1913 mCollisionPosition = 0xFFFFFFFF;
1914 mCollisionPositionCov = 0xFFFFFFFF;
1915 mTrackX = 0xFFFFFFFF;
1916 mTrackAlpha = 0xFFFFFFFF;
1917 mTrackSnp = 0xFFFFFFFF;
1918 mTrackTgl = 0xFFFFFFFF;
1919 mTrack1Pt = 0xFFFFFFFF;
1920 mTrackChi2 = 0xFFFFFFFF;
1921 mTrackCovDiag = 0xFFFFFFFF;
1922 mTrackCovOffDiag = 0xFFFFFFFF;
1923 mTrackSignal = 0xFFFFFFFF;
1924 mTrackTime = 0xFFFFFFFF;
1925 mTPCTime0 = 0xFFFFFFFF;
1926 mTrackTimeError = 0xFFFFFFFF;
1927 mTrackPosEMCAL = 0xFFFFFFFF;
1928 mTracklets = 0xFFFFFFFF;
1929 mMcParticleW = 0xFFFFFFFF;
1930 mMcParticlePos = 0xFFFFFFFF;
1931 mMcParticleMom = 0xFFFFFFFF;
1932 mCaloAmp = 0xFFFFFFFF;
1933 mCaloTime = 0xFFFFFFFF;
1934 mCPVPos = 0xFFFFFFFF;
1935 mCPVAmpl = 0xFFFFFFFF;
1936 mMuonTr1P = 0xFFFFFFFF;
1937 mMuonTrThetaX = 0xFFFFFFFF;
1938 mMuonTrThetaY = 0xFFFFFFFF;
1939 mMuonTrZmu = 0xFFFFFFFF;
1940 mMuonTrBend = 0xFFFFFFFF;
1941 mMuonTrNonBend = 0xFFFFFFFF;
1942 mMuonTrCov = 0xFFFFFFFF;
1943 mMuonCl = 0xFFFFFFFF;
1944 mMuonClErr = 0xFFFFFFFF;
1945 mV0Time = 0xFFFFFFFF;
1946 mV0ChannelTime = 0xFFFFFFFF;
1947 mFDDTime = 0xFFFFFFFF;
1948 mFDDChannelTime = 0xFFFFFFFF;
1949 mT0Time = 0xFFFFFFFF;
1950 mT0ChannelTime = 0xFFFFFFFF;
1951 mV0Amplitude = 0xFFFFFFFF;
1952 mFDDAmplitude = 0xFFFFFFFF;
1953 mT0Amplitude = 0xFFFFFFFF;
1957 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1960 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1963 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1964 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1965 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1966 : HepMCUpdate::anyKey);
1967 mXSectionUpdate = when;
1968 mPdfInfoUpdate = when;
1969 mHeavyIonUpdate = when;
1973 if (mStreamerFlags) {
1974 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1980void add_additional_meta_info(std::vector<TString>& keys, std::vector<TString>&
values)
1983 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1984 if (aod_external_meta_info_file !=
nullptr) {
1985 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1986 if (std::filesystem::exists(aod_external_meta_info_file)) {
1987 std::ifstream input_file(aod_external_meta_info_file);
1989 nlohmann::json json_data;
1991 input_file >> json_data;
1992 }
catch (nlohmann::json::parse_error& e) {
1993 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1994 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1995 std::cerr <<
"Byte position: " << e.byte <<
"\n";
1999 for (
const auto& [
key,
value] : json_data.items()) {
2000 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
2001 keys.push_back(
key.c_str());
2012 mTimer.Start(
false);
2015 updateTimeDependentParams(pc);
2040 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
2041 if (mCTPReadout == 1) {
2042 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
2043 createCTPReadout(recoData, ctpDigitsCreated, pc);
2044 LOG(info) <<
"CTP : ctpreadout created from AOD";
2045 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
2047 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
2048 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
2049 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
2050 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
2051 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
2052 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
2054 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
2058 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
2059 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
2060 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
2061 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
2062 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
2063 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
2064 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
2065 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
2066 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
2067 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
2068 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
2069 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
2070 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
2071 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
2072 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
2073 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
2074 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
2075 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
2076 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
2077 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
2078 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
2079 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
2080 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
2081 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
2082 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
2083 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
2084 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
2085 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
2086 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
2087 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
2088 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
2089 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
2090 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
2094 if (mEnableTRDextra) {
2095 trdExtraCursor = createTableCursor<o2::aod::TRDsExtra>(pc);
2110 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
2111 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
2112 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
2113 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
2114 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
2115 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
2116 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
2117 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
2118 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
2119 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
2122 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
2124 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
2126 mMCKineReader = mcReader.get();
2127 std::map<uint64_t, int> bcsMap;
2128 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
2129 if (!primVer2TRefs.empty()) {
2130 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
2133 mBCLookup.
init(bcsMap);
2136 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
2137 if (mTFNumber == -1L) {
2139 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
2141 tfNumber = mTFNumber;
2144 std::vector<float> aAmplitudes, aTimes;
2145 std::vector<uint8_t> aChannels;
2146 fv0aCursor.reserve(fv0RecPoints.size());
2147 for (
auto& fv0RecPoint : fv0RecPoints) {
2148 aAmplitudes.clear();
2151 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
2152 for (
auto& channel : channelData) {
2153 if (channel.charge > 0) {
2154 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
2155 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
2156 aChannels.push_back(channel.channel);
2159 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
2160 auto item = bcsMap.find(
bc);
2162 if (item != bcsMap.end()) {
2163 bcID = item->second;
2165 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
2170 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
2171 fv0RecPoint.getTrigger().getTriggersignals());
2173 if (mEnableFITextra) {
2174 fv0aExtraCursor(bcID,
2179 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
2180 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
2181 zdcCursor.reserve(zdcBCRecData.size());
2182 for (
auto zdcRecData : zdcBCRecData) {
2183 uint64_t
bc = zdcRecData.ir.toLong();
2184 auto item = bcsMap.find(
bc);
2186 if (item != bcsMap.end()) {
2187 bcID = item->second;
2189 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2191 int fe, ne, ft, nt, fi, ni;
2192 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2194 zdcChannelsE.clear();
2195 zdcAmplitudes.clear();
2197 zdcChannelsT.clear();
2198 for (
int ie = 0; ie < ne; ie++) {
2199 auto& zdcEnergyData = zdcEnergies[fe + ie];
2200 zdcEnergy.emplace_back(zdcEnergyData.energy());
2201 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2203 for (
int it = 0; it < nt; it++) {
2204 auto& tdc = zdcTDCData[ft + it];
2205 zdcAmplitudes.emplace_back(tdc.amplitude());
2206 zdcTime.emplace_back(tdc.value());
2218 std::vector<MCColInfo> mcColToEvSrc;
2224 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2225 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2226 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2229 if (mUseSigFiltMC) {
2230 std::vector<int> sourceIDs{};
2231 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2232 for (
auto const& colPart : mcParts[iCol]) {
2233 int sourceID = colPart.sourceID;
2234 if (std::find(sourceIDs.begin(), sourceIDs.end(), sourceID) == sourceIDs.end()) {
2235 sourceIDs.push_back(sourceID);
2237 if (sourceIDs.size() > 1) {
2241 if (sourceIDs.size() > 1) {
2245 if (sourceIDs.size() <= 1) {
2246 LOGP(fatal,
"Signal filtering cannot be enabled without embedding. Please fix the configuration either enabling the embedding, or turning off the signal filtering.");
2251 int totalNParts = 0;
2252 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2253 totalNParts += mcParts[iCol].size();
2255 mcCollisionsCursor.
reserve(totalNParts);
2257 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2258 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2259 auto globalBC = mcRecords[iCol].toLong();
2260 auto item = bcsMap.find(globalBC);
2262 if (item != bcsMap.end()) {
2263 bcID = item->second;
2265 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2266 <<
"for MC collision; BC = " << globalBC
2267 <<
", mc collision = " << iCol;
2269 auto& colParts = mcParts[iCol];
2270 auto nParts = colParts.size();
2271 for (
auto colPart : colParts) {
2272 auto eventID = colPart.entryID;
2273 auto sourceID = colPart.sourceID;
2276 if (nParts == 1 || sourceID == 0) {
2279 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2280 updateMCHeader(mcCollisionsCursor.
cursor,
2281 hepmcXSectionsCursor.
cursor,
2282 hepmcPdfInfosCursor.
cursor,
2283 hepmcHeavyIonsCursor.
cursor,
2291 mcColToEvSrc.emplace_back(
MCColInfo{iCol, sourceID, eventID, globalBC});
2296 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2300 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2301 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2303 fddCursor.reserve(fddRecPoints.size());
2304 for (
const auto& fddRecPoint : fddRecPoints) {
2305 for (
int i = 0;
i < 8;
i++) {
2306 aFDDAmplitudesA[
i] = 0;
2307 aFDDAmplitudesC[
i] = 0;
2308 aFDDTimesA[
i] = 0.f;
2309 aFDDTimesC[
i] = 0.f;
2311 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2312 uint64_t
bc = globalBC;
2313 auto item = bcsMap.find(
bc);
2315 if (item != bcsMap.end()) {
2316 bcID = item->second;
2318 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2320 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2321 for (
const auto& channel : channelData) {
2322 if (channel.mPMNumber < 8) {
2323 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2324 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2326 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2327 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2334 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2335 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2336 fddRecPoint.getTrigger().getTriggersignals());
2337 if (mEnableFITextra) {
2338 fddExtraCursor(bcID,
2345 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2346 std::vector<uint8_t> aChannelsA, aChannelsC;
2347 ft0Cursor.reserve(ft0RecPoints.size());
2348 for (
auto& ft0RecPoint : ft0RecPoints) {
2349 aAmplitudesA.clear();
2350 aAmplitudesC.clear();
2355 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2356 for (
auto& channel : channelData) {
2358 if (channel.QTCAmpl > 0) {
2360 if (channel.ChId < nFT0ChannelsAside) {
2361 aChannelsA.push_back(channel.ChId);
2362 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2363 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2365 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2366 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2367 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2371 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2372 uint64_t
bc = globalBC;
2373 auto item = bcsMap.find(
bc);
2375 if (item != bcsMap.end()) {
2376 bcID = item->second;
2378 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2385 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2386 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2387 ft0RecPoint.getTrigger().getTriggersignals());
2388 if (mEnableFITextra) {
2389 ft0ExtraCursor(bcID,
2397 mcColLabelsCursor.
reserve(primVerLabels.size());
2398 for (
size_t ivert = 0; ivert < primVerLabels.size(); ++ivert) {
2399 const auto&
label = primVerLabels[ivert];
2405 std::vector<std::pair<int32_t, int64_t>> candidates;
2406 for (
const auto& colInfo : mcColToEvSrc) {
2407 if (colInfo.sourceID ==
label.getSourceID() &&
2408 colInfo.eventID ==
label.getEventID()) {
2409 candidates.emplace_back(colInfo.colIndex, colInfo.bc);
2413 int32_t mcCollisionID = -1;
2414 if (candidates.size() == 1) {
2415 mcCollisionID = candidates[0].first;
2416 }
else if (candidates.size() > 1) {
2422 const auto& timeStamp = primVertices[ivert].getTimeStamp();
2423 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2424 const auto recoBC = relativeTime_to_GlobalBC(interactionTime);
2425 int64_t bestDiff = std::numeric_limits<int64_t>::max();
2426 for (
const auto& [colIndex,
bc] : candidates) {
2427 const auto bcDiff = std::abs(
static_cast<int64_t
>(
bc) -
static_cast<int64_t
>(recoBC));
2428 if (bcDiff < bestDiff) {
2430 mcCollisionID = colIndex;
2435 uint16_t mcMask = 0;
2436 mcColLabelsCursor(mcCollisionID, mcMask);
2440 cacheTriggers(recoData);
2441 countTPCClusters(recoData);
2443 int collisionID = 0;
2447 auto& trackReffwd = primVer2TRefs.back();
2448 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2450 for (
auto&
vertex : primVertices) {
2451 auto& trackReffwd = primVer2TRefs[collisionID];
2452 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2457 prepareStrangenessTracking(recoData);
2459 mGIDToTableFwdID.clear();
2460 mGIDToTableMFTID.clear();
2462 if (mPropTracks || mThinTracks) {
2466 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2467 for (
const auto&
v0 : v0s) {
2468 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2469 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2471 for (
const auto& cascade : cascades) {
2472 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2474 for (
const auto& id3Body : decays3Body) {
2475 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2476 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2477 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2486 mCurrentTRDTrigID = 0;
2489 auto& trackRef = primVer2TRefs.back();
2491 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor,
2492 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2493 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2495 mCurrentTRDTrigID = 0;
2498 collisionsCursor.reserve(primVertices.size());
2499 for (
auto&
vertex : primVertices) {
2500 auto& cov =
vertex.getCov();
2501 auto& timeStamp =
vertex.getTimeStamp();
2502 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2503 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2504 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2505 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2508 auto item = bcsMap.find(globalBC);
2510 if (item != bcsMap.end()) {
2511 bcID = item->second;
2513 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2515 collisionsCursor(bcID,
2516 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2517 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2518 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2519 truncateFloatFraction(cov[0], mCollisionPositionCov),
2520 truncateFloatFraction(cov[1], mCollisionPositionCov),
2521 truncateFloatFraction(cov[2], mCollisionPositionCov),
2522 truncateFloatFraction(cov[3], mCollisionPositionCov),
2523 truncateFloatFraction(cov[4], mCollisionPositionCov),
2524 truncateFloatFraction(cov[5], mCollisionPositionCov),
2526 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2527 vertex.getNContributors(),
2528 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2529 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2530 mVtxToTableCollID[collisionID] = mTableCollID++;
2532 auto& trackRef = primVer2TRefs[collisionID];
2534 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor, ambigTracksCursor,
2535 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2536 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2540 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2541 fillHMPID(recoData, hmpCursor);
2542 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2546 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2548 LOG(
debug) <<
"CTP input available";
2549 for (
auto& ctpDigit : ctpDigits) {
2550 uint64_t
bc = ctpDigit.intRecord.toLong();
2551 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2552 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2553 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2555 auto classMaskOrig = classMask;
2556 classMask = classMask & ~mEMCALTrgClassMask;
2557 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2559 bcToClassMask[
bc] = {classMask, inputMask};
2565 bcCursor.reserve(bcsMap.size());
2566 for (
auto& item : bcsMap) {
2567 uint64_t
bc = item.first;
2568 std::pair<uint64_t, uint64_t> masks{0, 0};
2570 auto bcClassPair = bcToClassMask.find(
bc);
2571 if (bcClassPair != bcToClassMask.end()) {
2572 masks = bcClassPair->second;
2581 bcToClassMask.clear();
2584 auto bcFlags = fillBCFlags(recoData, bcsMap);
2585 bcFlagsCursor.reserve(bcFlags.size());
2586 for (
auto f : bcFlags) {
2593 cpvClustersCursor.reserve(cpvClusters.size());
2594 for (
auto& cpvEvent : cpvTrigRecs) {
2595 uint64_t
bc = cpvEvent.getBCData().toLong();
2596 auto item = bcsMap.find(
bc);
2598 if (item != bcsMap.end()) {
2599 bcID = item->second;
2601 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2603 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2604 auto&
clu = cpvClusters[iClu];
2605 clu.getLocalPosition(posX, posZ);
2606 cpvClustersCursor(bcID,
2607 truncateFloatFraction(posX, mCPVPos),
2608 truncateFloatFraction(posZ, mCPVPos),
2609 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2610 clu.getPackedClusterStatus());
2619 fillMCParticlesTable(*mcReader,
2620 mcParticlesCursor.
cursor,
2626 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2627 mcColToEvSrc.clear();
2633 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2634 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2635 auto& trackRef = primVer2TRefs[iref];
2636 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2642 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2647 mGIDToTableID.clear();
2649 mGIDToTableFwdID.clear();
2651 mGIDToTableMFTID.clear();
2653 mVtxToTableCollID.clear();
2655 mV0ToTableID.clear();
2658 mIndexTableFwd.clear();
2660 mIndexTableMFT.clear();
2665 mGIDUsedBySVtx.clear();
2666 mGIDUsedByStr.clear();
2668 originCursor(tfNumber);
2671 TString dataType = mUseMC ?
"MC" :
"RAW";
2673 TString ROOTVersion = ROOT_RELEASE;
2674 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2675 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2676 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2678 if (mCollectConfigFiles) {
2679 collectConfigFiles(mMetaDataKeys, mMetaDataVals);
2698 for (
const auto& rof : rofs) {
2699 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2700 for (
int i =
first;
i < last;
i++) {
2701 mITSROFs.push_back(
count);
2711 for (
const auto& rof : rofs) {
2712 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2714 mMFTROFs.push_back(
count);
2721 mITSTPCTRDTriggers.clear();
2724 for (
const auto& trig : itstpctrigs) {
2725 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2727 mITSTPCTRDTriggers.push_back(
count);
2734 mTPCTRDTriggers.clear();
2737 for (
const auto& trig : tpctrigs) {
2738 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2740 mTPCTRDTriggers.push_back(
count);
2750 for (
const auto& rof : rofs) {
2753 mMCHROFs.push_back(
count);
2760AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2763 TrackExtraInfo extraInfoHolder;
2764 if (collisionID < 0) {
2767 bool needBCSlice = collisionID < 0;
2768 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2770 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2776 extraInfoHolder.trackTimeRes = terr;
2778 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2779 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2782 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2784 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2787 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2788 const auto& trackPar =
data.getTrackParam(trackIndex);
2789 extraInfoHolder.flags |= trackPar.getPID() << 28;
2790 auto src = trackIndex.getSource();
2792 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2793 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2794 const auto& tofInt = tofMatch.getLTIntegralOut();
2795 float intLen = tofInt.getL();
2796 extraInfoHolder.length = intLen;
2803 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2806 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2807 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2808 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2809 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2810 setTrackTime(tofSignal, 0.2,
true);
2814 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2815 extraInfoHolder.trdSignal = trdOrig.getSignal();
2816 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2817 if (extraInfoHolder.trackTimeRes < 0.) {
2819 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2821 setTrackTime(ttrig, 1.,
true);
2825 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2826 int nClusters = itsTrack.getNClusters();
2827 float chi2 = itsTrack.getChi2();
2829 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2831 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2833 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2836 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2840 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2841 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2842 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2845 if (tpcOrig.hasASideClusters()) {
2848 if (tpcOrig.hasCSideClusters()) {
2851 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2852 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2853 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2854 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2855 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2856 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2857 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2858 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2859 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2862 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2863 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2864 double err = mTimeMarginTrackTime + terr;
2865 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2868 p.setDeltaTFwd(tpcOrig.getDeltaTFwd());
2869 p.setDeltaTBwd(tpcOrig.getDeltaTBwd());
2870 extraInfoHolder.trackTimeRes =
p.getTimeErr();
2872 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2873 extraInfoHolder.isTPConly =
true;
2876 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2877 auto ts = trITSTPC.getTimeMUS();
2878 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2882 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2887 return extraInfoHolder;
2890AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2894 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2895 const auto& trackPar =
data.getTrackParam(trackIndex);
2896 if (contributorsGID.isIndexSet()) {
2898 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2903 std::array<float, 2> dcaInfo{-999., -999.};
2904 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2905 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2906 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2910 auto safeInt8Clamp = [](
auto value) -> int8_t {
2911 using ValType =
decltype(
value);
2912 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()))));
2914 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2915 using ValType =
decltype(
value);
2916 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()))));
2920 uint8_t clusterCounters[8] = {0};
2922 uint8_t sectorIndex, rowIndex;
2923 uint32_t clusterIndex;
2924 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2925 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2926 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2927 char indexTracklet = (rowIndex % 152) / 19;
2928 clusterCounters[indexTracklet]++;
2932 for (
int i = 0;
i < 8;
i++) {
2933 if (clusterCounters[
i] > 5) {
2934 byteMask |= (1 <<
i);
2937 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2938 trackQAHolder.tpcClusterByteMask = byteMask;
2939 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2940 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2941 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2942 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2943 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2944 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2945 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2947 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2948 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2949 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2950 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2953 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2955 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2956 const float qpt = trackPar.getQ2Pt();
2958 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2959 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2965 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2966 const auto& itsOrig =
data.getITSTrack(itsContGID);
2975 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2976 const float qpt = gloCopy.getQ2Pt();
2977 const float x = qpt / beta0;
2979 auto scaleCont = [&
x](
int i) ->
float {
2982 auto scaleGlo = [&
x](
int i) ->
float {
2987 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2988 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2989 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2990 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2991 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2993 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2994 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2995 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2996 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2997 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
3001 (*mStreamer) <<
"trackQA"
3002 <<
"trackITSOrig=" << itsOrig
3003 <<
"trackTPCOrig=" << tpcOrig
3004 <<
"trackITSTPCOrig=" << trackPar
3005 <<
"trackITSProp=" << itsCopy
3006 <<
"trackTPCProp=" << tpcCopy
3007 <<
"trackITSTPCProp=" << gloCopy
3010 <<
"scaleCont0=" << scaleCont(0)
3011 <<
"scaleCont1=" << scaleCont(1)
3012 <<
"scaleCont2=" << scaleCont(2)
3013 <<
"scaleCont3=" << scaleCont(3)
3014 <<
"scaleCont4=" << scaleCont(4)
3015 <<
"scaleGlo0=" << scaleGlo(0)
3016 <<
"scaleGlo1=" << scaleGlo(1)
3017 <<
"scaleGlo2=" << scaleGlo(2)
3018 <<
"scaleGlo3=" << scaleGlo(3)
3019 <<
"scaleGlo4=" << scaleGlo(4)
3020 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
3021 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
3022 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
3023 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
3024 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
3025 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
3026 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
3027 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
3028 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
3029 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
3030 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
3031 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
3032 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
3033 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
3034 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
3035 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
3036 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
3037 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
3038 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
3039 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
3040 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
3041 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
3042 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
3043 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
3044 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
3045 <<
"scaleTOF=" << scaleTOF
3052 return trackQAHolder;
3060 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
3065void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
3067 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
3068 constexpr float ETAEMCAL = 0.75;
3069 constexpr float ZEMCALFastCheck = 460.;
3070 constexpr float ETADCALINNER = 0.22;
3071 constexpr float ETAPHOS = 0.13653194;
3072 constexpr float ETAPHOSMARGIN = 0.17946979;
3073 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
3074 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
3075 constexpr short SECTORTYPE[18] = {
3076 SNONE, SNONE, SNONE, SNONE,
3077 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
3080 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
3091 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
3092 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
3093 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
3097 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
3098 (!outTr.rotateParam(outTr.getPhi()) ||
3100 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
3101 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
3107 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
3110 auto outTrTmp = outTr;
3112 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
3113 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
3114 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
3119 if (sectorTmp == sector) {
3127 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
3134 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
3139 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
3140 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
3141 if (etaAbs > ETAEMCAL) {
3142 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
3146 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
3147 if (!propExactSector(XPHOS)) {
3150 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
3151 tg = std::atan2(
r, outTr.getZ());
3152 eta = -std::log(std::tan(0.5f * tg));
3153 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
3156 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
3157 extraInfoHolder.trackEtaEMCAL = eta;
3158 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
3162std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
3164 std::set<uint64_t> emcalIncompletes;
3165 for (
const auto& trg : triggers) {
3166 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
3168 emcalIncompletes.insert(trg.getBCData().toLong());
3171 return emcalIncompletes;
3177 static bool initOnceDone =
false;
3178 if (!initOnceDone) {
3179 initOnceDone =
true;
3186 for (
auto i = 0U;
i < bs.size();
i++) {
3201 mTPCBinNS = elParam.ZbinWidth * 1.e3;
3204 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
3205 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
3209 if (mEnableTRDextra) {
3231 LOG(info) <<
"ITS Alpide param updated";
3233 par.printKeyValues();
3237 LOG(info) <<
"MFT Alpide param updated";
3239 par.printKeyValues();
3250 mEMCALTrgClassMask = 0;
3251 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3253 mEMCALTrgClassMask |= trgclass.classMask;
3256 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3260void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3271 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3272 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3273 assert(nbitsFrac > 1);
3274 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3276 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3277 << TOFTimePrecPS <<
" ps";
3280 if (!trackRef.getEntries()) {
3284 std::uint64_t maxBC = mStartIR.
toLong();
3285 const auto& tofClus =
data.getTOFClusters();
3292 for (
int ti =
start; ti <
end; ti++) {
3293 auto& trackIndex = GIndices[ti];
3294 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3295 const auto& tofInt = tofMatch.getLTIntegralOut();
3296 float intLen = tofInt.getL();
3297 float tofExpMom = 0.;
3307 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3308 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3309 double exp = intLen * energy / (cSpeed * tofExpMom);
3310 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3311 auto bc = relativeTime_to_GlobalBC(tofSignal);
3313 auto it = bcsMap.lower_bound(
bc);
3314 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3315 bcsMap.emplace_hint(it,
bc, 1);
3324 if ((--bcsMap.end())->first <= maxBC) {
3325 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3329 for (
auto& item : bcsMap) {
3335std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3347 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3370 auto upperindex =
p.first;
3371 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3374 if (upperindex !=
p.first) {
3378 slice[1] = upperindex;
3380 auto bcOfTimeRef =
p.second - this->mStartIR.
toLong();
3381 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3382 <<
" t: " << tmax <<
" " << slice[1]
3383 <<
" bcref: " << bcOfTimeRef;
3389 std::vector<uint8_t>
flags(bcsMap.size());
3392 auto bcIt = bcsMap.begin();
3393 auto itsrofs =
data.getITSTracksROFRecords();
3396 for (
auto& rof : itsrofs) {
3397 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3400 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3402 while (bcIt != bcsMap.end()) {
3403 if (bcIt->first < globalBC0) {
3407 if (bcIt->first > globalBC1) {
3417bool AODProducerWorkflowDPL::collectConfigFiles(std::vector<TString>& keys, std::vector<TString>&
values,
int indent)
3420 static std::string
pattern, directory;
3421 static size_t cachedNumberOfFiles = 0, cachedTotalFileSize = 0;
3422 static bool first =
true, discard =
false;
3431 if (dir ==
"/dev/null") {
3432 LOGP(warn,
"ConfigParams output is disabled, abandoning {} files collection for metadata",
pattern);
3436 directory = (dir.empty() || dir ==
"none") ?
"." : dir;
3437 if (!std::filesystem::is_directory(directory, ec)) {
3438 LOGP(error, R
"(No directory "{}" is found to look for {} configuration files)", directory, pattern);
3443 static std::unordered_map<std::string, std::string> cachedMap;
3444 std::vector<std::filesystem::path> files;
3445 size_t currentTotalFileSize = 0;
3447 for (
const auto&
entry :
std::filesystem::directory_iterator(directory)) {
3448 if (!
entry.is_regular_file()) {
3451 const std::string fileName =
entry.path().filename().string();
3452 if (fnmatch(
pattern.c_str(), fileName.c_str(), 0) != 0) {
3455 const auto fileSize =
entry.file_size(ec);
3457 LOGP(error,
"Cannot determine size of file {}, reason: {}",
entry.path().string(), ec.message());
3459 files.push_back(
entry.path());
3460 currentTotalFileSize +=
static_cast<size_t>(fileSize);
3463 if (files.size() != cachedNumberOfFiles || currentTotalFileSize != cachedTotalFileSize) {
3464 cachedNumberOfFiles = files.size();
3465 cachedTotalFileSize = currentTotalFileSize;
3469 if (!files.empty() && cachedMap.empty()) {
3470 for (
const auto& fname : files) {
3471 std::ifstream input(fname);
3473 LOGP(error,
"Cannot open JSON file {}", fname.string());
3474 cachedTotalFileSize = 0;
3477 nlohmann::json document;
3480 }
catch (
const nlohmann::json::parse_error& e) {
3481 LOGP(error,
"Cannot parse JSON file {}, reason: {}", fname.string(), e.what());
3482 cachedTotalFileSize = 0;
3486 if (!document.is_object()) {
3487 LOGP(error,
"Top-level JSON value is not an object in file: {}", fname.string());
3488 cachedTotalFileSize = 0;
3492 for (
auto it = document.begin(); it != document.end(); ++it) {
3493 const std::string&
key = it.key();
3494 if (cachedMap.find(
key) != cachedMap.end()) {
3495 LOGP(error,
"Duplicate top-level key {} in file {}",
key, fname.string());
3498 LOGP(info,
"Adding json config {} from file {} to AOD metadata",
key, fname.string());
3499 nlohmann::json valueDocument = nlohmann::json::object();
3500 valueDocument[
key] = it.value();
3501 cachedMap[
key] = valueDocument.dump(indent);
3506 for (
const auto& kv : cachedMap) {
3507 keys.push_back(kv.first.c_str());
3508 values.push_back(kv.second.c_str());
3515 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3516 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3523 auto dataRequest = std::make_shared<DataRequest>();
3524 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3526 dataRequest->requestTracks(
src, useMC);
3527 dataRequest->requestPrimaryVertices(useMC);
3529 dataRequest->requestCTPDigits(useMC);
3532 dataRequest->requestSecondaryVertices(useMC);
3534 if (enableStrangenessTracking) {
3535 dataRequest->requestStrangeTracks(useMC);
3536 LOGF(info,
"requestStrangeTracks Finish");
3545 dataRequest->requestTOFClusters(useMC);
3548 dataRequest->requestPHOSCells(useMC);
3551 dataRequest->requestTRDTracklets(
false);
3554 dataRequest->requestEMCALCells(useMC);
3557 dataRequest->requestCPVClusters(useMC);
3560 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3566 dataRequest->inputs,
3569 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3574 std::vector<OutputSpec> outputs{
3613 if (enableTRDextra) {
3615 dataRequest->inputs.emplace_back(
"trdlocalgainfactors",
"TRD",
"LOCALGAINFACTORS", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/LocalGainFactor"));
3616 dataRequest->inputs.emplace_back(
"trdnoisemap",
"TRD",
"NOISEMAP", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/NoiseMapMCM"));
3617 dataRequest->inputs.emplace_back(
"trdgaincalib",
"TRD",
"CALGAIN", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/CalGain"));
3621 outputs.insert(outputs.end(),
3622 {OutputForTable<McCollisions>::spec(),
3623 OutputForTable<HepMCXSections>::spec(),
3624 OutputForTable<HepMCPdfInfos>::spec(),
3625 OutputForTable<HepMCHeavyIons>::spec(),
3626 OutputForTable<McMFTTrackLabels>::spec(),
3627 OutputForTable<McFwdTrackLabels>::spec(),
3628 OutputForTable<StoredMcParticles_001>::spec(),
3629 OutputForTable<McTrackLabels>::spec(),
3630 OutputForTable<McCaloLabels_001>::spec(),
3635 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3639 "aod-producer-workflow",
3642 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra, enableTRDextra)},
3644 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3645 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3646 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3647 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3648 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3649 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3650 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3651 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3652 ConfigParamSpec{
"aod-parent", VariantType::String,
"", {
"Parent AOD file name (if any)"}},
3653 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3654 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3655 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3656 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3657 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3658 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3659 ConfigParamSpec{
"propagate-tracks-max-xiu", VariantType::Float, 5.0f, {
"Propagate tracks to IP if X_IU smaller than this value (and if propagate tracks enabled)"}},
3660 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)"}},
3661 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3662 ConfigParamSpec{
"store-all-mft-cov", VariantType::Bool,
false, {
"Store covariance matrices for all MFT tracks"}},
3663 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3664 ConfigParamSpec{
"trackqc-keepglobaltracks", VariantType::Bool,
false, {
"Always keep TrackQA for global tracks"}},
3665 ConfigParamSpec{
"trackqc-retainonlydedx", VariantType::Bool,
false, {
"Keep only dEdx information, zero out everything else"}},
3666 ConfigParamSpec{
"trackqc-fraction", VariantType::Float, float(0.1), {
"Fraction of tracks to QC"}},
3667 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3668 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3669 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3670 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3671 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3672 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
3673 ConfigParamSpec{
"mc-signal-filt", VariantType::Bool,
false, {
"Enable usage of signal filtering (only for MC with embedding)"}},
3674 ConfigParamSpec{
"collect-config-files", VariantType::Bool,
false, {
"Collect ConfigParams json files written by upsteam processors"}},
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 Names Generator class.
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()
static const std::string & getOutputDir()
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)
float getMPVdEdx(int iDet, bool defaultAvg=true) const
Simple noise status bit for each MCM of the TRD.
bool isTrackletFromNoisyMCM(const Tracklet64 &trklt) const
T getValue(int roc, int col, int row) const
void set(const std::string &s, int base=DefaultBase)
bool match(const std::vector< std::string > &queries, const char *pattern)
GLfloat GLfloat GLfloat alpha
GLint GLint GLsizei GLuint * counters
GLuint GLuint GLfloat weight
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLenum GLsizei GLsizei GLint * values
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
constexpr std::array< float, 2 > trackQAScaledTOF
constexpr std::array< float, 5 > trackQAScaleContP1
uint8_t itsSharedClusterMap uint8_t
constexpr std::array< float, 5 > trackQAScaleContP0
constexpr std::array< float, 5 > trackQAScaleGloP0
constexpr std::array< float, 5 > trackQAScaleGloP1
constexpr float trackQAScaleBins
constexpr float trackQARefRadius
bool updateHepMCHeavyIon(const HeavyIonCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
short updateMCCollisions(const CollisionCursor &cursor, int bcId, float time, o2::dataformats::MCEventHeader const &header, short generatorId=0, int sourceId=0, unsigned int mask=0xFFFFFFF0)
bool updateHepMCPdfInfo(const PdfInfoCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
uint32_t updateParticles(const ParticleCursor &cursor, int collisionID, std::vector< MCTrack > const &tracks, TrackToIndex &preselect, uint32_t offset=0, bool filter=false, bool background=false, uint32_t weightMask=0xFFFFFFF0, uint32_t momentumMask=0xFFFFFFF0, uint32_t positionMask=0xFFFFFFF0, bool signalFilter=false)
bool updateHepMCXSection(const XSectionCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra, bool enableTRDextra)
create a processor spec
void keepMCParticle(std::vector< std::vector< std::unordered_map< int, int > > > &store, int source, int event, int track, int value=1, bool useSigFilt=false)
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 ITS Vertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
const bool const int TrackITSInternal< NLayers > & track
int angle2Sector(float phi)
float sector2Angle(int sect)
constexpr float MPVDEDXDEFAULT
default Most Probable Value of TRD dEdx
const int TDCSignal[NTDCChannels]
constexpr int NTDCChannels
std::string fullVersion()
get full version information (official O2 release and git commit)
helper struct to keep mapping of colIndex to MC labels and bunch crossing
static constexpr auto 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
const U & getTrack(int src, int id) const
o2::InteractionRecord startIR
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
auto getDecays3BodyIdx() const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
gsl::span< const o2::trd::CalibratedTracklet > getTRDCalibratedTracklets() 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
const o2::dataformats::TrackTPCITS & getTPCITSTrack(GTrackID gid) 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
gsl::span< const o2::trd::Tracklet64 > getTRDTracklets() 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