diff --git a/Det/RichDet/RichDet/DeRichBase.h b/Det/RichDet/RichDet/DeRichBase.h index bca501f3e325bb0c128b3589f1aa649fdc152289..edb357e0d6093ee5085bf86626266fe9794f629c 100644 --- a/Det/RichDet/RichDet/DeRichBase.h +++ b/Det/RichDet/RichDet/DeRichBase.h @@ -23,6 +23,7 @@ // STL #include <memory> +#include <mutex> // Gaudi #include "GaudiKernel/MsgStream.h" @@ -164,7 +165,7 @@ private: protected: /// Access DeRichSystem on demand - DeRichSystem* deRichSys(); + DeRichSystem* deRichSys() const; protected: /// Get a scalar parameter value from an SIMD parameter @@ -174,7 +175,8 @@ protected: } private: + mutable std::mutex m_initLock; ///< update lock std::string m_myname = ""; ///< The name of this detector element std::unique_ptr<MsgStream> m_msgStream; ///< Message Stream Object - DeRichSystem* m_deRichS = nullptr; ///< Pointer to the overall RICH system object + mutable DeRichSystem* m_deRichS = nullptr; ///< Pointer to the overall RICH system object }; diff --git a/Det/RichDet/RichDet/DeRichHPDPanel.h b/Det/RichDet/RichDet/DeRichHPDPanel.h index 8e723e7a2f375b9370713f82aa0a8e6d7bc7dc10..ec1520fced3f547541a5109525bc25c111839ce9 100644 --- a/Det/RichDet/RichDet/DeRichHPDPanel.h +++ b/Det/RichDet/RichDet/DeRichHPDPanel.h @@ -207,9 +207,6 @@ private: // data std::vector<IDetectorElement*> m_DeSiSensors; ///< Container for the Si sensors as Det Elements std::vector<DeRichHPD*> m_DeHPDs; ///< Container for the HPDs as Det Elements - - /// DeRichSystem pointer - DeRichSystem* m_deRichS = nullptr; }; //========================================================================= diff --git a/Det/RichDet/RichDet/DeRichLocations.h b/Det/RichDet/RichDet/DeRichLocations.h index 8c89a0717ed59055d01ba4fa8a249e7ca1d5636c..53682f05685f3dfab396421dc692ef2936eee22c 100644 --- a/Det/RichDet/RichDet/DeRichLocations.h +++ b/Det/RichDet/RichDet/DeRichLocations.h @@ -28,6 +28,9 @@ #include "Kernel/RichDetectorType.h" #include "Kernel/RichRadiatorType.h" +// RichDet +#include "RichDet/RichDetConfigType.h" + // ******************************************************************************************* /** @namespace DeRichLocations @@ -83,6 +86,13 @@ namespace DeRichLocations { /// Rich2 Beampipe location in TDS inline const std::string Rich2BeamPipe = "/dd/Structure/LHCb/AfterMagnetRegion/Rich2/Rich2BeamPipe"; + /// Detector numbering locations + inline std::vector<std::string> detectorNumberings( const Rich::RichPhDetConfigType type ) noexcept { + if ( Rich::PMTConfig == type ) { return {"Rich1PMTDetectorNumbers", "Rich2PMTDetectorNumbers"}; } + if ( Rich::HPDConfig == type ) { return {"Rich1DetectorNumbers", "Rich2DetectorNumbers"}; } + return {}; + } + // ---------------------------------------------------------------------------------------- // Utility methods // ---------------------------------------------------------------------------------------- diff --git a/Det/RichDet/RichDet/DeRichPMT.h b/Det/RichDet/RichDet/DeRichPMT.h index 6b0f8b69bab168141a5cb810b299dbae4247d78b..12e9774a3520246cd8263c7233054ba3b9a9d9af 100644 --- a/Det/RichDet/RichDet/DeRichPMT.h +++ b/Det/RichDet/RichDet/DeRichPMT.h @@ -223,7 +223,6 @@ private: private: // implementation data - std::mutex m_initLock; bool m_initialised{false}; }; diff --git a/Det/RichDet/RichDet/DeRichPMTClassic.h b/Det/RichDet/RichDet/DeRichPMTClassic.h index 1187ad25438e2179d204207dd21c0e59d36cc99f..a0531c82c0466c839b38be8b660b18df07ab2908 100644 --- a/Det/RichDet/RichDet/DeRichPMTClassic.h +++ b/Det/RichDet/RichDet/DeRichPMTClassic.h @@ -223,7 +223,6 @@ private: private: // implementation data - std::mutex m_initLock; bool m_initialised{false}; }; diff --git a/Det/RichDet/RichDet/DeRichSystem.h b/Det/RichDet/RichDet/DeRichSystem.h index 4a11d785923c3968b04b95cec67cfeefefcfac58..5ddbdd535063426ca0fa1bf3bc926a82ced6caf3 100644 --- a/Det/RichDet/RichDet/DeRichSystem.h +++ b/Det/RichDet/RichDet/DeRichSystem.h @@ -293,11 +293,11 @@ public: /// The version of RichSystem inline int systemVersion() const noexcept { return m_version; } -private: // definitions +private: + // definitions + /// Map type to use. template <typename TO, typename FROM> - // using MyMap = GaudiUtils::HashMap< TO, FROM >; - // using MyMap = std::map< TO, FROM >; using MyMap = std::unordered_map<TO, FROM>; private: diff --git a/Det/RichDet/src/Lib/DeRichBase.cpp b/Det/RichDet/src/Lib/DeRichBase.cpp index 35cf4fe71ee00ef040d8646183bff17eaa22985b..d719d2a2e70eb4ae71c0763a8e6597062fb70f4e 100644 --- a/Det/RichDet/src/Lib/DeRichBase.cpp +++ b/Det/RichDet/src/Lib/DeRichBase.cpp @@ -17,8 +17,13 @@ #include "RichDet/DeRichSystem.h" // Access DeRichSystem on demand -DeRichSystem* DeRichBase::deRichSys() { +DeRichSystem* DeRichBase::deRichSys() const { + if ( UNLIKELY( !m_deRichS ) ) { + + // lock for update + std::lock_guard lock( m_initLock ); + // find the RichSystem SmartDataPtr<DetectorElement> afterMag( dataSvc(), "/dd/Structure/LHCb/AfterMagnetRegion" ); if ( !afterMag ) { @@ -52,7 +57,7 @@ DeRichSystem* DeRichBase::deRichSys() { } m_deRichS = deRichS; - } // close if for first time access + } return m_deRichS; } diff --git a/Det/RichDet/src/Lib/DeRichHPDPanel.cpp b/Det/RichDet/src/Lib/DeRichHPDPanel.cpp index 629003bf3b6108a07793899953c99e6487fa2c51..a93de36b4c6286775807989d9440136860524be9 100644 --- a/Det/RichDet/src/Lib/DeRichHPDPanel.cpp +++ b/Det/RichDet/src/Lib/DeRichHPDPanel.cpp @@ -71,9 +71,6 @@ StatusCode DeRichHPDPanel::initialize() { if ( msgLevel( MSG::DEBUG, msg ) ) msg << MSG::DEBUG << "Initialize " << name() << endmsg; - // cache the DeRichSystem pointer - m_deRichS = deRichSys(); - // register UMS dependency on local geometry updMgrSvc()->registerCondition( this, geometry(), &DeRichHPDPanel::geometryUpdate ); @@ -126,7 +123,7 @@ bool DeRichHPDPanel::smartID( const Gaudi::XYZPoint& globalPoint, LHCb::RichSmar } // check if the HPD is active or dead - if ( !m_deRichS->pdIsActive( id ) ) return false; + if ( !deRichSys()->pdIsActive( id ) ) return false; const auto HPDNumber = _pdNumber( id ); if ( HPDNumber.data() > nPDs() ) { @@ -270,8 +267,8 @@ LHCb::RichTraceMode::RayTraceResult DeRichHPDPanel::PDWindowPoint( const Gaudi:: res = checkPanelAcc( panelIntersection ); } else { // Inside an HPD - if ( !m_deRichS->pdIsActive( smartID ) || // check if the HPD is active or dead - ( mode.hpdKaptonShadowing() && // check for intersection with kapton shield + if ( !deRichSys()->pdIsActive( smartID ) || // check if the HPD is active or dead + ( mode.hpdKaptonShadowing() && // check for intersection with kapton shield HPD->testKaptonShadowing( pInPanel, vInPanel ) ) ) { res = LHCb::RichTraceMode::RayTraceResult::OutsidePDPanel; } @@ -333,7 +330,7 @@ LHCb::RichTraceMode::RayTraceResult DeRichHPDPanel::PDWindowPoint( const Gaudi:: windowPointGlobal = HPD->geometry()->toGlobal( windowPointInHPD ); // check if the HPD is active or dead - if ( !m_deRichS->pdIsActive( smartID ) ) { res = LHCb::RichTraceMode::RayTraceResult::OutsidePDPanel; } + if ( !deRichSys()->pdIsActive( smartID ) ) { res = LHCb::RichTraceMode::RayTraceResult::OutsidePDPanel; } } // found intersection with HPD window diff --git a/Det/RichDet/src/Lib/DeRichPMT.cpp b/Det/RichDet/src/Lib/DeRichPMT.cpp index d3c90f61d6b9cffe6417d78ca29d49ccca4ad198..992cbb21cf7c28ab92fccdfc9f52d5d4644a6b29 100644 --- a/Det/RichDet/src/Lib/DeRichPMT.cpp +++ b/Det/RichDet/src/Lib/DeRichPMT.cpp @@ -26,7 +26,6 @@ // local #include "RichDet/DeRich.h" #include "RichDet/DeRichPMT.h" -#include "RichDet/DeRichSystem.h" // RichUtils #include "RichUtils/FastMaths.h" @@ -71,7 +70,7 @@ StatusCode DeRichPMT::initialize() { // Common DePD init auto sc = DeRichPD::initialize(); - if ( !sc ) return sc; + if ( !sc ) { return sc; } m_dePmtAnode = ( !childIDetectorElements().empty() ? childIDetectorElements().front() : nullptr ); if ( !m_dePmtAnode ) { @@ -83,7 +82,13 @@ StatusCode DeRichPMT::initialize() { updMgrSvc()->registerCondition( this, geometry(), &DeRichPMT::updateGeometry ); updMgrSvc()->registerCondition( this, m_dePmtAnode->geometry(), &DeRichPMT::updateGeometry ); // Update PMT QE values whenever DeRichSystem updates - updMgrSvc()->registerCondition( this, deRichSys(), &DeRichPMT::initPMTQuantumEff ); + // Turn this off for now to avoid dependency on DeRichSystem. Anyway we do not yet have + // a complete set of PMT Q.E. conditions, so come back to this once this is in place. + // instead of depending on DeRichSystem we should just depend on the relevant condition. + // For now, just run the initialisation once by hand. + sc = DeRichPMT::initPMTQuantumEff(); + if ( !sc ) { return sc; } + // updMgrSvc()->registerCondition( this, deRichSys(), &DeRichPMT::initPMTQuantumEff ); // Trigger first update sc = updMgrSvc()->update( this ); diff --git a/Det/RichDet/src/Lib/DeRichPMTClassic.cpp b/Det/RichDet/src/Lib/DeRichPMTClassic.cpp index d95f07a53780e2ab9792df8d059ece396b6daaa6..a6f85a6a0705843b9b686e10593331be1ed92163 100644 --- a/Det/RichDet/src/Lib/DeRichPMTClassic.cpp +++ b/Det/RichDet/src/Lib/DeRichPMTClassic.cpp @@ -26,7 +26,6 @@ // local #include "RichDet/DeRich.h" #include "RichDet/DeRichPMTClassic.h" -#include "RichDet/DeRichSystem.h" // RichUtils #include "RichUtils/FastMaths.h" @@ -71,7 +70,7 @@ StatusCode DeRichPMTClassic::initialize() { // Common DePD init auto sc = DeRichPD::initialize(); - if ( !sc ) return sc; + if ( !sc ) { return sc; } m_dePmtAnode = ( !childIDetectorElements().empty() ? childIDetectorElements().front() : nullptr ); if ( !m_dePmtAnode ) { @@ -82,8 +81,15 @@ StatusCode DeRichPMTClassic::initialize() { // register for updates when geometry changes updMgrSvc()->registerCondition( this, geometry(), &DeRichPMTClassic::updateGeometry ); updMgrSvc()->registerCondition( this, m_dePmtAnode->geometry(), &DeRichPMTClassic::updateGeometry ); + // Update PMT QE values whenever DeRichSystem updates - updMgrSvc()->registerCondition( this, deRichSys(), &DeRichPMTClassic::initPMTQuantumEff ); + // Turn this off for now to avoid dependency on DeRichSystem. Anyway we do not yet have + // a complete set of PMT Q.E. conditions, so come back to this once this is in place. + // instead of depending on DeRichSystem we should just depend on the relevant condition. + // For now, just run the initialisation once by hand. + sc = DeRichPMTClassic::initPMTQuantumEff(); + if ( !sc ) { return sc; } + // updMgrSvc()->registerCondition( this, deRichSys(), &DeRichPMTClassic::initPMTQuantumEff ); // Trigger first update sc = updMgrSvc()->update( this ); @@ -201,7 +207,7 @@ StatusCode DeRichPMTClassic::getPMTParameters() { void DeRichPMTClassic::setPmtIsGrandFlag( const bool isGrand ) { m_PmtIsGrand = isGrand; // Update cached size parameters - const auto* deRich = getFirstRich(); + const auto deRich = getFirstRich(); if ( deRich ) { if ( isGrand ) { const auto GrandPmtPixelXSize = deRich->param<double>( "RichGrandPmtPixelXSize" ); @@ -222,7 +228,7 @@ void DeRichPMTClassic::setPmtIsGrandFlag( const bool isGrand ) { //============================================================================= StatusCode DeRichPMTClassic::initPMTQuantumEff() { - const auto* deRich = getFirstRich(); + const auto deRich = getFirstRich(); if ( !deRich ) { return StatusCode::FAILURE; } const auto PmtQELocation = deRich->param<std::string>( "RichPmtQETableName" ); SmartDataPtr<TabulatedProperty> pmtQuantumEffTabProp( dataSvc(), PmtQELocation ); diff --git a/Det/RichDet/src/Lib/DeRichSystem.cpp b/Det/RichDet/src/Lib/DeRichSystem.cpp index f8c76e05bc36ad7fa134b6658fa86dbd26486135..6d251b12e9b2820f971a74d3498d9f01e6e75e86 100644 --- a/Det/RichDet/src/Lib/DeRichSystem.cpp +++ b/Det/RichDet/src/Lib/DeRichSystem.cpp @@ -41,6 +41,9 @@ #include "boost/format.hpp" #include "boost/lexical_cast.hpp" +// STL +#include <algorithm> + //============================================================================= const CLID CLID_DERichSystem = 12005; // User defined @@ -65,23 +68,17 @@ StatusCode DeRichSystem::initialize() { std::vector<std::string> deRichLocs = getDeRichLocations(); // get condition names for detector numbers - std::vector<std::string> detCondNames; - const std::string str_PhotoDetConfig = "RichPhotoDetectorConfiguration"; - const std::string str_PhotoDetConfigValue = "DetectorConfiguration"; + // std::vector<std::string> detCondNames; + const std::string str_PhotoDetConfig = "RichPhotoDetectorConfiguration"; + const std::string str_PhotoDetConfigValue = "DetectorConfiguration"; if ( hasCondition( str_PhotoDetConfig ) ) { const auto deRC = condition( str_PhotoDetConfig ); if ( deRC->exists( str_PhotoDetConfigValue ) ) m_photDetConf = (Rich::RichPhDetConfigType)deRC->param<int>( str_PhotoDetConfigValue ); } - if ( m_photDetConf == Rich::PMTConfig ) { - detCondNames.push_back( "Rich1PMTDetectorNumbers" ); - detCondNames.push_back( "Rich2PMTDetectorNumbers" ); - } else if ( m_photDetConf == Rich::HPDConfig ) { - detCondNames.push_back( "Rich1DetectorNumbers" ); - detCondNames.push_back( "Rich2DetectorNumbers" ); - } else { - return Error( "Unknown detector configuration. " ); - } + + const auto detCondNames = DeRichLocations::detectorNumberings( m_photDetConf ); + if ( detCondNames.empty() ) { return Error( "Unknown detector configuration." ); } // check if the numbers match. if ( 0 != detCondNames.size() % deRichLocs.size() ) { @@ -178,8 +175,9 @@ StatusCode DeRichSystem::fillMaps( const Rich::DetectorType rich ) { if ( hasCondition( str_PhotoDetConfig ) ) { const auto deRC = condition( str_PhotoDetConfig ); - if ( deRC->exists( str_PhotoDetConfigValue ) ) + if ( deRC->exists( str_PhotoDetConfigValue ) ) { m_photDetConf = (Rich::RichPhDetConfigType)deRC->param<int>( str_PhotoDetConfigValue ); + } } std::string str_NumberOfPDs = ""; @@ -194,7 +192,7 @@ StatusCode DeRichSystem::fillMaps( const Rich::DetectorType rich ) { std::string str_PDLevel1IDs = ""; std::string str_Level1LogicalToHardwareIDMap = ""; - if ( m_photDetConf == Rich::PMTConfig ) { + if ( Rich::PMTConfig == m_photDetConf ) { str_NumberOfPDs = "NumberOfPMTs"; str_PDSmartIDs = "PMTSmartIDs"; str_PDHardwareIDs = "PMTHardwareIDs"; @@ -206,7 +204,7 @@ StatusCode DeRichSystem::fillMaps( const Rich::DetectorType rich ) { str_InactivePDs = "InactivePMTs"; str_PDLevel1IDs = "PMTLevel1IDs"; str_Level1LogicalToHardwareIDMap = "Level1LogicalToHardwareIDMap-PMT"; - } else if ( m_photDetConf == Rich::HPDConfig ) { + } else if ( Rich::HPDConfig == m_photDetConf ) { str_NumberOfPDs = "NumberOfHPDs"; str_PDSmartIDs = "HPDSmartIDs"; str_PDHardwareIDs = "HPDHardwareIDs"; @@ -218,8 +216,9 @@ StatusCode DeRichSystem::fillMaps( const Rich::DetectorType rich ) { str_InactivePDs = "InactiveHPDs"; str_PDLevel1IDs = "HPDLevel1IDs"; str_Level1LogicalToHardwareIDMap = "Level1LogicalToHardwareIDMap"; - } else - return Error( "Unknown detector configuration. " ); + } else { + return Error( "Unknown detector configuration" ); + } // load conditions _ri_debug << "Loading Conditions from " << m_detNumConds[rich] << endmsg; @@ -289,9 +288,7 @@ StatusCode DeRichSystem::fillMaps( const Rich::DetectorType rich ) { error() << "Invalid SmartID in the list of inactive PDs : " << inpd << endmsg; } } - } - - else { + } else { // hardware IDs _ri_debug << "Inactive PDs are taken from the hardware list" << endmsg; inacts.clear(); @@ -336,9 +333,30 @@ StatusCode DeRichSystem::fillMaps( const Rich::DetectorType rich ) { icopyN != copyNs.end(); ++iSoft, ++iHard, ++iL0, ++iL1, ++iL1In, ++icopyN ) { - // get data - const LHCb::RichSmartID32 pdID32( *iSoft ); // needed for 32->64 bit support - const LHCb::RichSmartID pdID( pdID32 ); // handles correct format conversion + // get PD ID + const LHCb::RichSmartID32 pdID32( *iSoft ); // needed for 32->64 bit support + LHCb::RichSmartID pdID( pdID32 ); // handles correct format conversion + + // PMT specific checks + if ( Rich::PMTConfig == m_photDetConf ) { + // check large PMT flag + const auto check_isLarge = isLargePD( pdID ); + if ( pdID.isLargePMT() != check_isLarge ) { + // should make this a warning/error/fatal when 'classic' PMT support is not required any longer. + _ri_debug << "IsLarge PMT flag mis-match " << pdID << " " << pdID.isLargePMT() << "->" << check_isLarge + << endmsg; + pdID.setLargePMT( check_isLarge ); + } + // check if this PD ID has a valid DePD object, if not skip. + // skip this for HPDs due to circular dep issues with DeRichSystem + if ( !dePD( pdID ) ) { + // should make this a warning/error/fatal when 'classic' PMT support is not required any longer. + _ri_debug << pdID << " has no DePD object !" << endmsg; + continue; + } + } + + // get readout numbers const Rich::DAQ::PDHardwareID hardID( *iHard ); const Rich::DAQ::Level1HardwareID L1ID( *iL1 ); const Rich::DAQ::Level0ID L0ID( *iL0 ); diff --git a/Kernel/LHCbKernel/Kernel/RichSmartID.h b/Kernel/LHCbKernel/Kernel/RichSmartID.h index eddb7b5c8a5c5133a1f4169bc85d4bf2cc9722eb..8e11ca82da47fa3b08a9875b88dfe3446576ab1c 100644 --- a/Kernel/LHCbKernel/Kernel/RichSmartID.h +++ b/Kernel/LHCbKernel/Kernel/RichSmartID.h @@ -693,11 +693,8 @@ namespace LHCb { return RichSmartID( key() & ( LIKELY( MaPMTID == idType() ) ? ( MaPMT::MaskRich + MaPMT::MaskPanel + MaPMT::MaskPDNumInCol + MaPMT::MaskPDCol + - // This should be included, but currently is causing problems because there - // is a bug in that the PD IDs stored in the DB do not have this flag set. - // So excluded for now here, but this should be added back once the DB is fixed. - // MaPMT::MaskLargePixel + - MaPMT::MaskRichIsSet + MaPMT::MaskPanelIsSet + MaPMT::MaskPDIsSet + MaskIDType ) + MaPMT::MaskLargePixel + MaPMT::MaskRichIsSet + MaPMT::MaskPanelIsSet + + MaPMT::MaskPDIsSet + MaskIDType ) : ( HPD::MaskRich + HPD::MaskPanel + HPD::MaskPDNumInCol + HPD::MaskPDCol + HPD::MaskRichIsSet + HPD::MaskPanelIsSet + HPD::MaskPDIsSet + MaskIDType ) ) ); }