From 6f539f6276d3e63a43c796fbc0f68cc9c85ed31a Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Mon, 13 Jan 2025 10:12:42 +0100 Subject: [PATCH] Optionally add time of FIT channels to AO2D Add output spec --- .../AODProducerWorkflowSpec.h | 8 ++- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 65 ++++++++++++++----- Detectors/AOD/src/aod-producer-workflow.cxx | 4 +- .../include/Framework/AnalysisDataModel.h | 20 ++++++ 4 files changed, 78 insertions(+), 19 deletions(-) diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index 05c2975d6413a..1bdd45c8d3429 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -218,7 +218,7 @@ O2_DEFINE_ENUM_BIT_OPERATORS(AODProducerStreamerMask) class AODProducerWorkflowDPL : public Task { public: - AODProducerWorkflowDPL(GID::mask_t src, std::shared_ptr dataRequest, std::shared_ptr gr, bool enableSV, bool useMC = true) : mUseMC(useMC), mEnableSV(enableSV), 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) : mUseMC(useMC), mEnableSV(enableSV), mEnableFITextra(enableFITextra), mInputSources(src), mDataRequest(dataRequest), mGGCCDBRequest(gr) {} ~AODProducerWorkflowDPL() override = default; void init(InitContext& ic) final; void run(ProcessingContext& pc) final; @@ -257,6 +257,7 @@ class AODProducerWorkflowDPL : public Task int mNThreads = 1; bool mUseMC = true; bool mEnableSV = true; // enable secondary vertices + bool mEnableFITextra = false; bool mFieldON = false; const float cSpeed = 0.029979246f; // speed of light in TOF units @@ -373,8 +374,11 @@ class AODProducerWorkflowDPL : public Task uint32_t mMuonCl = 0xFFFFFF00; // 15 bits uint32_t mMuonClErr = 0xFFFF0000; // 7 bits uint32_t mV0Time = 0xFFFFF000; // 11 bits + uint32_t mV0ChannelTime = 0xFFFFFF00; // 15 bits uint32_t mFDDTime = 0xFFFFF000; // 11 bits + uint32_t mFDDChannelTime = 0xFFFFFF00; // 15 bits uint32_t mT0Time = 0xFFFFFF00; // 15 bits + uint32_t mT0ChannelTime = 0xFFFFFFF0; // 19 bits uint32_t mV0Amplitude = 0xFFFFF000; // 11 bits uint32_t mFDDAmplitude = 0xFFFFF000; // 11 bits uint32_t mT0Amplitude = 0xFFFFF000; // 11 bits @@ -672,7 +676,7 @@ class AODProducerWorkflowDPL : public Task }; /// create a processor spec -framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun); +framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra); // 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 58648527f2856..b206d0669ddc4 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -1744,8 +1744,11 @@ void AODProducerWorkflowDPL::init(InitContext& ic) mMuonCl = 0xFFFFFFFF; mMuonClErr = 0xFFFFFFFF; mV0Time = 0xFFFFFFFF; + mV0ChannelTime = 0xFFFFFFFF; mFDDTime = 0xFFFFFFFF; + mFDDChannelTime = 0xFFFFFFFF; mT0Time = 0xFFFFFFFF; + mT0ChannelTime = 0xFFFFFFFF; mV0Amplitude = 0xFFFFFFFF; mFDDAmplitude = 0xFFFFFFFF; mT0Amplitude = 0xFFFFFFFF; @@ -1830,8 +1833,11 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto trackedV0Cursor = createTableCursor(pc); auto tracked3BodyCurs = createTableCursor(pc); auto fddCursor = createTableCursor(pc); + auto fddExtraCursor = createTableCursor(pc); auto ft0Cursor = createTableCursor(pc); + auto ft0ExtraCursor = createTableCursor(pc); auto fv0aCursor = createTableCursor(pc); + auto fv0aExtraCursor = createTableCursor(pc); auto fwdTracksCursor = createTableCursor(pc); auto fwdTracksCovCursor = createTableCursor(pc); auto fwdTrkClsCursor = createTableCursor(pc); @@ -1897,16 +1903,18 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) tfNumber = mTFNumber; } - std::vector aAmplitudes; + std::vector aAmplitudes, aTimes; std::vector aChannels; fv0aCursor.reserve(fv0RecPoints.size()); for (auto& fv0RecPoint : fv0RecPoints) { aAmplitudes.clear(); aChannels.clear(); + aTimes.clear(); const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData); for (auto& channel : channelData) { if (channel.charge > 0) { aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude)); + aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime)); aChannels.push_back(channel.channel); } } @@ -1923,6 +1931,11 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) aChannels, truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time), // ps to ns fv0RecPoint.getTrigger().getTriggersignals()); + + if (mEnableFITextra) { + fv0aExtraCursor(bcID, + aTimes); + } } std::vector zdcEnergy, zdcAmplitudes, zdcTime; @@ -2026,25 +2039,17 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) [](const std::vector& left, const std::vector& right) { return (left[0] < right[0]); }); // vector of FDD amplitudes - int16_t aFDDAmplitudesA[8] = {0u}; - int16_t aFDDAmplitudesC[8] = {0u}; + int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u}; + float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f}; // filling FDD table fddCursor.reserve(fddRecPoints.size()); for (const auto& fddRecPoint : fddRecPoints) { for (int i = 0; i < 8; i++) { aFDDAmplitudesA[i] = 0; aFDDAmplitudesC[i] = 0; + aFDDTimesA[i] = 0.f; + aFDDTimesC[i] = 0.f; } - - const auto channelData = fddRecPoint.getBunchChannelData(fddChData); - for (const auto& channel : channelData) { - if (channel.mPMNumber < 8) { - aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC; // amplitude - } else { - aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC; // amplitude - } - } - uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong(); uint64_t bc = globalBC; auto item = bcsMap.find(bc); @@ -2054,21 +2059,39 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) } else { LOG(fatal) << "Error: could not find a corresponding BC ID for a FDD rec. point; BC = " << bc; } + const auto channelData = fddRecPoint.getBunchChannelData(fddChData); + for (const auto& channel : channelData) { + if (channel.mPMNumber < 8) { + aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC; // amplitude + aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime); // time + } else { + aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC; // amplitude + aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime); // time + } + } + fddCursor(bcID, aFDDAmplitudesA, aFDDAmplitudesC, truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime), // ps to ns truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime), // ps to ns fddRecPoint.getTrigger().getTriggersignals()); + if (mEnableFITextra) { + fddExtraCursor(bcID, + aFDDTimesA, + aFDDTimesC); + } } // filling FT0 table - std::vector aAmplitudesA, aAmplitudesC; + std::vector aAmplitudesA, aAmplitudesC, aTimesA, aTimesC; std::vector aChannelsA, aChannelsC; ft0Cursor.reserve(ft0RecPoints.size()); for (auto& ft0RecPoint : ft0RecPoints) { aAmplitudesA.clear(); aAmplitudesC.clear(); + aTimesA.clear(); + aTimesC.clear(); aChannelsA.clear(); aChannelsC.clear(); const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData); @@ -2079,9 +2102,11 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) if (channel.ChId < nFT0ChannelsAside) { aChannelsA.push_back(channel.ChId); aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude)); + aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime)); } else { aChannelsC.push_back(channel.ChId - nFT0ChannelsAside); aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude)); + aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime)); } } } @@ -2102,6 +2127,11 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time), // ps to ns truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time), // ps to ns ft0RecPoint.getTrigger().getTriggersignals()); + if (mEnableFITextra) { + ft0ExtraCursor(bcID, + aTimesA, + aTimesC); + } } if (mUseMC) { @@ -3073,7 +3103,7 @@ void AODProducerWorkflowDPL::endOfStream(EndOfStreamContext& /*ec*/) mStreamer.reset(); } -DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableStrangenessTracking, bool useMC, bool CTPConfigPerRun) +DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableStrangenessTracking, bool useMC, bool CTPConfigPerRun, bool enableFITextra) { auto dataRequest = std::make_shared(); dataRequest->inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/Config", CTPConfigPerRun)); @@ -3133,8 +3163,11 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo OutputForTable::spec(), OutputForTable::spec(), OutputForTable::spec(), + OutputForTable::spec(), OutputForTable::spec(), + OutputForTable::spec(), OutputForTable::spec(), + OutputForTable::spec(), OutputForTable::spec(), OutputForTable::spec(), OutputForTable::spec(), @@ -3183,7 +3216,7 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo "aod-producer-workflow", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(src, dataRequest, ggRequest, enableSV, useMC)}, + AlgorithmSpec{adaptFromTask(src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)}, 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 1f39f11218be3..81e178642e403 100644 --- a/Detectors/AOD/src/aod-producer-workflow.cxx +++ b/Detectors/AOD/src/aod-producer-workflow.cxx @@ -37,6 +37,7 @@ void customize(std::vector& workflowOptions) {"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation"}}, {"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"}}, {"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"}}, @@ -54,6 +55,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) bool enableSV = !configcontext.options().get("disable-secondary-vertices"); bool enableST = !configcontext.options().get("disable-strangeness-tracker"); bool ctpcfgperrun = !configcontext.options().get("ctpconfig-run-independent"); + bool enableFITextra = configcontext.options().get("enable-FIT-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")); @@ -64,7 +66,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) } WorkflowSpec specs; - specs.emplace_back(o2::aodproducer::getAODProducerWorkflowSpec(src, enableSV, enableST, useMC, ctpcfgperrun)); + specs.emplace_back(o2::aodproducer::getAODProducerWorkflowSpec(src, enableSV, enableST, useMC, ctpcfgperrun, enableFITextra)); 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 934cc7df0c286..dd030c7370cca 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -1441,6 +1441,7 @@ namespace fv0a { DECLARE_SOA_INDEX_COLUMN(BC, bc); //! BC index DECLARE_SOA_COLUMN(Amplitude, amplitude, std::vector); //! Amplitudes of non-zero channels. The channel IDs are given in Channel (at the same index) +DECLARE_SOA_COLUMN(TimeFV0A, timeFV0A, std::vector); //! Time of non-zero channels. The channel IDs are given in Channel (at the same index). Only for the FITExtra table DECLARE_SOA_COLUMN(Channel, channel, std::vector); //! Channel IDs which had non-zero amplitudes. There are at maximum 48 channels. DECLARE_SOA_COLUMN(Time, time, float); //! Time in ns DECLARE_SOA_COLUMN(TriggerMask, triggerMask, uint8_t); //! @@ -1450,6 +1451,10 @@ DECLARE_SOA_TABLE(FV0As, "AOD", "FV0A", //! o2::soa::Index<>, fv0a::BCId, fv0a::Amplitude, fv0a::Channel, fv0a::Time, fv0a::TriggerMask); using FV0A = FV0As::iterator; +DECLARE_SOA_TABLE(FV0AsExtra, "AOD", "FV0AEXTRA", //! FV0AsExtra table + o2::soa::Index<>, fv0a::BCId, fv0a::TimeFV0A); +using FV0AExtra = FV0AsExtra::iterator; + // V0C table for Run2 only namespace fv0c { @@ -1467,8 +1472,10 @@ namespace ft0 { DECLARE_SOA_INDEX_COLUMN(BC, bc); //! BC index DECLARE_SOA_COLUMN(AmplitudeA, amplitudeA, std::vector); //! Amplitudes of non-zero channels on the A-side. The channel IDs are given in ChannelA (at the same index) +DECLARE_SOA_COLUMN(TimeFT0A, timeFT0A, std::vector); //! Time of non-zero channels on the A-side. The channel IDs are given in ChannelA (at the same index). Only for the FITExtra table DECLARE_SOA_COLUMN(ChannelA, channelA, std::vector); //! Channel IDs on the A side which had non-zero amplitudes. There are at maximum 96 channels. DECLARE_SOA_COLUMN(AmplitudeC, amplitudeC, std::vector); //! Amplitudes of non-zero channels on the C-side. The channel IDs are given in ChannelC (at the same index) +DECLARE_SOA_COLUMN(TimeFT0C, timeFT0C, std::vector); //! Time of non-zero channels on the C-side. The channel IDs are given in ChannelC (at the same index). Only for the FITExtra table DECLARE_SOA_COLUMN(ChannelC, channelC, std::vector); //! Channel IDs on the C side which had non-zero amplitudes. There are at maximum 112 channels. DECLARE_SOA_COLUMN(TimeA, timeA, float); //! Average A-side time DECLARE_SOA_COLUMN(TimeC, timeC, float); //! Average C-side time @@ -1512,6 +1519,11 @@ DECLARE_SOA_TABLE(FT0s, "AOD", "FT0", //! ft0::SumAmpA, ft0::SumAmpC); using FT0 = FT0s::iterator; +DECLARE_SOA_TABLE(FT0sExtra, "AOD", "FT0EXTRA", //! FT0sExtra table + o2::soa::Index<>, ft0::BCId, + ft0::TimeFT0A, ft0::TimeFT0C); +using FT0Extra = FT0sExtra::iterator; + namespace fdd { DECLARE_SOA_INDEX_COLUMN(BC, bc); //! BC index @@ -1521,6 +1533,9 @@ DECLARE_SOA_COLUMN(AmplitudeC, amplitudeC, float[4]); //! Amplitude in adjacent DECLARE_SOA_COLUMN(ChargeA, chargeA, int16_t[8]); //! Amplitude per channel A-side DECLARE_SOA_COLUMN(ChargeC, chargeC, int16_t[8]); //! Amplitude per channel C-side +DECLARE_SOA_COLUMN(TimeFDDA, timeFDDA, float[8]); //! Time per channel A-side, only for the FITExtra table +DECLARE_SOA_COLUMN(TimeFDDC, timeFDDC, float[8]); //! Time per channel C-side, only for the FITExtra table + DECLARE_SOA_COLUMN(TimeA, timeA, float); //! DECLARE_SOA_COLUMN(TimeC, timeC, float); //! DECLARE_SOA_COLUMN(TriggerMask, triggerMask, uint8_t); //! @@ -1542,6 +1557,11 @@ DECLARE_SOA_TABLE_VERSIONED(FDDs_001, "AOD", "FDD", 1, //! FDD table, version 00 using FDDs = FDDs_001; //! this defines the current default version using FDD = FDDs::iterator; +DECLARE_SOA_TABLE(FDDsExtra, "AOD", "FDDEXTRA", //! FDDsExtra table + o2::soa::Index<>, fdd::BCId, + fdd::TimeFDDA, fdd::TimeFDDC); +using FDDExtra = FDDsExtra::iterator; + namespace v0 { DECLARE_SOA_INDEX_COLUMN_FULL(PosTrack, posTrack, int, Tracks, "_Pos"); //! Positive track