Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REveUtil.cxx
Go to the documentation of this file.
1// @(#)root/eve7:$Id$
2// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <ROOT/REveManager.hxx>
13#include <ROOT/REveElement.hxx>
14#include <ROOT/REveUtil.hxx>
15
16#include <ROOT/RLogger.hxx>
17
18#include "TError.h"
19#include "TGeoManager.h"
20#include "TGeoMatrix.h"
21#include "TClass.h"
22#include "TMath.h"
23
24#include "TColor.h"
25
26#include <chrono>
27#include <cstdio>
28
29#include "TROOT.h"
30#include "TInterpreter.h"
31
32#include <list>
33#include <algorithm>
34#include <string>
35#include <regex>
36
37using namespace ROOT::Experimental;
38
39////////////////////////////////////////////////////////////////////////////////
40/// Milliseconds from a monotonic clock, counted from first use. Not a wall
41/// clock. Time base of the streamed motion stamps, see REveTrans::SetMotion().
42
43double REveUtil::ServerTimeMs()
44{
45 using clock = std::chrono::steady_clock;
46 static const clock::time_point origin = clock::now();
47 return std::chrono::duration<double, std::milli>(clock::now() - origin).count();
48}
49
50namespace {
51// Width of the server_time value in characters: up to 12 integer digits of ms,
52// the point and three decimals.
53constexpr int kServerTimeWidth = 16;
54} // namespace
55
56////////////////////////////////////////////////////////////////////////////////
57/// Append "server_time" to the JSON message `msg`, a non-empty object or array:
58/// as its last key, or as a last entry, a trailer. The value has a fixed width,
59/// padded with spaces, so StampServerTime() finds it from the end and sets it
60/// in place just before the message is sent. The client takes it as the server
61/// clock at send-out, see ServerTimeMs().
62
63void REveUtil::AppendServerTime(std::string &msg)
64{
65 const bool is_array = msg.back() == ']';
66 msg.pop_back();
67 msg += is_array ? ",{\"server_time\":" : ",\"server_time\":";
68 msg.append(kServerTimeWidth, ' ');
69 msg += is_array ? "}]" : "}";
70 StampServerTime(msg);
71}
72
73////////////////////////////////////////////////////////////////////////////////
74/// Set the "server_time" that AppendServerTime() put at the end of `msg` to now.
75
76void REveUtil::StampServerTime(std::string &msg)
77{
78 const std::size_t tail = msg.back() == ']' ? 2 : 1;
79 char buf[kServerTimeWidth + 1];
80 snprintf(buf, sizeof(buf), "%*.3f", kServerTimeWidth, ServerTimeMs());
81 msg.replace(msg.size() - tail - kServerTimeWidth, kServerTimeWidth, buf, kServerTimeWidth);
82}
83
84namespace REX = ROOT::Experimental;
85
86
87/** \class REveUtil
88\ingroup REve
89Standard utility functions for Eve.
90*/
91
93
94namespace
95{
96////////////////////////////////////////////////////////////////////////////////
97/// Remove last part of string 's', starting from the last
98/// occurrence of character 'c'.
99/// Remove directory part -- everything until the last '/'.
100
101void ChompTailAndDir(TString& s, char c='.')
102{
103 Ssiz_t p = s.Last(c);
104 if (p != kNPOS)
105 s.Remove(p);
106
107 Ssiz_t ls = s.Last('/');
108 if (ls != kNPOS)
109 s.Remove(0, ls + 1);
110}
111}
112
113////////////////////////////////////////////////////////////////////////////////
114/// Checks if macro 'mac' is loaded.
115
117{
118 // Axel's advice; now sth seems slow, using old method below for test.
119 // return gROOT->GetInterpreter()->IsLoaded(mac);
120
121 // Previous version expected function with same name and used ROOT's
122 // list of global functions.
123
124 TString foo(mac); ChompTailAndDir(foo);
125 if (gROOT->GetGlobalFunction(foo.Data(), nullptr, kFALSE) != nullptr)
126 return kTRUE;
127 else
128 return (gROOT->GetGlobalFunction(foo.Data(), nullptr, kTRUE) != nullptr);
129}
130
131////////////////////////////////////////////////////////////////////////////////
132/// Load and execute macro 'mac' if it has not been loaded yet.
133
134void REveUtil::AssertMacro(const char* mac)
135{
136 if( CheckMacro(mac) == kFALSE) {
137 gROOT->Macro(mac);
138 }
139}
140
141////////////////////////////////////////////////////////////////////////////////
142/// Execute macro 'mac'. Do not reload the macro.
143
144void REveUtil::Macro(const char* mac)
145{
146 if (CheckMacro(mac) == kFALSE) {
147 gROOT->LoadMacro(mac);
148 }
149 TString foo(mac); ChompTailAndDir(foo); foo += "()";
150 gROOT->ProcessLine(foo.Data());
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Makes sure that macro 'mac' is loaded, but do not reload it.
155
156void REveUtil::LoadMacro(const char* mac)
157{
158 if (CheckMacro(mac) == kFALSE) {
159 gROOT->LoadMacro(mac);
160 }
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Input string verification and sanitization
165
167{
168 static const std::regex bad_re("[^\\w](?:gSystem|gROOT)[^\\w]", std::regex::optimize);
169 static const std::regex public_extra_re("(?:\\|\")", std::regex::optimize);
170
171 auto beg = expr.cbegin(), end = expr.cend();
172 if (std::regex_search(beg, end, bad_re))
173 return false;
174
175 const bool is_public = true; // to come from gEve
176 if (is_public && std::regex_search(beg, end, public_extra_re))
177 return false;
178
179 return true;
180}
181
182////////////////////////////////////////////////////////////////////////////////
183/// Fill col with RGBA values corresponding to index ci. If alpha
184/// is true, set alpha component of col to 255.
185/// ROOT's indexed color palette does not support transparency.
186
188{
189 TColor* c = gROOT->GetColor(ci);
190 if (c)
191 {
192 col[0] = (UChar_t)(255*c->GetRed());
193 col[1] = (UChar_t)(255*c->GetGreen());
194 col[2] = (UChar_t)(255*c->GetBlue());
195 if (alpha) col[3] = 255;
196 }
197 else
198 {
199 // Set to magenta.
200 col[0] = 255; col[1] = 0; col[2] = 255;
201 if (alpha) col[3] = 255;
202 return;
203 }
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// Fill col with RGBA values corresponding to index ci and transparency.
208/// ROOT's indexed color palette does not support transparency.
209
210void REveUtil::ColorFromIdx(Color_t ci, UChar_t col[4], Char_t transparency)
211{
212 UChar_t alpha = (255*(100 - transparency))/100;
213
214 TColor* c = gROOT->GetColor(ci);
215 if (c)
216 {
217 col[0] = (UChar_t)(255*c->GetRed());
218 col[1] = (UChar_t)(255*c->GetGreen());
219 col[2] = (UChar_t)(255*c->GetBlue());
220 col[3] = alpha;
221 }
222 else
223 {
224 // Set to magenta.
225 col[0] = 255; col[1] = 0; col[2] = 255; col[3] = alpha;
226 return;
227 }
228}
229
230////////////////////////////////////////////////////////////////////////////////
231/// Fill col with weighted RGBA values corresponding to
232/// color-indices c1 and c2. If alpha is true, set alpha component
233/// of col to 255.
234
236 UChar_t col[4], Bool_t alpha)
237{
239 TColor* t2 = gROOT->GetColor(c2);
240 if(t1 && t2) {
241 col[0] = (UChar_t)(255*(f1*t1->GetRed() + f2*t2->GetRed()));
242 col[1] = (UChar_t)(255*(f1*t1->GetGreen() + f2*t2->GetGreen()));
243 col[2] = (UChar_t)(255*(f1*t1->GetBlue() + f2*t2->GetBlue()));
244 if (alpha) col[3] = 255;
245 }
246}
247
248////////////////////////////////////////////////////////////////////////////////
249/// Find address of Color_t data-member with name varname in object
250/// obj.
251///
252/// This is used to access color information for TGListTreeItem
253/// coloration from visualization macros that wrap TObjects into
254/// REveElementObjectPtr instances.
255
256Color_t* REveUtil::FindColorVar(TObject* obj, const char* varname)
257{
258 static const REveException eh("REveUtil::FindColorVar");
259
260 Int_t off = obj->IsA()->GetDataMemberOffset(varname);
261 if(off == 0)
262 throw(eh + "could not find member '" + varname + "' in class " + obj->IsA()->GetName() + ".");
263 return (Color_t*) (((char*)obj) + off);
264}
265
266////////////////////////////////////////////////////////////////////////////////
267/// Tweak all ROOT colors to become brighter (if value > 0) or
268/// darker (value < 0). Reasonable values for the value argument are
269/// from -2.5 to 2.5 (error will be printed otherwise).
270/// If value is zero, the original colors are restored.
271///
272/// You should call REveManager::FullRedraw3D() afterwards or set
273/// the argument full_redraw to true (default is false).
274
276{
277 if (value < -2.5 || value > 2.5)
278 {
279 Error("REveUtil::SetColorBrightness", "value '%f' out of range [-0.5, 0.5].", value);
280 return;
281 }
282
283 TObjArray *colors = (TObjArray*) gROOT->GetListOfColors();
284
285 if (fgDefaultColors == nullptr)
286 {
287 const Int_t n_col = colors->GetEntriesFast();
288 fgDefaultColors = new TObjArray(n_col);
289 for (Int_t i = 0; i < n_col; ++i)
290 {
291 TColor* c = (TColor*) colors->At(i);
292 if (c)
293 fgDefaultColors->AddAt(new TColor(*c), i);
294 }
295 }
296
297 const Int_t n_col = fgDefaultColors->GetEntriesFast();
298 for (Int_t i = 0; i < n_col; ++i)
299 {
300 TColor* cdef = (TColor*) fgDefaultColors->At(i);
301 if (cdef)
302 {
303 TColor* croot = (TColor*) colors->At(i);
304 if (!croot)
305 {
306 croot = new TColor(*cdef);
307 colors->AddAt(croot, i);
308 }
309 else
310 {
311 cdef->Copy(*croot);
312 }
313
314 Float_t r, g, b;
315 croot->GetRGB(r, g, b);
316 r = TMath::Power( r, (2.5 - value)/2.5);
317 g = TMath::Power(g, (2.5 - value)/2.5);
318 b = TMath::Power(b, (2.5 - value)/2.5);
319
320 r = TMath::Min(r, 1.0f);
321 g = TMath::Min(g, 1.0f);
322 b = TMath::Min(b, 1.0f);
323
324 croot->SetRGB(r, g, b);
325 }
326 else
327 {
328 delete colors->RemoveAt(i);
329 }
330 }
331
332 if (full_redraw && REX::gEve)
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Return true if interval Q is contained within interval M for U1 variables.
338/// It is assumed that all values are within the [-2pi, 2pi] interval and
339/// minM <= maxM & minQ <= maxQ.
340
342 Float_t minQ, Float_t maxQ)
343{
344 using namespace TMath;
345
346 if (maxQ < minM)
347 {
348 minQ += TwoPi(); maxQ += TwoPi();
349 }
350 else if (minQ > maxM)
351 {
352 minQ -= TwoPi(); maxQ -= TwoPi();
353 }
354 return minQ >= minM && maxQ <= maxM;
355}
356
357////////////////////////////////////////////////////////////////////////////////
358/// Return true if interval Q is overlapping within interval M for U1 variables.
359/// It is assumed that all values are within the [-2pi, 2pi] interval and
360/// minM <= maxM & minQ <= maxQ.
361
363 Float_t minQ, Float_t maxQ)
364{
365 using namespace TMath;
366
367 if (maxQ < minM)
368 {
369 minQ += TwoPi(); maxQ += TwoPi();
370 }
371 else if (minQ > maxM)
372 {
373 minQ -= TwoPi(); maxQ -= TwoPi();
374 }
375 return maxQ >= minM && minQ <= maxM;
376}
377
378////////////////////////////////////////////////////////////////////////////////
379/// Get fraction of interval [minQ, maxQ] in [minM, maxM]
380
382{
383 if (minQ>=minM && maxQ<=maxM)
384 return 1;
385
386 else if (minQ<minM && maxQ>maxM)
387 return (maxM-minM)/(maxQ-minQ);
388
389 else if (minQ>=minM && maxQ>maxM)
390 return (maxM-minQ)/(maxQ-minQ);
391
392 else if (minQ<minM && maxQ<=maxM)
393 return (maxQ-minM)/(maxQ-minQ);
394
395 return 0;
396}
397
398
399/** \class REveGeoManagerHolder
400\ingroup REve
401Exception safe wrapper for setting gGeoManager.
402Functionality to lock-unlock via setting of a static lock in
403TGeoManager should be added (new feature of TGeoManager).
404*/
405
406////////////////////////////////////////////////////////////////////////////////
407/// Constructor.
408/// If n_seg is specified and larger than 2, the new geo-manager's
409/// NSegments is set to this value.
410
412 fManager (gGeoManager),
413 fNSegments (0)
414{
415 gGeoManager = new_gmgr;
416 if (gGeoManager) {
418 if (n_seg > 2) {
421 }
422 } else {
423 gGeoIdentity = nullptr;
424 }
425}
426
427////////////////////////////////////////////////////////////////////////////////
428/// Destructor.
429
442
443/** \class REveRefCnt
444\ingroup REve
445Base-class for reference-counted objects.
446By default the object is destroyed when zero reference-count is reached.
447*/
448
449/** \class REveRefBackPtr
450\ingroup REve
451Base-class for reference-counted objects with reverse references to
452REveElement objects.
453*/
454
455////////////////////////////////////////////////////////////////////////////////
456/// Destructor. Noop, should complain if back-ref list is not empty.
457
459{
460 // !!! Complain if list not empty.
461}
462
463////////////////////////////////////////////////////////////////////////////////
464/// Increase reference count and add re to the list of back-references.
465
471
472////////////////////////////////////////////////////////////////////////////////
473/// Decrease reference count and remove re from the list of back-references.
474
476{
477 auto i = fBackRefs.find(re);
478 if (i != fBackRefs.end()) {
479 if (--(i->second) <= 0)
480 fBackRefs.erase(i);
482 } else {
483 Warning("REveRefBackPtr::DecRefCount", "element '%s' not found in back-refs.", re->GetCName());
484 }
485}
486
487////////////////////////////////////////////////////////////////////////////////
488/// Add given stamps to elements in the list of reverse references.
489
491{
492 for (auto &i: fBackRefs)
493 i.first->AddStamp(stamps);
494}
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define g(i)
Definition RSha256.hxx:105
short Color_t
Color number (short)
Definition RtypesCore.h:100
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:53
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:52
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:132
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
R__EXTERN TGeoManager * gGeoManager
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:538
#define gROOT
Definition TROOT.h:417
REveException Exception-type thrown by Eve classes.
Definition REveTypes.hxx:42
Int_t fNSegments
! previous settings for num segments
Definition REveUtil.hxx:98
TGeoManager * fManager
! hold manager
Definition REveUtil.hxx:97
REveGeoManagerHolder(TGeoManager *new_gmgr=nullptr, Int_t n_seg=0)
Constructor.
Definition REveUtil.cxx:411
void FullRedraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE)
Perform 3D redraw of all scenes and viewers.
~REveRefBackPtr() override
Destructor. Noop, should complain if back-ref list is not empty.
Definition REveUtil.cxx:458
virtual void StampBackPtrElements(UChar_t stamps)
Add given stamps to elements in the list of reverse references.
Definition REveUtil.cxx:490
static Bool_t IsU1IntervalOverlappingByMinMax(Float_t minM, Float_t maxM, Float_t minQ, Float_t maxQ)
Return true if interval Q is overlapping within interval M for U1 variables.
Definition REveUtil.cxx:362
static double ServerTimeMs()
Milliseconds from a monotonic clock, counted from first use.
Definition REveUtil.cxx:43
static void LoadMacro(const char *mac)
Makes sure that macro 'mac' is loaded, but do not reload it.
Definition REveUtil.cxx:156
static void Macro(const char *mac)
Execute macro 'mac'. Do not reload the macro.
Definition REveUtil.cxx:144
static Bool_t CheckMacro(const char *mac)
Checks if macro 'mac' is loaded.
Definition REveUtil.cxx:116
static Float_t GetFraction(Float_t minM, Float_t maxM, Float_t minQ, Float_t maxQ)
Get fraction of interval [minQ, maxQ] in [minM, maxM].
Definition REveUtil.cxx:381
static void AppendServerTime(std::string &msg)
Append "server_time" to the JSON message msg, a non-empty object or array: as its last key,...
Definition REveUtil.cxx:63
static void SetColorBrightness(Float_t value, Bool_t full_redraw=kFALSE)
Tweak all ROOT colors to become brighter (if value > 0) or darker (value < 0).
Definition REveUtil.cxx:275
static Bool_t IsU1IntervalContainedByMinMax(Float_t minM, Float_t maxM, Float_t minQ, Float_t maxQ)
Return true if interval Q is contained within interval M for U1 variables.
Definition REveUtil.cxx:341
static void ColorFromIdx(Color_t ci, UChar_t col[4], Bool_t alpha=kTRUE)
Fill col with RGBA values corresponding to index ci.
Definition REveUtil.cxx:187
static void StampServerTime(std::string &msg)
Set the "server_time" that AppendServerTime() put at the end of msg to now.
Definition REveUtil.cxx:76
static Color_t * FindColorVar(TObject *obj, const char *varname)
Find address of Color_t data-member with name varname in object obj.
Definition REveUtil.cxx:256
static void AssertMacro(const char *mac)
Load and execute macro 'mac' if it has not been loaded yet.
Definition REveUtil.cxx:134
static bool VerifyObjectFilterOrTableExpression(std::string_view expr)
Input string verification and sanitization.
Definition REveUtil.cxx:166
static TObjArray * fgDefaultColors
Definition REveUtil.hxx:38
Longptr_t GetDataMemberOffset(const char *membername) const
return offset for member name.
Definition TClass.cxx:3544
The color creation and management class.
Definition TColor.h:22
virtual void SetRGB(Float_t r, Float_t g, Float_t b)
Initialize this color and its "dark" and "bright" associated colors.
Definition TColor.cxx:1868
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition TColor.h:55
Float_t GetRed() const
Definition TColor.h:61
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1939
void Copy(TObject &color) const override
Copy this color to obj.
Definition TColor.cxx:1364
Float_t GetBlue() const
Definition TColor.h:63
Float_t GetGreen() const
Definition TColor.h:62
An identity transformation.
Definition TGeoMatrix.h:407
The manager class for any TGeo geometry.
Definition TGeoManager.h:46
TObjArray * GetListOfMatrices() const
void SetNsegments(Int_t nseg)
Set number of segments for approximating circles in drawing.
Int_t GetNsegments() const
Get number of segments approximating circles.
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
void AddAt(TObject *obj, Int_t idx) override
Add object at position ids.
TObject * At(Int_t idx) const override
Definition TObjArray.h:170
TObject * RemoveAt(Int_t idx) override
Remove object at index idx.
Mother of all ROOT objects.
Definition TObject.h:42
virtual TClass * IsA() const
Definition TObject.h:248
Basic string class.
Definition TString.h:137
const char * Data() const
Definition TString.h:385
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:939
TString & Remove(Ssiz_t pos)
Definition TString.h:695
return c1
Definition legend1.C:41
TF1 * f1
Definition legend1.C:11
return c2
Definition legend2.C:14
Namespace for ROOT features in testing.
Definition TROOT.h:100
R__EXTERN REveManager * gEve
TMath.
Definition TMathBase.h:35
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:734
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
auto * t1
Definition textangle.C:20