diff --git a/Detectors/FIT/FDD/simulation/include/FDDSimulation/Digitizer.h b/Detectors/FIT/FDD/simulation/include/FDDSimulation/Digitizer.h index c7bd444d5ce63..943babc0a23d0 100644 --- a/Detectors/FIT/FDD/simulation/include/FDDSimulation/Digitizer.h +++ b/Detectors/FIT/FDD/simulation/include/FDDSimulation/Digitizer.h @@ -16,6 +16,7 @@ #include "DataFormatsFDD/ChannelData.h" #include "DataFormatsFDD/Digit.h" #include "DataFormatsFDD/MCLabel.h" +#include "DataFormatsFIT/DeadChannelMap.h" #include "FDDSimulation/Detector.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "FDDSimulation/DigitizationParameters.h" @@ -87,6 +88,8 @@ class Digitizer void init(); void finish(); + void setDeadChannelMap(o2::fit::DeadChannelMap const* deadChannelMap) { mDeadChannelMap = deadChannelMap; }; + private: static constexpr int BCCacheMin = -1, BCCacheMax = 10, NBC2Cache = 1 + BCCacheMax - BCCacheMin; @@ -125,6 +128,8 @@ class Digitizer static Double_t PMResponse(Double_t* x, Double_t*); static Double_t SinglePhESpectrum(Double_t* x, Double_t* par); + o2::fit::DeadChannelMap const* mDeadChannelMap = nullptr; + ClassDefNV(Digitizer, 4); }; } // namespace fdd diff --git a/Detectors/FIT/FDD/simulation/src/Digitizer.cxx b/Detectors/FIT/FDD/simulation/src/Digitizer.cxx index adb056792d8e4..53d67dab86453 100644 --- a/Detectors/FIT/FDD/simulation/src/Digitizer.cxx +++ b/Detectors/FIT/FDD/simulation/src/Digitizer.cxx @@ -49,6 +49,13 @@ void Digitizer::process(const std::vector& hits, // LOG(info) << "Pulse"; // Conversion of hits to the analogue pulse shape for (auto& hit : sorted_hits) { + int iChannel = hit.GetDetectorID(); + + // If the dead channel map is used, and the channel with ID 'hit_ch' is dead, don't process this hit. + if (mDeadChannelMap && !mDeadChannelMap->isChannelAlive(iChannel)) { + continue; + } + if (hit.GetTime() > 20e3) { const int maxWarn = 10; static int warnNo = 0; @@ -60,7 +67,6 @@ void Digitizer::process(const std::vector& hits, } std::array cachedIR; - int iChannel = hit.GetDetectorID(); int nPhotoElectrons = simulateLightYield(iChannel, hit.GetNphot()); double delayScintillator = mRndScintDelay.getNextValue(); diff --git a/Detectors/FIT/FT0/simulation/include/FT0Simulation/Digitizer.h b/Detectors/FIT/FT0/simulation/include/FT0Simulation/Digitizer.h index bd5693707673f..3a035a247c6ef 100644 --- a/Detectors/FIT/FT0/simulation/include/FT0Simulation/Digitizer.h +++ b/Detectors/FIT/FT0/simulation/include/FT0Simulation/Digitizer.h @@ -13,6 +13,7 @@ #define ALICEO2_FT0_DIGITIZER_H #include "CommonDataFormat/InteractionRecord.h" +#include "DataFormatsFIT/DeadChannelMap.h" #include "DataFormatsFT0/Digit.h" #include "DataFormatsFT0/ChannelData.h" #include "DataFormatsFT0/MCLabel.h" @@ -73,6 +74,7 @@ class Digitizer void SetChannelOffset(o2::ft0::FT0ChannelTimeCalibrationObject const* caliboffsets) { mCalibOffset = caliboffsets; }; + void setDeadChannelMap(o2::fit::DeadChannelMap const* deadChannelMap) { mDeadChannelMap = deadChannelMap; }; double getTimeOffsetWrtBC() const { return mIntRecord.getTimeOffsetWrtBC(); } struct CFDOutput { @@ -165,6 +167,7 @@ class Digitizer o2::dataformats::MCTruthContainer& labels); o2::ft0::FT0ChannelTimeCalibrationObject const* mCalibOffset = nullptr; + o2::fit::DeadChannelMap const* mDeadChannelMap = nullptr; ClassDefNV(Digitizer, 3); }; diff --git a/Detectors/FIT/FT0/simulation/src/Digitizer.cxx b/Detectors/FIT/FT0/simulation/src/Digitizer.cxx index 583f62019f8a0..0c3c26ec5b62b 100644 --- a/Detectors/FIT/FT0/simulation/src/Digitizer.cxx +++ b/Detectors/FIT/FT0/simulation/src/Digitizer.cxx @@ -204,8 +204,16 @@ void Digitizer::process(const std::vector* hits, if (hit.GetEnergyLoss() > 0) { continue; } - const auto& params = FT0DigParam::Instance(); + Int_t hit_ch = hit.GetDetectorID(); + + // If the dead channel map is used, and the channel with ID 'hit_ch' is dead, don't process this hit. + if (mDeadChannelMap && !mDeadChannelMap->isChannelAlive(hit_ch)) { + continue; + } + + const auto& params = FT0DigParam::Instance(); + Bool_t is_A_side = (hit_ch < 4 * mGeometry.NCellsA); Float_t time_compensate = is_A_side ? params.mA_side_cable_cmps : params.mC_side_cable_cmps; Double_t hit_time = hit.GetTime() - time_compensate; @@ -248,6 +256,9 @@ void Digitizer::storeBC(BCCache& bc, auto channel_begin = channel_end; channel_end = std::find_if(channel_begin, particles.end(), [ipmt](BCCache::particle const& p) { return p.hit_ch != ipmt; }); + + // The hits between 'channel_begin' and 'channel_end' now contains all hits for channel 'ipmt' + if (channel_end - channel_begin < params.mAmp_trsh) { continue; } diff --git a/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx index 75892b27a1589..99150a3cb83fb 100644 --- a/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/FDDDigitizerSpec.cxx @@ -11,6 +11,7 @@ #include "FDDDigitizerSpec.h" #include "TChain.h" +#include "Framework/CCDBParamSpec.h" #include "Framework/ControlService.h" #include "Framework/ConfigParamRegistry.h" #include "Framework/DataProcessorSpec.h" @@ -28,6 +29,7 @@ #include "DataFormatsFDD/Digit.h" #include "DataFormatsFDD/ChannelData.h" #include "DataFormatsFDD/MCLabel.h" +#include "DataFormatsFIT/DeadChannelMap.h" using namespace o2::framework; using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; @@ -49,7 +51,18 @@ class FDDDPLDigitizerTask : public o2::base::BaseDPLDigitizer //mDigitizer.setCCDBServer(dopt.ccdb); mDigitizer.init(); //mROMode = mDigitizer.isContinuous() ? o2::parameters::GRPObject::CONTINUOUS : o2::parameters::GRPObject::PRESENT; + mUseDeadChannelMap = !ic.options().get("disable-dead-channel-map"); + mUpdateDeadChannelMap = mUseDeadChannelMap; } + + void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) + { + // Initialize the dead channel map only once + if (matcher == ConcreteDataMatcher("FDD", "DeadChannelMap", 0)) { + mUpdateDeadChannelMap = false; + } + } + void run(framework::ProcessingContext& pc) { if (mFinished) { @@ -70,6 +83,12 @@ class FDDDPLDigitizerTask : public o2::base::BaseDPLDigitizer LOG(info) << "FDD TIME RECEIVED " << record.getTimeNS(); } + // Initialize the dead channel map + if (mUpdateDeadChannelMap && mUseDeadChannelMap) { + auto deadChannelMap = pc.inputs().get("fdddeadchannelmap"); + mDigitizer.setDeadChannelMap(deadChannelMap.get()); + } + auto& eventParts = context->getEventParts(); // loop over all composite collisions given from context @@ -128,6 +147,9 @@ class FDDDPLDigitizerTask : public o2::base::BaseDPLDigitizer // RS: at the moment using hardcoded flag for continuous readout o2::parameters::GRPObject::ROMode mROMode = o2::parameters::GRPObject::ROMode(o2::parameters::GRPObject::CONTINUOUS | o2::parameters::GRPObject::TRIGGERING); // readout mode + + bool mUseDeadChannelMap = true; + bool mUpdateDeadChannelMap = true; }; o2::framework::DataProcessorSpec getFDDDigitizerSpec(int channel, bool mctruth) @@ -137,6 +159,11 @@ o2::framework::DataProcessorSpec getFDDDigitizerSpec(int channel, bool mctruth) // input description // algorithmic description (here a lambda getting called once to setup the actual processing function) // options that can be used for this processor (here: input file names where to take the hits) + std::vector inputs; + inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe); + inputs.emplace_back("fdddeadchannelmap", "FDD", "DeadChannelMap", 0, + Lifetime::Condition, + ccdbParamSpec("FDD/Calib/DeadChannelMap", {}, -1)); std::vector outputs; outputs.emplace_back("FDD", "DIGITSBC", 0, Lifetime::Timeframe); outputs.emplace_back("FDD", "DIGITSCH", 0, Lifetime::Timeframe); @@ -148,10 +175,10 @@ o2::framework::DataProcessorSpec getFDDDigitizerSpec(int channel, bool mctruth) return DataProcessorSpec{ "FDDDigitizer", - Inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe}}, + inputs, outputs, AlgorithmSpec{adaptFromTask()}, - Options{}}; + Options{{"disable-dead-channel-map", VariantType::Bool, false, {"Don't mask dead channels"}}}}; } } // namespace fdd } // namespace o2 diff --git a/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx index f539145462300..4eda984358634 100644 --- a/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/FT0DigitizerSpec.cxx @@ -18,6 +18,7 @@ #include "Headers/DataHeader.h" #include "Steer/HitProcessingManager.h" // for DigitizationContext #include "FT0Simulation/Digitizer.h" +#include "DataFormatsFIT/DeadChannelMap.h" #include "DataFormatsFT0/ChannelData.h" #include "DataFormatsFT0/HitType.h" #include "DataFormatsFT0/Digit.h" @@ -58,13 +59,19 @@ class FT0DPLDigitizerTask : public o2::base::BaseDPLDigitizer mDigitizer.init(); mROMode = o2::parameters::GRPObject::ROMode(o2::parameters::GRPObject::TRIGGERING | (mDigitizer.isContinuous() ? o2::parameters::GRPObject::CONTINUOUS : o2::parameters::GRPObject::PRESENT)); mDisableQED = ic.options().get("disable-qed"); + mUseDeadChannelMap = !ic.options().get("disable-dead-channel-map"); + mUpdateDeadChannelMap = mUseDeadChannelMap; } void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) { if (matcher == ConcreteDataMatcher("FT0", "TimeOffset", 0)) { mUpdateCCDB = false; - return; + } + + // Initialize the dead channel map only once + if (matcher == ConcreteDataMatcher("FT0", "DeadChannelMap", 0)) { + mUpdateDeadChannelMap = false; } } @@ -85,6 +92,13 @@ class FT0DPLDigitizerTask : public o2::base::BaseDPLDigitizer auto caliboffsets = pc.inputs().get("ft0offsets"); mDigitizer.SetChannelOffset(caliboffsets.get()); } + + // Initialize the dead channel map + if (mUpdateDeadChannelMap && mUseDeadChannelMap) { + auto deadChannelMap = pc.inputs().get("ft0deadchannelmap"); + mDigitizer.setDeadChannelMap(deadChannelMap.get()); + } + // if there is nothing to do ... return if (timesview.size() == 0) { return; @@ -158,6 +172,8 @@ class FT0DPLDigitizerTask : public o2::base::BaseDPLDigitizer bool mDisableQED = false; bool mUseCCDB = true; bool mUpdateCCDB = true; + bool mUseDeadChannelMap = true; + bool mUpdateDeadChannelMap = true; std::vector mSimChains; }; @@ -183,13 +199,18 @@ o2::framework::DataProcessorSpec getFT0DigitizerSpec(int channel, bool mctruth, Lifetime::Condition, ccdbParamSpec("FT0/Calib/ChannelTimeOffset")); } + inputs.emplace_back("ft0deadchannelmap", "FT0", "DeadChannelMap", 0, + Lifetime::Condition, + ccdbParamSpec("FT0/Calib/DeadChannelMap", {}, -1)); + return DataProcessorSpec{ "FT0Digitizer", inputs, outputs, AlgorithmSpec{adaptFromTask(useCCDB)}, Options{{"pileup", VariantType::Int, 1, {"whether to run in continuous time mode"}}, - {"disable-qed", o2::framework::VariantType::Bool, false, {"disable QED handling"}}}}; + {"disable-qed", VariantType::Bool, false, {"disable QED handling"}}, + {"disable-dead-channel-map", VariantType::Bool, false, {"Don't mask dead channels"}}}}; } } // namespace ft0