//#include //#include //#include //#include //#include #include "TEveManager.h" #include "TGeoManager.h" #include "TEveGeoNode.h" #include "TEvePointSet.h" #include "TEveBoxSet.h" #include "TEveLine.h" #include "TEveScene.h" #include "TEveEventManager.h" #include "TGeoManager.h" #include "TGeoMaterial.h" #include "TGeoMedium.h" #include "TGeoVolume.h" #include "TGeoTrack.h" #include "TParticle.h" #include "TRandom.h" #include "TTimer.h" #include "TPad.h" #include "TROOT.h" #include "RtypesCore.h" #include "TMath.h" #include "Math/GenVector/PositionVector3D.h" #include "TEveCaloLegoOverlay.h" #include "TEveCalo.h" //============================================================================== // Forward declarations //------------------------------------------------------------------------------ TEveCalo3D* MakeCalo3D(TEveCaloData* data, TEveWindowSlot* slot); TEveCaloLego* MakeCaloLego(TEveCaloData* data, TEveWindowSlot* slot); void MakeViewerScene(TEveWindowSlot* slot, TEveViewer*& v, TEveScene*& s); //============================================================================== // Constants. //------------------------------------------------------------------------------ const Double_t kX_max = 300; // Top Volume Box dimensions const Double_t kY_max = 300; const Double_t kZ_max = 300; const Double_t kR_min = 240; // child Tube dimensions const Double_t kR_max = 250; const Double_t kZ_d = 300; const TLorentzVector vrtxo = TLorentzVector(0., 0., 0., 0.); // collision point const TEveVectorD origin = TEveVectorD(0., 0., 0.); Double_t kCenter[3] = {-500., 500., 50.}; // GL camera center? //------------------------------------------------------------------------------ void pbr_create_geo() { // define a new geometry object "EZB_sim_geo" if (gGeoManager) { delete gGeoManager; } // new call below initializes gGeoManager global pointer new TGeoManager("EZB_sim_geo", "simple detector geometry-cube enclosure+cylinder"); //-- materials definitions TGeoMaterial *matVacuum = new TGeoMaterial("Vacuum", 0,0,0); TGeoMaterial *matAl = new TGeoMaterial("Al", 26.98,13,2.7); //-- media definitions TGeoMedium *Vacuum = new TGeoMedium("Vacuum",1, matVacuum); TGeoMedium *Al = new TGeoMedium("Root Material",2, matAl); matVacuum->SetTransparency(80); matAl->SetTransparency(70); // [0] this is the top volume cube TGeoVolume *top = gGeoManager->MakeBox("TOP",Vacuum,kX_max,kY_max,kZ_max); gGeoManager->SetTopVisible(); gGeoManager->SetTopVolume(top); top->SetFillColor(3); // [1] this is the cylinder TGeoVolume *vcylinder= gGeoManager->MakeTube("Cylinder",Al, kR_min, kR_max, kZ_d); // Al <-> nullptr <- placeholder for TGeoMedium* vcylinder->SetLineColor(kGreen); TGeoShape *scylinder= vcylinder->GetShape(); top->AddNode(vcylinder,1); gGeoManager->CloseGeometry(); } void qpbr_tracks() { Double_t rfP0 = 1.0; // set incoming beam particle momentum Double_t rfE0 = 10.0; // set incoming beam particle energy Double_t tauc = 1.0; // collision time (arbitrary) //_ geometry rendering pbr_create_geo(); TEveManager::Create(); // this initializes gEve global pointer TEveGeoTopNode* top = new TEveGeoTopNode(gGeoManager, gGeoManager->GetTopNode()); // "/TOP_1/Cylinder_1" top->SetVisOption(0); top->SetVisLevel(6); gEve->AddGlobalElement(top); //_ end geometry rendering //_ track generation auto propag = new TEveTrackPropagator(); propag->SetStepper(TEveTrackPropagator::kRungeKutta); propag->SetMaxR(kR_min); // these set maximum extents of track propagation propag->SetMaxZ(kZ_d); //propag->SetRnrDecay(kFALSE); auto tracks = new TEveElementList("Tracks"); auto pmc = new TEvePathMarkD(TEvePathMarkD::kDecay, origin, tauc ); // collision vertex mark // at the origin TEveVector4D endpoint; Double_t Rho; Double_t Phi =0.; Double_t rfE; Int_t itrk; TTree *tep = new TTree("tep", "TTree itrk,x,y,z,t,E"); // endpoint storage for hits on Cylinder_1 tep->Branch("itrk",&itrk,"itrk/I"); tep->Branch("x",&endpoint.fX,"x/D"); tep->Branch("y",&endpoint.fY,"y/D"); tep->Branch("z",&endpoint.fZ,"z/D"); tep->Branch("t",&endpoint.fT,"t/D"); tep->Branch("E",&rfE,"E/D"); //////////////////////////////// // 2x primary particle beams // //////////////////////////////// const Int_t Nptracks = 2; auto p1 = new TParticle(); auto p2 = new TParticle(); // primary vertex p1->SetProductionVertex(0.,0., kZ_max ,0.); p2->SetProductionVertex(0.,0.,-kZ_max ,0.); p1->SetMomentum(0.,0.,-rfP0,rfE0); p2->SetMomentum(0.,0.,+rfP0,rfE0); auto track = new TEveTrack(p1,0,propag); track->AddPathMark(*pmc); track->MakeTrack(); //_generate track time (track 0) auto trackp = propag->GetLastPoints(); endpoint = trackp.back(); endpoint += TEveVector4D(0.0,0.0,0.0, tauc); endpoint.Dump(); //_end generate track time track->SetElementName("Beam 0"); track->SetMainColor(kYellow); tracks->AddElement(track); TEveTrack *track0 = track; track = new TEveTrack(p2,1,propag); track->AddPathMark(*pmc); track->MakeTrack(); //_generate track time (track 1) trackp = propag->GetLastPoints(); endpoint = trackp.back(); endpoint += TEveVector4D(0.0,0.0,0.0, tauc); endpoint.Dump(); //_end generate track time track->SetElementName("Beam 1"); track->SetMainColor(kYellow); tracks->AddElement(track); TEveTrack *track1 = track; ///////////////////////////////////////////////////////////////// // 4x secondary particle products (arbitrary Energy+Momentum) // ///////////////////////////////////////////////////////////////// auto rnd = gRandom; const Int_t Nstracks = 4; for (Int_t i =Nptracks; i<(Nstracks+Nptracks); i++) { auto p = new TParticle(); rfE = rnd->Uniform(rfE0); p->SetProductionVertex(vrtxo); p->SetMomentum(4.*pow(-1,i),0.,(1.+i)*pow(-1,i),rfE); auto track = new TEveTrack(p,i,propag); track->MakeTrack(); //_establish parent-child linkage track0->AddElement(track); track1->AddElement(track); track->AddParent(track0); track->AddParent(track1); //_end establish parent-child linkage //_generate track time (track i) trackp = propag->GetLastPoints(); endpoint = trackp.back(); endpoint += TEveVector4D(0.0,0.0,0.0, tauc+i); // detection time (arbitrary) endpoint.Dump(); //_end generate track time track->SetMainColor(kBlue); track->SetName(Form("p %d",i-Nptracks+1)); track->SetLineColor((pow(-1,i) > 0 ? kBlue : kRed)); track->SetRnrPoints(kTRUE); track->SetMarkerStyle(4); track->PrintPathMarks(); //_detect Cylinder_1 hits Rho = TMath::Sqrt(endpoint.fX*endpoint.fX+endpoint.fY*endpoint.fY); if(Rho == kR_min) { // we have a hit, store x,y,z,t,E cout << "track " << itrk << " matches" << endl; itrk = i; tep->Fill(); // store to tree } //_end detect Cylinder_1 hits } //_create lego plots tep->Print(); tep->Show(1); tep->Scan("z:E"); const Double_t k1eps = 1.0 + 0.01; // small tolerance to ensure values at the min/max boundaries are counted TH2D *h2 = new TH2D("ZPhiE","Z,Phi vs E",10,-(kZ_d*k1eps),(kZ_d*k1eps),10,-(TMath::Pi()*k1eps),(TMath::Pi()*k1eps)); ROOT::Math::Cylindrical3D< Double_t > p3D; Int_t nentries = (Int_t)tep->GetEntries(); for (Int_t i=0; iGetEntry(i); p3D.SetXYZ(endpoint.fX,endpoint.fY,endpoint.fZ); Rho = p3D.Rho(); Phi = p3D.Phi(); cout<< "Rho Z Phi rfE "<Fill(Rho,Phi,rfE); h2->Fill(p3D.Z(),Phi,rfE); } h2->Draw("lego2 0"); // Create a new tab window auto slot = TEveWindow::CreateWindowInTab(gEve->GetBrowser()->GetTabRight()); // Set new window for 2 vertical sub-slots auto packH = slot->MakePack(); packH->SetElementName("Composite Views"); packH->SetHorizontal(); packH->SetShowTitleBar(kFALSE); slot = packH->NewSlot(); auto pack0 = slot->MakePack(); pack0->SetShowTitleBar(kFALSE); auto slotTop = pack0->NewSlot(); auto slotBottom = pack0->NewSlot(); auto data = new TEveCaloDataHist(); data->AddHistogram((TH2F *)h2); data->RefSliceInfo(0).Setup("ECAL", 0.000, kRed ); data->GetEtaBins()->SetTitleFont(100); data->GetEtaBins()->SetTitle("Z "); data->GetPhiBins()->SetTitleFont(100); data->GetPhiBins()->SetTitle("Phi "); data->IncDenyDestroy(); gEve->AddToListTree(data, kFALSE); //auto calo3D = MakeCalo3D(data, slotTop); auto lego = MakeCaloLego(data, slotBottom); //_end create lego plots gEve->GetEventScene()->AddElement(tracks); gEve->GetDefaultViewer()->SetName("Viewer - GL"); gEve->GetDefaultViewer()->SetElementName("GL"); //_ end track generation auto ev = gEve->GetDefaultViewer(); auto es = gEve->GetEventScene(); slotTop->ReplaceWindow(ev); //auto v = new TEveViewer("GL-2"); //v->SpawnGLViewer(gEve->GetEditor()->SpawnNewEditor(ev)); //slotTop->ReplaceWindow(v); gEve->GetDefaultGLViewer()->SetCurrentCamera(TGLViewer::kCameraPerspYOZ); //gEve->GetDefaultGLViewer()->CurrentCamera().Configure(0.5,0.,kCenter,TMath::Pi()/3., TMath::Pi()/4.); //gEve->GetDefaultGLViewer()->SetCurrentCamera(TGLViewer::kCameraOrthoXOY); //gEve->GetDefaultGLViewer()->CurrentCamera().RotateRad(TMath::Pi()/3., TMath::Pi()/4.); gEve->GetBrowser()->GetTabRight()->SetTab(1); gEve->FullRedraw3D(kTRUE); } //______________________________________________________________________________ //__________ _________ //__________ Following taken from tutorials/eve/calorimeters.C _________ //______________________________________________________________________________ //______________________________________________________________________________ void MakeViewerScene(TEveWindowSlot* slot, TEveViewer*& v, TEveScene*& s) { // Create a scene and a viewer in the given slot. v = new TEveViewer("Viewer."); v->SpawnGLViewer(gEve->GetEditor()); slot->ReplaceWindow(v); gEve->GetViewers()->AddElement(v); s = gEve->SpawnNewScene("Scene."); v->AddScene(s); } //______________________________________________________________________________ TEveCaloLego* MakeCaloLego(TEveCaloData* data, TEveWindowSlot* slot) { // Eta-phi lego view. TEveViewer* v; TEveScene* s; if (slot) { MakeViewerScene(slot, v, s); } else { v = gEve->GetDefaultViewer(); s = gEve->GetEventScene(); } v->SetElementName("Viewer - Lego"); s->SetElementName("Scene - Lego"); auto lego = new TEveCaloLego(data); s->AddElement(lego); // By the default lego extends is (1x1x1). Resize it to put in 'natural' // coordinates, so that y extend in 2*Pi and set height of lego two times // smaller than y extend to have better view in 3D perspective. lego->InitMainTrans(); //lego->RefMainTrans().SetScale(TMath::TwoPi(), TMath::TwoPi(), TMath::Pi()); lego->RefMainTrans().SetScale( 0.1, 10.0 ,4.0 ); // draws scales and axis on borders of window auto glv = v->GetGLViewer(); TEveCaloLegoOverlay* overlay = new TEveCaloLegoOverlay(); glv->AddOverlayElement(overlay); overlay->SetCaloLego(lego); // set event handler to move from perspective to orthographic view. //glv->SetCurrentCamera(TGLViewer::kCameraOrthoXOY); //glv->SetCurrentCamera(TGLViewer::kCameraOrthoXnOZ); glv->SetCurrentCamera(TGLViewer::kCameraPerspYOZ); glv->CurrentCamera().Configure(0.5,1.,kCenter,TMath::Pi()/3., TMath::Pi()/4.); glv->CurrentCamera().RotateRad(0., TMath::Pi()/2.); // glv->CurrentCamera().Configure(0.5,1.,kCenter,TMath::Pi()/3., TMath::Pi()/4.); glv->SetEventHandler(new TEveLegoEventHandler(glv->GetGLWidget(), glv, lego)); gEve->AddToListTree(lego, kTRUE); return lego; } //______________________________________________________________________________ TEveCalo3D* MakeCalo3D(TEveCaloData* data, TEveWindowSlot* slot) { // 3D cartesian view. TEveViewer* v; TEveScene* s; MakeViewerScene(slot, v, s); v->SetElementName("View - 3D"); s->SetElementName("Scene - 3D"); auto calo3d = new TEveCalo3D(data); calo3d->SetBarrelRadius(kR_min); calo3d->SetEndCapPos(kZ_d); s->AddElement(calo3d); return calo3d; }