diff --git a/algo/ca/core/tracking/CaFramework.cxx b/algo/ca/core/tracking/CaFramework.cxx index ed3d8d20071a94350ea2cc13dd55edd3e93b2f3a..dba8546f4da58c865adaf77681d05bb1c464a8e4 100644 --- a/algo/ca/core/tracking/CaFramework.cxx +++ b/algo/ca/core/tracking/CaFramework.cxx @@ -38,8 +38,6 @@ void Framework::Init(const TrackingMode mode) { fpTrackFinder = std::make_unique<ca::TrackFinder>(fParameters, fDefaultMass, mode, fMonitorData, fNofThreads, fCaRecoTime); - - fKf.Init(); } // --------------------------------------------------------------------------------------------------------------------- diff --git a/algo/kf/core/CMakeLists.txt b/algo/kf/core/CMakeLists.txt index 5644088641ff9575ab1d53b5bad4b58d5b3ff49f..40e4d5bb05dccfebffe0c2d343823180ef086edf 100644 --- a/algo/kf/core/CMakeLists.txt +++ b/algo/kf/core/CMakeLists.txt @@ -17,7 +17,6 @@ set(SRCS ${CMAKE_CURRENT_SOURCE_DIR}/geo/KfFieldSlice.cxx ${CMAKE_CURRENT_SOURCE_DIR}/geo/KfFieldRegion.cxx ${CMAKE_CURRENT_SOURCE_DIR}/geo/KfSetup.cxx - ${CMAKE_CURRENT_SOURCE_DIR}/geo/KfSetupSerializer.cxx ${CMAKE_CURRENT_SOURCE_DIR}/pars/KfParameters.cxx ${CMAKE_CURRENT_SOURCE_DIR}/utils/KfUtils.cxx ) @@ -75,6 +74,7 @@ install( geo/KfMaterialMap.h geo/KfSetup.h geo/KfTarget.h + geo/KfField.h pars/KfParameters.h utils/KfVector.h utils/KfSimd.h diff --git a/algo/kf/core/KfFramework.cxx b/algo/kf/core/KfFramework.cxx index 21334b755857c0bbb7e005c87469e15ea38f7cbc..5eb5bbbcae94ae89feedbc92dc86a83db05a99b0 100644 --- a/algo/kf/core/KfFramework.cxx +++ b/algo/kf/core/KfFramework.cxx @@ -11,38 +11,6 @@ using cbm::algo::kf::Framework; -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename DataT> -bool Framework<DataT>::Init() -try { - std::stringstream errMsg; - try { - fPars.Init(); - } - catch (const std::runtime_error& err) { - errMsg << "\tParameters initialization errors: " << err.what() << '\n'; - } - - //try { - // fSetup.Init(); - //} - //catch (const std::runtime_error& err) { - // errMsg << "\tSetup initialization errors: " << err.what() << '\n'; - //} - - if (!errMsg.str().empty()) { - throw std::runtime_error(errMsg.str()); - } - - L_(info) << '\n' << fPars.ToString(3) << '\n' << fSetup.ToString(3); - return true; -} -catch (const std::exception& err) { - L_(error) << "kf::Framework: initialization failed. Reason: " << err.what(); - return false; -} - namespace cbm::algo::kf { diff --git a/algo/kf/core/KfFramework.h b/algo/kf/core/KfFramework.h index ea5309a051dfd21534d00fef968a80788151cea4..2d1c39f1bbae165de9a7b71b061f9cc09838bac2 100644 --- a/algo/kf/core/KfFramework.h +++ b/algo/kf/core/KfFramework.h @@ -39,12 +39,6 @@ namespace cbm::algo::kf /// \brief Move assignment operator Framework& operator=(Framework&&) = delete; - /// \brief Initialization method - bool Init(); - - /// \brief Initialization satus - bool IsInitialized() const { return fbInitialized; } - /// \brief Parameters access kf::Parameters<T>& Pars() { return fPars; } diff --git a/algo/kf/core/geo/KfSetup.cxx b/algo/kf/core/geo/KfSetup.cxx index e2ac6a105fa3ce59d3c4a8a2a3f45e24286c65c6..af7b923f2b59382013524fa515920584f0e4f35a 100644 --- a/algo/kf/core/geo/KfSetup.cxx +++ b/algo/kf/core/geo/KfSetup.cxx @@ -12,12 +12,13 @@ #include <sstream> using cbm::algo::kf::Setup; -using cbm::algo::kf::SetupFactory; +using cbm::algo::kf::SetupInitializer; // // Setup methods definition // + // --------------------------------------------------------------------------------------------------------------------- // template<typename T> @@ -44,6 +45,7 @@ std::string Setup<T>::ToString(int verbosity, int indentLevel) const return msg.str(); } + namespace cbm::algo::kf { template class Setup<float>; @@ -51,18 +53,17 @@ namespace cbm::algo::kf template class Setup<fvec>; } // namespace cbm::algo::kf - // -// SetupFactory methods definition +// SetupInitializer methods definition // // --------------------------------------------------------------------------------------------------------------------- // -void SetupFactory::AddMaterial(const MaterialMap& material) +void SetupInitializer::AddMaterial(const MaterialMap& material) { if (!fMaterialLayers.emplace(material).second) { std::stringstream msg; - msg << "SetupFactory::AddMaterial: attempt of adding a duplicating material layer " << material.ToString() + msg << "SetupInitializer::AddMaterial: attempt of adding a duplicating material layer " << material.ToString() << ".\nThe next material layers were already added:"; for (const auto& el : fMaterialLayers) { msg << "\n\t- " << el.ToString(); @@ -74,7 +75,7 @@ void SetupFactory::AddMaterial(const MaterialMap& material) // --------------------------------------------------------------------------------------------------------------------- // template<typename T> -Setup<T> SetupFactory::MakeSetup(bool bProvideOrigField) const +Setup<T> SetupInitializer::MakeSetup(bool bProvideOrigField) const { Setup<T> setup; // Target initialization @@ -89,7 +90,7 @@ Setup<T> SetupFactory::MakeSetup(bool bProvideOrigField) const // Material layers initialization if (fMaterialLayers.size() > defs::MaxNofMaterialLayers) { std::stringstream msg; - msg << "kf::SetupFactory::MakeSetup(): too many material layers are provided (" << fMaterialLayers.size() + msg << "kf::SetupInitializer::MakeSetup(): too many material layers are provided (" << fMaterialLayers.size() << "), the maximum allowed number of the layers kf::defs::MaxNofMaterialLayers = " << defs::MaxNofMaterialLayers; throw std::logic_error(msg.str()); @@ -104,7 +105,7 @@ Setup<T> SetupFactory::MakeSetup(bool bProvideOrigField) const // --------------------------------------------------------------------------------------------------------------------- // -void SetupFactory::Reset() +void SetupInitializer::Reset() { fFieldFactory.Reset(); fMaterialLayers.clear(); @@ -112,7 +113,8 @@ void SetupFactory::Reset() // --------------------------------------------------------------------------------------------------------------------- // -void SetupFactory::SetTargetProperties(double x, double y, double z, double fieldInitStep, const MaterialMap& material) +void SetupInitializer::SetTargetProperties(double x, double y, double z, double fieldInitStep, + const MaterialMap& material) { fTarget.SetX(x); fTarget.SetY(y); @@ -121,3 +123,17 @@ void SetupFactory::SetTargetProperties(double x, double y, double z, double fiel fFieldFactory.SetTarget(x, y, z); fFieldFactory.SetStep(fieldInitStep); } + +// --------------------------------------------------------------------------------------------------------------------- +// +void SetupInitializer::Store(const Setup<double>& setup, const std::string& fileName) +{ + std::ofstream ofs(fileName, std::ios::binary); + if (!ofs) { + std::stringstream msg; + msg << "kf::SetupInitializer::Store: failed openning file \"" << fileName << "\" to store the setup"; + throw std::runtime_error(msg.str()); + } + boost::archive::binary_oarchive oa(ofs); + oa << setup; +} diff --git a/algo/kf/core/geo/KfSetup.h b/algo/kf/core/geo/KfSetup.h index 994c056a04b584656f0bfb1e3ca23c601fb761ec..2efe22422af90836aea9641e5394d4c1f74cac1b 100644 --- a/algo/kf/core/geo/KfSetup.h +++ b/algo/kf/core/geo/KfSetup.h @@ -15,10 +15,14 @@ #include "KfTarget.h" #include "KfVector.h" +#include <boost/archive/binary_iarchive.hpp> +#include <boost/archive/binary_oarchive.hpp> #include <boost/serialization/access.hpp> #include <boost/serialization/split_free.hpp> +#include <fstream> #include <optional> +#include <sstream> #include <string> #include <vector> @@ -107,6 +111,7 @@ namespace cbm::algo::kf /// \param target Target instance void SetTarget(const Target<double>& target) { fTarget = target; } + private: /// \brief BOOST serialization load method template<class Archive> void load(Archive& ar, const unsigned int /*version*/) @@ -141,27 +146,27 @@ namespace cbm::algo::kf }; - /// \class SetupFactory + /// \class SetupInitializer /// \brief Creates a valid initialized Setup instance - class SetupFactory { + class SetupInitializer { public: /// \brief Default constructor - SetupFactory() = default; + SetupInitializer() = default; /// \brief Copy constructor - SetupFactory(const SetupFactory&) = delete; + SetupInitializer(const SetupInitializer&) = delete; /// \brief Move constructor - SetupFactory(SetupFactory&&) = delete; + SetupInitializer(SetupInitializer&&) = delete; /// \brief Destructor - ~SetupFactory() = default; + ~SetupInitializer() = default; /// \brief Copy assignment operator - SetupFactory& operator=(const SetupFactory&) = delete; + SetupInitializer& operator=(const SetupInitializer&) = delete; /// \brief Move assignment operator - SetupFactory& operator=(SetupFactory&&) = delete; + SetupInitializer& operator=(SetupInitializer&&) = delete; /// \brief Adds magnetic field slice reference /// \param halfSizeX Half-size of the slice in x-direction [cm] @@ -202,6 +207,22 @@ namespace cbm::algo::kf /// \param material Target material layer void SetTargetProperties(double x, double y, double z, double fieldInitStep, const MaterialMap& material); + /// \brief Stores a serialized setup to a file + /// \param setup A reference to the Setup (NOTE: a double-Setup must be passed explicitly) + /// \param fileName Output file name + /// + /// Only a Setup with T = double can be serialized, so if a particular setup instance has another floating-point + /// type, it will be converted to the double-version. In the serialization only the interpolated magnetic field + /// variant is stored, the original field version will be set to nullopt during the loading from the file. + static void Store(const Setup<double>& setup, const std::string& fileName); + + /// \brief Loads a serialized setup from a file + /// \tparam T Underlying floating-point type for the output setup object + /// \param fileName Input file name + /// \throw std::runtime_error If the fileName cannot be opened + template<typename T> + static Setup<T> Load(const std::string& fileName); + private: std::set<MaterialMap> fMaterialLayers{}; ///< Set of material maps FieldFactory fFieldFactory; ///< Instance of field factory @@ -247,4 +268,31 @@ namespace cbm::algo::kf foOrigField = std::make_optional(field); } } + + // ------------------------------------------------------------------------------------------------------------------- + // + template<typename T> + Setup<T> SetupInitializer::Load(const std::string& fileName) + { + Setup<double> setup; + std::ifstream ifs(fileName, std::ios::binary); + if (!ifs) { + std::stringstream msg; + msg << "kf::SetupInitializer::Load: intput setup file \"" << fileName << "\" was not found"; + throw std::runtime_error(msg.str()); + } + try { + boost::archive::binary_iarchive ia(ifs); + ia >> setup; + } + catch (const std::exception& err) { + std::stringstream msg; + msg << "kf::SetupInitializer::Load: input setup file \"" << fileName + << "\" has inconsistent format or was " + "corrupted. The exception message: " + << err.what(); + throw std::runtime_error(msg.str()); + } + return Setup<T>(setup); + } } // namespace cbm::algo::kf diff --git a/algo/kf/core/geo/KfSetupSerializer.cxx b/algo/kf/core/geo/KfSetupSerializer.cxx deleted file mode 100644 index 52cb6658334b1df83ff0a65df39a05e536583ff0..0000000000000000000000000000000000000000 --- a/algo/kf/core/geo/KfSetupSerializer.cxx +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Sergei Zharko [committer] */ - -/// @file KfSetupSerializer.cxx -/// @brief Helper class for a kf::Setup loading/storing (implementation) -/// @since 26.08.2024 -/// @author Sergei Zharko <s.zharko@gsi.de> - -#include "KfSetupSerializer.h" - -using cbm::algo::kf::Setup; -using cbm::algo::kf::SetupSerializer; - -// --------------------------------------------------------------------------------------------------------------------- -// -void SetupSerializer::Store(const Setup<double>& setup, const std::string& fileName) -{ - std::ofstream ofs(fileName, std::ios::binary); - if (!ofs) { - std::stringstream msg; - msg << "kf::SetupSerializer::Store: failed openning file \"" << fileName << "\" to store the setup"; - throw std::runtime_error(msg.str()); - } - boost::archive::binary_oarchive oa(ofs); - oa << setup; -} diff --git a/algo/kf/core/geo/KfSetupSerializer.h b/algo/kf/core/geo/KfSetupSerializer.h deleted file mode 100644 index 98af29fc96f7969705600ef6270bea2e45b117aa..0000000000000000000000000000000000000000 --- a/algo/kf/core/geo/KfSetupSerializer.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Sergei Zharko [committer] */ - -/// @file KfSetupSerializer.h -/// @brief Helper class for a kf::Setup loading/storing (header) -/// @since 26.08.2024 -/// @author Sergei Zharko <s.zharko@gsi.de> - -#pragma once - -#include "KfSetup.h" - -#include <boost/archive/binary_iarchive.hpp> -#include <boost/archive/binary_oarchive.hpp> - -#include <fstream> -#include <sstream> -#include <string> - -namespace cbm::algo::kf -{ - /// \class SetupSerializer - /// \brief A helper class for storing/loading a kf::Setup instance - /// - /// A particular setup instance is dependent from a template parameter, which represents an underlying floating - /// point data-type. Only a Setup with T = double can be serialized, so if a particular setup instance has - /// another floating-point type, it will be converted to the double-precision version. - /// Moreover, a Setup instance has two magnetic field representation, an interpolated magnetic field and an - /// optional original field. In the serialization only the interpolated magnetic field variant is stored, the - /// original field version will be set to nullopt during the loading from the file. - /// - class SetupSerializer { - public: - /// \brief Stores a serialized setup to a file - /// \param setup A reference to the Setup (NOTE: a double-Setup must be passed explicitly) - /// \param fileName Output file name - static void Store(const Setup<double>& setup, const std::string& fileName); - - /// \brief Loads a serialized setup from a file - /// \tparam T Underlying floating-point type for the output setup object - /// \param fileName Input file name - /// \throw std::runtime_error If the fileName cannot be opened - template<typename T> - static Setup<T> Load(const std::string& fileName); - }; - - - // ------------------------------------------------------------------------------------------------------------------- - // - template<typename T> - Setup<T> SetupSerializer::Load(const std::string& fileName) - { - Setup<double> setup; - - std::ifstream ifs(fileName, std::ios::binary); - if (!ifs) { - std::stringstream msg; - msg << "kf::SetupSerializer::Load: intput setup file \"" << fileName << "\" was not found"; - throw std::runtime_error(msg.str()); - } - - try { - boost::archive::binary_iarchive ia(ifs); - ia >> setup; - } - catch (const std::exception& err) { - std::stringstream msg; - msg << "kf::SetupSerializer::Load: input setup file \"" << fileName - << "\" has inconsistent format or was " - "corrupted. The exception message: " - << err.what(); - throw std::runtime_error(msg.str()); - } - - return Setup<T>(setup); - } -} // namespace cbm::algo::kf diff --git a/algo/kf/core/pars/KfParameters.cxx b/algo/kf/core/pars/KfParameters.cxx index ce76c88c748f8c900b3819ef64bdff40d1d3bb97..6f82792172baff9852b6d0bda3bc2372e117ca38 100644 --- a/algo/kf/core/pars/KfParameters.cxx +++ b/algo/kf/core/pars/KfParameters.cxx @@ -13,33 +13,11 @@ using cbm::algo::kf::Parameters; -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename DataT> -void Parameters<DataT>::CheckConsistency() const -{ - std::stringstream errMsg; - - // checks go here... the errMsg is to be filled on each checking stage - - if (!errMsg.str().empty()) { - throw std::runtime_error(errMsg.str()); - } -} // --------------------------------------------------------------------------------------------------------------------- // -template<typename DataT> -void Parameters<DataT>::Init() -{ - fbInitialized = true; - this->CheckConsistency(); -} - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename DataT> -std::string Parameters<DataT>::ToString(int verbosity, int indentLevel) const +template<typename T> +std::string Parameters<T>::ToString(int verbosity, int indentLevel) const { std::stringstream msg; @@ -54,6 +32,7 @@ std::string Parameters<DataT>::ToString(int verbosity, int indentLevel) const return msg.str(); } + namespace cbm::algo::kf { template class Parameters<float>; diff --git a/algo/kf/core/pars/KfParameters.h b/algo/kf/core/pars/KfParameters.h index 922f4454a492b96b544eacff64f65f3c43593a90..b8815e0cb4380cdc784dd6aaeb8e4b6a6f2e31c5 100644 --- a/algo/kf/core/pars/KfParameters.h +++ b/algo/kf/core/pars/KfParameters.h @@ -10,55 +10,58 @@ #pragma once #include "KfDefs.h" +#include "KfUtils.h" #include <boost/serialization/access.hpp> #include <string> +#include <yaml-cpp/yaml.h> + namespace cbm::algo::kf { /// \class Parameters /// \brief Parameter set of the Kalman-filter framework - /// \tparam DataT Underlying data type - template<typename DataT> + /// \tparam T Underlying floating-point type + template<typename T> class Parameters { + template<typename I> + friend class Parameters; + public: + using Real_t = T; + /// \brief Default constructor Parameters() = default; - /// \brief Copy constructor - Parameters(const Parameters&) = default; - - /// \brief Move constructor - Parameters(Parameters&&) = default; + /// \brief Copy constructor + /// \tparam I Underlying floating-point type of the source + template<typename I> + Parameters(const Parameters<I>& other) : fDefaultMass(utils::simd::Cast<I, T>(other.fDefaultMass)) + { + } /// \brief Destructor ~Parameters() = default; /// \brief Copy assignment operator - Parameters& operator=(const Parameters&) = default; - - /// \brief Move assignment operator - Parameters& operator=(Parameters&&) = default; - - /// \brief Checks parameters instance - /// \note Throws std::runtime_error, if the class inconsistent - void CheckConsistency() const; + /// \tparam I Underlying floating-point type of the source + template<typename I> + Parameters& operator=(const Parameters<I>& other) + { + if constexpr (std::is_same_v<I, T>) { + if (this == &other) { + return *this; + } + } + fDefaultMass = utils::simd::Cast<I, T>(other.fDefaultMass); + } /// \brief Gets default mass - const DataT GetDefaultMass() const { return fDefaultMass; } - - /// \brief Initialization method - void Init(); - - /// \brief Returns initialization status - bool IsInitialized() const { return fbInitialized; } - - /// \brief Resets the contents of the parameters - void Reset() { *this = std::move(Parameters<DataT>{}); } + const T GetDefaultMass() const { return fDefaultMass; } /// \brief Sets default mass - void SetDefaultMass(DataT mass) { fDefaultMass = mass; } + void SetDefaultMass(T mass) { fDefaultMass = mass; } /// \brief String representation of the contents /// \param verbosity A verbose level for output @@ -72,12 +75,9 @@ namespace cbm::algo::kf void serialize(Archive& ar, const unsigned int /*version*/) { ar& fDefaultMass; - ar& fbInitialized; } - DataT fDefaultMass = defs::PionMass<DataT>; ///< Default particle mass [GeV/c2] - - bool fbInitialized = false; ///< Is instance initialized + T fDefaultMass = defs::PionMass<T>; ///< Default particle mass [GeV/c2] }; } // namespace cbm::algo::kf