g4tools  5.4.0
colormap
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_sg_colormap
5 #define tools_sg_colormap
6 
7 #include "../colorf"
8 #include "../mathf"
9 #include "../scast"
10 #include "style_parser"
11 
12 #include <string>
13 #include <cfloat> //FLT_MAX
14 
15 namespace tools {
16 namespace sg {
17 
19 #ifdef TOOLS_MEM
20  static const std::string& s_class() {
21  static const std::string s_v("tools::sg::base_colormap");
22  return s_v;
23  }
24 #endif
25 public:
26  virtual void get_color(float,colorf&) const = 0;
27  virtual void* cast(const std::string&) const = 0;
28 public:
30 #ifdef TOOLS_MEM
31  mem::increment(s_class().c_str());
32 #endif
33  }
35  :m_values(aFrom.m_values),m_colors(aFrom.m_colors){
36 #ifdef TOOLS_MEM
37  mem::increment(s_class().c_str());
38 #endif
39  }
41  m_values = aFrom.m_values;
42  m_colors = aFrom.m_colors;
43  return *this;
44  }
45  virtual ~base_colormap(){
46 #ifdef TOOLS_MEM
47  mem::decrement(s_class().c_str());
48 #endif
49  }
50 public:
51  size_t colorn() const {return m_colors.size();}
52  size_t valn() const {return m_values.size();}
53  colorf color(size_t a_index) const {
54  size_t n = m_colors.size();
55  if(a_index>=n) return colorf(0.5F,0.5F,0.5F);
56  return m_colors[a_index];
57  }
58  float value(size_t a_index) const {
59  size_t n = m_values.size();
60  if(a_index>=n) return 0;
61  return m_values[a_index];
62  }
63 public:
64  // helper :
65  void set_colors(void(*aGet)(float,colorf&),size_t a_ncell) {
66  m_colors.clear();
67  m_colors.resize(a_ncell);
68  if(!a_ncell) return;
69  float d = 1.0F/(a_ncell-1);
70  for(size_t index=0;index<a_ncell;index++) {
71  aGet(d*index,m_colors[index]);
72  }
73  }
74 
76  size_t _valn = m_values.size();
77  if(_valn==1) {
78  m_values[0] = take_log(m_values[0]);
79  } else if(_valn>=2) {
80  //CERN/PAW coloring :
81  if(m_values[0]==0) m_values[0] = 10e-5F;
82  float vmin = take_log(m_values[0]);
83  float vmax = take_log(m_values[_valn-1]);
84  float dv = (vmax-vmin)/(_valn-1);
85  for(size_t count=0;count<_valn;count++) {
86  m_values[count] = vmin + dv * count;
87  }
88  }
89  }
90 
91 protected:
92  static float take_log(float aVal){
93  if(aVal<=0) {
94  return -FLT_MAX;
95  } else {
96  return flog10(aVal);
97  }
98  }
99 
100 protected:
101  std::vector<float> m_values;
102  std::vector<colorf> m_colors;
103 };
104 
106 public:
108 public:
109  virtual void get_color(float a_value,colorf& a_col) const{
110  get_by_value(a_value,m_values,m_colors,a_col);
111  }
112  virtual void* cast(const std::string& a_class) const {
113  if(void* p = cmp_cast<by_value_colormap>(this,a_class)) {return p;}
114  else return 0;
115  }
116 public:
117  by_value_colormap(std::ostream& a_out,
118  const sg::cmaps_t& a_cmaps,
119  const std::string& aString){
120  set_by_value(a_out,a_cmaps,aString,m_values,m_colors);
121  }
125  return *this;
126  }
127  virtual ~by_value_colormap(){}
128 protected:
129  static void set_by_value(std::ostream& a_out,
130  const sg::cmaps_t& a_cmaps,
131  const std::string& aString,
132  std::vector<float>& aValues,
133  std::vector<colorf>& aColors) {
134  // The given string is of the format :
135  // [<color name> <value>] <color name>
136  // or :
137  // [<value> <color name>] <value>
138  // For example :
139  // black 10 cyan 50 green 100 orange 200 blue 300 pink 400 red
140  std::vector<std::string> ws;
141  words(aString," ",false,ws);
142  size_t wordn = ws.size();
143  size_t number = wordn/2;
144  if(number<=0) {
145  aValues.clear();
146  aColors.clear();
147  } else if((2*number+1)!=wordn) {
148  a_out << "by_value_colormap::set_by_value :"
149  << " An odd number (" << wordn
150  << " given) of words is expected in " << sout(aString) << "."
151  << std::endl;
152  aValues.clear();
153  aColors.clear();
154  } else {
155  // look if :
156  // <col> <num> <col> ... <num> <col>
157  // or :
158  // <num> <col> <num> ... <col> <num>
159  // FIXME : case of <col> being three floats ?
160  colorf c;
161  if(sg::find_color(a_cmaps,ws[0],c)) {
162  // <col> <num> <col> ... <num> <col>
163  aValues.resize(number);
164  aColors.resize(number+1);
165  for(size_t count=0;count<number;count++) {
166  {const std::string& word = ws[2*count];
167  if(!sg::find_color(a_cmaps,word,aColors[count])) {
168  a_out << "by_value_colormap::set_by_value :"
169  << " in " << sout(aString)
170  << ", " << word << " not a color."
171  << std::endl;
172  aValues.clear();
173  aColors.clear();
174  return;
175  }}
176  {const std::string& word = ws[2*count+1];
177  if(!to(word,aValues[count])) {
178  a_out << "by_value_colormap::set_by_value :"
179  << " in " << sout(aString)
180  << ", " << word << " not a number."
181  << std::endl;
182  aValues.clear();
183  aColors.clear();
184  return;
185  }}
186  }
187  const std::string& word = ws[wordn-1];
188  if(!sg::find_color(a_cmaps,word,aColors[number])) {
189  a_out << "by_value_colormap::set_by_value :"
190  << " in " << sout(aString)
191  << ", " << word << " not a color."
192  << std::endl;
193  aValues.clear();
194  aColors.clear();
195  }
196  } else {
197  // <num> <col> <num> ... <col> <num>
198  aValues.resize(number+1);
199  aColors.resize(number);
200  for(size_t count=0;count<number;count++) {
201  {const std::string& word = ws[2*count];
202  if(!to(word,aValues[count])) {
203  a_out << "by_value_colormap::set_by_value :"
204  << " in " << sout(aString)
205  << ", " << word << " not a number."
206  << std::endl;
207  aValues.clear();
208  aColors.clear();
209  return;
210  }}
211  {const std::string& word = ws[2*count+1];
212  if(!sg::find_color(a_cmaps,word,aColors[count])) {
213  a_out << "by_value_colormap::set_by_value :"
214  << " in " << sout(aString)
215  << ", " << word << " not a color."
216  << std::endl;
217  aValues.clear();
218  aColors.clear();
219  return;
220  }}
221  }
222  {const std::string& word = ws[wordn-1];
223  if(!to(word,aValues[number])) {
224  a_out << "by_value_colormap::set_by_value :"
225  << " in " << sout(aString)
226  << ", " << word << " not a number."
227  << std::endl;
228  aValues.clear();
229  aColors.clear();
230  return;
231  }}
232  }
233  }
234  }
235 
236  static void get_by_value(float aValue,
237  const std::vector<float>& aValues,
238  const std::vector<colorf>& aColors,
239  colorf& a_col){
240  // There are aValuen (n) entries in aValues and (n+1) aColors
241  // aColors[0] aValues[0] aColors[1] aValues[1]...
242  // aValues[n-2] aColors[n-1] aValues[n-1] aColors[n]
243  // black 10 cyan 50 green 100 orange 200 blue 300 pink 400 red
244  // valuen = 6
245  // values[0] 10
246  // values[1] 50
247  // values[2] 100
248  // values[3] 200
249  // values[4] 300
250  // values[5] 400
251  //
252  // colors[0] black
253  // colors[1] cyan
254  // colors[2] green
255  // colors[3] orange
256  // colors[4] blue
257  // colors[5] pink
258  // colors[6] red
259  size_t _valn = aValues.size();
260  if(!_valn) {a_col = colorf_black();return;}
261  if(aColors.size()==(_valn+1)) {
262  // col0 val0 col1 val1 col2 val2 col3
263  if(aValue<aValues[0]) {
264  a_col = aColors[0];
265  } else {
266  for(int count=0;count<=int(_valn-2);count++) {
267  if( (aValues[count]<=aValue) && (aValue<aValues[count+1]) ) {
268  a_col = aColors[count+1];
269  return;
270  }
271  }
272  a_col = aColors[_valn];
273  }
274  } else if((aColors.size()+1)==_valn) {
275  // val0 col0 val1 col1 val2 col2 val3
276  for(int count=0;count<=int(_valn-2);count++) {
277  if( (aValues[count]<=aValue) && (aValue<aValues[count+1]) ) {
278  a_col = aColors[count];
279  return;
280  }
281  }
282  if(aValue<aValues[0]) {a_col = aColors[0];return;}
283  if(aValue>=aValues[_valn-1]) {a_col = aColors[aColors.size()-1];return;}
284  a_col = colorf_black();
285  } else {
286  a_col = colorf_black();
287  }
288  }
289 
290 };
291 
293 public:
295 public:
296  virtual void get_color(float a_value,colorf& a_col) const { //a_value in [0,1]
297  get_grey(a_value,a_col);
298  }
299  virtual void* cast(const std::string& a_class) const {
300  if(void* p = cmp_cast<grey_scale_colormap>(this,a_class)) {return p;}
301  else return 0;
302  }
303 public:
304  grey_scale_colormap() {} //if not drawn in sg::plotter.
305  grey_scale_colormap(float a_min,float a_max,size_t a_ncell){
306  //note : a_min, a_max, a_ncell (and then m_colors, m_values) are used by sg::plotter::update_cmap().
307  m_values.resize(2);
308  m_values[0] = a_min;
309  m_values[1] = a_max;
310  set_colors(get_grey,a_ncell);
311  }
315  return *this;
316  }
318 protected:
319  static void get_grey(float a_ratio,colorf& a_col) {
320  if(a_ratio<0.0F) a_ratio = 0;
321  if(a_ratio>1.0F) a_ratio = 1;
322  a_col.set_value(a_ratio,a_ratio,a_ratio,1);
323  }
324 };
325 
327 public:
329 public:
330  virtual void get_color(float a_value,colorf& a_col) const { //a_value in [0,1]
331  get_grey_inverse(a_value,a_col);
332  }
333  virtual void* cast(const std::string& a_class) const {
334  if(void* p = cmp_cast<grey_scale_inverse_colormap>(this,a_class)) {return p;}
335  else return 0;
336  }
337 public:
338  grey_scale_inverse_colormap() {} //if not drawn in sg::plotter.
339  grey_scale_inverse_colormap(float a_min,float a_max,size_t a_ncell){
340  //note : a_min, a_max, a_ncell (and then m_colors, m_values) are used by sg::plotter::update_cmap().
341  m_values.resize(2);
342  m_values[0] = a_min;
343  m_values[1] = a_max;
344  set_colors(get_grey_inverse,a_ncell);
345  }
349  return *this;
350  }
352 protected:
353  static void get_grey_inverse(float a_ratio,colorf& a_col){
354  if(a_ratio<0.0F) a_ratio = 0;
355  if(a_ratio>1.0F) a_ratio = 1;
356  a_ratio = 1 - a_ratio;
357  a_col.set_value(a_ratio,a_ratio,a_ratio,1);
358  }
359 };
360 
362 public:
364 public:
365  virtual void get_color(float a_value,colorf& a_col) const { //a_value in [0,1]
366  get_violet_to_red(a_value,a_col);
367  }
368  virtual void* cast(const std::string& a_class) const {
369  if(void* p = cmp_cast<violet_to_red_colormap>(this,a_class)) {return p;}
370  else return 0;
371  }
372 public:
373  violet_to_red_colormap() {} //if not drawn in sg::plotter.
374  violet_to_red_colormap(float a_min,float a_max,size_t a_ncell){
375  //note : a_min, a_max, a_ncell (and then m_colors, m_values) are used by sg::plotter::update_cmap().
376  set(a_min,a_max,a_ncell);
377  }
381  return *this;
382  }
384 public:
385  void set(float a_min,float a_max,size_t a_ncell){
386  m_values.resize(2);
387  m_values[0] = a_min;
388  m_values[1] = a_max;
389  set_colors(get_violet_to_red,a_ncell);
390  }
391 protected:
392  static void get_violet_to_red(float a_ratio,colorf& a_col){
393  if(a_ratio<0.0F) a_ratio = 0;
394  if(a_ratio>1.0F) a_ratio = 1;
395  // a_ratio in [0,1]
396  // From ROOT pretty palette.
397  // Initialize with the spectrum Violet->Red
398  // The color model used here is based on the HLS model which
399  // is much more suitable for creating palettes than RGB.
400  // Fixing the saturation and lightness we can scan through the
401  // spectrum of visible light by using "hue" alone.
402  // In Root hue takes values from 0 to 360.
403  float saturation = 1;
404  float lightness = 0.5;
405  float hue_mn = 0;
406  float hue_mx = 280;
407  float hue = hue_mx - a_ratio * (hue_mx-hue_mn);
408  float r,g,b;
409  hls_to_rgb(hue,lightness,saturation,r,g,b);
410  a_col.set_value(r,g,b,1);
411  }
412 
413 };
414 
416 public:
418 public:
419  virtual void get_color(float,colorf& a_col) const { //a_value in [0,1]
420  a_col = m_colors[0];
421  }
422  virtual void* cast(const std::string& a_class) const {
423  if(void* p = cmp_cast<const_colormap>(this,a_class)) {return p;}
424  else return 0;
425  }
426 public:
427  const_colormap(const colorf& aColor){m_colors.push_back(aColor);}
431  return *this;
432  }
433  virtual ~const_colormap(){}
434 };
435 
436 }}
437 
438 #endif
tools::sg::grey_scale_inverse_colormap::grey_scale_inverse_colormap
grey_scale_inverse_colormap(float a_min, float a_max, size_t a_ncell)
Definition: colormap:339
tools::sg::const_colormap::get_color
virtual void get_color(float, colorf &a_col) const
Definition: colormap:419
tools::sg::base_colormap
Definition: colormap:18
style_parser
tools::sg::find_color
bool find_color(const cmaps_t &a_cmaps, const std::string &a_s, colorf &a_col)
Definition: style_colormap:549
tools::sg::base_colormap::m_values
std::vector< float > m_values
Definition: colormap:101
tools::sg::violet_to_red_colormap::~violet_to_red_colormap
virtual ~violet_to_red_colormap()
Definition: colormap:383
tools::sg::violet_to_red_colormap::violet_to_red_colormap
violet_to_red_colormap()
Definition: colormap:373
tools::sg::base_colormap::m_colors
std::vector< colorf > m_colors
Definition: colormap:102
tools::sg::base_colormap::set_colors
void set_colors(void(*aGet)(float, colorf &), size_t a_ncell)
Definition: colormap:65
tools::colorf
Definition: colorf:11
tools::sg::grey_scale_inverse_colormap::get_grey_inverse
static void get_grey_inverse(float a_ratio, colorf &a_col)
Definition: colormap:353
tools::sg::grey_scale_colormap::operator=
grey_scale_colormap & operator=(const grey_scale_colormap &aFrom)
Definition: colormap:313
tools::sg::base_colormap::operator=
base_colormap & operator=(const base_colormap &aFrom)
Definition: colormap:40
tools::sg::by_value_colormap::operator=
by_value_colormap & operator=(const by_value_colormap &aFrom)
Definition: colormap:123
tools::sg::base_colormap::take_log
static float take_log(float aVal)
Definition: colormap:92
tools::sg::base_colormap::color
colorf color(size_t a_index) const
Definition: colormap:53
tools::sg::violet_to_red_colormap::set
void set(float a_min, float a_max, size_t a_ncell)
Definition: colormap:385
tools::sg::by_value_colormap::get_color
virtual void get_color(float a_value, colorf &a_col) const
Definition: colormap:109
tools::sg::base_colormap::get_color
virtual void get_color(float, colorf &) const =0
tools::sg::grey_scale_colormap::cast
virtual void * cast(const std::string &a_class) const
Definition: colormap:299
tools::sg::violet_to_red_colormap::operator=
violet_to_red_colormap & operator=(const violet_to_red_colormap &aFrom)
Definition: colormap:379
tools::sg::violet_to_red_colormap
Definition: colormap:361
tools::sg::const_colormap::operator=
const_colormap & operator=(const const_colormap &aFrom)
Definition: colormap:429
tools::sg::grey_scale_inverse_colormap::operator=
grey_scale_inverse_colormap & operator=(const grey_scale_inverse_colormap &aFrom)
Definition: colormap:347
TOOLS_SCLASS
#define TOOLS_SCLASS(a_name)
Definition: S_STRING:41
tools::sg::base_colormap::value
float value(size_t a_index) const
Definition: colormap:58
tools::sg::grey_scale_inverse_colormap::get_color
virtual void get_color(float a_value, colorf &a_col) const
Definition: colormap:330
tools::sg::grey_scale_colormap
Definition: colormap:292
tools::sg::base_colormap::base_colormap
base_colormap()
Definition: colormap:29
tools::sg::grey_scale_inverse_colormap::cast
virtual void * cast(const std::string &a_class) const
Definition: colormap:333
tools::sout
Definition: sout:17
tools::sg::cmaps_t
std::map< std::string, style_colormap > cmaps_t
Definition: style_colormap:536
tools::sg::violet_to_red_colormap::get_color
virtual void get_color(float a_value, colorf &a_col) const
Definition: colormap:365
tools::sg::grey_scale_inverse_colormap
Definition: colormap:326
tools::sg::grey_scale_inverse_colormap::grey_scale_inverse_colormap
grey_scale_inverse_colormap(const grey_scale_inverse_colormap &aFrom)
Definition: colormap:346
tools::sg::base_colormap::set_PAW_coloring
void set_PAW_coloring()
Definition: colormap:75
tools::sg::const_colormap
Definition: colormap:415
tools::sg::by_value_colormap::cast
virtual void * cast(const std::string &a_class) const
Definition: colormap:112
tools::sg::violet_to_red_colormap::violet_to_red_colormap
violet_to_red_colormap(const violet_to_red_colormap &aFrom)
Definition: colormap:378
tools::sg::violet_to_red_colormap::violet_to_red_colormap
violet_to_red_colormap(float a_min, float a_max, size_t a_ncell)
Definition: colormap:374
tools::sg::base_colormap::~base_colormap
virtual ~base_colormap()
Definition: colormap:45
tools::sg::grey_scale_colormap::~grey_scale_colormap
virtual ~grey_scale_colormap()
Definition: colormap:317
tools::flog10
float flog10(const float &x)
Definition: mathf:53
tools::to
std::vector< std::string > to(int a_argc, char **a_argv)
Definition: args:507
tools::sg::base_colormap::colorn
size_t colorn() const
Definition: colormap:51
tools::sg::by_value_colormap::set_by_value
static void set_by_value(std::ostream &a_out, const sg::cmaps_t &a_cmaps, const std::string &aString, std::vector< float > &aValues, std::vector< colorf > &aColors)
Definition: colormap:129
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::sg::const_colormap::cast
virtual void * cast(const std::string &a_class) const
Definition: colormap:422
tools::sg::grey_scale_inverse_colormap::grey_scale_inverse_colormap
grey_scale_inverse_colormap()
Definition: colormap:338
tools::words
void words(const std::string &a_string, const std::string &a_sep, bool a_take_empty, std::vector< std::string > &a_words, bool a_clear=true)
Definition: words:12
tools::sg::violet_to_red_colormap::cast
virtual void * cast(const std::string &a_class) const
Definition: colormap:368
tools::vec4::set_value
void set_value(const T &a0, const T &a1, const T &a2, const T &a3)
Definition: vec4:100
tools::sg::const_colormap::const_colormap
const_colormap(const colorf &aColor)
Definition: colormap:427
tools::sg::grey_scale_colormap::get_grey
static void get_grey(float a_ratio, colorf &a_col)
Definition: colormap:319
tools::sg::by_value_colormap
Definition: colormap:105
tools::sg::const_colormap::~const_colormap
virtual ~const_colormap()
Definition: colormap:433
tools::sg::grey_scale_inverse_colormap::~grey_scale_inverse_colormap
virtual ~grey_scale_inverse_colormap()
Definition: colormap:351
tools::sg::base_colormap::valn
size_t valn() const
Definition: colormap:52
tools::hls_to_rgb
void hls_to_rgb(T hue, T light, T satur, T &a_r, T &a_g, T &a_b)
Definition: hls:24
tools::sg::by_value_colormap::by_value_colormap
by_value_colormap(std::ostream &a_out, const sg::cmaps_t &a_cmaps, const std::string &aString)
Definition: colormap:117
tools::sg::by_value_colormap::get_by_value
static void get_by_value(float aValue, const std::vector< float > &aValues, const std::vector< colorf > &aColors, colorf &a_col)
Definition: colormap:236
tools::sg::by_value_colormap::by_value_colormap
by_value_colormap(const by_value_colormap &aFrom)
Definition: colormap:122
tools::sg::grey_scale_colormap::get_color
virtual void get_color(float a_value, colorf &a_col) const
Definition: colormap:296
tools::sg::violet_to_red_colormap::get_violet_to_red
static void get_violet_to_red(float a_ratio, colorf &a_col)
Definition: colormap:392
tools::sg::by_value_colormap::~by_value_colormap
virtual ~by_value_colormap()
Definition: colormap:127
tools::sg::const_colormap::const_colormap
const_colormap(const const_colormap &aFrom)
Definition: colormap:428
tools::sg::grey_scale_colormap::grey_scale_colormap
grey_scale_colormap(float a_min, float a_max, size_t a_ncell)
Definition: colormap:305
tools::sg::grey_scale_colormap::grey_scale_colormap
grey_scale_colormap(const grey_scale_colormap &aFrom)
Definition: colormap:312
tools::sg::grey_scale_colormap::grey_scale_colormap
grey_scale_colormap()
Definition: colormap:304
tools::sg::base_colormap::cast
virtual void * cast(const std::string &) const =0
tools::sg::base_colormap::base_colormap
base_colormap(const base_colormap &aFrom)
Definition: colormap:34