diff --git a/Detectors/TPC/base/CMakeLists.txt b/Detectors/TPC/base/CMakeLists.txt index d4331ed42f220..c13fec6f03ab7 100644 --- a/Detectors/TPC/base/CMakeLists.txt +++ b/Detectors/TPC/base/CMakeLists.txt @@ -69,7 +69,8 @@ o2_target_root_dictionary(TPCBase include/TPCBase/CRUCalibHelpers.h include/TPCBase/IonTailSettings.h include/TPCBase/FEEConfig.h - include/TPCBase/DeadChannelMapCreator.h) + include/TPCBase/DeadChannelMapCreator.h + include/TPCBase/CDBTypes.h) o2_add_test(Base COMPONENT_NAME tpc PUBLIC_LINK_LIBRARIES O2::TPCBase diff --git a/Detectors/TPC/base/include/TPCBase/CDBInterface.h b/Detectors/TPC/base/include/TPCBase/CDBInterface.h index 4ad354e9676ee..1356aa01ca880 100644 --- a/Detectors/TPC/base/include/TPCBase/CDBInterface.h +++ b/Detectors/TPC/base/include/TPCBase/CDBInterface.h @@ -24,7 +24,11 @@ #include "CCDB/BasicCCDBManager.h" #include "CCDB/CcdbApi.h" #include "TPCBase/CalDet.h" +#include "TPCBase/FEEConfig.h" +#include "TPCBase/CDBTypes.h" +#include "TPCBase/DeadChannelMapCreator.h" #include "DataFormatsTPC/LtrCalibData.h" +#include "DataFormatsTPC/Defs.h" #include "CommonUtils/NameConf.h" namespace o2::tpc @@ -35,63 +39,6 @@ class ParameterElectronics; class ParameterGas; class ParameterGEM; -/// Calibration and parameter types for CCDB -enum class CDBType { - CalPedestal, ///< Pedestal calibration - CalNoise, ///< Noise calibration - CalPedestalNoise, ///< Pedestal and Noise calibration - CalPulser, ///< Pulser calibration - CalCE, ///< Laser CE calibration - CalPadGainFull, ///< Full pad gain calibration - CalPadGainResidual, ///< ResidualpPad gain calibration (e.g. from tracks) - CalLaserTracks, ///< Laser track calibration data - CalVDriftTgl, ///< ITS-TPC difTgl vdrift calibration - CalTimeGain, ///< Gain variation over time - CalGas, ///< DCS gas measurements - CalTemperature, ///< DCS temperature measurements - CalHV, ///< DCS HV measurements - CalTopologyGain, ///< Q cluster topology correction - /// - ConfigFEEPad, ///< FEE pad-by-pad configuration map - ConfigFEE, ///< FEE configuration map for each tag - ConfigRunInfo, ///< FEE run information (run -> tag) - /// - ParDetector, ///< Parameter for Detector - ParElectronics, ///< Parameter for Electronics - ParGas, ///< Parameter for Gas - ParGEM, ///< Parameter for GEM - /// - CalIDC0A, ///< I_0(r,\phi) = _t - CalIDC0C, ///< I_0(r,\phi) = _t - CalIDC1A, ///< I_1(t) = _{r,\phi} - CalIDC1C, ///< I_1(t) = _{r,\phi} - CalIDCDeltaA, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) - CalIDCDeltaC, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) - CalIDCFourierA, ///< Fourier coefficients of CalIDC1 - CalIDCFourierC, ///< Fourier coefficients of CalIDC1 - CalIDCPadStatusMapA, ///< Status map of the pads (dead etc. obatined from CalIDC0) - CalIDCPadStatusMapC, ///< Status map of the pads (dead etc. obatined from CalIDC0) - CalIDCGroupingParA, ///< Parameters which were used for the averaging of the CalIDCDelta - CalIDCGroupingParC, ///< Parameters which were used for the averaging of the CalIDCDelta - /// - CalSAC0, ///< I_0(r,\phi) = _t - CalSAC1, ///< I_1(t) = _{r,\phi} - CalSACDelta, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) - CalSACFourier, ///< Fourier coefficients of CalSAC1 - /// - CalITPC0, ///< 2D average TPC clusters for longer time interval - CalITPC1, ///< 1D integrated TPC clusters - /// - CalCorrMap, ///< Cluster correction map (high IR rate distortions) - CalCorrMapRef, ///< Cluster correction reference map (static distortions) - /// - CalCorrDerivMap, ///< Cluster correction map (derivative map) - /// - CalTimeSeries, ///< integrated DCAs for longer time interval - CalScaler, ///< Scaler from IDCs or combined estimator - /// - CorrMapParam, ///< parameters for CorrectionMapsLoader configuration -}; /// Upload intervention type enum class CDBIntervention { @@ -99,63 +46,6 @@ enum class CDBIntervention { Automatic, ///< Automatic upload }; -/// Storage name in CCDB for each calibration and parameter type -const std::unordered_map CDBTypeMap{ - {CDBType::CalPedestal, "TPC/Calib/Pedestal"}, - {CDBType::CalNoise, "TPC/Calib/Noise"}, - {CDBType::CalPedestalNoise, "TPC/Calib/PedestalNoise"}, - {CDBType::CalPulser, "TPC/Calib/Pulser"}, - {CDBType::CalCE, "TPC/Calib/CE"}, - {CDBType::CalPadGainFull, "TPC/Calib/PadGainFull"}, - {CDBType::CalPadGainResidual, "TPC/Calib/PadGainResidual"}, - {CDBType::CalLaserTracks, "TPC/Calib/LaserTracks"}, - {CDBType::CalTimeGain, "TPC/Calib/TimeGain"}, - {CDBType::CalGas, "TPC/Calib/Gas"}, - {CDBType::CalTemperature, "TPC/Calib/Temperature"}, - {CDBType::CalHV, "TPC/Calib/HV"}, - {CDBType::CalTopologyGain, "TPC/Calib/TopologyGainPiecewise"}, - {CDBType::CalVDriftTgl, "TPC/Calib/VDriftTgl"}, - // - {CDBType::ConfigFEEPad, "TPC/Config/FEEPad"}, - {CDBType::ConfigFEE, "TPC/Config/FEE"}, - {CDBType::ConfigRunInfo, "TPC/Config/RunInfo"}, - // - {CDBType::ParDetector, "TPC/Parameter/Detector"}, - {CDBType::ParElectronics, "TPC/Parameter/Electronics"}, - {CDBType::ParGas, "TPC/Parameter/Gas"}, - {CDBType::ParGEM, "TPC/Parameter/GEM"}, - // IDCs - {CDBType::CalIDC0A, "TPC/Calib/IDC_0_A"}, - {CDBType::CalIDC0C, "TPC/Calib/IDC_0_C"}, - {CDBType::CalIDC1A, "TPC/Calib/IDC_1_A"}, - {CDBType::CalIDC1C, "TPC/Calib/IDC_1_C"}, - {CDBType::CalIDCDeltaA, "TPC/Calib/IDC_DELTA_A"}, - {CDBType::CalIDCDeltaC, "TPC/Calib/IDC_DELTA_C"}, - {CDBType::CalIDCFourierA, "TPC/Calib/IDC_FOURIER_A"}, - {CDBType::CalIDCFourierC, "TPC/Calib/IDC_FOURIER_C"}, - {CDBType::CalIDCPadStatusMapA, "TPC/Calib/IDC_PadStatusMap_A"}, - {CDBType::CalIDCPadStatusMapC, "TPC/Calib/IDC_PadStatusMap_C"}, - {CDBType::CalIDCGroupingParA, "TPC/Calib/IDC_GROUPINGPAR_A"}, - {CDBType::CalIDCGroupingParC, "TPC/Calib/IDC_GROUPINGPAR_C"}, - // SACs - {CDBType::CalSAC0, "TPC/Calib/SAC_0"}, - {CDBType::CalSAC1, "TPC/Calib/SAC_1"}, - {CDBType::CalSACDelta, "TPC/Calib/SAC_DELTA"}, - {CDBType::CalSACFourier, "TPC/Calib/SAC_FOURIER"}, - // ITPCCs - {CDBType::CalITPC0, "TPC/Calib/ITPCC_0"}, - {CDBType::CalITPC1, "TPC/Calib/ITPCC_1"}, - // correction maps - {CDBType::CalCorrMap, "TPC/Calib/CorrectionMapV2"}, - {CDBType::CalCorrMapRef, "TPC/Calib/CorrectionMapRefV2"}, - // derivative map correction - {CDBType::CalCorrDerivMap, "TPC/Calib/CorrectionMapDerivativeV2"}, - // time series - {CDBType::CalTimeSeries, "TPC/Calib/TimeSeries"}, - {CDBType::CalScaler, "TPC/Calib/Scaler"}, - // correction maps loader params - {CDBType::CorrMapParam, "TPC/Calib/CorrMapParam"}, -}; /// Poor enum reflection ... const std::unordered_map CDBInterventionMap{ @@ -178,6 +68,7 @@ class CDBInterface { public: using CalPadMapType = std::unordered_map; + using CalPadFlagType = CalDet; CDBInterface(const CDBInterface&) = delete; @@ -233,6 +124,17 @@ class CDBInterface /// \return common mode per pad values const CalPad& getCMkValues(); + /// Pad status flags from IDCs + const CalPadFlagType& getPadFlags(); + + /// Return FEEConfig + const FEEConfig& getFEEConfig(); + + /// Dead channel map creator + DeadChannelMapCreator& getDeadChannelMapCreator() { return mDeadChannelMapCreator; } + + /// Dead channel map + const CalDet& getDeadChannelMap(); /// Return the Detector parameters /// /// The function checks if the object is already loaded and returns it @@ -325,6 +227,7 @@ class CDBInterface { auto& cdb = o2::ccdb::BasicCCDBManager::instance(); cdb.setURL(url.data()); + mDeadChannelMapCreator.init(url); } /// set the Zero suppression threshold in sigma of noise in case @@ -344,25 +247,29 @@ class CDBInterface } private: - CDBInterface() = default; + CDBInterface(); // ===| Pad calibrations |==================================================== - std::unique_ptr mPedestals; ///< Pedestal object - std::unique_ptr mPedestalsCRU; ///< Pedestal object with 10+2bit precision as used in CRU - std::unique_ptr mNoise; ///< Noise object - std::unique_ptr mZeroSuppression; ///< Zero suppression object - std::unique_ptr mGainMap; ///< Gain map object - std::unique_ptr mITFraction; ///< Ion Tail fraction - std::unique_ptr mITExpLambda; ///< Ion Tail exp(-lambda) - std::unique_ptr mCMkValues; ///< Ion Tail exp(-lambda) + std::unique_ptr mPedestals; ///< Pedestal object + std::unique_ptr mPedestalsCRU; ///< Pedestal object with 10+2bit precision as used in CRU + std::unique_ptr mNoise; ///< Noise object + std::unique_ptr mZeroSuppression; ///< Zero suppression object + std::unique_ptr mGainMap; ///< Gain map object + std::unique_ptr mITFraction; ///< Ion Tail fraction + std::unique_ptr mITExpLambda; ///< Ion Tail exp(-lambda) + std::unique_ptr mCMkValues; ///< Ion Tail exp(-lambda) + std::unique_ptr mPadFlags; ///< Pad flags from IDCs + + std::unique_ptr mFEEConfig; ///< FEE Config // ===| switches and parameters |============================================= bool mUseDefaults = false; ///< use defaults instead of CCDB float mDefaultZSsigma = 3.f; ///< sigma to use in case the default zero suppression is created - std::string mPedestalNoiseFileName; ///< optional file name for pedestal and noise data - std::string mGainMapFileName; ///< optional file name for the gain map - std::string mFEEParamFileName; ///< optional file name for the FEE parameters (ion tail, common mode, threshold, pedestals) + std::string mPedestalNoiseFileName; ///< optional file name for pedestal and noise data + std::string mGainMapFileName; ///< optional file name for the gain map + std::string mFEEParamFileName; ///< optional file name for the FEE parameters (ion tail, common mode, threshold, pedestals) + DeadChannelMapCreator mDeadChannelMapCreator; ///< creation of dead channel map // =========================================================================== // ===| functions |=========================================================== @@ -377,6 +284,9 @@ class CDBInterface void createDefaultGainMap(); ///< creation of default gain map if requested void createDefaultIonTailParams(); ///< creation of default ion tail parameters void createDefaultCMParams(); ///< creation of default common mode parameters + void createDefaultPadFlags(); ///< creation of default pad flags + + void createFEEConfig(); ///< create a best guess FEEConfig; }; /// Get an object from the CCDB. diff --git a/Detectors/TPC/base/include/TPCBase/CDBTypes.h b/Detectors/TPC/base/include/TPCBase/CDBTypes.h new file mode 100644 index 0000000000000..c17d21c8587ae --- /dev/null +++ b/Detectors/TPC/base/include/TPCBase/CDBTypes.h @@ -0,0 +1,142 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file CDBTypes.h +/// \brief CDB Type definitions for TPC +/// \author Jens Wiechula, Jens.Wiechula@ikf.uni-frankfurt.de + +#ifndef AliceO2_TPC_CDBTypes_H_ +#define AliceO2_TPC_CDBTypes_H_ + +#include +#include + +namespace o2::tpc +{ + +/// Calibration and parameter types for CCDB +enum class CDBType { + CalPedestal, ///< Pedestal calibration + CalNoise, ///< Noise calibration + CalPedestalNoise, ///< Pedestal and Noise calibration + CalPulser, ///< Pulser calibration + CalCE, ///< Laser CE calibration + CalPadGainFull, ///< Full pad gain calibration + CalPadGainResidual, ///< ResidualpPad gain calibration (e.g. from tracks) + CalLaserTracks, ///< Laser track calibration data + CalVDriftTgl, ///< ITS-TPC difTgl vdrift calibration + CalTimeGain, ///< Gain variation over time + CalGas, ///< DCS gas measurements + CalTemperature, ///< DCS temperature measurements + CalHV, ///< DCS HV measurements + CalTopologyGain, ///< Q cluster topology correction + /// + ConfigFEEPad, ///< FEE pad-by-pad configuration map + ConfigFEE, ///< FEE configuration map for each tag + ConfigRunInfo, ///< FEE run information (run -> tag) + /// + ParDetector, ///< Parameter for Detector + ParElectronics, ///< Parameter for Electronics + ParGas, ///< Parameter for Gas + ParGEM, ///< Parameter for GEM + /// + CalIDC0A, ///< I_0(r,\phi) = _t + CalIDC0C, ///< I_0(r,\phi) = _t + CalIDC1A, ///< I_1(t) = _{r,\phi} + CalIDC1C, ///< I_1(t) = _{r,\phi} + CalIDCDeltaA, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) + CalIDCDeltaC, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) + CalIDCFourierA, ///< Fourier coefficients of CalIDC1 + CalIDCFourierC, ///< Fourier coefficients of CalIDC1 + CalIDCPadStatusMapA, ///< Status map of the pads (dead etc. obatined from CalIDC0) + CalIDCPadStatusMapC, ///< Status map of the pads (dead etc. obatined from CalIDC0) + CalIDCGroupingParA, ///< Parameters which were used for the averaging of the CalIDCDelta + CalIDCGroupingParC, ///< Parameters which were used for the averaging of the CalIDCDelta + /// + CalSAC0, ///< I_0(r,\phi) = _t + CalSAC1, ///< I_1(t) = _{r,\phi} + CalSACDelta, ///< \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) ) + CalSACFourier, ///< Fourier coefficients of CalSAC1 + /// + CalITPC0, ///< 2D average TPC clusters for longer time interval + CalITPC1, ///< 1D integrated TPC clusters + /// + CalCorrMap, ///< Cluster correction map (high IR rate distortions) + CalCorrMapRef, ///< Cluster correction reference map (static distortions) + /// + CalCorrDerivMap, ///< Cluster correction map (derivative map) + /// + CalTimeSeries, ///< integrated DCAs for longer time interval + CalScaler, ///< Scaler from IDCs or combined estimator + /// + CorrMapParam, ///< parameters for CorrectionMapsLoader configuration +}; + +/// Storage name in CCDB for each calibration and parameter type +const std::unordered_map CDBTypeMap{ + {CDBType::CalPedestal, "TPC/Calib/Pedestal"}, + {CDBType::CalNoise, "TPC/Calib/Noise"}, + {CDBType::CalPedestalNoise, "TPC/Calib/PedestalNoise"}, + {CDBType::CalPulser, "TPC/Calib/Pulser"}, + {CDBType::CalCE, "TPC/Calib/CE"}, + {CDBType::CalPadGainFull, "TPC/Calib/PadGainFull"}, + {CDBType::CalPadGainResidual, "TPC/Calib/PadGainResidual"}, + {CDBType::CalLaserTracks, "TPC/Calib/LaserTracks"}, + {CDBType::CalTimeGain, "TPC/Calib/TimeGain"}, + {CDBType::CalGas, "TPC/Calib/Gas"}, + {CDBType::CalTemperature, "TPC/Calib/Temperature"}, + {CDBType::CalHV, "TPC/Calib/HV"}, + {CDBType::CalTopologyGain, "TPC/Calib/TopologyGainPiecewise"}, + {CDBType::CalVDriftTgl, "TPC/Calib/VDriftTgl"}, + // + {CDBType::ConfigFEEPad, "TPC/Config/FEEPad"}, + {CDBType::ConfigFEE, "TPC/Config/FEE"}, + {CDBType::ConfigRunInfo, "TPC/Config/RunInfo"}, + // + {CDBType::ParDetector, "TPC/Parameter/Detector"}, + {CDBType::ParElectronics, "TPC/Parameter/Electronics"}, + {CDBType::ParGas, "TPC/Parameter/Gas"}, + {CDBType::ParGEM, "TPC/Parameter/GEM"}, + // IDCs + {CDBType::CalIDC0A, "TPC/Calib/IDC_0_A"}, + {CDBType::CalIDC0C, "TPC/Calib/IDC_0_C"}, + {CDBType::CalIDC1A, "TPC/Calib/IDC_1_A"}, + {CDBType::CalIDC1C, "TPC/Calib/IDC_1_C"}, + {CDBType::CalIDCDeltaA, "TPC/Calib/IDC_DELTA_A"}, + {CDBType::CalIDCDeltaC, "TPC/Calib/IDC_DELTA_C"}, + {CDBType::CalIDCFourierA, "TPC/Calib/IDC_FOURIER_A"}, + {CDBType::CalIDCFourierC, "TPC/Calib/IDC_FOURIER_C"}, + {CDBType::CalIDCPadStatusMapA, "TPC/Calib/IDC_PadStatusMap_A"}, + {CDBType::CalIDCPadStatusMapC, "TPC/Calib/IDC_PadStatusMap_C"}, + {CDBType::CalIDCGroupingParA, "TPC/Calib/IDC_GROUPINGPAR_A"}, + {CDBType::CalIDCGroupingParC, "TPC/Calib/IDC_GROUPINGPAR_C"}, + // SACs + {CDBType::CalSAC0, "TPC/Calib/SAC_0"}, + {CDBType::CalSAC1, "TPC/Calib/SAC_1"}, + {CDBType::CalSACDelta, "TPC/Calib/SAC_DELTA"}, + {CDBType::CalSACFourier, "TPC/Calib/SAC_FOURIER"}, + // ITPCCs + {CDBType::CalITPC0, "TPC/Calib/ITPCC_0"}, + {CDBType::CalITPC1, "TPC/Calib/ITPCC_1"}, + // correction maps + {CDBType::CalCorrMap, "TPC/Calib/CorrectionMapV2"}, + {CDBType::CalCorrMapRef, "TPC/Calib/CorrectionMapRefV2"}, + // derivative map correction + {CDBType::CalCorrDerivMap, "TPC/Calib/CorrectionMapDerivativeV2"}, + // time series + {CDBType::CalTimeSeries, "TPC/Calib/TimeSeries"}, + {CDBType::CalScaler, "TPC/Calib/Scaler"}, + // correction maps loader params + {CDBType::CorrMapParam, "TPC/Calib/CorrMapParam"}, +}; + +} // namespace o2::tpc +#endif diff --git a/Detectors/TPC/base/include/TPCBase/CalDet.h b/Detectors/TPC/base/include/TPCBase/CalDet.h index 835e3638642df..cab1bd5757f27 100644 --- a/Detectors/TPC/base/include/TPCBase/CalDet.h +++ b/Detectors/TPC/base/include/TPCBase/CalDet.h @@ -155,15 +155,35 @@ inline const T CalDet::getValue(const int sector, const int globalPadInSector { // This shold be a temporary speedup, a proper restructuring of Mapper and CalDet/CalArray is needed. // The default granularity for the moment should be ROC, for the assumptions below this should be assured - assert(mPadSubset == PadSubset::ROC); - int roc = sector; + const Mapper& mapper = Mapper::instance(); + auto padPos = mapper.padPos(globalPadInSector); // global row in sector + const auto globalRow = padPos.getRow(); + + int rocNumber = sector; int padInROC = globalPadInSector; const int padsInIROC = Mapper::getPadsInIROC(); if (globalPadInSector >= padsInIROC) { - roc += Mapper::getNumberOfIROCs(); + rocNumber += Mapper::getNumberOfIROCs(); padInROC -= padsInIROC; } - return mData[roc].getValue(padInROC); + + switch (mPadSubset) { + case PadSubset::ROC: { + return mData[rocNumber].getValue(padInROC); + break; + } + case PadSubset::Partition: { + return T{}; + break; + } + case PadSubset::Region: { + const ROC roc(rocNumber); + const auto mappedPad = padPos.getPad(); + return mData[Mapper::REGION[globalRow] + roc.getSector() * Mapper::NREGIONS].getValue(Mapper::OFFSETCRUGLOBAL[globalRow] + mappedPad); + break; + } + } + return T{}; } //______________________________________________________________________________ diff --git a/Detectors/TPC/base/include/TPCBase/DeadChannelMapCreator.h b/Detectors/TPC/base/include/TPCBase/DeadChannelMapCreator.h index 9ae2f8d548a9e..dbdefb4ef0f37 100644 --- a/Detectors/TPC/base/include/TPCBase/DeadChannelMapCreator.h +++ b/Detectors/TPC/base/include/TPCBase/DeadChannelMapCreator.h @@ -12,15 +12,18 @@ #ifndef ALICEO2_TPC_DeadChannelMapCreator_H_ #define ALICEO2_TPC_DeadChannelMapCreator_H_ +#include #include #include +#include #include "Rtypes.h" #include "CCDB/CcdbApi.h" #include "DataFormatsTPC/Defs.h" -#include "TPCBase/CDBInterface.h" +#include "TPCBase/CDBTypes.h" +#include "TPCBase/CalDet.h" #include "TPCBase/FEEConfig.h" namespace o2::tpc @@ -51,7 +54,7 @@ class DeadChannelMapCreator void reset(); - void init(); + void init(std::string_view url = ""); void load(long timeStampOrRun); void loadFEEConfigViaRunInfoTS(long timeStamp); void loadFEEConfigViaRunInfo(long timeStampOrRun); @@ -64,6 +67,9 @@ class DeadChannelMapCreator const CalDet& getDeadChannelMapFEE() const { return mDeadChannelMapFEE; } const CalDet& getDeadChannelMap() const { return mDeadChannelMap; } + const FEEConfig* getFEEConfig() const { return mFEEConfig.get(); } + const CalDetFlag_t* getPadFlags() const { return mPadStatusMap.get(); } + void drawDeadChannelMapIDC(); void drawDeadChannelMapFEE(); void drawDeadChannelMap(); diff --git a/Detectors/TPC/base/include/TPCBase/FEEConfig.h b/Detectors/TPC/base/include/TPCBase/FEEConfig.h index 5093c6b51600c..ef495e9f219da 100644 --- a/Detectors/TPC/base/include/TPCBase/FEEConfig.h +++ b/Detectors/TPC/base/include/TPCBase/FEEConfig.h @@ -102,11 +102,16 @@ struct FEEConfig { bool isZSEnabled() const; bool isResyncEnabled() const; + void setAllLinksOn(); + void print() const; + void printShort() const; /// Dead channel map including deactivated links and single channels CalDet getDeadChannelMap() const; + const CalPad& getPadMap(PadConfig config) const { return padMaps.at(PadConfigNames.at(config)); } + ClassDefNV(FEEConfig, 2); }; diff --git a/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h b/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h index 42dfc2d3a7d9a..a44410d29ae15 100644 --- a/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h +++ b/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h @@ -21,9 +21,7 @@ #include "CommonUtils/ConfigurableParamHelper.h" #include "CommonConstants/LHCConstants.h" -namespace o2 -{ -namespace tpc +namespace o2::tpc { enum class DigitzationMode : char { @@ -32,7 +30,8 @@ enum class DigitzationMode : char { ZeroSuppressionCMCorr = 2, ///< Apply noise, pedestal and saturation and then from that subtract the pedestal and apply zero suppression SubtractPedestal = 3, ///< Apply noise, pedestal and saturation and then from that subtract the pedestal NoSaturation = 4, ///< Apply only noise and pedestal - PropagateADC = 5 ///< Just propagate the bare ADC value + PropagateADC = 5, ///< Just propagate the bare ADC value + Auto = 6, ///< Automatically decide based on DCS settings in CCDB }; struct ParameterElectronics : public o2::conf::ConfigurableParamHelper { @@ -49,11 +48,12 @@ struct ParameterElectronics : public o2::conf::ConfigurableParamHelper(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("Pedestals"); + // return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("Pedestals"); + return getFEEConfig().getPadMap(FEEConfig::PadConfig::Pedestals); } if (!mPedestalsCRU) { @@ -135,7 +142,8 @@ const CalPad& CDBInterface::getZeroSuppressionThreshold() } } else { // return from CDB, assume that check for object existence are done there - return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("ThresholdMap"); + // return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("ThresholdMap"); + return getFEEConfig().getPadMap(FEEConfig::PadConfig::ThresholdMap); } return *mZeroSuppression; } @@ -178,7 +186,8 @@ const CalPad& CDBInterface::getITFraction() } } else { // return from CDB, assume that check for object existence are done there - return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("ITfraction"); + // return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("ITfraction"); + return getFEEConfig().getPadMap(FEEConfig::PadConfig::ITfraction); } if (!mITFraction) { @@ -202,7 +211,8 @@ const CalPad& CDBInterface::getITExpLambda() } } else { // return from CDB, assume that check for object existence are done there - return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("ITexpLambda"); + // return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("ITexpLambda"); + return getFEEConfig().getPadMap(FEEConfig::PadConfig::ITexpLambda); } if (!mITExpLambda) { @@ -226,14 +236,63 @@ const CalPad& CDBInterface::getCMkValues() } } else { // return from CDB, assume that check for object existence are done there - return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("CMkValues"); + // return getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)).at("CMkValues"); + return getFEEConfig().getPadMap(FEEConfig::PadConfig::CMkValues); } - if (!mITExpLambda) { + if (!mCMkValues) { LOG(fatal) << "No valid ion tail slope (expLamda) parameters were loaded"; } - return *mITExpLambda; + return *mCMkValues; +} + +//______________________________________________________________________________ +const CDBInterface::CalPadFlagType& CDBInterface::getPadFlags() +{ + if (mUseDefaults) { + if (!mPadFlags) { + createDefaultPadFlags(); + } + } else { + // return from CDB, assume that check for object existence are done there + return getObjectFromCDB(CDBTypeMap.at(CDBType::CalIDCPadStatusMapA)); + } + + if (!mPadFlags) { + LOG(fatal) << "No valid ion tail slope (expLamda) parameters were loaded"; + } + + return *mPadFlags; +} + +//______________________________________________________________________________ +const CalDet& CDBInterface::getDeadChannelMap() +{ + auto& cdb = o2::ccdb::BasicCCDBManager::instance(); + getFEEConfig(); + mDeadChannelMapCreator.setDeadChannelMapIDCPadStatus(getPadFlags()); + mDeadChannelMapCreator.finalizeDeadChannelMap(); + return mDeadChannelMapCreator.getDeadChannelMap(); +} + +//______________________________________________________________________________ +const FEEConfig& CDBInterface::getFEEConfig() +{ + if (!mUseDefaults) { + auto& cdb = o2::ccdb::BasicCCDBManager::instance(); + mDeadChannelMapCreator.loadFEEConfigViaRunInfoTS(cdb.getTimestamp()); + + const auto feeConfig = mDeadChannelMapCreator.getFEEConfig(); + if (feeConfig != nullptr) { + return *feeConfig; + } + + LOGP(warning, "Could not retrieve FEEConfig"); + } + + createFEEConfig(); + return *mFEEConfig; } //______________________________________________________________________________ @@ -478,6 +537,50 @@ void CDBInterface::createDefaultCMParams() LOGP(info, "created default ion tail per-pad parameters"); } +//______________________________________________________________________________ +void CDBInterface::createDefaultPadFlags() +{ + mPadFlags = std::make_unique("CMkValues"); + + *mPadFlags = PadFlags::flagGoodPad; + + LOGP(info, "created default pad flags"); +} + +//______________________________________________________________________________ +void CDBInterface::createFEEConfig() +{ + if (mFEEConfig) { + return; + } + + if (!mUseDefaults) { + LOGP(info, "trying to load default FEEConfig"); + mDeadChannelMapCreator.loadFEEConfig(7, 1680525888290); // load oldest physics configuration + if (mFEEConfig) { + return; + } + } + + LOGP(info, "creating best guess FEEConfig"); + auto feeConfig = new FEEConfig; + feeConfig->setAllLinksOn(); + feeConfig->tag = FEEConfig::Tags::Physics30sigma; + + if (!mUseDefaults) { + feeConfig->padMaps = getObjectFromCDB(CDBTypeMap.at(CDBType::ConfigFEEPad)); + } else { + auto& maps = feeConfig->padMaps; + maps["CMkValues"] = getCMkValues(); + maps["ITexpLambda"] = getITExpLambda(); + maps["ITfraction"] = getITFraction(); + maps["ThresholdMap"] = getZeroSuppressionThreshold(); + maps["Pedestals"] = getPedestalsCRU(); + } + + mFEEConfig.reset(feeConfig); +} + //______________________________________________________________________________ bool CDBStorage::checkMetaData(MetaData_t metaData) const { diff --git a/Detectors/TPC/base/src/DeadChannelMapCreator.cxx b/Detectors/TPC/base/src/DeadChannelMapCreator.cxx index feac43b1de858..2b16abd676d31 100644 --- a/Detectors/TPC/base/src/DeadChannelMapCreator.cxx +++ b/Detectors/TPC/base/src/DeadChannelMapCreator.cxx @@ -9,6 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include #include #include #include "CommonUtils/NameConf.h" @@ -18,9 +19,9 @@ using namespace o2::tpc; -void DeadChannelMapCreator::init() +void DeadChannelMapCreator::init(std::string_view url) { - mCCDBApi.init(o2::base::NameConf::getCCDBServer()); + mCCDBApi.init(url.empty() ? o2::base::NameConf::getCCDBServer() : url.data()); } //______________________________________________________________________________ diff --git a/Detectors/TPC/base/src/FEEConfig.cxx b/Detectors/TPC/base/src/FEEConfig.cxx index e3685928b3dca..8a4a45ecfa6a4 100644 --- a/Detectors/TPC/base/src/FEEConfig.cxx +++ b/Detectors/TPC/base/src/FEEConfig.cxx @@ -78,7 +78,7 @@ size_t FEEConfig::getNumberActiveLinks() const bool FEEConfig::isCMCEnabled() const { const auto nEnabled = std::accumulate(cruConfig.begin(), cruConfig.end(), size_t(0), [](size_t b, const auto& c) { return b + (c.cmcEnabled > 0); }); - if (nEnabled != cruConfig.size()) { + if ((nEnabled > 0) && (nEnabled != cruConfig.size())) { LOGP(warning, "CMC not enabled for all CRUs: {} < {}", nEnabled, cruConfig.size()); } @@ -88,7 +88,7 @@ bool FEEConfig::isCMCEnabled() const bool FEEConfig::isITFEnabled() const { const auto nEnabled = std::accumulate(cruConfig.begin(), cruConfig.end(), size_t(0), [](size_t b, const auto& c) { return b + (c.itfEnabled); }); - if (nEnabled != cruConfig.size()) { + if ((nEnabled > 0) && (nEnabled != cruConfig.size())) { LOGP(warning, "ITF not enabled for all CRUs: {} < {}", nEnabled, cruConfig.size()); } @@ -98,7 +98,7 @@ bool FEEConfig::isITFEnabled() const bool FEEConfig::isZSEnabled() const { const auto nEnabled = std::accumulate(cruConfig.begin(), cruConfig.end(), size_t(0), [](size_t b, const auto& c) { return b + (c.zsEnabled); }); - if (nEnabled != cruConfig.size()) { + if ((nEnabled > 0) && (nEnabled != cruConfig.size())) { LOGP(warning, "ZS not enabled for all CRUs: {} < {}", nEnabled, cruConfig.size()); } @@ -108,12 +108,32 @@ bool FEEConfig::isZSEnabled() const bool FEEConfig::isResyncEnabled() const { const auto nEnabled = std::accumulate(cruConfig.begin(), cruConfig.end(), size_t(0), [](size_t b, const auto& c) { return b + (c.resyncEnabled); }); - if (nEnabled != cruConfig.size()) { + if ((nEnabled > 0) && (nEnabled != cruConfig.size())) { LOGP(warning, "Resync not enabled for all CRUs: {} < {}", nEnabled, cruConfig.size()); } return nEnabled > (cruConfig.size() / 2); } + +void FEEConfig::setAllLinksOn() +{ + const auto& mapper = Mapper::instance(); + + // ===| Check active link map |=== + for (int iCRU = 0; iCRU < cruConfig.size(); ++iCRU) { + const CRU cru(iCRU); + const PartitionInfo& partInfo = mapper.getMapPartitionInfo()[cru.partition()]; + const int nFECs = partInfo.getNumberOfFECs(); + const int fecOffset = (nFECs + 1) / 2; + cruConfig.at(iCRU).linkOn = 0; + for (int iFEC = 0; iFEC < nFECs; ++iFEC) { + const int fecTest = (iFEC < fecOffset) ? iFEC : 10 + (iFEC - fecOffset); + const int fecBIT = 1 << fecTest; + cruConfig.at(iCRU).linkOn |= fecBIT; + } + } +} + void FEEConfig::print() const { fmt::print("\n"); @@ -157,6 +177,12 @@ void FEEConfig::print() const } } +void FEEConfig::printShort() const +{ + LOGP(info, "FEEConfig: tag: {}, #active links: {}, CMC enabled: {}, ITF enabled: {}, ZS enabled: {}, resync enabled: {}", + (int)tag, getNumberActiveLinks(), isCMCEnabled(), isITFEnabled(), isZSEnabled(), isResyncEnabled()); +} + CalDet FEEConfig::getDeadChannelMap() const { const auto& mapper = Mapper::instance(); diff --git a/Detectors/TPC/base/src/TPCBaseLinkDef.h b/Detectors/TPC/base/src/TPCBaseLinkDef.h index 6f54e3b320809..33b6cf2c03392 100644 --- a/Detectors/TPC/base/src/TPCBaseLinkDef.h +++ b/Detectors/TPC/base/src/TPCBaseLinkDef.h @@ -31,6 +31,7 @@ #pragma link C++ class std::vector < o2::tpc::CalDet < float>> + ; #pragma link C++ class std::vector < o2::tpc::CalDet < float>*> + ; #pragma link C++ class std::unordered_map < std::string, o2::tpc::CalDet < float>> + ; +#pragma link C++ enum o2::tpc::CDBType; #pragma link C++ class o2::tpc::CDBInterface; #pragma link C++ class o2::tpc::CDBStorage; #pragma link C++ class o2::tpc::ContainerFactory; diff --git a/Detectors/TPC/simulation/include/TPCSimulation/DigitContainer.h b/Detectors/TPC/simulation/include/TPCSimulation/DigitContainer.h index 413df5bd00323..2a4e9e5b923ce 100644 --- a/Detectors/TPC/simulation/include/TPCSimulation/DigitContainer.h +++ b/Detectors/TPC/simulation/include/TPCSimulation/DigitContainer.h @@ -86,6 +86,8 @@ class DigitContainer std::deque mTimeBins; ///< Time bin Container for the ADC value std::unique_ptr mPrevDigArr; ///< Keep track of ToT and ion tail cumul from last time bin o2::utils::DebugStreamer mStreamer; ///< Debug streamer + + void reportSettings(); }; inline DigitContainer::DigitContainer() diff --git a/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h b/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h index 0cb59bff038f2..743dfc3bd6977 100644 --- a/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h +++ b/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h @@ -97,7 +97,7 @@ class DigitGlobalPad const CRU& cru, TimeBin timeBin, GlobalPadNumber globalPad, o2::dataformats::LabelContainer, false>& labelContainer, - float commonMode = 0.f, const PrevDigitInfo& prevDigit = PrevDigitInfo(), Streamer* debugStream = nullptr); + float commonMode = 0.f, const PrevDigitInfo& prevDigit = PrevDigitInfo(), Streamer* debugStream = nullptr, const CalDet* deadMap = nullptr); private: /// Compare two MC labels regarding trackID, eventID and sourceID @@ -210,7 +210,7 @@ inline void DigitGlobalPad::fillOutputContainer(std::vector& output, const CRU& cru, TimeBin timeBin, GlobalPadNumber globalPad, o2::dataformats::LabelContainer, false>& labels, - float commonMode, const PrevDigitInfo& prevDigit, Streamer* debugStream) + float commonMode, const PrevDigitInfo& prevDigit, Streamer* debugStream, const CalDet* deadMap) { const Mapper& mapper = Mapper::instance(); SAMPAProcessing& sampaProcessing = SAMPAProcessing::instance(); @@ -222,6 +222,7 @@ inline void DigitGlobalPad::fillOutputContainer(std::vector& output, float noise, pedestal; const float mADC = sampaProcessing.makeSignal(mChargePad, cru.sector(), globalPad, commonMode, pedestal, noise, prevDigit.tot); + const bool isDead = (deadMap == nullptr) ? false : deadMap->getValue(cru.sector(), globalPad); if (debugStream && Streamer::checkStream(o2::utils::StreamFlags::streamDigits)) { int sector = cru.sector(); @@ -236,11 +237,12 @@ inline void DigitGlobalPad::fillOutputContainer(std::vector& output, << "adc=" << adc << "prevDig=" << prevDigitTmp << "cm=" << commonMode + << "isDead=" << isDead << "\n"; } /// only write out the data if there is actually charge on that pad - if (mADC > 0) { + if (!isDead && (mADC > 0)) { /// Write out the Digit const auto digiPos = output.size(); diff --git a/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h b/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h index 762a0b0d66ad7..361b1fb8f6572 100644 --- a/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h +++ b/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h @@ -77,7 +77,9 @@ class DigitTime /// \param prevTime Previous time bin to calculate CM and ToT template void fillOutputContainer(std::vector& output, dataformats::MCTruthContainer& mcTruth, - std::vector& commonModeOutput, const Sector& sector, TimeBin timeBin, PrevDigitInfoArray* prevTime = nullptr, Streamer* debugStream = nullptr, const CalPad* itParams[2] = nullptr); + std::vector& commonModeOutput, const Sector& sector, TimeBin timeBin, + PrevDigitInfoArray* prevTime = nullptr, Streamer* debugStream = nullptr, + const CalPad* itParams[2] = nullptr, const CalDet* deadMap = nullptr); private: std::array mCommonMode; ///< Common mode container - 4 GEM ROCs per sector @@ -127,7 +129,8 @@ inline float DigitTime::getCommonMode(const GEMstack& gemstack) const template inline void DigitTime::fillOutputContainer(std::vector& output, dataformats::MCTruthContainer& mcTruth, std::vector& commonModeOutput, const Sector& sector, TimeBin timeBin, - PrevDigitInfoArray* prevTime, Streamer* debugStream, const CalPad* padParams[3]) + PrevDigitInfoArray* prevTime, Streamer* debugStream, const CalPad* padParams[3], + const CalDet* deadMap) { const auto& mapper = Mapper::instance(); const auto& eleParam = ParameterElectronics::Instance(); @@ -164,7 +167,7 @@ inline void DigitTime::fillOutputContainer(std::vector& output, dataforma prevDigit = (*prevTime)[iPad]; } const CRU cru = mapper.getCRU(sector, iPad); - digit.fillOutputContainer(output, mcTruth, cru, timeBin, iPad, mLabels, getCommonMode(cru), prevDigit, debugStream); + digit.fillOutputContainer(output, mcTruth, cru, timeBin, iPad, mLabels, getCommonMode(cru), prevDigit, debugStream, deadMap); } } } diff --git a/Detectors/TPC/simulation/src/DigitContainer.cxx b/Detectors/TPC/simulation/src/DigitContainer.cxx index 4914178b88eac..c2e7226706eb2 100644 --- a/Detectors/TPC/simulation/src/DigitContainer.cxx +++ b/Detectors/TPC/simulation/src/DigitContainer.cxx @@ -43,9 +43,11 @@ void DigitContainer::fillOutputContainer(std::vector& output, // Without this we might get crashes in the clusterization step. static const int maxTimeBinForTimeFrame = o2::conf::DigiParams::Instance().maxOrbitsToDigitize != -1 ? ((o2::conf::DigiParams::Instance().maxOrbitsToDigitize * 3564 + 2 * 8 - 2) / 8) : -1; + auto& cdb = CDBInterface::instance(); + // ion tail per pad parameters const CalPad* padParams[3] = {nullptr, nullptr, nullptr}; - auto& cdb = CDBInterface::instance(); + if (eleParam.doIonTailPerPad) { const auto& itSettings = IonTailSettings::Instance(); if (itSettings.padITCorrFile.size()) { @@ -66,6 +68,21 @@ void DigitContainer::fillOutputContainer(std::vector& output, mPrevDigArr = std::make_unique(); } + // dead channel map + const CalDet* deadMap = {nullptr}; + if (eleParam.applyDeadMap) { + deadMap = &cdb.getDeadChannelMap(); + } + + static bool reportedSettings = false; + if (!reportedSettings) { + reportSettings(); + if (deadMap) { + LOGP(info, "Using dead map with {} masked pads", deadMap->getSum()); + } + reportedSettings = true; + } + for (auto& time : mTimeBins) { /// the time bins between the last event and the timing of this event are uncorrelated and can be written out /// OR the readout is triggered (i.e. not continuous) and we can dump everything in any case, as long it is within one drift time interval @@ -92,27 +109,36 @@ void DigitContainer::fillOutputContainer(std::vector& output, if (time) { switch (digitizationMode) { case DigitzationMode::FullMode: { - time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams); + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); break; } case DigitzationMode::ZeroSuppression: { - time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams); + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); break; } case DigitzationMode::ZeroSuppressionCMCorr: { - time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams); + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); break; } case DigitzationMode::SubtractPedestal: { - time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams); + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); break; } case DigitzationMode::NoSaturation: { - time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams); + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); break; } case DigitzationMode::PropagateADC: { - time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams); + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); + break; + } + case DigitzationMode::Auto: { + const auto& feeConfig = cdb.getFEEConfig(); + if (feeConfig.isCMCEnabled()) { + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); + } else { + time->fillOutputContainer(output, mcTruth, commonModeOutput, sector, timeBin, mPrevDigArr.get(), debugStream, padParams, deadMap); + } break; } } @@ -131,3 +157,13 @@ void DigitContainer::fillOutputContainer(std::vector& output, } } } + +void DigitContainer::reportSettings() +{ + auto& cdb = CDBInterface::instance(); + const auto& eleParam = ParameterElectronics::Instance(); + const auto& feeConfig = cdb.getFEEConfig(); + LOGP(info, "ParameterElectronics: doIonTail={}, doIonTailPerPad={}, doCommonModePerPad={}, doSaturationTail={}, doNoiseEmptyPads={}, applyDeadMap={}, commonModeCoupling={}, DigiMode={}", + eleParam.doIonTail, eleParam.doIonTailPerPad, eleParam.doCommonModePerPad, eleParam.doSaturationTail, eleParam.doNoiseEmptyPads, eleParam.applyDeadMap, eleParam.commonModeCoupling, (int)eleParam.DigiMode); + feeConfig.printShort(); +} diff --git a/Detectors/TPC/simulation/src/Digitizer.cxx b/Detectors/TPC/simulation/src/Digitizer.cxx index a40d7cb9ef4e7..7bac9e6ebb3e0 100644 --- a/Detectors/TPC/simulation/src/Digitizer.cxx +++ b/Detectors/TPC/simulation/src/Digitizer.cxx @@ -210,6 +210,6 @@ void Digitizer::setUseSCDistortions(std::string_view finp) void Digitizer::setStartTime(double time) { SAMPAProcessing& sampaProcessing = SAMPAProcessing::instance(); - sampaProcessing.updateParameters(); + sampaProcessing.updateParameters(mVDrift); mDigitContainer.setStartTime(sampaProcessing.getTimeBinFromTime(time - mOutputDigitTimeOffset)); }