Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:47

0001 /// \defgroup ROOT7PadCoordSystems ROOT7 RPad coordinate systems
0002 /// \ingroup ROOT7Graphics
0003 /// \brief The ROOT7 RPad coordinate systems.
0004 ///
0005 /// \author Axel Naumann <axel@cern.ch>
0006 /// \date 2017-07-06
0007 
0008 /*************************************************************************
0009  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
0010  * All rights reserved.                                                  *
0011  *                                                                       *
0012  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0013  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0014  *************************************************************************/
0015 
0016 #ifndef ROOT7_RPadLength
0017 #define ROOT7_RPadLength
0018 
0019 #include <vector>
0020 #include <string>
0021 #include <cmath>
0022 
0023 namespace ROOT {
0024 namespace Experimental {
0025 
0026    /** \class RPadLength
0027        \ingroup ROOT7PadCoordSystems
0028        \brief A length in RPad.
0029     */
0030 
0031 class RPadLength  {
0032 
0033 protected:
0034 
0035    std::vector<double> fArr; ///< components [0] - normalized, [1] - pixel, [2] - user
0036 
0037 public:
0038    template <class DERIVED>
0039    struct CoordSysBase {
0040       double  fVal{0.};      ///<! Coordinate value
0041 
0042       CoordSysBase() = default;
0043       CoordSysBase(double val): fVal(val) {}
0044       DERIVED &ToDerived() { return static_cast<DERIVED &>(*this); }
0045 
0046       DERIVED operator-() { return DERIVED(-fVal); }
0047 
0048       friend DERIVED operator+(DERIVED lhs, DERIVED rhs) { return DERIVED{lhs.fVal + rhs.fVal}; }
0049       friend DERIVED operator-(DERIVED lhs, DERIVED rhs) { return DERIVED{lhs.fVal - rhs.fVal}; }
0050       friend double operator/(DERIVED lhs, DERIVED rhs) { return lhs.fVal / rhs.fVal; }
0051       DERIVED &operator+=(const DERIVED &rhs)
0052       {
0053          fVal += rhs.fVal;
0054          return ToDerived();
0055       }
0056       DERIVED &operator-=(const DERIVED &rhs)
0057       {
0058          fVal -= rhs.fVal;
0059          return ToDerived();
0060       }
0061       DERIVED &operator*=(double scale)
0062       {
0063          fVal *= scale;
0064          return ToDerived();
0065       }
0066       friend DERIVED operator*(const DERIVED &lhs, double rhs) { return DERIVED(lhs.fVal * rhs); }
0067       friend DERIVED operator*(double lhs, const DERIVED &rhs) { return DERIVED(lhs * rhs.fVal); }
0068       friend DERIVED operator/(const DERIVED &lhs, double rhs) { return DERIVED(lhs.fVal * rhs); }
0069       friend bool operator<(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal < rhs.fVal; }
0070       friend bool operator>(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal > rhs.fVal; }
0071       friend bool operator<=(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal <= rhs.fVal; }
0072       friend bool operator>=(const DERIVED &lhs, const DERIVED &rhs) { return lhs.fVal >= rhs.fVal; }
0073       // no ==, !=
0074    };
0075 
0076    /// \defgroup TypesafeCoordinates Typesafe Coordinates
0077    /// \ingroup ROOT7PadCoordSystems
0078    /// These define typesafe coordinates used by RPad to identify which coordinate system a coordinate is referring to
0079    /// The origin (0,0) is in the `RPad`'s bottom left corner for all of them.
0080    /// \{
0081 
0082    /** \struct Normal
0083        \brief A normalized coordinate.
0084 
0085      0 in the left, bottom corner, 1 in the top, right corner of the `RPad`.
0086      Resizing the pad will resize the objects with it.
0087     */
0088    struct Normal: CoordSysBase<Normal> {
0089       using CoordSysBase<Normal>::CoordSysBase;
0090    };
0091 
0092    /** \struct Pixel
0093        \brief A pixel coordinate.
0094 
0095      0 in the left, bottom corner, 1 in the top, right corner of the `RPad`.
0096      Resizing the pad will keep the pixel-position of the objects positioned in `Pixel` coordinates.
0097     */
0098    struct Pixel: CoordSysBase<Pixel> {
0099       using CoordSysBase<Pixel>::CoordSysBase;
0100    };
0101 
0102    /** \struct User
0103        \brief A user coordinate.
0104 
0105        as defined by the EUserCoordSystem parameter of the `RPad`.
0106     */
0107    struct User: CoordSysBase<User> {
0108       using CoordSysBase<User>::CoordSysBase;
0109    };
0110    /// \}
0111 
0112    RPadLength() {}
0113 
0114    /// Constructor from a `Normal` coordinate.
0115    RPadLength(Normal normal): RPadLength() { SetNormal(normal.fVal); }
0116 
0117    /// By default all numeric values are normal values
0118    RPadLength(double normal): RPadLength() { SetNormal(normal); }
0119 
0120    /// Constructor from a `Pixel` coordinate.
0121    RPadLength(Pixel px): RPadLength() { SetPixel(px.fVal); }
0122 
0123    /// Constructor from a `User` coordinate.
0124    RPadLength(User user) : RPadLength() { SetUser(user.fVal); }
0125 
0126    /// Constructor for normal and pixel coordinate.
0127    RPadLength(Normal normal, Pixel px): RPadLength() { SetPixel(px.fVal); SetNormal(normal.fVal);  }
0128 
0129    /// Constructor for normal, pixel and user coordinate.
0130    RPadLength(Normal normal, Pixel px, User user): RPadLength() { SetUser(user.fVal); SetPixel(px.fVal); SetNormal(normal.fVal);  }
0131 
0132    /// Constructor from string representation
0133    RPadLength(const std::string &csscode) : RPadLength() { if (!csscode.empty()) ParseString(csscode); }
0134 
0135    bool HasNormal() const { return !fArr.empty(); }
0136    bool HasPixel() const { return fArr.size() > 1; }
0137    bool HasUser() const { return fArr.size() > 2; }
0138 
0139    RPadLength &SetNormal(double v)
0140    {
0141       if (fArr.empty())
0142          fArr.resize(1);
0143       fArr[0] = v;
0144       return *this;
0145    }
0146 
0147    RPadLength &SetPixel(double v)
0148    {
0149       if (fArr.size() < 2)
0150          fArr.resize(2, 0.);
0151       fArr[1] = v;
0152       return *this;
0153    }
0154 
0155    RPadLength &SetUser(double v)
0156    {
0157       if (fArr.size() < 3)
0158          fArr.resize(3, 0.);
0159       fArr[2] = v;
0160       return *this;
0161    }
0162 
0163    double GetNormal() const { return !fArr.empty() ? fArr[0] : 0.; }
0164    double GetPixel() const { return fArr.size() > 1 ? fArr[1] : 0.; }
0165    double GetUser() const { return fArr.size() > 2 ? fArr[2] : 0.; }
0166 
0167    void ClearUser()
0168    {
0169       if (fArr.size() > 2)
0170          fArr.resize(2);
0171    }
0172 
0173    void ClearPixelAndUser()
0174    {
0175       if (fArr.size() > 1)
0176          fArr.resize(1);
0177    }
0178 
0179    void Clear() { fArr.clear(); }
0180 
0181    bool Empty() const { return fArr.empty(); }
0182 
0183    /// Add two `RPadLength`s.
0184    friend RPadLength operator+(RPadLength lhs, const RPadLength &rhs)
0185    {
0186       RPadLength res;
0187       if (lhs.HasUser() || rhs.HasUser())
0188          res.SetUser(lhs.GetUser() + rhs.GetUser());
0189       if (lhs.HasPixel() || rhs.HasPixel())
0190          res.SetPixel(lhs.GetPixel() + rhs.GetPixel());
0191       if (lhs.HasNormal() || rhs.HasNormal())
0192          res.SetNormal(lhs.GetNormal() + rhs.GetNormal());
0193       return res;
0194    }
0195 
0196    /// Subtract two `RPadLength`s.
0197    friend RPadLength operator-(RPadLength lhs, const RPadLength &rhs)
0198    {
0199       RPadLength res;
0200       if (lhs.HasUser() || rhs.HasUser())
0201          res.SetUser(lhs.GetUser() - rhs.GetUser());
0202       if (lhs.HasPixel() || rhs.HasPixel())
0203          res.SetPixel(lhs.GetPixel() - rhs.GetPixel());
0204       if (lhs.HasNormal() || rhs.HasNormal())
0205          res.SetNormal(lhs.GetNormal() - rhs.GetNormal());
0206       return res;
0207    }
0208 
0209    /// Unary -.
0210    RPadLength operator-()
0211    {
0212       RPadLength res;
0213       if (HasUser()) res.SetUser(-GetUser());
0214       if (HasPixel()) res.SetPixel(-GetPixel());
0215       if (HasNormal()) res.SetNormal(-GetNormal());
0216       return res;
0217    }
0218 
0219    /// Add a `RPadLength`.
0220    RPadLength &operator+=(const RPadLength &rhs)
0221    {
0222       if (HasUser() || rhs.HasUser())
0223          SetUser(GetUser() + rhs.GetUser());
0224       if (HasPixel() || rhs.HasPixel())
0225          SetPixel(GetPixel() + rhs.GetPixel());
0226       if (HasNormal() || rhs.HasNormal())
0227          SetNormal(GetNormal() + rhs.GetNormal());
0228       return *this;
0229    }
0230 
0231    /// Subtract a `RPadLength`.
0232    RPadLength &operator-=(const RPadLength &rhs)
0233    {
0234       if (HasUser() || rhs.HasUser())
0235          SetUser(GetUser() - rhs.GetUser());
0236       if (HasPixel() || rhs.HasPixel())
0237          SetPixel(GetPixel() - rhs.GetPixel());
0238       if (HasNormal() || rhs.HasNormal())
0239          SetNormal(GetNormal() - rhs.GetNormal());
0240       return *this;
0241    }
0242 
0243    /// Multiply a `RPadLength`.
0244    RPadLength &operator*=(double scale)
0245    {
0246       if (HasUser()) SetUser(scale*GetUser());
0247       if (HasPixel()) SetPixel(scale*GetPixel());
0248       if (HasNormal()) SetNormal(scale*GetNormal());
0249       return *this;
0250    }
0251 
0252    /// Compare a `RPadLength`.
0253    bool operator==(const RPadLength &rhs) const
0254    {
0255       if ((HasUser() != rhs.HasUser()) ||
0256           (HasUser() && std::fabs(GetUser() - rhs.GetUser()) > 1e-30)) return false;
0257 
0258       if(std::fabs(GetPixel() - rhs.GetPixel()) > 1e-4) return false;
0259 
0260       if (std::fabs(GetNormal() - rhs.GetNormal()) > 1e-6) return false;
0261 
0262       return true;
0263    };
0264 
0265    std::string AsString() const;
0266 
0267    bool ParseString(const std::string &val);
0268 
0269 };
0270 
0271 /// User-defined literal for `RPadLength::Normal`
0272 ///
0273 /// Use as
0274 /// ```
0275 /// using namespace ROOT::Experimental;
0276 /// RLine(0.1_normal, 0.0_normal, RLineExtent(0.2_normal, 0.5_normal));
0277 /// ```
0278 inline RPadLength::Normal operator"" _normal(long double val)
0279 {
0280    return RPadLength::Normal{(double)val};
0281 }
0282 inline RPadLength::Normal operator"" _normal(unsigned long long int val)
0283 {
0284    return RPadLength::Normal{(double)val};
0285 }
0286 
0287 /// User-defined literal for `RPadLength::Pixel`
0288 ///
0289 /// Use as
0290 /// ```
0291 /// using namespace ROOT::Experimental;
0292 /// RLine(100_px, 0_px, RLineExtent(20_px, 50_px));
0293 /// ```
0294 inline RPadLength::Pixel operator"" _px(long double val)
0295 {
0296    return RPadLength::Pixel{(double)val};
0297 }
0298 inline RPadLength::Pixel operator"" _px(unsigned long long int val)
0299 {
0300    return RPadLength::Pixel{(double)val};
0301 }
0302 
0303 /// User-defined literal for `RPadLength::User`
0304 ///
0305 /// Use as
0306 /// ```
0307 /// using namespace ROOT::Experimental;
0308 /// RLine(0.1_user, 0.0_user, RLineExtent(0.2_user, 0.5_user));
0309 /// ```
0310 inline RPadLength::User operator"" _user(long double val)
0311 {
0312    return RPadLength::User{(double)val};
0313 }
0314 inline RPadLength::User operator"" _user(unsigned long long int val)
0315 {
0316    return RPadLength::User{(double)val};
0317 }
0318 
0319 } // namespace Experimental
0320 } // namespace ROOT
0321 
0322 #endif