Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*************************************************************************
0002  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
0003  * All rights reserved.                                                  *
0004  *                                                                       *
0005  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0006  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0007  *************************************************************************/
0008 
0009 #ifndef ROOT7_RPalette
0010 #define ROOT7_RPalette
0011 
0012 #include <string_view>
0013 #include <ROOT/RColor.hxx>
0014 
0015 #include <utility>
0016 #include <vector>
0017 
0018 namespace ROOT {
0019 namespace Experimental {
0020 
0021 /** \class RPalette
0022 \ingroup GpadROOT7
0023 \brief A set of colors. `RColor`s can be conveniently generated from this.
0024 
0025   A palette associates a color with an ordinal number: for a normalized palette,
0026   this number ranges from 0..1. For user-valued palettes, the palette yields a color for
0027   user-coordinates (for instance histogram content), in an arbitrary range.
0028 
0029   A palette can be a smooth gradients by interpolation of support points, or a set of
0030   discrete colors.
0031 
0032 \author Axel Naumann <axel@cern.ch>
0033 \date 2017-09-26
0034 \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
0035 
0036 */
0037 
0038 class RPalette {
0039 public:
0040    /// An ordinal value and its associated color.
0041    struct OrdinalAndColor {
0042       double fOrdinal{0.}; ///< The value associated with the color.
0043       RColor fColor;       ///< The color associated with the value.
0044 
0045       /// Compare two `OrdinalAndColor`s, for sorting.
0046       friend bool operator<(const OrdinalAndColor &lhs, const OrdinalAndColor &rhs)
0047       {
0048          return lhs.fOrdinal < rhs.fOrdinal;
0049       }
0050 
0051       /// Compare an `OrdinalAndColor` and an ordinal value.
0052       friend bool operator<(const OrdinalAndColor &lhs, double rhs) { return lhs.fOrdinal < rhs; }
0053 
0054    };
0055 
0056 private:
0057    /// Palette colors: the color points and their ordinal value.
0058    std::vector<OrdinalAndColor> fColors;
0059 
0060    /// Whether to interpolate between the colors (in contrast to picking one of fColors).
0061    bool fInterpolate = true;
0062 
0063    /// Whether the palette's ordinal numbers are normalized.
0064    bool fNormalized = true;
0065 
0066    RPalette(bool interpolate, bool knownNormalized, const std::vector<OrdinalAndColor> &points);
0067    RPalette(bool interpolate, const std::vector<RColor> &points);
0068 
0069 public:
0070    /// Tag type used to signal that the palette's colors should not be interpolated.
0071    struct Discrete_t {
0072    };
0073 
0074    /// Tag value used to signal that the palette's colors should not be interpolated. Can be passed to the
0075    /// constructor: `RPalette palette(RPalette::kDiscrete, {{-100., RColor::kWhite}, {100., RColor::kRed}})`
0076    static constexpr const Discrete_t kDiscrete{};
0077 
0078    RPalette() = default;
0079 
0080    /// Construct a RPalette from a vector of (ordinal|color) pairs as interpolation points.
0081    /// Palette colors will be these points for the ordinal, and interpolated in between the
0082    /// ordinal points. The points will be sorted.
0083    /// The palette is normalized if the lowest ordinal is 0. and the highest ordinal is 1.;
0084    /// otherwise, the palette is a user-valued palette.
0085    RPalette(const std::vector<OrdinalAndColor> &interpPoints): RPalette(true, false, interpPoints) {}
0086 
0087    /// Construct a RPalette from a vector of (ordinal|color) pairs. For a given value, the palette returns
0088    /// the color with an ordinal that is closest to the value. The points will be sorted.
0089    /// The palette is normalized if the lowest ordinal is 0. and the highest ordinal is 1.;
0090    /// otherwise, the palette is a user-valued palette.
0091    RPalette(Discrete_t, const std::vector<OrdinalAndColor> &points): RPalette(false, false, points) {}
0092 
0093    /// Construct a normalized RPalette from a vector of colors as interpolation points. The ordinal associated
0094    /// with each color is equidistant from 0..1, i.e. for three colors it will be 0., 0.5 and 1, respectively.
0095    /// Palette colors will be these points for the ordinal associated with the color,
0096    /// and interpolated in between the ordinal points.
0097    RPalette(const std::vector<RColor> &interpPoints): RPalette(true, interpPoints) {}
0098 
0099    /// Construct a normalized RPalette from a vector of colors. The ordinal associated
0100    /// with each color is equidistant from 0..1, i.e. for three colors it will be 0., 0.5 and 1, respectively.
0101    /// For a given value, the palette returns the color with an ordinal that is closest to the value.
0102    RPalette(Discrete_t, const std::vector<RColor> &points): RPalette(false, points) {}
0103 
0104    /// Whether the palette is normalized, i.e. covers colors in the ordinal range 0..1.
0105    bool IsNormalized() const { return fNormalized; }
0106 
0107    /// Whether the palette is discrete, i.e. does no interpolation between colors.
0108    bool IsDiscrete() const { return !fInterpolate; }
0109 
0110    /// Whether the palette is a smooth gradient generated by interpolating between the color points.
0111    bool IsGradient() const { return fInterpolate; }
0112 
0113    /// Get the color associated with the ordinal value. The value is expected to be 0..1 for a normalized
0114    /// palette.
0115    RColor GetColor(double ordinal);
0116 
0117    ///\{
0118    ///\name Global Palettes
0119 
0120    /// Register a palette in the set of global palettes, making it available to `GetPalette()`.
0121    /// This function is not thread safe; any concurrent call to global Palette manipulation must be synchronized!
0122    static void RegisterPalette(std::string_view name, const RPalette &palette);
0123 
0124    /// Get a global palette by name. Returns an empty palette if no palette with that name is known.
0125    /// This function is not thread safe; any concurrent call to global Palette manipulation must be synchronized!
0126    static const RPalette &GetPalette(std::string_view name = "");
0127 
0128    ///\}
0129 };
0130 
0131 } // namespace Experimental
0132 } // namespace ROOT
0133 
0134 #endif