Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
event_demo.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_eve_7
3/// This example display geometry, tracks and hits in web browser
4///
5/// \macro_code
6///
7/// \author Alja Mrak-Tadel
8
9#include <vector>
10#include <string>
11#include <iostream>
12
13#include "TClass.h"
14#include "TRandom.h"
15#include "TGeoTube.h"
16#include "TGeoSphere.h"
17#include "TParticle.h"
18#include "TApplication.h"
19#include "TMatrixDSym.h"
20#include "TVector.h"
21#include "TMatrixDEigen.h"
22
23#include <ROOT/REveGeoShape.hxx>
24#include <ROOT/REveScene.hxx>
25#include <ROOT/REveViewer.hxx>
26#include <ROOT/REveElement.hxx>
27#include <ROOT/REveCompound.hxx>
28#include <ROOT/REveManager.hxx>
29#include <ROOT/REveUtil.hxx>
30#include <ROOT/REveGeoShape.hxx>
33#include <ROOT/REvePointSet.hxx>
34#include <ROOT/REveJetCone.hxx>
35#include <ROOT/REveTrans.hxx>
36#include <ROOT/REveTrack.hxx>
38
39namespace REX = ROOT::Experimental;
40
41// globals
42REX::REveManager *eveMng = nullptr;
45REX::REveScene *rPhiGeomScene = nullptr, *rPhiEventScene = nullptr;
46REX::REveScene *rhoZGeomScene = nullptr, *rhoZEventScene = nullptr;
47REX::REveViewer *rphiView = nullptr;
48REX::REveViewer *rhoZView = nullptr;
49
50const Double_t kR_min = 240;
51const Double_t kR_max = 250;
52const Double_t kZ_d = 300;
53
54REX::REvePointSet *getPointSet(int npoints = 2, float s = 2, int color = 28)
55{
56 TRandom &r = *gRandom;
57
58 auto ps = new REX::REvePointSet("fu", "", npoints);
59
60 for (Int_t i = 0; i < npoints; ++i)
61 ps->SetNextPoint(r.Uniform(-s, s), r.Uniform(-s, s), r.Uniform(-s, s));
62
63 ps->SetMarkerColor(color);
64 ps->SetMarkerSize(8);
65 ps->SetMarkerStyle(4);
66 return ps;
67}
68
69void addPoints()
70{
71 REX::REveElement *event = eveMng->GetEventScene();
72
73 auto pntHolder = new REX::REveCompound("Hits");
74
75 auto ps1 = getPointSet(20, 100);
76 ps1->SetName("Points_1");
77 ps1->SetTitle("Points_1 title"); // used as tooltip
78
79 pntHolder->AddElement(ps1);
80
81 auto ps2 = getPointSet(10, 200, 4);
82 ps2->SetName("Points_2");
83 ps2->SetTitle("Points_2 title"); // used as tooltip
84 ps2->SetAlwaysSecSelect(true);
85 pntHolder->AddElement(ps2);
86
87 event->AddElement(pntHolder);
88}
89
90void addTracks()
91{
92 TRandom &r = *gRandom;
93
94 REX::REveElement *event = eveMng->GetEventScene();
95 auto prop = new REX::REveTrackPropagator();
96 prop->SetMagFieldObj(new REX::REveMagFieldDuo(350, 3.5, -2.0));
97 prop->SetMaxR(300);
98 prop->SetMaxZ(600);
99 prop->SetMaxOrbs(6);
100
101 auto trackHolder = new REX::REveCompound("Tracks");
102
103 double v = 0.2;
104 double m = 5;
105
106 int N_Tracks = 10 + r.Integer(20);
107 for (int i = 0; i < N_Tracks; i++) {
108 TParticle p;
109
110 int pdg = 11 * (r.Integer(2) > 0 ? 1 : -1);
111 p.SetPdgCode(pdg);
112
113 p.SetProductionVertex(r.Uniform(-v, v), r.Uniform(-v, v), r.Uniform(-v, v), 1);
114 p.SetMomentum(r.Uniform(-m, m), r.Uniform(-m, m), r.Uniform(-m, m) * r.Uniform(1, 3), 1);
115 auto track = new REX::REveTrack(&p, 1, prop);
116 track->MakeTrack();
117 if (i % 4 == 3)
118 track->SetLineStyle(kDashed); // enabled dashed style for some tracks
119 track->SetMainColor(kBlue);
120 track->SetName(Form("RandomTrack_%d", i));
121 track->SetTitle(Form("RandomTrack_%d title", i)); // used as tooltip
122 trackHolder->AddElement(track);
123 }
124
125 event->AddElement(trackHolder);
126}
127
128void addJets()
129{
130 TRandom &r = *gRandom;
131
132 REX::REveElement *event = eveMng->GetEventScene();
133 auto jetHolder = new REX::REveCompound("Jets");
134
135 int N_Jets = 5 + r.Integer(5);
136 for (int i = 0; i < N_Jets; i++) {
137 auto jet = new REX::REveJetCone(Form("Jet_%d", i));
138 jet->SetTitle(Form("Jet_%d\n pT = %.2f", i, r.Uniform(1, 40))); // used as tooltip
139 jet->SetCylinder(2 * kR_max, 2 * kZ_d);
140 jet->AddEllipticCone(r.Uniform(-3.5, 3.5), r.Uniform(0, TMath::TwoPi()), r.Uniform(0.02, 0.2),
141 r.Uniform(0.02, 0.3));
142 jet->SetFillColor(kPink - 8);
143 jet->SetLineColor(kBlack);
144
145 jetHolder->AddElement(jet);
146 }
147 event->AddElement(jetHolder);
148}
149
150void makeEventScene()
151{
152 addPoints();
153 addTracks();
154 addJets();
155}
156
158{
159 auto b1 = new REX::REveGeoShape("Barrel 1");
160 b1->SetShape(new TGeoTube(kR_min, kR_max, kZ_d));
161 b1->SetMainColor(kCyan);
162 b1->SetNSegments(80);
163 b1->SetMainTransparency(70);
164 eveMng->GetGlobalScene()->AddElement(b1);
165
166 // Debug of surface fill in RPhi (index buffer screwed).
167 // b1->SetNSegments(3);
168 b1->SetNSegments(40);
169
170 // an example of axis guides
171 eveMng->GetDefaultViewer()->SetAxesType(REX::REveViewer::EAxesType::kAxesOrigin);
172}
173
175{
176 // project RhoPhi
177 rPhiGeomScene = eveMng->SpawnNewScene("RPhi Geometry", "RPhi");
178 rPhiEventScene = eveMng->SpawnNewScene("RPhi Event Data", "RPhi");
179
180 mngRhoPhi = new REX::REveProjectionManager(REX::REveProjection::kPT_RPhi);
181
182 rphiView = eveMng->SpawnNewViewer("RPhi View", "");
183 rphiView->SetCameraType(REX::REveViewer::kCameraOrthoXOY);
184 rphiView->AddScene(rPhiGeomScene);
185 rphiView->AddScene(rPhiEventScene);
186
187 // ----------------------------------------------------------------
188
189 rhoZGeomScene = eveMng->SpawnNewScene("RhoZ Geometry", "RhoZ");
190 rhoZEventScene = eveMng->SpawnNewScene("RhoZ Event Data", "RhoZ");
191
192 mngRhoZ = new REX::REveProjectionManager(REX::REveProjection::kPT_RhoZ);
193
194 rhoZView = eveMng->SpawnNewViewer("RhoZ View", "");
195 rhoZView->SetCameraType(REX::REveViewer::kCameraOrthoXOY);
196 rhoZView->AddScene(rhoZGeomScene);
197 rhoZView->AddScene(rhoZEventScene);
198}
199
200void projectScenes(bool geomp, bool eventp)
201{
202 if (geomp) {
203 for (auto &ie : eveMng->GetGlobalScene()->RefChildren()) {
204 mngRhoPhi->SetCurrentDepth(0);
205 mngRhoPhi->ImportElements(ie, rPhiGeomScene);
206 mngRhoZ->SetCurrentDepth(0);
207 mngRhoZ->ImportElements(ie, rhoZGeomScene);
208 }
209 }
210 if (eventp) {
211 int depth = 50;
212 for (auto &ie : eveMng->GetEventScene()->RefChildren()) {
213 mngRhoPhi->SetCurrentDepth(depth);
214 mngRhoPhi->ImportElements(ie, rPhiEventScene);
215 mngRhoZ->SetCurrentDepth(depth);
216 mngRhoZ->ImportElements(ie, rhoZEventScene);
217 depth -= 10;
218 }
219 }
220
221 // auto t0 = eveMng->GetEventScene()->FindChild("Tracks")->FirstChild();
222 // printf("t0=%p, %s %s\n", t0, t0->GetElementName(), t0->IsA()->GetName());
223 // dynamic_cast<REX::REveTrack*>(t0)->Print("all");
224
225 // auto t1 = rPhiEventScene->FindChild("Tracks [P]")->FirstChild();
226 // printf("t1=%p, %s %s\n", t1, t1->GetElementName(), t1->IsA()->GetName());
227 // dynamic_cast<REX::REveTrack*>(t1)->Print("all");
228}
229
230//==============================================================================
231
232class EventManager : public REX::REveElement {
233private:
234 bool fAutoplay{false};
235 int fPlayDelay{10};
236 int fCount{0};
237 std::chrono::duration<double> fDeltaTime{1};
238
239 std::thread *fTimerThread{nullptr};
240 std::mutex fMutex;
241 std::condition_variable fCV;
242
243public:
245 {
246 std::chrono::milliseconds ms(100);
247 fDeltaTime = ms;
248 }
249
250 ~EventManager() override {}
251
252 void NextEvent()
253 {
254 auto scene = eveMng->GetEventScene();
255 scene->DestroyElements();
257 projectScenes(false, true);
258 // if (++fCount % 10 == 0) printf("At event %d\n", fCount);
259 }
260
261 void autoplay_scheduler()
262 {
263 while (true) {
264 bool autoplay;
265 {
266 std::unique_lock<std::mutex> lock{fMutex};
267 if (!fAutoplay) {
268 // printf("exit thread pre wait\n");
269 return;
270 }
271 if (fCV.wait_for(lock, fDeltaTime) != std::cv_status::timeout) {
272 printf("autoplay not timed out \n");
273 if (!fAutoplay) {
274 printf("exit thread post wait\n");
275 return;
276 } else {
277 continue;
278 }
279 }
281 }
282 if (autoplay) {
283 REX::REveManager::ChangeGuard ch;
284 NextEvent();
285 } else {
286 return;
287 }
288 }
289 }
290
291 void Autoplay()
292 {
293 static std::mutex autoplay_mutex;
294 std::unique_lock<std::mutex> aplock{autoplay_mutex};
295 {
296 std::unique_lock<std::mutex> lock{fMutex};
298 if (fAutoplay) {
299 if (fTimerThread) {
300 fTimerThread->join();
301 delete fTimerThread;
302 fTimerThread = nullptr;
303 }
304 NextEvent();
305 fTimerThread = new std::thread{[this] { autoplay_scheduler(); }};
306 } else {
307 fCV.notify_all();
308 }
309 }
310 }
311
312 virtual void QuitRoot()
313 {
314 printf("Quit ROOT\n");
315 REX::REveManager::QuitRoot();
316 }
317};
318
319void event_demo()
320{
321 // disable browser cache - all scripts and html files will be loaded every time, useful for development
322 // gEnv->SetValue("WebGui.HttpMaxAge", 0);
323
324 gRandom->SetSeed(0); // make random seed
325
326 eveMng = REX::REveManager::Create();
327
328 auto eventMng = new EventManager();
329 eventMng->SetName("EventManager");
330 eveMng->GetWorld()->AddElement(eventMng);
331
332 eveMng->GetWorld()->AddCommand("QuitRoot", "sap-icon://log", eventMng, "QuitRoot()");
333
334 eveMng->GetWorld()->AddCommand("NextEvent", "sap-icon://step", eventMng, "NextEvent()");
335
336 eveMng->GetWorld()->AddCommand("Autoplay", "sap-icon://refresh", eventMng, "Autoplay()");
337
340
341 if (true) {
343 projectScenes(true, true);
344 }
345
346 eveMng->Show();
347}
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
@ kPink
Definition Rtypes.h:68
@ kBlack
Definition Rtypes.h:66
@ kCyan
Definition Rtypes.h:67
@ kBlue
Definition Rtypes.h:67
@ kDashed
Definition TAttLine.h:54
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h prop
R__EXTERN TRandom * gRandom
Definition TRandom.h:73
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2570
REveMagFieldDuo Interface to magnetic field with two different values depending on radius.
REveProjectionManager Manager class for steering of projections and managing projected objects.
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
REveViewer Reve representation of TGLViewer.
Cylindrical tube class.
Definition TGeoTube.h:17
Description of the dynamic properties of a particle.
Definition TParticle.h:26
This is the base class for the ROOT Random number generators.
Definition TRandom.h:28
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition TRandom.cxx:614
Namespace for ROOT features in testing.
Definition TROOT.h:100
constexpr Double_t TwoPi()
Definition TMath.h:47
TMarker m
Definition textangle.C:8