From ccc303985276dac43bc980b45aa6d9726c248c7c Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Tue, 21 Jun 2022 15:08:59 +0200 Subject: [PATCH] L1: L1NaN.h introduced --- reco/L1/CMakeLists.txt | 1 + reco/L1/L1Algo/L1MaterialInfo.cxx | 2 +- reco/L1/L1Algo/L1MaterialInfo.h | 30 +++++++++---- reco/L1/L1Algo/L1NaN.h | 66 ++++++++++++++++++++++++++++ reco/L1/L1Algo/L1Station.h | 22 +++++----- reco/L1/L1Algo/L1UMeasurementInfo.h | 12 +++-- reco/L1/L1Algo/L1Utils.h | 4 +- reco/L1/L1Algo/L1XYMeasurementInfo.h | 13 ++++-- 8 files changed, 122 insertions(+), 28 deletions(-) create mode 100644 reco/L1/L1Algo/L1NaN.h diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt index 879ca5f061..cc8a444983 100644 --- a/reco/L1/CMakeLists.txt +++ b/reco/L1/CMakeLists.txt @@ -280,6 +280,7 @@ Install(FILES CbmL1Counters.h L1Algo/L1Parameters.h L1Algo/L1Constants.h L1Algo/L1Utils.h + L1Algo/L1NaN.h vectors/vec_arithmetic.h vectors/std_alloc.h DESTINATION include diff --git a/reco/L1/L1Algo/L1MaterialInfo.cxx b/reco/L1/L1Algo/L1MaterialInfo.cxx index bf3fea8630..13878ccbe4 100644 --- a/reco/L1/L1Algo/L1MaterialInfo.cxx +++ b/reco/L1/L1Algo/L1MaterialInfo.cxx @@ -3,7 +3,7 @@ Authors: Sergey Gorbunov, Sergei Zharko [committer] */ #include "L1MaterialInfo.h" - +#include "L1Utils.h" #include <FairLogger.h> #include <iomanip> diff --git a/reco/L1/L1Algo/L1MaterialInfo.h b/reco/L1/L1Algo/L1MaterialInfo.h index 9d8818a3b3..4f357f7e4a 100644 --- a/reco/L1/L1Algo/L1MaterialInfo.h +++ b/reco/L1/L1Algo/L1MaterialInfo.h @@ -11,20 +11,26 @@ #include <vector> #include "L1Def.h" -#include "L1Utils.h" +#include "L1NaN.h" /// Class L1MaterialInfo contains SIMDized vector fields of the /// The fields of the structure should ONLY be initialized within L1BaseStationInfo::SetMaterial(double, double) method, when the /// stations sequence is initialized struct L1MaterialInfo { - fvec thick {L1Utils::kNaN}; ///< Average thickness of the station in arbitary length units - fvec RL { - L1Utils::kNaN}; ///< Average radiation length (X0) of the station material in THE SAME UNITS as the thickness - fvec RadThick {L1Utils::kNaN}; ///< Average thickness in units of radiation length (X/X0) - fvec logRadThick {L1Utils::kNaN}; + fvec thick {L1NaN::SetNaN<decltype(thick)>()}; ///< Average thickness of the station in arbitary length units + /// Average radiation length (X0) of the station material in THE SAME UNITS as the thickness + fvec RL {L1NaN::SetNaN<decltype(RL)>()}; + fvec RadThick {L1NaN::SetNaN<decltype(RadThick)>()}; ///< Average thickness in units of radiation length (X/X0) + fvec logRadThick {L1NaN::SetNaN<decltype(logRadThick)>()}; ///< Log of average thickness in units of radiation length /// Verifies class invariant consistency void CheckConsistency() const; + + /// Checks, if the fields are NaN + bool IsNaN() const + { + return L1NaN::IsNaN(thick) || L1NaN::IsNaN(RL) || L1NaN::IsNaN(RadThick) || L1NaN::IsNaN(logRadThick); + } /// String representation of class contents /// \param indentLevel number of indent characters in the output @@ -71,6 +77,12 @@ public: /// \param x X coordinate of the point [cm] (SIMDized vector) /// \param y Y coordinate of the point [cm] (SIMDized veotor) fvec GetRadThick(fvec x, fvec y) const; + + /// Checks, if the fields are NaN + bool IsNaN() const + { + return L1NaN::IsNaN(fNbins) || L1NaN::IsNaN(fRmax) || L1NaN::IsNaN(fFactor); + } /// Verifies class invariant consistency void CheckConsistency() const; @@ -93,9 +105,9 @@ public: void Swap(L1Material& other) noexcept; private: - int fNbins {-1}; ///< Number of rows (columns) in the material budget table - float fRmax {L1Utils::kNaN}; ///< Size of the station in x and y dimensions [cm] - float fFactor {L1Utils::kNaN}; ///< Factor used in the recalculation of point coordinates to row/column id + int fNbins {L1NaN::SetNaN<decltype(fNbins)>()}; ///< Number of rows (columns) in the material budget table + float fRmax {L1NaN::SetNaN<decltype(fRmax)>()}; ///< Size of the station in x and y dimensions [cm] + float fFactor {L1NaN::SetNaN<decltype(fFactor)>()}; ///< Factor used in the recalculation of point coordinates to row/column id std::vector<float> fTable {}; ///< Material budget table } _fvecalignment; diff --git a/reco/L1/L1Algo/L1NaN.h b/reco/L1/L1Algo/L1NaN.h new file mode 100644 index 0000000000..b5a2349c13 --- /dev/null +++ b/reco/L1/L1Algo/L1NaN.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergei Zharko [committer] */ + +/*************************************************************************************************** + * @file L1NaN.h + * @brief Definition of setters and checkers for NaN values + * @since 21.06.2022 + * @author S.Zharko <s.zharko@gsi.de> + ***************************************************************************************************/ + +#ifndef L1NaN_h +#define L1NaN_h 1 + +#include <limits> +#include <type_traits> +#include <cmath> +#include "vectors/P4_F32vec4.h" + +/// Namespace L1NaN defines functions to set variables to NaN and check wether they are NaN or not +/// +namespace L1NaN { + /// Returns NaN value for a floating point variable + template <typename T, typename std::enable_if<std::is_floating_point<T>::value, T>::type* = nullptr> + constexpr auto SetNaN() + { + return std::numeric_limits<T>::signaling_NaN(); + } + + /// Returns MaN value for an intergral variable + template <typename T, typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, T>::type* = nullptr> + constexpr auto SetNaN() + { + return T(-1); // -1 for signed integers and MAX_INT for unsigned integers + } + + /// Returns MaN value for fvec variable + template <typename T, typename std::enable_if<std::is_same<T, fvec>::value, T>::type* = nullptr> + constexpr auto SetNaN() + { + return fvec(SetNaN<fscal>()); + } + + /// Checks, if the floating point variable is NaN + template <typename T, typename std::enable_if<std::is_floating_point<T>::value, T>::type* = nullptr> + bool IsNaN(T value) + { + return std::isnan(value); + } + + /// Checks, if the integral variable is NaN + template <typename T, typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, T>::type* = nullptr> + bool IsNaN(T value) + { + return T(-1) == value; + } + + /// Checks, if the fvec variable is NaN + template <typename T, typename std::enable_if<std::is_same<T, fvec>::value, T>::type* = nullptr> + bool IsNaN(T value) + { + return value.IsNanAny(); // NOTE: Here we consider fvec a NaN if at least one of its words is NaN + } +}; + +#endif // L1NaN_h diff --git a/reco/L1/L1Algo/L1Station.h b/reco/L1/L1Algo/L1Station.h index 01b82ae659..803153a8e9 100644 --- a/reco/L1/L1Algo/L1Station.h +++ b/reco/L1/L1Algo/L1Station.h @@ -9,6 +9,7 @@ #include "L1Field.h" #include "L1MaterialInfo.h" +#include "L1NaN.h" #include "L1UMeasurementInfo.h" #include "L1Utils.h" #include "L1XYMeasurementInfo.h" @@ -16,16 +17,17 @@ /// Structure L1Station /// Contains a set of geometry parameters for a particular station /// -struct L1Station { - int type {-1}; - int timeInfo {-1}; ///< flag: if time information can be used - int fieldStatus {-1}; ///< flag: 1 - station is INSIDE the field, 0 - station is OUTSIDE the field - fvec z {L1Utils::kNaN}; ///< z position of station [cm] - fvec Rmin {L1Utils::kNaN}; ///< min radius of the station [cm] - fvec Rmax {L1Utils::kNaN}; ///< max radius of the station [cm] - fvec dt {L1Utils::kNaN}; ///< time resolution [ns] - L1MaterialInfo - materialInfo {}; ///< structure containing station thickness(X), rad. length (X0), X/X0 and log(X/X0) values +class L1Station { +public: + int type {L1NaN::SetNaN<decltype(type)>()}; + int timeInfo {L1NaN::SetNaN<decltype(timeInfo)>()}; ///< flag: if time information can be used + int fieldStatus {L1NaN::SetNaN<decltype(fieldStatus)>()}; ///< flag: 1 - station is INSIDE the field, 0 - station is OUTSIDE the field + fvec z {L1NaN::SetNaN<decltype(z)>()}; ///< z position of station [cm] + fvec Rmin {L1NaN::SetNaN<decltype(Rmin)>()}; ///< min radius of the station [cm] + fvec Rmax {L1NaN::SetNaN<decltype(Rmax)>()}; ///< max radius of the station [cm] + fvec dt {L1NaN::SetNaN<decltype(dt)>()}; ///< time resolution [ns] + /// structure containing station thickness(X), rad. length (X0), X/X0 and log(X/X0) values + L1MaterialInfo materialInfo {}; L1FieldSlice fieldSlice {}; L1UMeasurementInfo frontInfo {}; L1UMeasurementInfo backInfo {}; diff --git a/reco/L1/L1Algo/L1UMeasurementInfo.h b/reco/L1/L1Algo/L1UMeasurementInfo.h index 4a8a6076ec..6383eebcee 100644 --- a/reco/L1/L1Algo/L1UMeasurementInfo.h +++ b/reco/L1/L1Algo/L1UMeasurementInfo.h @@ -8,14 +8,15 @@ #include <string> #include "L1Def.h" +#include "L1NaN.h" #include "L1Utils.h" class L1UMeasurementInfo { public: - fvec cos_phi {0.f}; - fvec sin_phi {0.f}; - fvec sigma2 {0.f}; + fvec cos_phi {L1NaN::SetNaN<decltype(cos_phi)>()}; + fvec sin_phi {L1NaN::SetNaN<decltype(sin_phi)>()}; + fvec sigma2 {L1NaN::SetNaN<decltype(sigma2)>()}; /// String representation of class contents /// \param indentLevel number of indent characters in the output @@ -24,6 +25,11 @@ public: /// Check consistency void CheckConsistency() const; + /// Checks, if the fields are NaN + bool IsNaN() const + { + return L1NaN::IsNaN(cos_phi) || L1NaN::IsNaN(sin_phi) || L1NaN::IsNaN(sigma2); + } } _fvecalignment; diff --git a/reco/L1/L1Algo/L1Utils.h b/reco/L1/L1Algo/L1Utils.h index 37256872c6..22c69e5720 100644 --- a/reco/L1/L1Algo/L1Utils.h +++ b/reco/L1/L1Algo/L1Utils.h @@ -15,6 +15,7 @@ #include <map> #include <sstream> #include <string> +#include <type_traits> #include <unordered_map> #include <cmath> @@ -31,10 +32,9 @@ struct L1Utils { /// \param lhs Left floating point to compare /// \param rhs Right floating point to compare /// \return Comparison result: true - equals within epsilon - template<typename T> + template <typename T, typename std::enable_if<std::is_floating_point<T>::value, T>::type* = nullptr> static bool CmpFloats(T lhs, T rhs) { - static_assert(!std::numeric_limits<T>::is_integer, "L1Utils::CmpFloatingPoint does not work with integers"); return fabs(lhs - rhs) < 2. * std::numeric_limits<T>::epsilon() * fabs(lhs + rhs) || fabs(lhs - rhs) < std::numeric_limits<T>::min(); } diff --git a/reco/L1/L1Algo/L1XYMeasurementInfo.h b/reco/L1/L1Algo/L1XYMeasurementInfo.h index 57ef4b4d6e..85cdd745ea 100644 --- a/reco/L1/L1Algo/L1XYMeasurementInfo.h +++ b/reco/L1/L1Algo/L1XYMeasurementInfo.h @@ -8,13 +8,14 @@ #include <string> #include "L1Def.h" +#include "L1NaN.h" class L1XYMeasurementInfo { public: - fvec C00 {0}; - fvec C10 {0}; - fvec C11 {0}; + fvec C00 {L1NaN::SetNaN<decltype(C00)>()}; + fvec C10 {L1NaN::SetNaN<decltype(C10)>()}; + fvec C11 {L1NaN::SetNaN<decltype(C11)>()}; /// Consistency checker void CheckConsistency() const; @@ -22,6 +23,12 @@ public: /// String representation of class contents /// \param indentLevel number of indent characters in the output std::string ToString(int indentLevel = 0) const; + + /// Checks, if the fields are NaN + bool IsNaN() const + { + return L1NaN::IsNaN(C00) || L1NaN::IsNaN(C10) || L1NaN::IsNaN(C11); + } } _fvecalignment; -- GitLab