/// \file /// \ingroup tutorial_eve7 /// This example display geometry, tracks and hits in web browser /// /// \macro_code /// #include #include #include #include "TClass.h" #include "TRandom.h" #include "TGeoTube.h" #include "TGeoSphere.h" #include "TParticle.h" #include "TApplication.h" #include "TMatrixDSym.h" #include "TVector.h" #include "TMatrixDEigen.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace REX = ROOT::Experimental; // globals REX::REveManager *eveMng = nullptr; REX::REveProjectionManager *mngRhoPhi = nullptr; REX::REveProjectionManager *mngRhoZ = nullptr; REX::REveScene *rPhiGeomScene = nullptr, *rPhiEventScene = nullptr; REX::REveScene *rhoZGeomScene = nullptr, *rhoZEventScene = nullptr; REX::REveViewer *rphiView = nullptr; REX::REveViewer *rhoZView = nullptr; const Double_t kR_min = 240; const Double_t kR_max = 250; const Double_t kZ_d = 300; REX::REvePointSet *getPointSet(int npoints = 2, float s=2, int color=28) { TRandom &r = *gRandom; auto ps = new REX::REvePointSet("fu", "", npoints); for (Int_t i=0; iSetNextPoint(r.Uniform(-s,s), r.Uniform(-s,s), r.Uniform(-s,s)); ps->SetMarkerColor(color); ps->SetMarkerSize(3+r.Uniform(1, 7)); ps->SetMarkerStyle(4); return ps; } void addPoints() { REX::REveElement* event = eveMng->GetEventScene(); auto pntHolder = new REX::REveElement("Hits"); auto ps1 = getPointSet(20, 100); ps1->SetName("Points_1"); ps1->SetTitle("Points_1 title"); // used as tooltip pntHolder->AddElement(ps1); auto ps2 = getPointSet(10, 200, 4); ps2->SetName("Points_2"); ps2->SetTitle("Points_2 title"); // used as tooltip pntHolder->AddElement(ps2); event->AddElement(pntHolder); } void addTracks() { TRandom &r = *gRandom; REX::REveElement* event = eveMng->GetEventScene(); auto prop = new REX::REveTrackPropagator(); prop->SetMagFieldObj(new REX::REveMagFieldDuo(350, 3.5, -2.0)); prop->SetMaxR(300); prop->SetMaxZ(600); prop->SetMaxOrbs(6); auto trackHolder = new REX::REveElement("Tracks"); double v = 0.2; double m = 5; int N_Tracks = 10 + r.Integer(20); for (int i = 0; i < N_Tracks; i++) { TParticle* p = new TParticle(); int pdg = 11 * (r.Integer(2) > 0 ? 1 : -1); p->SetPdgCode(pdg); p->SetProductionVertex(r.Uniform(-v,v), r.Uniform(-v,v), r.Uniform(-v,v), 1); p->SetMomentum(r.Uniform(-m,m), r.Uniform(-m,m), r.Uniform(-m,m)*r.Uniform(1, 3), 1); auto track = new REX::REveTrack(p, 1, prop); track->MakeTrack(); if (i % 4 == 3) track->SetLineStyle(2); // enabled dashed style for some tracks track->SetMainColor(kBlue); track->SetName(Form("RandomTrack_%d", i)); track->SetTitle(Form("RandomTrack_%d title", i)); // used as tooltip trackHolder->AddElement(track); } event->AddElement(trackHolder); } void addJets() { TRandom &r = *gRandom; REX::REveElement *event = eveMng->GetEventScene(); auto jetHolder = new REX::REveElement("Jets"); int N_Jets = 5 + r.Integer(5); for (int i = 0; i < N_Jets; i++) { auto jet = new REX::REveJetCone(Form("Jet_%d", i)); jet->SetTitle(Form("Jet_%d title", i)); // used as tooltip jet->SetCylinder(2*kR_max, 2*kZ_d); jet->AddEllipticCone(r.Uniform(-3.5, 3.5), r.Uniform(0, TMath::TwoPi()), r.Uniform(0.02, 0.2), r.Uniform(0.02, 0.3)); jet->SetFillColor(kPink - 8); jet->SetLineColor(kViolet - 7); jetHolder->AddElement(jet); } event->AddElement(jetHolder); } void addVertex() { float pos[3] = {1.46589e-06,-1.30522e-05,-1.98267e-05}; // symnetric matrix double a[16] = {1.46589e-01,-1.30522e-02,-1.98267e-02, 0, -1.30522e-02, 4.22955e-02,-5.86628e-03, 0, -1.98267e-02,-5.86628e-03, 2.12836e-01, 0, 0, 0, 0, 1}; REX::REveTrans t; t.SetFrom(a); TMatrixDSym xxx(3); for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) { xxx(i,j) = t(i+1,j+1); } TMatrixDEigen eig(xxx); TVectorD xxxEig ( eig.GetEigenValues() ); xxxEig = xxxEig.Sqrt(); TMatrixD vecEig = eig.GetEigenVectors(); REX::REveVector v[3]; int ei = 0; for (int i = 0; i < 3; ++i) { v[i].Set(vecEig(0,i), vecEig(1,i), vecEig(2,i)); v[i] *= xxxEig(i); } REX::REveEllipsoid* ell = new REX::REveEllipsoid("VertexError"); ell->InitMainTrans(); ell->SetMainColor(kGreen + 10); ell->SetLineWidth(2); ell->SetBaseVectors(v[0], v[1], v[2]); ell->Outline(); REX::REveElement *event = eveMng->GetEventScene(); event->AddElement(ell); return; //center auto ps = new REX::REvePointSet(); ps->SetMainColor(kGreen + 10); ps->SetNextPoint(pos[0], pos[1], pos[2]); ps->SetMarkerStyle(4); ps->SetMarkerSize(4); event->AddElement(ps); } void makeEventScene() { addPoints(); addTracks(); addJets(); addVertex(); } void makeGeometryScene() { auto b1 = new REX::REveGeoShape("Barrel 1"); b1->SetShape(new TGeoTube(kR_min, kR_max, kZ_d)); b1->SetMainColor(kCyan); eveMng->GetGlobalScene()->AddElement(b1); // Debug of surface fill in RPhi (index buffer screwed). // b1->SetNSegments(3); b1->SetNSegments(40); } void createProjectionStuff() { // project RhoPhi rPhiGeomScene = eveMng->SpawnNewScene("RPhi Geometry","RPhi"); rPhiEventScene = eveMng->SpawnNewScene("RPhi Event Data","RPhi"); mngRhoPhi = new REX::REveProjectionManager(REX::REveProjection::kPT_RPhi); rphiView = eveMng->SpawnNewViewer("RPhi View", ""); rphiView->AddScene(rPhiGeomScene); rphiView->AddScene(rPhiEventScene); // ---------------------------------------------------------------- rhoZGeomScene = eveMng->SpawnNewScene("RhoZ Geometry", "RhoZ"); rhoZEventScene = eveMng->SpawnNewScene("RhoZ Event Data","RhoZ"); mngRhoZ = new REX::REveProjectionManager(REX::REveProjection::kPT_RhoZ); rhoZView = eveMng->SpawnNewViewer("RhoZ View", ""); rhoZView->AddScene(rhoZGeomScene); rhoZView->AddScene(rhoZEventScene); } void projectScenes(bool geomp, bool eventp) { if (geomp) { for (auto &ie : eveMng->GetGlobalScene()->RefChildren()) { mngRhoPhi->ImportElements(ie, rPhiGeomScene); mngRhoZ ->ImportElements(ie, rhoZGeomScene); } } if (eventp) { for (auto &ie : eveMng->GetEventScene()->RefChildren()) { mngRhoPhi->ImportElements(ie, rPhiEventScene); mngRhoZ ->ImportElements(ie, rhoZEventScene); } } // auto t0 = eveMng->GetEventScene()->FindChild("Tracks")->FirstChild(); // printf("t0=%p, %s %s\n", t0, t0->GetElementName(), t0->IsA()->GetName()); // dynamic_cast(t0)->Print("all"); // auto t1 = rPhiEventScene->FindChild("Tracks [P]")->FirstChild(); // printf("t1=%p, %s %s\n", t1, t1->GetElementName(), t1->IsA()->GetName()); // dynamic_cast(t1)->Print("all"); } //============================================================================== class EventManager : public REX::REveElement { public: EventManager() = default; virtual ~EventManager() {} virtual void NextEvent() { eveMng->DisableRedraw(); auto scene = eveMng->GetEventScene(); scene->DestroyElements(); makeEventScene(); for (auto &ie : scene->RefChildren()) { if (mngRhoPhi) mngRhoPhi->ImportElements(ie, rPhiEventScene); if (mngRhoZ) mngRhoZ ->ImportElements(ie, rhoZEventScene); } eveMng->EnableRedraw(); eveMng->DoRedraw3D(); } virtual void QuitRoot() { printf("Quit ROOT\n"); if (gApplication) gApplication->Terminate(); } }; void event_demo() { // disable browser cache - all scripts and html files will be loaded every time, useful for development // gEnv->SetValue("WebGui.HttpMaxAge", 0); gRandom->SetSeed(0); // make random seed eveMng = REX::REveManager::Create(); auto eventMng = new EventManager(); eventMng->SetName("EventManager"); eveMng->GetWorld()->AddElement(eventMng); eveMng->GetWorld()->AddCommand("QuitRoot", "sap-icon://log", eventMng, "QuitRoot()"); eveMng->GetWorld()->AddCommand("NextEvent", "sap-icon://step", eventMng, "NextEvent()"); makeGeometryScene(); makeEventScene(); if (1) { createProjectionStuff(); projectScenes(true, true); } eveMng->Show(); }