Logo ROOT  
Reference Guide
collection_proxies.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_eve7
3/// This example display collection of ??? in web browser
4///
5/// \macro_code
6///
7
8
10//#include "ROOT/REveDataProxyBuilderBase.hxx"
11//#include "ROOT/REveDataSimpleProxyBuilder.hxx"
13#include "ROOT/REveManager.hxx"
16#include <ROOT/REveGeoShape.hxx>
17#include <ROOT/REveJetCone.hxx>
18#include <ROOT/REvePointSet.hxx>
21#include <ROOT/REveScene.hxx>
24#include <ROOT/REveTrack.hxx>
26#include <ROOT/REveViewer.hxx>
28
29#include "TGeoTube.h"
30#include "TList.h"
31#include "TParticle.h"
32#include "TRandom.h"
33#include "TApplication.h"
34
35
36namespace REX = ROOT::Experimental;
37
38bool gRhoZView = false;
39
41
42
43//==============================================================================
44//============== EMULATE FRAMEWORK CLASSES =====================================
45//==============================================================================
46
47using namespace ROOT::Experimental;
48
49// a demo class, can be provided from experiment framework
50class XYJet : public TParticle
51{
52private:
53 float m_etaSize{0};
54 float m_phiSize{0};
55
56public:
57 float GetEtaSize() const { return m_etaSize; }
58 float GetPhiSize() const { return m_phiSize; }
59 void SetEtaSize(float iEtaSize) { m_etaSize = iEtaSize; }
60 void SetPhiSize(float iPhiSize) { m_phiSize = iPhiSize; }
61
62 XYJet(Int_t pdg, Int_t status, Int_t mother1, Int_t mother2, Int_t daughter1, Int_t daughter2,
63 Double_t px, Double_t py, Double_t pz, Double_t etot) :
64 TParticle(pdg, status, mother1, mother2, daughter1, daughter2, px, py, pz, etot, 0, 0, 0, 0)
65 {}
66
67 ClassDef(XYJet, 1);
68};
69
70class Event
71{
72public:
73 int eventId{0};
74 int N_tracks{0};
75 int N_jets{0};
76
77 Event() = default;
78
79 void MakeJets(int N)
80 {
81 TRandom &r = *gRandom;
82 r.SetSeed(0);
83 TList* list = new TList();
84 list->SetName("XYJets");
85 for (int i = 1; i <= N; ++i)
86 {
87 double pt = r.Uniform(0.5, 10);
88 double eta = r.Uniform(-2.55, 2.55);
89 double phi = r.Uniform(-TMath::Pi(), TMath::Pi());
90
91 double px = pt * std::cos(phi);
92 double py = pt * std::sin(phi);
93 double pz = pt * (1. / (std::tan(2*std::atan(std::exp(-eta)))));
94
95 auto jet = new XYJet(0, 0, 0, 0, 0, 0, px, py, pz, std::sqrt(px*px + py*py + pz*pz + 80*80));
96 jet->SetEtaSize(r.Uniform(0.02, 0.2));
97 jet->SetPhiSize(r.Uniform(0.01, 0.3));
98 list->Add(jet);
99 }
100 m_data.push_back(list);
101 }
102
103 void MakeParticles(int N)
104 {
105 TRandom &r = *gRandom;
106 r.SetSeed(0);
107 TList* list = new TList();
108 list->SetName("XYTracks");
109 for (int i = 1; i <= N; ++i)
110 {
111 double pt = r.Uniform(0.5, 10);
112 double eta = r.Uniform(-2.55, 2.55);
113 double phi = r.Uniform(0, TMath::TwoPi());
114
115 double px = pt * std::cos(phi);
116 double py = pt * std::sin(phi);
117 double pz = pt * (1. / (std::tan(2*std::atan(std::exp(-eta)))));
118
119 // printf("Event::MakeParticles %2d: pt=%.2f, eta=%.2f, phi=%.2f\n", i, pt, eta, phi);
120
121 auto particle = new TParticle(0, 0, 0, 0, 0, 0,
122 px, py, pz, std::sqrt(px*px + py*py + pz*pz + 80*80),
123 0, 0, 0, 0 );
124
125 int pdg = 11 * (r.Integer(2) > 0 ? 1 : -1);
126 particle->SetPdgCode(pdg);
127
128 list->Add(particle);
129 }
130 m_data.push_back(list);
131 }
132
133 std::vector<TList*> m_data;
134
135 void Clear()
136 {
137 for (auto &l : m_data)
138 delete l;
139 m_data.clear();
140 }
141
142 void Create()
143 {
144 Clear();
145 MakeJets(4);
146 MakeParticles(100);
147 eventId++;
148 }
149};
150
151
152//==============================================================================
153//== PROXY BUILDERS ============================================================
154//==============================================================================
155
156class XYJetProxyBuilder: public REveDataSimpleProxyBuilderTemplate<XYJet>
157{
158 bool HaveSingleProduct() const override { return false; }
159
161
162 void BuildViewType(const XYJet& dj, int idx, REveElement* iItemHolder,
163 std::string viewType, const REveViewContext* context) override
164 {
165 auto jet = new REveJetCone();
166 jet->SetCylinder(context->GetMaxR(), context->GetMaxZ());
167 jet->AddEllipticCone(dj.Eta(), dj.Phi(), dj.GetEtaSize(), dj.GetPhiSize());
168 SetupAddElement(jet, iItemHolder, true);
169 jet->SetLineColor(jet->GetMainColor());
170
171 float size = 50.f * dj.Pt(); // values are saved in scale
172 double theta = dj.Theta();
173 // printf("%s jet theta = %f, phi = %f \n", iItemHolder->GetCName(), theta, dj.Phi());
174 double phi = dj.Phi();
175
176
177 if (viewType == "Projected" )
178 {
179 static const float_t offr = 6;
180 float r_ecal = context->GetMaxR() + offr;
181 float z_ecal = context->GetMaxZ() + offr;
182
183 float transAngle = abs(atan(r_ecal/z_ecal));
184 double r = 0;
185 bool debug = false;
186 if (theta < transAngle || 3.14-theta < transAngle)
187 {
188 z_ecal = context->GetMaxZ() + offr/transAngle;
189 r = z_ecal/fabs(cos(theta));
190 }
191 else
192 {
193 debug = true;
194 r = r_ecal/sin(theta);
195 }
196
197 REveVector p1(0, (phi<TMath::Pi() ? r*fabs(sin(theta)) : -r*fabs(sin(theta))), r*cos(theta));
198 REveVector p2(0, (phi<TMath::Pi() ? (r+size)*fabs(sin(theta)) : -(r+size)*fabs(sin(theta))), (r+size)*cos(theta));
199
200 auto marker = new REveScalableStraightLineSet("jetline");
201 marker->SetScaleCenter(p1.fX, p1.fY, p1.fZ);
202 marker->AddLine(p1, p2);
203 marker->SetLineWidth(4);
204 if (debug)
205 marker->AddMarker(0, 0.9);
206
207 SetupAddElement(marker, iItemHolder, true);
208 marker->SetName(Form("line %s %d", Collection()->GetCName(), idx));
209 }
210 }
211
212
214
215 void LocalModelChanges(int idx, REveElement* el, const REveViewContext* ctx) override
216 {
217 printf("LocalModelChanges jet %s ( %s )\n", el->GetCName(), el->FirstChild()->GetCName());
218 REveJetCone* cone = dynamic_cast<REveJetCone*>(el->FirstChild());
219 cone->SetLineColor(cone->GetMainColor());
220 }
221};
222
223
224class TrackProxyBuilder : public REveDataSimpleProxyBuilderTemplate<TParticle>
225{
227
228 void Build(const TParticle& p, int idx, REveElement* iItemHolder, const REveViewContext* context) override
229 {
230 const TParticle *x = &p;
231 auto track = new REveTrack((TParticle*)(x), 1, context->GetPropagator());
232 track->MakeTrack();
233 SetupAddElement(track, iItemHolder, true);
234 }
235};
236
237
238//==============================================================================
239//== XY MANGER ================================================================
240//==============================================================================
241
242class XYManager
243{
244private:
245 Event *m_event{nullptr};
246
247 std::vector<REveScene *> m_scenes;
248 REveViewContext *m_viewContext {nullptr};
249 REveProjectionManager *m_mngRhoZ {nullptr};
250
251 std::vector<REveDataProxyBuilderBase *> m_builders;
252
253 REveScene *m_collections {nullptr};
254 bool m_inEventLoading {false};
255
256public:
257 XYManager(Event* event) : m_event(event)
258 {
259 //view context
260 float r = 300;
261 float z = 300;
262 auto prop = new REveTrackPropagator();
263 prop->SetMagFieldObj(new REveMagFieldDuo(350, -3.5, 2.0));
264 prop->SetMaxR(r);
265 prop->SetMaxZ(z);
266 prop->SetMaxOrbs(6);
267 prop->IncRefCount();
268
269 m_viewContext = new REveViewContext();
270 m_viewContext->SetBarrel(r, z);
271 m_viewContext->SetTrackPropagator(prop);
272
273 // table specs
274 auto tableInfo = new REveTableViewInfo();
275
276 tableInfo->table("TParticle").
277 column("pt", 1, "i.Pt()").
278 column("eta", 3, "i.Eta()").
279 column("phi", 3, "i.Phi()");
280
281 tableInfo->table("XYJet").
282 column("eta", 1, "i.Eta()").
283 column("phi", 1, "i.Phi()").
284 column("etasize", 2, "i.GetEtaSize()").
285 column("phisize", 2, "i.GetPhiSize()");
286
287 m_viewContext->SetTableViewInfo(tableInfo);
288
289 createScenesAndViews();
290 }
291
292 void createScenesAndViews()
293 {
294 // collections
295 m_collections = eveMng->SpawnNewScene("Collections", "Collections");
296
297 // 3D
298 m_scenes.push_back(eveMng->GetEventScene());
299
300 // Geometry
301 auto b1 = new REveGeoShape("Barrel 1");
302 float dr = 3;
303 b1->SetShape(new TGeoTube(m_viewContext->GetMaxR() , m_viewContext->GetMaxR() + dr, m_viewContext->GetMaxZ()));
304 b1->SetMainColor(kCyan);
306
307 // RhoZ
308 if (gRhoZView)
309 {
310 auto rhoZEventScene = eveMng->SpawnNewScene("RhoZ Scene","Projected");
311 m_mngRhoZ = new REveProjectionManager(REveProjection::kPT_RhoZ);
312 m_mngRhoZ->SetImportEmpty(true);
313 auto rhoZView = eveMng->SpawnNewViewer("RhoZ View", "");
315 m_scenes.push_back(rhoZEventScene);
316
317 auto pgeoScene = eveMng->SpawnNewScene("Projection Geometry","xxx");
318 m_mngRhoZ->ImportElements(b1,pgeoScene );
319 rhoZView->AddScene(pgeoScene);
320 }
321
322 // Table
323 if (1)
324 {
325 auto tableScene = eveMng->SpawnNewScene ("Tables", "Tables");
326 auto tableView = eveMng->SpawnNewViewer("Table", "Table View");
327 tableView->AddScene(tableScene);
328 tableScene->AddElement(m_viewContext->GetTableViewInfo());
329 m_scenes.push_back(tableScene);
330 }
331 }
332
333 // this should be handeled with framefor plugins
334 REveDataProxyBuilderBase* makeGLBuilderForType(TClass* c)
335 {
336 std::string cn = c->GetName();
337 if (cn == "XYJet") {
338 return new XYJetProxyBuilder();
339 }
340 else
341 {
342 return new TrackProxyBuilder();
343 }
344 }
345
346 void LoadCurrentEvent(REveDataCollection* collection)
347 {
348 for (auto &l : m_event->m_data) {
349 TIter next(l);
350 if (collection->GetName() == std::string(l->GetName()))
351 {
352 collection->ClearItems();
353 collection->DestroyElements();
354
355 for (int i = 0; i <= l->GetLast(); ++i)
356 {
357 std::string cname = collection->GetName();
358 auto len = cname.size();
359 char end = cname[len-1];
360 if (end == 's') {
361 cname = cname.substr(0, len-1);
362 }
363 TString pname(Form("%s %2d", cname.c_str(), i));
364 collection->AddItem(l->At(i), pname.Data(), "");
365 }
366 }
367 collection->ApplyFilter();
368 }
369 }
370
371 void NextEvent()
372 {
373 m_inEventLoading = true;
374
375 for (auto &el: m_collections->RefChildren())
376 {
377 auto c = dynamic_cast<REveDataCollection *>(el);
378 LoadCurrentEvent(c);
379 }
380
381 for (auto proxy : m_builders)
382 {
383 proxy->Build();
384 }
385
386 m_inEventLoading = false;
387 }
388
389 void addCollection(REveDataCollection* collection, bool showInTable)
390 {
391 m_collections->AddElement(collection);
392
393 // load data
394 LoadCurrentEvent(collection);
395
396 // GL view types
397 auto glBuilder = makeGLBuilderForType(collection->GetItemClass());
398 glBuilder->SetCollection(collection);
399 glBuilder->SetHaveAWindow(true);
400 for (auto scene : m_scenes)
401 {
402 REveElement *product = glBuilder->CreateProduct(scene->GetTitle(), m_viewContext);
403
404 if (strncmp(scene->GetCTitle(), "Table", 5) == 0) continue;
405
406 if (!strncmp(scene->GetCTitle(), "Projected", 8))
407 {
408 m_mngRhoZ->ImportElements(product, scene);
409 }
410 else
411 {
412 scene->AddElement(product);
413 }
414 }
415 m_builders.push_back(glBuilder);
416 glBuilder->Build();
417
418 // Table view types
419 auto tableBuilder = new REveTableProxyBuilder();
420 tableBuilder->SetHaveAWindow(true);
421 tableBuilder->SetCollection(collection);
422 REveElement* tablep = tableBuilder->CreateProduct("table-type", m_viewContext);
423 auto tableMng = m_viewContext->GetTableViewInfo();
424 if (showInTable)
425 {
426 tableMng->SetDisplayedCollection(collection->GetElementId());
427 }
428 tableMng->AddDelegate([=]() { tableBuilder->ConfigChanged(); });
429 for (REveScene* scene : m_scenes)
430 {
431 if (strncmp(scene->GetCTitle(), "Table", 5) == 0)
432 {
433 scene->AddElement(tablep);
434 tableBuilder->Build(collection, tablep, m_viewContext );
435 }
436 }
437 m_builders.push_back(tableBuilder);
438
439 collection->SetHandlerFunc([&] (REveDataCollection* collection)
440 {
441 this->CollectionChanged( collection );
442 });
443
444 collection->SetHandlerFuncIds([&] (REveDataCollection* collection, const REveDataCollection::Ids_t& ids)
445 {
446 this->ModelChanged( collection, ids );
447 });
448 }
449
450 void finishViewCreate()
451 {
452 auto mngTable = m_viewContext->GetTableViewInfo();
453 if (mngTable)
454 {
455 for (auto &el : m_collections->RefChildren())
456 {
457 if (el->GetName() == "XYTracks")
458 mngTable->SetDisplayedCollection(el->GetElementId());
459 }
460 }
461 }
462
463 void CollectionChanged(REveDataCollection* collection)
464 {
465 printf("collection changes not implemented %s!\n", collection->GetCName());
466 }
467
468 void ModelChanged(REveDataCollection* collection, const REveDataCollection::Ids_t& ids)
469 {
470 if (m_inEventLoading) return;
471
472 for (auto proxy : m_builders)
473 {
474 if (proxy->Collection() == collection)
475 {
476 // printf("Model changes check proxy %s: \n", proxy->Type().c_str());
477 proxy->ModelChanges(ids);
478 }
479 }
480 }
481};
482
483
484//==============================================================================
485//== Event Manager =============================================================
486//==============================================================================
487
488class EventManager : public REveElement
489{
490private:
491 Event* m_event;
492 XYManager* m_xymng;
493
494public:
495 EventManager(Event* e, XYManager* m): m_event(e), m_xymng(m) {}
496
497 virtual ~EventManager() {}
498
499 virtual void NextEvent()
500 {
501 m_event->Create();
502 m_xymng->NextEvent();
503 }
504
505 virtual void QuitRoot()
506 {
507 printf("Quit ROOT\n");
509 }
510};
511
512
513//==============================================================================
514//== main() ====================================================================
515//==============================================================================
516
517void collection_proxies(bool proj=true)
518{
519 eveMng = REveManager::Create();
520
521 auto event = new Event();
522 event->Create();
523
524 gRhoZView = true;
525
526 // debug settings
527 auto xyManager = new XYManager(event);
528
529 if (1)
530 {
531 REveDataCollection* trackCollection = new REveDataCollection("XYTracks");
532 trackCollection->SetItemClass(TParticle::Class());
533 trackCollection->SetMainColor(kGreen);
534 trackCollection->SetFilterExpr("i.Pt() > 4.1 && std::abs(i.Eta()) < 1");
535 xyManager->addCollection(trackCollection, true);
536 }
537
538 if (1)
539 {
540 REveDataCollection* jetCollection = new REveDataCollection("XYJets");
541 jetCollection->SetItemClass(XYJet::Class());
542 jetCollection->SetMainColor(kRed);
543 xyManager->addCollection(jetCollection, false);
544 }
545
546 auto eventMng = new EventManager(event, xyManager);
547 eventMng->SetName("EventManager");
548 eveMng->GetWorld()->AddElement(eventMng);
549
550 eveMng->GetWorld()->AddCommand("QuitRoot", "sap-icon://log", eventMng, "QuitRoot()");
551 eveMng->GetWorld()->AddCommand("NextEvent", "sap-icon://step", eventMng, "NextEvent()");
552
553 eveMng->Show();
554}
void Class()
Definition: Class.C:29
ROOT::R::TRInterface & r
Definition: Object.C:4
#define c(i)
Definition: RSha256.hxx:101
#define e(i)
Definition: RSha256.hxx:103
int Int_t
Definition: RtypesCore.h:41
double Double_t
Definition: RtypesCore.h:55
#define ClassDef(name, id)
Definition: Rtypes.h:326
@ kRed
Definition: Rtypes.h:64
@ kGreen
Definition: Rtypes.h:64
@ kCyan
Definition: Rtypes.h:64
R__EXTERN TApplication * gApplication
Definition: TApplication.h:166
#define N
double cos(double)
double atan(double)
double tan(double)
double sqrt(double)
double sin(double)
double exp(double)
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
char * Form(const char *fmt,...)
void SetFilterExpr(const TString &filter)
void SetHandlerFuncIds(std::function< void(REveDataCollection *, const Ids_t &)> handler_func)
void AddItem(void *data_ptr, const std::string &n, const std::string &t)
void SetHandlerFunc(std::function< void(REveDataCollection *)> handler_func)
virtual void LocalModelChanges(int idx, REveElement *el, const REveViewContext *ctx)
void SetupAddElement(REveElement *el, REveElement *parent, bool set_color=true) const
void BuildViewType(const void *iData, int index, REveElement *itemHolder, std::string viewType, const REveViewContext *context) override
const char * GetCName() const
virtual void AddElement(REveElement *el)
Add el to the list of children.
virtual void DestroyElements()
Destroy all children of this element.
REveElement * FirstChild() const
Returns the first child element or 0 if the list is empty.
ElementId_t GetElementId() const
virtual void SetMainColor(Color_t color)
Set main color of the element.
virtual Color_t GetMainColor() const
REveMagFieldDuo Interface to magnetic field with two different values depending on radius.
REveScene * GetEventScene() const
REveScene * GetGlobalScene() const
REveScene * SpawnNewScene(const char *name, const char *title="")
Create a new scene.
REveViewer * SpawnNewViewer(const char *name, const char *title="")
Create a new GL viewer.
REveScene * GetWorld() const
void Show(const RWebDisplayArgs &args="")
Show eve manager in specified browser.
REveProjectionManager Manager class for steering of projections and managing projected objects.
void AddCommand(const std::string &name, const std::string &icon, const REveElement *element, const std::string &action)
Definition: REveScene.hxx:121
virtual void SetLineColor(Color_t c)
Definition: REveShape.hxx:65
REveTrackPropagator Calculates path of a particle taking into account special path-marks and imposed ...
REveTrack Track with given vertex, momentum and optional referece-points (path-marks) along its path.
Definition: REveTrack.hxx:40
REveTrackPropagator * GetPropagator() const
virtual void AddScene(REveScene *scene)
Add 'scene' to the list of scenes.
Definition: REveViewer.cxx:60
virtual void Terminate(Int_t status=0)
Terminate the application by call TSystem::Exit() unless application has been told to return from Run...
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
void SetName(const char *name)
Definition: TCollection.h:204
Cylindrical tube class.
Definition: TGeoTube.h:18
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
Description of the dynamic properties of a particle.
Definition: TParticle.h:26
TParticle()
reference to the particle record in PDG database
Definition: TParticle.cxx:63
This is the base class for the ROOT Random number generators.
Definition: TRandom.h:27
Basic string class.
Definition: TString.h:131
void collection_proxies(bool proj=true)
REX::REveManager * eveMng
bool gRhoZView
TPaveText * pt
REX::REveViewer * rhoZView
Definition: event_demo.C:48
REX::REveScene * rhoZEventScene
Definition: event_demo.C:46
Double_t x[n]
Definition: legend1.C:17
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
constexpr Double_t Pi()
Definition: TMath.h:38
constexpr Double_t TwoPi()
Definition: TMath.h:45
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4