diff --git a/CMakeLists.txt b/CMakeLists.txt index 37611f00a968bd3dbb5574d5787f5da6a36b552e..87991e55b12ec2ea4afe045da7dfe5de81ea4d96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ set(${VarName} Det/VPDet Det/RichDet Det/MuonDet + Det/TorchDet Tools/GitEntityResolver Tools/XmlTools ) diff --git a/Det/TorchDet/CMakeLists.txt b/Det/TorchDet/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c6e75b14ad197468ba5ebe868a0b86173d6869b0 --- /dev/null +++ b/Det/TorchDet/CMakeLists.txt @@ -0,0 +1,48 @@ +############################################################################### +# (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, 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. # +############################################################################### +#[=======================================================================[.rst: +Det/TorchDet +------------ +#]=======================================================================] + +gaudi_add_library(TorchDetLib + SOURCES + src/lib/legacy/DeTorchDetector.cpp + src/lib/legacy/DeTorchModule.cpp + LINK + PUBLIC + Gaudi::GaudiKernel + Run2Support::DetDescLib + LHCb::LHCbKernel + ) + +gaudi_add_module(TorchDet + SOURCES + src/component/legacy/XmlDeTorchCnv.cpp + LINK + Run2Support::DetDescCnvLib + Run2Support::TorchDetLib +) + +target_link_libraries(TorchDet + PRIVATE + fmt::fmt + LHCb::LHCbAlgsLib + Run2Support::XmlToolsLib + yaml-cpp + ) + +gaudi_add_dictionary(TorchDetDict + HEADERFILES dict/TorchDetDict.h + SELECTION dict/TorchDetDict.xml + LINK Run2Support::TorchDetLib +) + diff --git a/Det/TorchDet/dict/TorchDetDict.h b/Det/TorchDet/dict/TorchDetDict.h new file mode 100644 index 0000000000000000000000000000000000000000..e64fe31e1b7fea23763c76af8a78d4ef946bfbd1 --- /dev/null +++ b/Det/TorchDet/dict/TorchDetDict.h @@ -0,0 +1,17 @@ +/*****************************************************************************\ +* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ +#ifdef TORCHDET_DETDICT_H +#define TORCHDET_DETDICT_H 1 + +#include "TorchDet/DeTorchDetector.h" +#include "TorchDet/DeTorchModule.h" + +#endif diff --git a/Det/TorchDet/dict/TorchDetDict.xml b/Det/TorchDet/dict/TorchDetDict.xml new file mode 100644 index 0000000000000000000000000000000000000000..1f9dbdb3be5e783f42fab6bde455142850a58169 --- /dev/null +++ b/Det/TorchDet/dict/TorchDetDict.xml @@ -0,0 +1,17 @@ +<!-- + (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration + + This software is distributed under the terms of the GNU General Public + Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". + + In applying this licence, 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. +--> +<lcgdict> + + <class name="DeTorchDetector" /> + <class name="DeTorchModule" /> + <class name="std::vector<DeTorchModule*>" /> + +</lcgdict> diff --git a/Det/TorchDet/include/TorchDet/DeTorchDetector.h b/Det/TorchDet/include/TorchDet/DeTorchDetector.h new file mode 100644 index 0000000000000000000000000000000000000000..92687a319b0f92cbeb48de393fa175fe611e8b45 --- /dev/null +++ b/Det/TorchDet/include/TorchDet/DeTorchDetector.h @@ -0,0 +1,69 @@ +/*****************************************************************************\ +* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ +#pragma once + +#include <string> + +namespace DeTorchDetectorLocation { + inline const std::string Default = "/dd/Structure/LHCb/AfterMagnetRegion/Torch"; +} // namespace DeTorchDetectorLocation + +#include "DetDesc/Condition.h" +#include "DetDesc/DetectorElement.h" + +# include "DeTorchModule.h" +constexpr CLID CLID_DeTorchDetector = 22; + +class DeTorch : public DetDesc::DetectorElementPlus { +public: + using DetectorElementPlus::DetectorElementPlus; + + StatusCode initialize() override; + + const CLID& clID() const override; + + static const CLID& classID() { return CLID_DeTorchDetector; } + + int sensitiveVolumeID( const Gaudi::XYZPoint& point ) const override; + + const DeTorchModule* findModule( const Gaudi::XYZPoint& globalPoint ) const; + + const std::vector<DeTorchModule*>& modules() const { return m_modules; } + + unsigned int numModules() const { return m_modules.size(); } + + unsigned int moduleNumber( const DeTorchModule* module ) const; + + double radiatorPosition() const { return m_radiatorZPos; } + + double fullDepth() const { return m_fullDepth; } + + Gaudi::XYZPoint fromDetector( const Gaudi::XYZPoint& detectedPoint ) const { + return m_geometry->toGlobal( detectedPoint ); + } + +private: + IGeometryInfoPlus* m_geometry = nullptr; + + std::vector<DeTorchModule*> m_modules; + + double m_radiatorZPos; + double m_fullDepth; + unsigned int m_modulesPerHalf; + + mutable std::unique_ptr<MsgStream> m_msg; + + MsgStream& msg() const { + if ( !m_msg ) m_msg.reset( new MsgStream( msgSvc(), "DeTorch" ) ); + return *m_msg; + } +}; + diff --git a/Det/TorchDet/include/TorchDet/DeTorchModule.h b/Det/TorchDet/include/TorchDet/DeTorchModule.h new file mode 100644 index 0000000000000000000000000000000000000000..112a7289339a83bfb462d349e516243476ad4431 --- /dev/null +++ b/Det/TorchDet/include/TorchDet/DeTorchModule.h @@ -0,0 +1,64 @@ +/*****************************************************************************\ +* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ +#pragma once + +// DetDesc +# include "DetDesc/DetectorElement.h" +# include "DetDesc/IGeometryInfo.h" + +constexpr CLID CLID_DeTorchModule = 23; + +class DeTorchModule : public DetDesc::DetectorElementPlus { +public: + using DetectorElementPlus::DetectorElementPlus; + + StatusCode initialize() override; + + const CLID& clID() const override; + + static const CLID& classID() { return CLID_DeTorchModule; } + + double radiatorDepth() const { return m_radiatorDepth; } + + double radiatorWidth() const { return m_radiatorWidth; } + + double radiatorHeight() const { return m_radiatorHeight; } + + unsigned int number() const { return m_moduleNumber; } + + unsigned int half() const { return m_moduleHalf; } + + Gaudi::XYZPoint toRadiator( const Gaudi::XYZPoint& globalPoint ) const; + + Gaudi::XYZPoint toDetector( const Gaudi::XYZPoint& globalPoint ) const; + + Gaudi::XYZPoint fromDetector( const Gaudi::XYZPoint& detectedPoint ) const; + + double radiatorPosition() const; + + bool inRadiator( const Gaudi::XYZPoint& globalPoint ) const; + +private: + IGeometryInfoPlus* m_geometry = nullptr; + + double m_radiatorDepth; + double m_radiatorWidth; + double m_radiatorHeight; + double m_radiatorZOffset; + double m_radiatorYOffset; + double m_detectorYOffset; + double m_detectorZOffset; + double m_angleWedge; + + unsigned int m_moduleHalf; + unsigned int m_moduleNumber; +}; + diff --git a/Det/TorchDet/src/component/legacy/XmlDeTorchCnv.cpp b/Det/TorchDet/src/component/legacy/XmlDeTorchCnv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec632ef7ef5141e907e22fc63d119433a804a379 --- /dev/null +++ b/Det/TorchDet/src/component/legacy/XmlDeTorchCnv.cpp @@ -0,0 +1,20 @@ +/*****************************************************************************\ +* (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ +#include "DetDescCnv/XmlUserDetElemCnv.h" + +#include "TorchDet/DeTorchDetector.h" +#include "TorchDet/DeTorchModule.h" + +typedef XmlUserDetElemCnv<DeTorch> XmlDeTorchDetectorCnv; +DECLARE_CONVERTER( XmlDeTorchDetectorCnv ) + +typedef XmlUserDetElemCnv<DeTorchModule> XmlDeTorchModuleCnv; +DECLARE_CONVERTER( XmlDeTorchModuleCnv ) diff --git a/Det/TorchDet/src/lib/legacy/DeTorchDetector.cpp b/Det/TorchDet/src/lib/legacy/DeTorchDetector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f610deb70c58894847294d1d511e73520b9f3f49 --- /dev/null +++ b/Det/TorchDet/src/lib/legacy/DeTorchDetector.cpp @@ -0,0 +1,61 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ +#include "TorchDet/DeTorchDetector.h" + +const CLID& DeTorch::clID() const { return DeTorch::classID(); } + +StatusCode DeTorch::initialize() { + + // Initialise the base class + StatusCode sc = DetectorElementPlus::initialize(); + + m_geometry = geometryPlus(); + + if ( sc.isFailure() ) { + msg() << MSG::ERROR << "Cannot initialize DeTorch" << endmsg; + return sc; + } + + for ( const auto& half : this->childIDetectorElements() ) { + + for ( const auto& imodule : half->childIDetectorElements() ) { + + auto module = dynamic_cast<DeTorchModule*>( imodule ); + + if ( module ) m_modules.push_back( module ); + } + } + + m_modulesPerHalf = m_modules.size() / 2; + m_radiatorZPos = param<double>( "TorchRadiatorZPos" ); + m_fullDepth = param<double>( "TorchFullDepth" ); + + return sc; +} + +const DeTorchModule* DeTorch::findModule( const Gaudi::XYZPoint& globalPoint ) const { + + auto it = std::find_if( m_modules.begin(), m_modules.end(), + [&globalPoint]( const DeTorchModule* m ) -> bool { return m->isInside( globalPoint ); } ); + + return ( it != m_modules.end() ? *it : nullptr ); +} + +unsigned int DeTorch::moduleNumber( const DeTorchModule* module ) const { + return m_modulesPerHalf * module->half() + module->number(); +} + +int DeTorch::sensitiveVolumeID( const Gaudi::XYZPoint& point ) const { + auto module = findModule( point ); + return moduleNumber( module ); +} + + diff --git a/Det/TorchDet/src/lib/legacy/DeTorchModule.cpp b/Det/TorchDet/src/lib/legacy/DeTorchModule.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c2e1ecdfc5720562f10ed8844a6be6f218f25e9 --- /dev/null +++ b/Det/TorchDet/src/lib/legacy/DeTorchModule.cpp @@ -0,0 +1,114 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ +#include "TorchDet/DeTorchModule.h" +#include "GaudiKernel/PhysicalConstants.h" + +const CLID& DeTorchModule::clID() const { return DeTorchModule::classID(); } + +StatusCode DeTorchModule::initialize() { + + // Initialize the base object + StatusCode sc = DetectorElementPlus::initialize(); + + m_geometry = geometryPlus(); + + m_radiatorDepth = param<double>( "TorchRadiatorDepth" ); + m_radiatorWidth = param<double>( "TorchRadiatorWidth" ); + m_radiatorHeight = param<double>( "TorchRadiatorHeight" ); + m_angleWedge = param<double>( "TorchWedgeAngle" ); + m_moduleNumber = param<int>( "ModuleNumber" ); + + // Get the detector half + m_moduleHalf = ( param<std::string>( "ModuleLocation" ) == "Upper" ? 0 : 1 ); + + double detectorOffset = param<double>( "TorchDetectorOffset" ); + double radiatorZOffset = param<double>( "TorchRadiatorZOff" ); + double radiatorYOffset = param<double>( "TorchRadiatorYOff" ); + + // Position of the centre of the front face of the radiator + m_radiatorYOffset = radiatorYOffset; + m_radiatorZOffset = radiatorZOffset - 0.5 * m_radiatorDepth; + + // Position of the centre of the detector plane + m_detectorYOffset = m_radiatorYOffset + detectorOffset * std::cos( m_angleWedge ) + 0.5 * m_radiatorHeight; + m_detectorZOffset = m_radiatorZOffset - detectorOffset * std::sin( m_angleWedge ); + + return StatusCode::SUCCESS; +} + +Gaudi::XYZPoint DeTorchModule::toRadiator( const Gaudi::XYZPoint& globalPoint ) const { + + Gaudi::XYZPoint localPoint = m_geometry->toLocal( globalPoint ); + + double xlocal = localPoint.X(); + double ylocal = localPoint.Y() - m_radiatorYOffset; + double zlocal = localPoint.Z() - m_radiatorZOffset; + + return Gaudi::XYZPoint( xlocal, ylocal, zlocal ); +} + +Gaudi::XYZPoint DeTorchModule::toDetector( const Gaudi::XYZPoint& globalPoint ) const { + + // Coordinate in the local system of the module + Gaudi::XYZPoint localPoint = m_geometry->toLocal( globalPoint ); + + double angleBlock = 0.5 * Gaudi::Units::pi - m_angleWedge; + + double xlocal = localPoint.X(); + double ylocal = 0; + double zlocal = 0; + + ylocal += ( localPoint.Y() - m_detectorYOffset ) / std::cos( m_angleWedge ); + zlocal += ( localPoint.Y() - m_detectorYOffset ) * std::cos( angleBlock ); + zlocal += ( localPoint.Z() - m_detectorZOffset ) * std::sin( angleBlock ); + + return Gaudi::XYZPoint( xlocal, ylocal, zlocal ); +} + +Gaudi::XYZPoint DeTorchModule::fromDetector( const Gaudi::XYZPoint& detectedPoint ) const { + + // Coordinate in the local system of the module + + // double angleBlock = 0.5 * Gaudi::Units::pi - m_angleWedge; + + double xlocal = detectedPoint.X(); + + double ylocal = m_detectorYOffset + detectedPoint.Y() * std::cos( m_angleWedge ); + double zlocal = m_detectorZOffset - detectedPoint.Y() * std::sin( m_angleWedge ); + + Gaudi::XYZPoint globalPoint = m_geometry->toGlobal( Gaudi::XYZPoint( xlocal, ylocal, zlocal ) ); + + return globalPoint; +} + +bool DeTorchModule::inRadiator( const Gaudi::XYZPoint& globalPoint ) const { + + Gaudi::XYZPoint localPoint = toRadiator( globalPoint ); + + bool test = true; + + test &= ( std::abs( localPoint.X() ) < 0.5 * m_radiatorWidth ); + test &= ( std::abs( localPoint.Y() ) < 0.5 * m_radiatorHeight ); + + // Check on z-position + test &= ( localPoint.Z() > 0 && localPoint.Z() < m_radiatorDepth ); + + return test; +} + +double DeTorchModule::radiatorPosition() const { + + Gaudi::XYZPoint globalPoint = this->toGlobal( Gaudi::XYZPoint( 0, 0, 0 ) ); + + double zpos = globalPoint.Z() + m_radiatorZOffset; + + return zpos; +}