diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index 2c58db42ed856..588cd575ee7f5 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -19,6 +19,10 @@ #include "DataFormatsGlobalTracking/RecoContainer.h" #include "DataFormatsPHOS/Cell.h" #include "DataFormatsTRD/TrackTRD.h" +#include "TRDBase/PadCalibrationsAliases.h" +#include "DataFormatsTRD/NoiseCalibration.h" +#include "DataFormatsTRD/CalGain.h" +#include "DataFormatsTRD/Constants.h" #include "DetectorsBase/GRPGeomHelper.h" #include "DetectorsBase/Propagator.h" #include "Framework/DataProcessorSpec.h" @@ -215,7 +219,7 @@ enum struct AODProducerStreamerFlags : uint8_t { class AODProducerWorkflowDPL : public Task { public: - AODProducerWorkflowDPL(GID::mask_t src, std::shared_ptr dataRequest, std::shared_ptr gr, bool enableSV, bool useMC = true, bool enableFITextra = false) : mUseMC(useMC), mEnableSV(enableSV), mEnableFITextra(enableFITextra), mInputSources(src), mDataRequest(dataRequest), mGGCCDBRequest(gr) {} + AODProducerWorkflowDPL(GID::mask_t src, std::shared_ptr dataRequest, std::shared_ptr gr, bool enableSV, bool useMC = true, bool enableFITextra = false, bool enableTRDextra = false) : mUseMC(useMC), mEnableSV(enableSV), mEnableFITextra(enableFITextra), mEnableTRDextra(enableTRDextra), mInputSources(src), mDataRequest(dataRequest), mGGCCDBRequest(gr) {} ~AODProducerWorkflowDPL() override = default; void init(InitContext& ic) final; void run(ProcessingContext& pc) final; @@ -250,6 +254,10 @@ class AODProducerWorkflowDPL : public Task o2::dataformats::MeanVertexObject mVtx; float mMaxPropXiu{5.0f}; // max X_IU for which track is to be propagated if mPropTracks is true. (other option: o2::constants::geom::XTPCInnerRef + 0.1f) + const o2::trd::LocalGainFactor* mTRDLocalGain; // TRD local gain factors from krypton calibration + const o2::trd::CalGain* mTRDGainCalib; // TRD time-dependent gain calib at chamber level + const o2::trd::NoiseStatusMCM* mTRDNoiseMap; // TRD noise map + std::unordered_set mGIDUsedBySVtx; std::unordered_set mGIDUsedByStr; @@ -261,6 +269,7 @@ class AODProducerWorkflowDPL : public Task bool mUseSigFiltMC = false; // enable signal filtering for MC with embedding bool mEnableSV = true; // enable secondary vertices bool mEnableFITextra = false; + bool mEnableTRDextra = false; bool mFieldON = false; const float cSpeed = 0.029979246f; // speed of light in TOF units @@ -278,6 +287,7 @@ class AODProducerWorkflowDPL : public Task TStopwatch mTimer; bool mEMCselectLeading{false}; uint64_t mEMCALTrgClassMask = 0; + size_t mCurrentTRDTrigID = 0; // current index of the TRD trigger record, to speed up search // unordered map connects global indices and table indices of barrel tracks std::unordered_map mGIDToTableID; @@ -525,6 +535,9 @@ class AODProducerWorkflowDPL : public Task template void addToTracksQATable(TracksQACursorType& tracksQACursor, TrackQA& trackQAInfoHolder); + template + void addToTRDsExtra(const o2::globaltracking::RecoContainer& recoData, TRDsExtraCursorType& trdExtraCursor, const GIndex& trkIdx, int trkTableIdx); + template void addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor, GIndex trackID, const o2::globaltracking::RecoContainer& data, int collisionID, @@ -544,7 +557,7 @@ class AODProducerWorkflowDPL : public Task // helper for track tables // * fills tables collision by collision // * interaction time is for TOF information - template void fillTrackTablesPerCollision(int collisionID, @@ -556,6 +569,7 @@ class AODProducerWorkflowDPL : public Task TracksCovCursorType& tracksCovCursor, TracksExtraCursorType& tracksExtraCursor, TracksQACursorType& tracksQACursor, + TRDsExtraCursorType& trdsExtraCursor, AmbigTracksCursorType& ambigTracksCursor, MFTTracksCursorType& mftTracksCursor, MFTTracksCovCursorType& mftTracksCovCursor, @@ -680,7 +694,7 @@ class AODProducerWorkflowDPL : public Task }; /// create a processor spec -framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra); +framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra, bool enableTRDextra); // helper interface for calo cells to "befriend" emcal and phos cells class CellHelper diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 852419a9895eb..fcb419d6c441b 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -33,7 +33,6 @@ #include "DataFormatsPHOS/TriggerRecord.h" #include "DataFormatsPHOS/EventHandler.h" #include "DataFormatsTPC/TrackTPC.h" -#include "DataFormatsTRD/TriggerRecord.h" #include "DataFormatsZDC/BCRecData.h" #include "DataFormatsZDC/ZDCEnergy.h" #include "DataFormatsZDC/ZDCTDCData.h" @@ -45,6 +44,9 @@ #include "CommonDataFormat/InteractionRecord.h" #include "DataFormatsTRD/TrackTRD.h" #include "DataFormatsTRD/TrackTriggerRecord.h" +#include "DataFormatsTRD/CalibratedTracklet.h" +#include "DataFormatsTRD/TriggerRecord.h" +#include "DataFormatsTRD/Tracklet64.h" #include "DataFormatsGlobalTracking/RecoContainer.h" #include "Framework/AnalysisDataModel.h" #include "Framework/ConfigParamRegistry.h" @@ -390,6 +392,121 @@ void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACurs mTrackQCRetainOnlydEdx ? std::numeric_limits::min() : trackQAInfoHolder.dTofdZ); } +template +void AODProducerWorkflowDPL::addToTRDsExtra(const o2::globaltracking::RecoContainer& recoData, TRDsExtraCursorType& trdExtraCursor, const GIndex& trkIdx, int trkTableIdx) +{ + int q0s[6] = {-1}, q1s[6] = {-1}, q2s[6] = {-1}; + float q0sCor[6] = {-1}, q1sCor[6] = {-1}, q2sCor[6] = {-1}; + float ttgls[6] = {-999}, tphis[6] = {-999}; + + auto contributorsGID = recoData.getSingleDetectorRefs(trkIdx); + if (!contributorsGID[GIndex::Source::TRD].isIndexSet()) { // should be redunant + return; + } + const auto& trk = recoData.getTrack(contributorsGID[GIndex::Source::TRD]); + o2::track::TrackPar trkC{contributorsGID[GIndex::Source::ITSTPC].isIndexSet() ? recoData.getTPCITSTrack(contributorsGID[GIndex::Source::ITSTPC]).getParamOut() : recoData.getTPCTrack(contributorsGID[GIndex::Source::TPC]).getParamOut()}; + const auto& trklets = recoData.getTRDTracklets(); + const auto& ctrklets = recoData.getTRDCalibratedTracklets(); + for (int iLay{0}; iLay < 6; ++iLay) { + q0s[iLay] = q1s[iLay] = q2s[iLay] = -1; + q0sCor[iLay] = q1sCor[iLay] = q2sCor[iLay] = -1; + tphis[iLay] = ttgls[iLay] = -999; + auto trkltId = trk.getTrackletIndex(iLay); + if (trkltId < 0) { + continue; + } + const auto& tracklet = trklets[trkltId]; + if (mTRDNoiseMap->isTrackletFromNoisyMCM(tracklet)) { + continue; + } + // we need to propagate into TRD local system + int trkltDet = tracklet.getDetector(); + int trkltSec = trkltDet / 30; + if (trkltSec != o2::math_utils::angle2Sector(trkC.getAlpha())) { + if (!trkC.rotate(o2::math_utils::sector2Angle(trkltSec))) { + break; + } + } + if (!o2::base::Propagator::Instance()->PropagateToXBxByBz(trkC, ctrklets[trkltId].getX(), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr)) { + break; + } + + auto tphi = trkC.getSnp() / std::sqrt((1.f - trkC.getSnp()) * (1.f + trkC.getSnp())); + auto trackletLength = std::sqrt(1.f + tphi * tphi + trkC.getTgl() * trkC.getTgl()); + float cor = mTRDLocalGain->getValue(tracklet.getHCID() / 2, tracklet.getPadCol(), tracklet.getPadRow()) * mTRDGainCalib->getMPVdEdx(tracklet.getDetector()) / o2::trd::constants::MPVDEDXDEFAULT * trackletLength; + q0s[iLay] = tracklet.getQ0(); + q1s[iLay] = tracklet.getQ1(); + q2s[iLay] = tracklet.getQ2(); + q0sCor[iLay] = (float)tracklet.getQ0() / cor; + q1sCor[iLay] = (float)tracklet.getQ1() / cor; + q2sCor[iLay] = (float)tracklet.getQ2() / cor; + ttgls[iLay] = trkC.getTgl(); + tphis[iLay] = tphi; + + // z-row merging, we want to merge only with tracklets from the same trigger record + if (trk.getIsCrossingNeighbor(iLay) && trk.getHasNeighbor()) { + // find the trigger the tracklet belongs to + auto trigsTRD = recoData.getTRDTriggerRecords(); + size_t trdSelID = -1; + + const auto& trig = trigsTRD[mCurrentTRDTrigID]; + bool foundTRDTrigger = false; + // first check current trigger + if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) { + trdSelID = mCurrentTRDTrigID; + foundTRDTrigger = true; + } else { + // then check next trigger + if (mCurrentTRDTrigID < trigsTRD.size() - 1) { + const auto& trig = trigsTRD[mCurrentTRDTrigID + 1]; + if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) { + trdSelID = mCurrentTRDTrigID + 1; + foundTRDTrigger = true; + } + } + } + + size_t low = 0, up = trigsTRD.size() - 1; + + // otherwise binary search + while (low <= up && !foundTRDTrigger) { + trdSelID = low + std::floor((up - low) / 2); + const auto& trig = trigsTRD[trdSelID]; + if (trig.getFirstTracklet() > trkltId) { + up = trdSelID - 1; + } else { + if (trig.getFirstTracklet() + trig.getNumberOfTracklets() <= trkltId) { + low = trdSelID + 1; + } else { + foundTRDTrigger = true; + } + } + } + //------------------- + mCurrentTRDTrigID = trdSelID; + const auto& trigSel = trigsTRD[trdSelID]; + + // loop on other tracklets from the same trigger record + for (const auto& trklt : trklets.subspan(trigSel.getFirstTracklet(), trigSel.getNumberOfTracklets())) { + if (tracklet.getTrackletWord() == trklt.getTrackletWord() || tracklet.getDetector() != trklt.getDetector()) { + continue; + } + if (std::abs(tracklet.getPadCol() - trklt.getPadCol()) <= 1 && std::abs(tracklet.getPadRow() - trklt.getPadRow()) == 1) { + cor = mTRDLocalGain->getValue(trklt.getHCID() / 2, trklt.getPadCol(), trklt.getPadRow()) * mTRDGainCalib->getMPVdEdx(tracklet.getDetector()) / o2::trd::constants::MPVDEDXDEFAULT * trackletLength; + q0s[iLay] += trklt.getQ0(); + q1s[iLay] += trklt.getQ1(); + q2s[iLay] += trklt.getQ2(); + q0sCor[iLay] += (float)trklt.getQ0() / cor; + q1sCor[iLay] += (float)trklt.getQ1() / cor; + q2sCor[iLay] += (float)trklt.getQ2() / cor; + } + } + } + } + + trdExtraCursor(trkTableIdx, q0s, q1s, q2s, q0sCor, q1sCor, q2sCor, ttgls, tphis); +} + template void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor, GIndex trackID, const o2::globaltracking::RecoContainer& data, int collisionID, @@ -430,8 +547,7 @@ void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksC ambigMFTTracksCursor(mTableTrMFTID, bcSlice); } } - -template void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, @@ -443,6 +559,7 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, TracksCovCursorType& tracksCovCursor, TracksExtraCursorType& tracksExtraCursor, TracksQACursorType& tracksQACursor, + TRDsExtraCursor& trdsExtraCursor, AmbigTracksCursorType& ambigTracksCursor, MFTTracksCursorType& mftTracksCursor, MFTTracksCovCursorType& mftTracksCovCursor, @@ -553,7 +670,9 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, addToTracksTable(tracksCursor, tracksCovCursor, trOrig, collisionID, aod::track::TrackIU); } addToTracksExtraTable(tracksExtraCursor, extraInfoHolder); - + if (mEnableTRDextra && trackIndex.includesDet(GIndex::Source::TRD)) { + addToTRDsExtra(data, trdsExtraCursor, trackIndex, mTableTrID); + } // collecting table indices of barrel tracks for V0s table if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) { ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice); @@ -1934,6 +2053,12 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto cpvClustersCursor = createTableCursor(pc); auto originCursor = createTableCursor(pc); + /// Extra tables + o2::framework::Produces trdExtraCursor; + if (mEnableTRDextra) { + trdExtraCursor = createTableCursor(pc); + } + // Declare MC cursors type without adding the output for a table o2::framework::Produces mcColLabelsCursor; o2::framework::Produces mcCollisionsCursor; @@ -2294,14 +2419,16 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) } } + mCurrentTRDTrigID = 0; // reinitialize index for TRD trigger record search // filling unassigned tracks first // so that all unassigned tracks are stored in the beginning of the table together auto& trackRef = primVer2TRefs.back(); // references to unassigned tracks are at the end // fixme: interaction time is undefined for unassigned tracks (?) - fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, + fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor, ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor, fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap); + mCurrentTRDTrigID = 0; // reinitialize index for TRD trigger record search // filling collisions and tracks into tables collisionID = 0; collisionsCursor.reserve(primVertices.size()); @@ -2340,7 +2467,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto& trackRef = primVer2TRefs[collisionID]; // passing interaction time in [ps] - fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor, + fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor, ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor, fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap); collisionID++; @@ -3011,6 +3138,11 @@ void AODProducerWorkflowDPL::updateTimeDependentParams(ProcessingContext& pc) mFieldON = std::abs(o2::base::Propagator::Instance()->getNominalBz()) > 0.01; pc.inputs().get("ctpconfig"); + if (mEnableTRDextra) { + mTRDLocalGain = pc.inputs().get("trdlocalgainfactors").get(); + mTRDNoiseMap = pc.inputs().get("trdnoisemap").get(); + mTRDGainCalib = pc.inputs().get("trdgaincalib").get(); // time dependent gain + } } if (mPropTracks) { pc.inputs().get("meanvtx"); @@ -3222,7 +3354,7 @@ void AODProducerWorkflowDPL::endOfStream(EndOfStreamContext& /*ec*/) mStreamer.reset(); } -DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableStrangenessTracking, bool useMC, bool CTPConfigPerRun, bool enableFITextra) +DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableStrangenessTracking, bool useMC, bool CTPConfigPerRun, bool enableFITextra, bool enableTRDextra) { auto dataRequest = std::make_shared(); dataRequest->inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/Config", CTPConfigPerRun)); @@ -3313,6 +3445,13 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo OutputSpec{"TFF", "TFFilename"}, OutputSpec{"AMD", "AODMetadataKeys"}, OutputSpec{"AMD", "AODMetadataVals"}}; + /// Extra tables + if (enableTRDextra) { + outputs.push_back(OutputForTable::spec()); + dataRequest->inputs.emplace_back("trdlocalgainfactors", "TRD", "LOCALGAINFACTORS", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/LocalGainFactor")); + dataRequest->inputs.emplace_back("trdnoisemap", "TRD", "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/NoiseMapMCM")); + dataRequest->inputs.emplace_back("trdgaincalib", "TRD", "CALGAIN", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/CalGain")); + } if (useMC) { outputs.insert(outputs.end(), @@ -3336,7 +3475,7 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo "aod-producer-workflow", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)}, + AlgorithmSpec{adaptFromTask(src, dataRequest, ggRequest, enableSV, useMC, enableFITextra, enableTRDextra)}, Options{ ConfigParamSpec{"run-number", VariantType::Int64, -1L, {"The run-number. If left default we try to get it from DPL header."}}, ConfigParamSpec{"aod-timeframe-id", VariantType::Int64, -1L, {"Set timeframe number"}}, diff --git a/Detectors/AOD/src/aod-producer-workflow.cxx b/Detectors/AOD/src/aod-producer-workflow.cxx index 81e178642e403..f6bfaae170bbd 100644 --- a/Detectors/AOD/src/aod-producer-workflow.cxx +++ b/Detectors/AOD/src/aod-producer-workflow.cxx @@ -38,6 +38,7 @@ void customize(std::vector& workflowOptions) {"disable-secondary-vertices", o2::framework::VariantType::Bool, false, {"disable filling secondary vertices"}}, {"disable-strangeness-tracker", o2::framework::VariantType::Bool, false, {"disable filling strangeness tracking"}}, {"enable-FIT-extra", o2::framework::VariantType::Bool, false, {"enable FIT extra output"}}, + {"enable-TRD-extra", o2::framework::VariantType::Bool, false, {"enable TRD extra output"}}, {"info-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of sources to use"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}, {"combine-source-devices", o2::framework::VariantType::Bool, false, {"merge DPL source devices"}}, @@ -56,6 +57,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) bool enableST = !configcontext.options().get("disable-strangeness-tracker"); bool ctpcfgperrun = !configcontext.options().get("ctpconfig-run-independent"); bool enableFITextra = configcontext.options().get("enable-FIT-extra"); + bool enableTRDextra = configcontext.options().get("enable-TRD-extra"); GID::mask_t allowedSrc = GID::getSourcesMask("ITS,MFT,MCH,MID,MCH-MID,TPC,TRD,ITS-TPC,TPC-TOF,TPC-TRD,ITS-TPC-TOF,ITS-TPC-TRD,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,FT0,FV0,FDD,ZDC,EMC,CTP,PHS,CPV,HMP"); GID::mask_t src = allowedSrc & GID::getSourcesMask(configcontext.options().get("info-sources")); @@ -66,7 +68,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) } WorkflowSpec specs; - specs.emplace_back(o2::aodproducer::getAODProducerWorkflowSpec(src, enableSV, enableST, useMC, ctpcfgperrun, enableFITextra)); + specs.emplace_back(o2::aodproducer::getAODProducerWorkflowSpec(src, enableSV, enableST, useMC, ctpcfgperrun, enableFITextra, enableTRDextra)); auto srcCls = src & ~(GID::getSourceMask(GID::MCH) | GID::getSourceMask(GID::MID)); // Don't read global MID and MCH clusters (those attached to tracks are always read) auto srcMtc = src; diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index e3032830beaac..9f48685820634 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -470,13 +470,13 @@ DECLARE_SOA_DYNAMIC_COLUMN(TPCFractionSharedCls, tpcFractionSharedCls, //! Fract return (float)tpcNClsShared / (float)tpcNClsFound; }); -DECLARE_SOA_DYNAMIC_COLUMN(TRDHasNeighbor, trdPattern, //! Flag to check if at least one tracklet of a TRD Track has a neighboring tracklet +DECLARE_SOA_DYNAMIC_COLUMN(TRDHasNeighbor, trdHasNeighbor, //! Flag to check if at least one tracklet of a TRD Track has a neighboring tracklet [](uint8_t trdPattern) -> bool { return trdPattern & o2::aod::track::HasNeighbor; }); -DECLARE_SOA_DYNAMIC_COLUMN(TRDHasCrossing, trdPattern, //! Flag to check if at least one tracklet of a TRD Track crossed a padrow +DECLARE_SOA_DYNAMIC_COLUMN(TRDHasCrossing, trdHasCrossing, //! Flag to check if at least one tracklet of a TRD Track crossed a padrow [](uint8_t trdPattern) -> bool { return trdPattern & o2::aod::track::HasCrossing; }); -DECLARE_SOA_DYNAMIC_COLUMN(TRDNLayers, trdPattern, //! Number of TRD tracklets in a Track +DECLARE_SOA_DYNAMIC_COLUMN(TRDNTracklets, trdNTracklets, //! Number of TRD tracklets in a Track [](uint8_t trdPattern) -> std::size_t { return std::bitset<6>(trdPattern).count(); }); } // namespace track @@ -589,6 +589,7 @@ DECLARE_SOA_TABLE_FULL(StoredTracksExtra_000, "TracksExtra", "AOD", "TRACKEXTRA" track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, track::TPCFractionSharedCls, + track::TRDHasCrossing, track::TRDHasNeighbor, track::TRDNTracklets, track::TrackEtaEMCAL, track::TrackPhiEMCAL, track::TrackTime, track::TrackTimeRes); DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_001, "TracksExtra", "AOD", "TRACKEXTRA", 1, // On disk version of TracksExtra, version 1 @@ -618,6 +619,7 @@ DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_001, "TracksExtra", "AOD", "T track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, track::TPCFractionSharedCls, + track::TRDHasCrossing, track::TRDHasNeighbor, track::TRDNTracklets, track::TrackEtaEMCAL, track::TrackPhiEMCAL, track::TrackTime, track::TrackTimeRes); DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_002, "TracksExtra", "AOD", "TRACKEXTRA", 2, // On disk version of TracksExtra, version 2 @@ -648,6 +650,7 @@ DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_002, "TracksExtra", "AOD", "T track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, track::TPCFractionSharedCls, + track::TRDHasCrossing, track::TRDHasNeighbor, track::TRDNTracklets, track::TrackEtaEMCAL, track::TrackPhiEMCAL, track::TrackTime, track::TrackTimeRes); DECLARE_SOA_EXTENDED_TABLE(TracksExtra_000, StoredTracksExtra_000, "EXTRACKEXTRA", 0, //! Additional track information (clusters, PID, etc.) @@ -1610,6 +1613,26 @@ DECLARE_SOA_TABLE(FDDsExtra, "AOD", "FDDEXTRA", //! FDDsExtra table fdd::TimeFDDA, fdd::TimeFDDC); using FDDExtra = FDDsExtra::iterator; +namespace trd +{ +DECLARE_SOA_INDEX_COLUMN(Track, track); //! Track index +DECLARE_SOA_COLUMN(TRDQ0s, trdQ0s, int[6]); //! Q0 charge (un-corrected) +DECLARE_SOA_COLUMN(TRDQ1s, trdQ1s, int[6]); //! Q1 charge (un-corrected) +DECLARE_SOA_COLUMN(TRDQ2s, trdQ2s, int[6]); //! Q2 charge (un-corrected) +DECLARE_SOA_COLUMN(TRDQ0sCorrected, trdQ0sCorrected, float[6]); //! Q0 charge (corrected) +DECLARE_SOA_COLUMN(TRDQ1sCorrected, trdQ1sCorrected, float[6]); //! Q1 charge (corrected) +DECLARE_SOA_COLUMN(TRDQ2sCorrected, trdQ2sCorrected, float[6]); //! Q2 charge (corrected) +DECLARE_SOA_COLUMN(TRDTgls, trdTgls, float[6]); //! Local tracklet TgL +DECLARE_SOA_COLUMN(TRDPhis, trdPhis, float[6]); //! Local tracklet phi +} // namespace trd + +DECLARE_SOA_TABLE(TRDsExtra, "AOD", "TRDEXTRA", //! TRDExtra table + o2::soa::Index<>, trd::TrackId, + trd::TRDQ0s, trd::TRDQ1s, trd::TRDQ2s, + trd::TRDQ0sCorrected, trd::TRDQ1sCorrected, trd::TRDQ2sCorrected, + trd::TRDTgls, trd::TRDPhis); +using TRDExtra = TRDsExtra::iterator; + namespace v0 { DECLARE_SOA_INDEX_COLUMN_FULL(PosTrack, posTrack, int, Tracks, "_Pos"); //! Positive track