Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveDataClasses.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007, 2018
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/REveDataClasses.hxx>
13 #include <ROOT/REveUtil.hxx>
14 
15 #include "TROOT.h"
16 #include "TMethod.h"
17 #include "TMethodArg.h"
18 #include "TColor.h"
19 #include "TClass.h"
20 
21 #include "json.hpp"
22 #include <sstream>
23 
24 
25 using namespace ROOT::Experimental;
26 namespace REX = ROOT::Experimental;
27 
28 
29 Color_t REveDataCollection::fgDefaultColor = kBlue;
30 
31 //==============================================================================
32 // REveDataCollection
33 //==============================================================================
34 
35 REveDataCollection::REveDataCollection(const std::string& n, const std::string& t) :
36  REveElement(n, t)
37 {
38  fChildClass = TClass::GetClass<REveDataItem>();
39 
40  SetupDefaultColorAndTransparency(fgDefaultColor, true, true);
41 
42  _handler_func = 0;
43  _handler_func_ids = 0;
44 }
45 
46 void REveDataCollection::AddItem(void *data_ptr, const std::string& n, const std::string& t)
47 {
48  auto el = new REveDataItem(n, t);
49  AddElement(el);
50  el->SetMainColor(GetMainColor());
51  fItems.emplace_back(data_ptr, el);
52 }
53 
54 //------------------------------------------------------------------------------
55 
56 void REveDataCollection::SetFilterExpr(const TString& filter)
57 {
58  static const REveException eh("REveDataCollection::SetFilterExpr ");
59 
60  if (!fItemClass) throw eh + "item class has to be set before the filter expression.";
61 
62  fFilterExpr = filter;
63 
64  std::stringstream s;
65  s << "*((std::function<bool(" << fItemClass->GetName() << "*)>*)" << std::hex << std::showbase << (size_t)&fFilterFoo
66  << ") = [](" << fItemClass->GetName() << "* p){" << fItemClass->GetName() << " &i=*p; return ("
67  << fFilterExpr.Data() << "); }";
68 
69  // printf("%s\n", s.Data());
70  try {
71  gROOT->ProcessLine(s.str().c_str());
72  // AMT I don't know why ApplyFilter call is separated
73  ApplyFilter();
74  }
75  catch (const std::exception &exc)
76  {
77  std::cerr << "EveDataCollection::SetFilterExpr" << exc.what();
78  }
79 
80 }
81 
82 void REveDataCollection::ApplyFilter()
83 {
84  Ids_t ids;
85  int idx = 0;
86  for (auto &ii : fItems)
87  {
88  bool res = fFilterFoo(ii.fDataPtr);
89 
90  // printf("Item:%s -- filter result = %d\n", ii.fItemPtr->GetElementName(), res);
91 
92  ii.fItemPtr->SetFiltered( ! res );
93 
94  ids.push_back(idx++);
95  }
96  StampObjProps();
97  if ( _handler_func_ids) _handler_func_ids( this , ids);
98 }
99 
100 //______________________________________________________________________________
101 
102 Int_t REveDataCollection::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
103 {
104  Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
105  j["fFilterExpr"] = fFilterExpr.Data();
106  j["publicFunction"] = nlohmann::json::array();
107 
108  TIter x( fItemClass->GetListOfAllPublicMethods());
109  while (TObject *obj = x()) {
110  TMethod *method = dynamic_cast<TMethod *>(obj);
111 
112  nlohmann::json m;
113  m["name"] = method->GetPrototype();
114  j["publicFunction"].push_back(m);
115  }
116 
117  return ret;
118 }
119 
120 //______________________________________________________________________________
121 
122 void REveDataCollection::SetCollectionColorRGB(UChar_t r, UChar_t g, UChar_t b)
123 {
124  Color_t oldv = GetMainColor();
125  Color_t newv = TColor::GetColor(r, g, b);
126  int idx = 0;
127  Ids_t ids;
128  for (auto & chld : fChildren)
129  {
130  // if (chld->GetMainColor() == oldv) {
131  chld->SetMainColor(newv);
132  printf(" REveDataCollection::SetCollectionColorRGB going to change color for idx %d --------------------\n", idx);
133  ids.push_back(idx);
134  // }
135 
136  idx++;
137  }
138 
139  REveElement::SetMainColor(newv);
140  printf("REveDataCollection::SetCollectionColorRGB color ched to %d ->%d\n", oldv, GetMainColor());
141  _handler_func_ids( this , ids);
142 }
143 
144 //______________________________________________________________________________
145 
146 void REveDataCollection::SetCollectionVisible(bool iRnrSelf)
147 {
148  SetRnrSelf(iRnrSelf);
149 
150  Ids_t ids;
151 
152  for (int i = 0; i < GetNItems(); ++i ) {
153  ids.push_back(i);
154  GetDataItem(i)->SetRnrSelf(fRnrSelf);
155  }
156 
157  _handler_func_ids( this , ids);
158 }
159 
160 
161 
162 //______________________________________________________________________________
163 
164 void REveDataCollection::ItemChanged(REveDataItem* iItem)
165 {
166  int idx = 0;
167  Ids_t ids;
168  for (auto & chld : fChildren)
169  {
170  if (chld == iItem) {
171  ids.push_back(idx);
172  _handler_func_ids( this , ids);
173  return;
174  }
175  idx++;
176  }
177 }
178 
179 //==============================================================================
180 // REveDataItem
181 //==============================================================================
182 
183 REveDataItem::REveDataItem(const std::string& n, const std::string& t) :
184  REveElement(n, t)
185 {
186  SetupDefaultColorAndTransparency(kMagenta, true, true);
187 }
188 
189 Int_t REveDataItem::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
190 {
191  Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
192  j["fFiltered"] = fFiltered;
193  return ret;
194 }
195 
196 void REveDataItem::SetItemColorRGB(UChar_t r, UChar_t g, UChar_t b)
197 {
198  Color_t color = TColor::GetColor(r, g, b);
199  REveElement::SetMainColor(color);
200  REveDataCollection* c = dynamic_cast<REveDataCollection*>(fMother);
201  c->ItemChanged(this);
202 }
203 
204 void REveDataItem::SetItemRnrSelf(bool iRnrSelf)
205 {
206  REveElement::SetRnrSelf(iRnrSelf);
207  REveDataCollection* c = dynamic_cast<REveDataCollection*>(fMother);
208  c->ItemChanged(this);
209 }
210 
211 void REveDataItem::SetFiltered(bool f)
212 {
213  if (f != fFiltered)
214  {
215  fFiltered = f;
216  StampObjProps();
217  }
218 }
219 
220 void REveDataItem::FillImpliedSelectedSet(Set_t &impSelSet)
221 {
222  for (auto &n : fNieces)
223  {
224  impSelSet.insert(n);
225  n->FillImpliedSelectedSet(impSelSet);
226 
227  if (gDebug > 1)
228  {
229  printf("REveDataItem::FillImpliedSelectedSet added niece '%s' [%s]\n",
230  n->GetCName(), n->IsA()->GetName());
231  }
232  }
233 }
234 
235 //==============================================================================
236 // REveDataTable
237 //==============================================================================
238 
239 REveDataTable::REveDataTable(const std::string& n, const std::string& t) :
240  REveElement(n, t)
241 {
242  fChildClass = TClass::GetClass<REveDataColumn>();
243 }
244 
245 void REveDataTable::PrintTable()
246 {
247  Int_t Nit = fCollection->GetNItems();
248 
249  for (Int_t i = 0; i< Nit; ++i)
250  {
251  void *data = fCollection->GetDataPtr(i);
252  REveDataItem *item = fCollection->GetDataItem(i);
253 
254  printf("| %-20s |", item->GetCName());
255 
256  for (auto & chld : fChildren)
257  {
258  auto clmn = dynamic_cast<REveDataColumn*>(chld);
259 
260  printf(" %10s |", clmn->EvalExpr(data).c_str());
261  }
262  printf("\n");
263  }
264 }
265 
266 Int_t REveDataTable::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
267 {
268  int ret = REveElement::WriteCoreJson(j, rnr_offset);
269  Int_t Nit = fCollection->GetNItems();
270 
271  nlohmann::json jarr = nlohmann::json::array();
272 
273  for (Int_t i = 0; i < Nit; ++i) {
274  void *data = fCollection->GetDataPtr(i);
275  nlohmann::json row;
276  for (auto &chld : fChildren) {
277  auto clmn = dynamic_cast<REveDataColumn *>(chld);
278  row[chld->GetCName()] = clmn->EvalExpr(data);
279  }
280  jarr.push_back(row);
281  }
282  j["body"] = jarr;
283  j["fCollectionId"] = fCollection->GetElementId();
284  return ret;
285 }
286 
287 void REveDataTable::AddNewColumn(const std::string& expr, const std::string& title, int prec)
288 {
289  auto c = new REX::REveDataColumn(title);
290  AddElement(c);
291 
292  c->SetExpressionAndType(expr, REX::REveDataColumn::FT_Double);
293  c->SetPrecision(prec);
294 
295  StampObjProps();
296 }
297 
298 //==============================================================================
299 // REveDataColumn
300 //==============================================================================
301 
302 REveDataColumn::REveDataColumn(const std::string& n, const std::string& t) :
303  REveElement(n, t)
304 {
305 }
306 
307 void REveDataColumn::SetExpressionAndType(const std::string& expr, FieldType_e type)
308 {
309  auto table = dynamic_cast<REveDataTable*>(fMother);
310  auto coll = table->GetCollection();
311  auto icls = coll->GetItemClass();
312 
313  fExpression = expr;
314  fType = type;
315 
316  const char *rtyp = nullptr;
317  const void *fooptr = nullptr;
318 
319  switch (fType)
320  {
321  case FT_Double: rtyp = "double"; fooptr = &fDoubleFoo; break;
322  case FT_Bool: rtyp = "bool"; fooptr = &fBoolFoo; break;
323  case FT_String: rtyp = "std::string"; fooptr = &fStringFoo; break;
324  }
325 
326  std::stringstream s;
327  s << "*((std::function<" << rtyp << "(" << icls->GetName() << "*)>*)" << std::hex << std::showbase << (size_t)fooptr
328  << ") = [](" << icls->GetName() << "* p){" << icls->GetName() << " &i=*p; return (" << fExpression.Data()
329  << "); }";
330 
331  // printf("%s\n", s.str().c_str());
332  try {
333  gROOT->ProcessLine(s.str().c_str());
334  }
335  catch (const std::exception &exc)
336  {
337  std::cerr << "REveDataColumn::SetExpressionAndType" << exc.what();
338  }
339 }
340 
341 void REveDataColumn::SetPrecision(Int_t prec)
342 {
343  fPrecision = prec;
344 }
345 
346 std::string REveDataColumn::EvalExpr(void *iptr)
347 {
348  switch (fType)
349  {
350  case FT_Double:
351  {
352  TString ostr;
353  ostr.Form("%.*f", fPrecision, fDoubleFoo(iptr));
354  return ostr.Data();
355  }
356  case FT_Bool:
357  {
358  return fBoolFoo(iptr) ? fTrue : fFalse;
359  }
360  case FT_String:
361  {
362  return fStringFoo(iptr);
363  }
364  }
365  return "XYZ";
366 }