diff --git a/CMakeLists.txt b/CMakeLists.txt index c97bd9a650d1e8a89da75f210eafc82cf3e30c38..ade15a1a8b8ff4e54e69c92146c680a07eaaf98e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ add_library(DetectorLib SHARED Detector/LHCb/src/DeLHCbHandles.cpp Detector/LHCb/src/InteractionRegion.cpp Detector/LHCb/src/Tell40Links.cpp + Detector/LHCb/src/LHCInfo.cpp Detector/Rich/src/DeRich.cpp Detector/Rich/src/DeRichRadiator.cpp Detector/Rich/src/DeRichMapmt.cpp diff --git a/Core/tests/CMakeLists.txt b/Core/tests/CMakeLists.txt index d116c353a1d970fdd5c858338c288d19ce0ba8dd..3b3a14f58704aa6ac3548430a22122c2b5bebba9 100644 --- a/Core/tests/CMakeLists.txt +++ b/Core/tests/CMakeLists.txt @@ -28,6 +28,7 @@ add_executable(test_DDS src/test_DDS_limit_IOV.cpp src/test_DDS_tell40links.cpp src/test_DDS_interactionregion.cpp + src/test_DDS_lhcinfo.cpp src/test_conddb_schema_handling.cpp src/test_condition_git_reader.cpp ) diff --git a/Core/tests/src/test_DDS_lhcinfo.cpp b/Core/tests/src/test_DDS_lhcinfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65d24768a6aeb68e44fa62b1d11e39745bf8e272 --- /dev/null +++ b/Core/tests/src/test_DDS_lhcinfo.cpp @@ -0,0 +1,70 @@ +/*****************************************************************************\ +* (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 +#include + +#include + +TEST_CASE( "LHCCondition loading" ) { + namespace fs = std::filesystem; + using Catch::Matchers::Contains; + + Detector::Test::Fixture f; + + auto& description = f.description(); + + description.fromXML( "compact/run3/trunk/LHCb.xml" ); + + REQUIRE( description.state() == dd4hep::Detector::READY ); + + auto det = description.detector( "/world" ); + // the `!!` is needed because handles have `operator!` but not `operator bool` + REQUIRE( !!det ); + + LHCb::Detector::DetectorDataService dds( description, {"/world"} ); + dds.initialize( nlohmann::json( {{"repository", "file:tests/ConditionsIOV"}} ) ); + + { + // get a condition slice where the condition exists + // - we should get the values from the condition + + auto slice = dds.get_slice( 200 ); + REQUIRE( slice ); + + LHCb::Detector::DeLHCb lhcb = slice->get( det, LHCb::Detector::Keys::deKey ); + REQUIRE( !!lhcb ); + + auto lhcinfo = lhcb.lhcInfo(); + REQUIRE( lhcinfo.has_value() ); + + CHECK( lhcinfo.value().fillnumber == 7974 ); + CHECK( lhcinfo.value().lhcstate == "INJECTION" ); + CHECK( lhcinfo.value().lhcenergy == 450 ); + CHECK( abs( lhcinfo.value().lhcbclockphase - 0.46556840909089 ) < 1e-6 ); + } + + { + // get a condition slice where the condition doesn't exist + // - we should get the fallback values + auto slice = dds.get_slice( 0 ); + REQUIRE( slice ); + + LHCb::Detector::DeLHCb lhcb = slice->get( det, LHCb::Detector::Keys::deKey ); + REQUIRE( !!lhcb ); + + auto lhcinfo = lhcb.lhcInfo(); + REQUIRE( !lhcinfo.has_value() ); + } +} diff --git a/Detector/LHCb/include/Detector/LHCb/DeLHCb.h b/Detector/LHCb/include/Detector/LHCb/DeLHCb.h index e942f3ebff31a198d6521e29c635a261bfb1ca1e..0d99ece88d2fec5daf4c5607a064b5e2cb65e48c 100644 --- a/Detector/LHCb/include/Detector/LHCb/DeLHCb.h +++ b/Detector/LHCb/include/Detector/LHCb/DeLHCb.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ namespace LHCb::Detector { std::vector children; Tell40Links m_tell40links; std::optional m_interactionRegion; + std::optional m_lhcinfo; }; // Utility method to lookup DeIOV object from the condition slice @@ -46,6 +48,7 @@ namespace LHCb::Detector { /// Provide the position, spread, and tilt of the interaction region std::optional interactionRegion() const { return this->access()->m_interactionRegion; } + std::optional lhcInfo() const { return this->access()->m_lhcinfo; } }; // Utility method to setup DeLHCb diff --git a/Detector/LHCb/include/Detector/LHCb/LHCInfo.h b/Detector/LHCb/include/Detector/LHCb/LHCInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..d432bd810223eb416623fad41a91a0dd2e2f53ba --- /dev/null +++ b/Detector/LHCb/include/Detector/LHCb/LHCInfo.h @@ -0,0 +1,29 @@ +/*****************************************************************************\ +* (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 + +namespace LHCb::Detector { + struct LHCInfo { + + LHCInfo() = default; + LHCInfo( const nlohmann::json& obj ); + + unsigned int fillnumber{}; + std::string lhcstate{}; + int lhcenergy{}; + float lhcbclockphase{}; + float xangleh{}; + float xanglev{}; + std::string beamtype{}; + }; +} // namespace LHCb::Detector diff --git a/Detector/LHCb/src/DeLHCb.cpp b/Detector/LHCb/src/DeLHCb.cpp index a17b7fa8333e76d6dc21cd57e1b85506b1720860..a8531146aeb2ac67f44432dc36496933c5a4e5a7 100644 --- a/Detector/LHCb/src/DeLHCb.cpp +++ b/Detector/LHCb/src/DeLHCb.cpp @@ -21,7 +21,6 @@ LHCb::Detector::detail::DeLHCbObject::DeLHCbObject( const dd4hep::DetElement& de, dd4hep::cond::ConditionUpdateContext& ctxt ) : DeIOVObject( de, ctxt, 9000000, false ) { - { auto cond = ctxt.condition( hash_key( de, "Tell40Links" ), false ); if ( cond.isValid() ) { @@ -36,6 +35,13 @@ LHCb::Detector::detail::DeLHCbObject::DeLHCbObject( const dd4hep::DetElement& if ( !ir.is_null() ) { m_interactionRegion = ir; } } } + { + auto cond = ctxt.condition( hash_key( de, "LHC" ), false ); + if ( cond.isValid() ) { + auto lhcinfo = cond.get(); + if ( !lhcinfo.is_null() ) { m_lhcinfo = lhcinfo; } + } + } } void LHCb::Detector::detail::DeLHCbObject::applyToAllChildren( @@ -124,5 +130,10 @@ void LHCb::Detector::setup_DeLHCb_callback( dd4hep::Detector& description ) { depbuilder.add( hash_key( de, "InteractionRegion" ) ); } + 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" ) ); + } + ( *requests )->addDependency( depbuilder.release() ); } diff --git a/Detector/LHCb/src/LHCInfo.cpp b/Detector/LHCb/src/LHCInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..78f4dbeacb0bac65da7ffda1767dbe5d887585af --- /dev/null +++ b/Detector/LHCb/src/LHCInfo.cpp @@ -0,0 +1,33 @@ +/*****************************************************************************\ +* (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 + +#include + +#include +#include + +#include + +LHCb::Detector::LHCInfo::LHCInfo( const nlohmann::json& obj ) { + if ( !obj.contains( "FillNumber" ) || !obj.contains( "LHCState" ) || !obj.contains( "LHCEnergy" ) || + !obj.contains( "LHCbClockPhase" ) ) { + throw std::runtime_error{"LHC condition is empty"}; + } + + fillnumber = obj.at( "FillNumber" ); + lhcstate = obj.at( "LHCState" ); + lhcenergy = obj.at( "LHCEnergy" ); + lhcbclockphase = obj.at( "LHCbClockPhase" ); + if ( obj.contains( "XAngleH" ) ) xangleh = obj.at( "XAngleH" ); + if ( obj.contains( "XAngleV" ) ) xanglev = obj.at( "XAngleV" ); + if ( obj.contains( "BeamType" ) ) beamtype = obj.at( "BeamType" ); +} diff --git a/tests/ConditionsIOV/.schema.json b/tests/ConditionsIOV/.schema.json index ccc777d2c6af994c3646cd981fcb52fb984b5714..610e08c52c11a47bc51c5d743333cf0903f6ea25 100644 --- a/tests/ConditionsIOV/.schema.json +++ b/tests/ConditionsIOV/.schema.json @@ -1391,6 +1391,9 @@ "Conditions/LHCb/Online/InteractionRegion.yml": [ "InteractionRegion" ], + "Conditions/LHCb/Online/LHC.yml": [ + "LHC" + ], "Conditions/LHCb/Online/Magnet.yml": [ "Magnet" ], diff --git a/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/.condition b/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/.condition new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/0 b/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/0 new file mode 100644 index 0000000000000000000000000000000000000000..b7721432b12a66ddabaa9ce930225346ae9103a9 --- /dev/null +++ b/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/0 @@ -0,0 +1,3 @@ +# Special case of empty condition +--- +LHC: diff --git a/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/200 b/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/200 new file mode 100644 index 0000000000000000000000000000000000000000..ca461d4b2545dde5d85f10e31626d9504f7345f0 --- /dev/null +++ b/tests/ConditionsIOV/Conditions/LHCb/Online/LHC.yml/200 @@ -0,0 +1,14 @@ +# Example of LHC condition +# ``` +# LHCCondition: +# fillnumber: [int] +# lhcbstate: [string] +# lhcbenergy: [int] +# lhcbclockphase: [float] +# ``` +--- +LHC: + FillNumber: 7974 + LHCState: INJECTION + LHCEnergy: 450 + LHCbClockPhase: 0.46556840909089