diff --git a/CMakeLists.txt b/CMakeLists.txt index a8580226209ef99214c65052832ef8ccafba944c..b192dde8fe5eb372b3e67e15c0d98e6252439d77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,7 @@ add_library(DetectorLib SHARED Detector/LHCb/src/DeLHCb.cpp Detector/LHCb/src/DeLHCbHandles.cpp Detector/LHCb/src/InteractionRegion.cpp + Detector/LHCb/src/VPGlobalCoordinateTransform.cpp Detector/LHCb/src/SMOGInfo.cpp Detector/LHCb/src/Tell40Links.cpp Detector/LHCb/src/LHCInfo.cpp diff --git a/Detector/LHCb/include/Detector/LHCb/DeLHCb.h b/Detector/LHCb/include/Detector/LHCb/DeLHCb.h index 4e5102ab55d791027f33d26734a582d1a4b575a3..a4631024795411c525a50e1403d08127a9ade8e8 100644 --- a/Detector/LHCb/include/Detector/LHCb/DeLHCb.h +++ b/Detector/LHCb/include/Detector/LHCb/DeLHCb.h @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -32,9 +33,10 @@ namespace LHCb::Detector { void applyToAllChildren( const std::function )>& ) const override; std::vector children; Tell40Links m_tell40links; - std::optional m_interactionRegion; - std::optional m_lhcinfo; - std::optional m_SMOG; + std::optional m_interactionRegion; + std::optional m_lhcinfo; + std::optional m_SMOG; + std::optional m_vpCoordinateTransform; }; // Utility method to lookup DeIOV object from the condition slice @@ -53,6 +55,14 @@ namespace LHCb::Detector { std::optional lhcInfo() const { return this->access()->m_lhcinfo; } // Provides the SMOG injection type, the injected gas and the injection stability const std::optional SMOG() const { return this->access()->m_SMOG; } + + // Offline calibration conditions + + // Transforms related to the VELO, which affect the vertex positions, + // and all positions downstream, after re-aligning + std::optional vpGlobalCoordinateTransformation() const { + return this->access()->m_vpCoordinateTransform; + } }; // Utility method to setup DeLHCb diff --git a/Detector/LHCb/include/Detector/LHCb/VPGlobalCoordinateTransform.h b/Detector/LHCb/include/Detector/LHCb/VPGlobalCoordinateTransform.h new file mode 100644 index 0000000000000000000000000000000000000000..6aa58b32b4ff5605d8b2c11eea7e4f33b842010f --- /dev/null +++ b/Detector/LHCb/include/Detector/LHCb/VPGlobalCoordinateTransform.h @@ -0,0 +1,32 @@ +/*****************************************************************************\ +* (c) Copyright 2024 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 + +#include +#include + +/** + * This condition is only present for the offline calibration. + */ +namespace LHCb::Detector { + struct VPGlobalCoordinateTransform { + + VPGlobalCoordinateTransform() = default; + VPGlobalCoordinateTransform( const nlohmann::json& obj ); + + ROOT::Math::Translation3D oldPosition; + ROOT::Math::RotationZYX oldRotation; + + bool enabled; + }; +} // namespace LHCb::Detector diff --git a/Detector/LHCb/src/DeLHCb.cpp b/Detector/LHCb/src/DeLHCb.cpp index c35eff95842bae26a2840ad6ee189b24642f22ce..a4479c1a6c7e661b613b3898977e848ac8c38c50 100644 --- a/Detector/LHCb/src/DeLHCb.cpp +++ b/Detector/LHCb/src/DeLHCb.cpp @@ -49,6 +49,13 @@ LHCb::Detector::detail::DeLHCbObject::DeLHCbObject( const dd4hep::DetElement& if ( !SMOG.is_null() ) { m_SMOG = SMOG; } } } + { + auto cond = ctxt.condition( hash_key( de, "OfflineVPGlobalCoordinateTransform" ), false ); + if ( cond.isValid() ) { + auto coordinateTransformData = cond.get(); + if ( !coordinateTransformData.is_null() ) { m_vpCoordinateTransform = coordinateTransformData; } + } + } } void LHCb::Detector::detail::DeLHCbObject::applyToAllChildren( @@ -137,6 +144,16 @@ void LHCb::Detector::setup_DeLHCb_callback( dd4hep::Detector& description ) { depbuilder.add( hash_key( de, "InteractionRegion" ) ); } + // read possible offline coordinate transformations, if needed + if ( !schema || schema->has( "Conditions/LHCb/OfflineCalib/OfflineVPGlobalCoordinateTransform.yml", + "OfflineVPGlobalCoordinateTransform" ) ) { + ( *requests ) + ->addLocation( de, LHCb::Detector::item_key( "OfflineVPGlobalCoordinateTransform" ), + "Conditions/LHCb/OfflineCalib/OfflineVPGlobalCoordinateTransform.yml", + "OfflineVPGlobalCoordinateTransform" ); + depbuilder.add( hash_key( de, "OfflineVPGlobalCoordinateTransform" ) ); + } + if ( !schema || schema->has( "Conditions/LHCb/Online/LHC.yml", "LHC" ) ) { ( *requests )->addLocation( de, LHCb::Detector::item_key( "LHC" ), "Conditions/LHCb/Online/LHC.yml", "LHC" ); depbuilder.add( hash_key( de, "LHC" ) ); diff --git a/Detector/LHCb/src/VPGlobalCoordinateTransform.cpp b/Detector/LHCb/src/VPGlobalCoordinateTransform.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2b118e6dce99a6cd449d818556ae70964d9be0f --- /dev/null +++ b/Detector/LHCb/src/VPGlobalCoordinateTransform.cpp @@ -0,0 +1,67 @@ +/*****************************************************************************\ +* (c) Copyright 2024 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 + +#include + +#include +#include + +#include + +template +std::array arrayFromJson( const nlohmann::json& jsonArray, const double unit ) { + if ( jsonArray.size() != Size ) { throw std::runtime_error{"Condition array is not of expected size"}; } + + std::array values; + + for ( std::size_t i{0}; i < Size; ++i ) { + if ( jsonArray[i].is_string() ) { + values[i] = dd4hep::_toDouble( jsonArray[i].get() ); + } else if ( jsonArray[i].is_number() ) { + values[i] = jsonArray[i].get() * unit; + } else { + throw std::runtime_error{"Condition contains unexpected types"}; + } + } + + return values; +} + +LHCb::Detector::VPGlobalCoordinateTransform::VPGlobalCoordinateTransform( const nlohmann::json& obj ) { + if ( !obj.contains( "oldPosition" ) || !obj.contains( "oldRotation" ) ) { + throw std::runtime_error{ + "Could not find old position & rotation information - are you running the latest version of the software?"}; + } + + if ( !obj.contains( "newPosition" ) || !obj.contains( "newRotation" ) ) { + throw std::runtime_error{"VPGlobalCoordinateTrransform condition is empty"}; + } + + constexpr std::size_t posSize{3}; + constexpr std::size_t rotationSize{3}; + + auto& oldPos = obj.at( "oldPosition" ); + std::array oldPosVals{arrayFromJson( oldPos, dd4hep::mm )}; + + auto& oldRotationData = obj.at( "oldRotation" ); + std::array oldRotationVals{arrayFromJson( oldRotationData, dd4hep::radian )}; + + oldPosition.SetComponents( oldPosVals.begin(), oldPosVals.end() ); + + // The order in the yaml is RX RY RZ - mind the 'rbegin' and 'rend'! + oldRotation.SetComponents( oldRotationVals.rbegin(), oldRotationVals.rend() ); + + const auto& read_enabled_flag = obj.at( "enabled" ); + + // support both 'true/false' and 1 / 0 + enabled = read_enabled_flag.is_boolean() ? read_enabled_flag.get() : bool( read_enabled_flag.get() ); +} diff --git a/Detector/VP/include/Detector/VP/DeVP.h b/Detector/VP/include/Detector/VP/DeVP.h index f8d7e33568e83493e9e46acb3532d7d55208e4aa..daff5c923c1d544d4474c1e7295a34aa4ad9fc6b 100644 --- a/Detector/VP/include/Detector/VP/DeVP.h +++ b/Detector/VP/include/Detector/VP/DeVP.h @@ -12,6 +12,7 @@ #include "Core/DeIOV.h" #include "Core/Keys.h" +#include "Core/Units.h" #include "Detector/VP/DeVPSensor.h" #include