diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt index 879ca5f061fc35292d9503540a4f3cfd1e86bbb4..cc8a444983f5f144b9a11bd372c6e35436b08421 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 bf3fea863074ce76dc98c26f9236861ae0753b17..13878ccbe467f226f9e3d364be2ec24fc970c1e7 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 9d8818a3b33e8ad0f518ae5f947cbd2d2d60c62d..4f357f7e4a09c48692b34fe536d9ea3de4ecf884 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 0000000000000000000000000000000000000000..b5a2349c13075a0204a348935ed7ff6cae339b6d --- /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 01b82ae659273771dbe69b5bfdf491519d6f1f14..803153a8e945b7a8a66fcfb5c0d9cfaf346475c2 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 4a8a6076ec12a06e7654a2e8be0301110194532b..6383eebceee9df1e5cc98f20d30577f8acb5787a 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 37256872c6a937330e7a3c9f4f0e6526e662db2b..22c69e5720c4fe198a600697bab9b4118bd31b0a 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 57ef4b4d6ef0dd8750c3fc837b403902e4a3516d..85cdd745ea1661a793d336a49e787133de509dfb 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;