#include #include #include #include #include #include #include #include #include "TGeoBBox.h" #include "TGeoTube.h" #include "TGeoSphere.h" #include #include #include #include "TGLabel.h" #include "TGTab.h" #include #include #include #include #include "TVector3.h" #include #include "HKED.h" #include "HKED_Util.h" #include "EvNavHandler.h" void load_event(); bool SetupEventDisplay(HKED* EventDisplay,TString WCSimFileName ,TString fitQunFileName); void createGeometry(TGeoManager* geom, bool UseSimpleGeometry, HKED* gHKED ); TGeoVolume* createCylinder(TString name, float radius,float height); using HKED_Util::UnrollView; using std::cout; using std::endl; int main(int argc, char **argv) { TString WCSimFileName; TString fitQunFileName; if(argc>1) WCSimFileName=argv[1]; if(argc>2) fitQunFileName=argv[2]; // Use TApplication if you don't need prompt. // or TRint if you do argc=0; TApplication *app = new TApplication("HK Event Display", &argc, argv); // See arguments to Create() and constructor -- you can choose not to show the window // or some GUI parts. TEveManager::Create(kTRUE,"V"); HKED *gHKED = HKED::GetInstance(); if(SetupEventDisplay(gHKED,WCSimFileName,fitQunFileName)) { app->Run(kFALSE); } // Optionally shutdown eve here (not really needed): TEveManager::Terminate(); app->Terminate(0); return 0; } bool SetupEventDisplay(HKED* gHKED,TString WCSimFileName ,TString fitQunFileName) { const char *filetypes[] = { "ROOT files", "*.root", "All files", "*", 0, 0 }; TString CurrentDirectory=gSystem->pwd(); TString originalDirectory=CurrentDirectory; TGFileInfo fi; TFile *WCSimFile ; do { if(WCSimFileName.Length()==0) { fi.fFileTypes = filetypes; fi.fIniDir = StrDup(CurrentDirectory); cout<<" Please choose your WCSim file or cancel to exit the program."<GetRoot(), 0, kFDOpen, &fi); if (!fi.fFilename) { cout<<" No WCSim file chosen "<IsZombie()) { cout<<" Failed to open "<IsZombie()); gSystem->cd(originalDirectory); TGFileInfo fi2; fi2.fFileTypes = filetypes; fi2.fIniDir = StrDup(CurrentDirectory); TFile *fiTQunFile{nullptr}; TTree *fiTQunTree{nullptr}; if(fitQunFileName.Length()==0) { cout<<" Please choose your fiTQun file, cancel if you don't have one "<GetRoot(), 0, kFDOpen, &fi2); fitQunFileName=fi2.fFilename; } if (fitQunFileName.Length()==0) { cout<<" No fiTQun file chosen "<Get("fiTQun"); gHKED->fiTQun.Init(fiTQunTree); } gSystem->cd(originalDirectory); /* Initialise WCSim */ gHKED->InitialiseWCSim(WCSimFile ); /* Initialise Eve */ gStyle->SetPalette(gHKED->fPredefinedPalette ,0); TColor::InvertPalette(); gEve->GetBrowser()->SetTabTitle("3D View",TRootBrowser::kRight,0); gEve->GetDefaultViewer()->SetName("3D View"); TGLViewer* GLViewer =gEve->GetDefaultViewer()->GetGLViewer(); GLViewer->SetCurrentCamera(TGLViewer::kCameraPerspXOY); GLViewer->CurrentCamera().SetExternalCenter(kTRUE); GLViewer->CurrentCamera().SetCenterVec(0,0,0); GLViewer->UpdateScene(); // Create a clip box centree at 0, length 6000 TGLClipSet* thisClipSet=GLViewer->GetClipSet(); thisClipSet->SetClipType(TGLClip::kClipBox); TGLClipBox* thisClip = (TGLClipBox*) thisClipSet->GetCurrentClip(); thisClip->SetMode(TGLClip::kOutside); TGLVector3 min_point,max_point; const float maxDimension{4500.0}; min_point.Set(-maxDimension,-maxDimension, -maxDimension); max_point.Set(maxDimension,maxDimension,maxDimension); thisClip->Setup( min_point,max_point); GLViewer->SetClipAutoUpdate(kFALSE); GLViewer->RefreshPadEditor(); GLViewer->RequestDraw(); GLViewer->SetResetCamerasOnUpdate(kFALSE); /* Initialise the html summary tab */ gHKED->fgHtmlSummary = new HtmlSummary("HyperK Event Display Summary Table"); auto slot = TEveWindow::CreateWindowInTab(gEve->GetBrowser()->GetTabRight()); gHKED->fgHtml = new TGHtml(0, 100, 100); TEveWindowFrame *wf = slot->MakeFrame(gHKED->fgHtml); gHKED->fgHtml->MapSubwindows(); wf->SetElementName("Summary"); /* Initialise the geometry objects */ gSystem->Load("libGeom"); auto geom = new TGeoManager("HyperK", "HyperK Detector"); geom->SetVerboseLevel(0); createGeometry(geom,kTRUE,gHKED); TGeoNode* node = gGeoManager->GetTopNode(); gHKED->geomRoot = new TEveGeoTopNode(gGeoManager, node); gHKED->geomRoot->SetVisLevel(4); gHKED->geomRoot->GetNode()->GetVolume()->SetVisibility(kFALSE); gEve->AddGlobalElement(gHKED->geomRoot); gEve->Redraw3D(kTRUE); /* Set up the event control GUI */ gEve->GetBrowser()->GetTabRight()->SetTab(1); //make_gui(gHKED); gHKED->Setup(); /* Get Eve started */ gEve->GetDefaultGLViewer()->UpdateScene(); // Reset camera after the first event has been shown. gEve->Redraw3D(kTRUE); gHKED->load_event(); return kTRUE; } void createGeometry(TGeoManager* geom, bool UseSimpleGeometry ,HKED *gHKED) { /* Find the maximum values of X,Y,Z */ float maxX=0; float maxY=0; float maxZ=0; float minZ=0; // I assume z goes negative! float maxR=0; for(int tubeId=0;tubeIdwcsimrootgeom->GetWCNumPMT();tubeId++) { WCSimRootPMT pmt = gHKED->wcsimrootgeom -> GetPMT ( tubeId ); int location=pmt.GetCylLoc(); if(location !=0 && location !=1 && location !=2)continue; double pmtX = pmt.GetPosition (0); double pmtY = pmt.GetPosition (1); double pmtZ = pmt.GetPosition (2); if(pmtX>maxX)maxX=pmtX; if(pmtY>maxY)maxY=pmtY; if(pmtZ>maxZ)maxZ=pmtZ; if(pmtZmaxR)maxR=R; } gHKED->SetLimits( maxX, maxY, minZ, maxZ, maxR ); /// Now we know the maximum extent // MATERIALS, MIXTURES AND TRACKING MEDIA // Material: world TGeoMaterial* worldMaterial = new TGeoMaterial("world", 0.0,0.0,0.0); worldMaterial->SetIndex(0); worldMaterial->SetTransparency(60); // Medium: medium0 Int_t numed = 0; // medium number auto worldMedium = new TGeoMedium("worldMedium", numed,worldMaterial); //, par); float dx = 2*maxX; float dy = 2*maxY; float dz = 2*maxZ; TGeoShape *pworldbox_1 = new TGeoBBox("worldbox", dx,dy,dz); gHKED->WorldVolume = new TGeoVolume("FullGeometry",pworldbox_1, worldMedium); gHKED->WorldVolume->SetVisLeaves(kTRUE); gHKED->SimpleVolume = new TGeoVolume("SimpleGeometry",pworldbox_1, worldMedium); gHKED->SimpleVolume->SetVisLeaves(kTRUE); //UnrolledVolume = new TGeoVolume("UnrolledGeometry",pworldbox_1, pMed1); //UnrolledVolume->SetVisLeaves(kTRUE); //UnrolledVolume = new TGeoVolume("UnrolledGeometry",pworldbox_1, pMed1); //UnrolledVolume->SetVisLeaves(kTRUE); gHKED->FlatGeometry = new TEveElementList("Flat Geometry"); TEveGeoShape *Shape; // SET TOP VOLUME OF GEOMETRY geom->SetMaxVisNodes(gHKED->wcsimrootgeom->GetWCNumPMT()+1000); if(UseSimpleGeometry ) geom->SetTopVolume(gHKED->SimpleVolume); else geom->SetTopVolume(gHKED->WorldVolume); //FlatGeometry->SetTopVolume(UnrolledVolume); // SHAPES, VOLUMES AND GEOMETRICAL HIERARCHY // Shape: phototube type: TGeoSphere float PMTRadius = gHKED->wcsimrootgeom->GetWCPMTRadius() ; Double_t rmin = 0.900000*PMTRadius; Double_t rmax = PMTRadius; Double_t theta1 = 0.000000; Double_t theta2 = 90.000000; Double_t phi1 = 0.000000; Double_t phi2 = 360.000000; /* Full geometry uses hemisphere for tube, UseSimpleGeometry=>just a disk */ Double_t zSize=0.1*PMTRadius; TGeoShape *PhotoTubeShape = new TGeoTube("phototube",0.0,rmax,zSize); TGeoShape *PhotoSphereShape = new TGeoSphere("photosphere",rmin,rmax,theta1, theta2,phi1,phi2); // Volume: phototube auto PhotoTubeVolume = new TGeoVolume("phototube",PhotoTubeShape, worldMedium); PhotoTubeVolume->SetVisLeaves(kTRUE); PhotoTubeVolume->SetLineColor(kYellow-5); auto PhotoSphereVolume = new TGeoVolume("photosphere",PhotoSphereShape, worldMedium); PhotoSphereVolume->SetVisLeaves(kTRUE); PhotoSphereVolume->SetLineColor(kYellow-5); TGeoRotation rota("rot",10,20,30); TGeoTranslation trans; TGeoCombiTrans *c1 = new TGeoCombiTrans(trans,rota); /* Read in location of ALL phototubes and add to the different scenes */ Double_t theta, phi; double pmtX2=0; double pmtY2=0; double pmtZ2=0; for(int tubeId=0;tubeIdwcsimrootgeom->GetWCNumPMT();tubeId++) { WCSimRootPMT pmt = gHKED->wcsimrootgeom -> GetPMT ( tubeId ); double pmtX = pmt.GetPosition (0); double pmtY = pmt.GetPosition (1); double pmtZ = pmt.GetPosition (2); int location= pmt.GetCylLoc(); pmtX2=pmtX; pmtY2=pmtY; pmtZ2=pmtZ; // Work out x,y in unrolled view UnrollView(&pmtX2,&pmtY2,&pmtZ2,location,maxY); theta=0.0; phi=0.0; float rad2deg=57.3; if(location==1) { float lengthXY=sqrt(pmtX*pmtX+pmtY*pmtY); float xd=pmtX/lengthXY; float yd=pmtY/lengthXY; TVector3 D(xd,yd,0.0); theta=D.Theta()*rad2deg; phi=D.Phi()*rad2deg; } else { theta=0.0; phi=0.0; if(location==2)theta=180.0; } if(location==0 || location ==1 || location ==2) { /* create a fake geometry object out of tevegeoshapes for the rolled out view*/ /* TGeoTranslation PhototubeUnrolledPositionMatrix("ExlodedShift",pmtX2,pmtY2,pmtZ2); auto shape = new TEveGeoShape(Form("Phototube %i",tubeId)); shape->SetShape(PhotoTubeShape); shape->SetTransMatrix(PhototubeUnrolledPositionMatrix); shape->SetMainColor(kYellow-5); shape->SetMainTransparency(70); if(tubeId<100) { cout<<" adding object to FlatGeometry at "<AddElement(shape); } */ /* now the 'normal' root geometry objects */ TGeoRotation TubeRotation("rotation",phi-90.0,theta,0.0); //D.Phi(),D.Theta,0.0); TGeoTranslation PhototubePositionMatrix("shift",pmtX,pmtY,pmtZ); TGeoCombiTrans *ShiftAndTwist = new TGeoCombiTrans(PhototubePositionMatrix,TubeRotation); //SimpleVolume->AddNode(PhotoTubeVolume, tubeId, ShiftAndTwist); gHKED->WorldVolume-> AddNode(PhotoSphereVolume, tubeId, ShiftAndTwist); } } TGeoVolume* OutlineVolume = createCylinder("Inner Detector",maxR,maxZ); OutlineVolume->SetVisLeaves(kTRUE); OutlineVolume->SetLineColor(kGray); gHKED->WorldVolume->AddNode(OutlineVolume,0); gHKED->SimpleVolume->AddNode(OutlineVolume,0); geom->CloseGeometry(); /* Create a simple background box object to represent the unrolled cylinder in the unrolled view */ TEveBox* cylinder=new TEveBox("UnrolledBarell"); pmtX2=maxY*3.1416; pmtY2=maxZ; //pmtZ2=maxZ; // Work out x,y in unrolled view //UnrollView(&pmtX2,&pmtY2,&pmtZ2,1,maxY); pmtZ2=-10000; cylinder->SetVertex(0,-pmtX2,-pmtY2,pmtZ2-100); cylinder->SetVertex(1,-pmtX2,+pmtY2,pmtZ2-100); cylinder->SetVertex(2, pmtX2,+pmtY2,pmtZ2-100); cylinder->SetVertex(3, pmtX2,-pmtY2,pmtZ2-100); cylinder->SetVertex(4,-pmtX2,-pmtY2,pmtZ2+100); cylinder->SetVertex(5,-pmtX2,+pmtY2,pmtZ2+100); cylinder->SetVertex(6, pmtX2,+pmtY2,pmtZ2+100); cylinder->SetVertex(7, pmtX2,-pmtY2,pmtZ2+100); cylinder->SetMainColor(kGray); cylinder->SetMainTransparency(80); //cylinder->SetLineColor(kGray); gHKED->FlatGeometry->AddElement(cylinder); for(int location=0;location<3;location+=2) { auto arr=new TEveArrow(); arr->SetTubeR(maxR); arr->SetConeR(0.1); arr->SetConeL(0.0); arr->SetDrawQuality(100); arr->SetMainColor(kGray); //arr->SetLineColor(kGray); arr->SetMainTransparency(80); pmtX2=0.0; pmtY2=0.0; pmtZ2=maxZ; if(location==2) pmtZ2=-maxZ; UnrollView(&pmtX2,&pmtY2,&pmtZ2,location,maxY); arr->SetOrigin(pmtX2,pmtY2,-10000); gHKED->FlatGeometry->AddElement(arr); } } TGeoVolume* createCylinder(TString name,float radius,float height) { TGeoMaterial* pMaterial = new TGeoMaterial(name, 0,0,0); pMaterial->SetIndex(0); pMaterial->SetTransparency(86); TGeoMedium* pMedium = new TGeoMedium(name, 1,pMaterial); TGeoXtru *xtru = new TGeoXtru(2); int nvertices=1000; double x[nvertices]; double y[nvertices]; #define PI 3.14159 float stepSize=2*PI/(float)nvertices; float angle=0.0; for(int step=0;stepDefinePolygon(nvertices,x,y); xtru->DefineSection(0,-height); xtru->DefineSection(1,height); return new TGeoVolume(name,xtru,pMedium); }