def MakeGeometry(): # Make the geometry of a simple parabolic telescope manager = ROOT.AOpticsManager("manager", "SimpleParabolicTelescope") manager.SetNsegments( 100) # Set the smoothness of surface drawing. Display use only. # Make the world worldbox = ROOT.TGeoBBox("worldbox", 10 * m, 10 * m, 10 * m) world = ROOT.AOpticalComponent("world", worldbox) manager.SetTopVolume(world) # Define a paraboloid for the mirror para = ROOT.TGeoParaboloid("mirror_para", 0, kMirrorRad, kMirrorSag / 2.) mirror_tr1 = ROOT.TGeoTranslation("mirror_tr1", 0, 0, kMirrorSag / 2.) mirror_tr1.RegisterYourself() mirror_tr2 = ROOT.TGeoTranslation("mirror_tr2", 0, 0, kMirrorSag / 2. - 1 * um) mirror_tr2.RegisterYourself() # Composite two TGeoParaboloid to make a thin parabolic surface mirror_comp = ROOT.TGeoCompositeShape( "mirror_comp", "mirror_para:mirror_tr2 - mirror_para:mirror_tr1") # Make a parabolic mirror mirror = ROOT.AMirror("mirror", mirror_comp) world.AddNode(mirror, 1) # Define a tube for the forcal surface focal_tube = ROOT.TGeoTube("focal_tube", 0, kFocalRad, 10 * um) focal_tr = ROOT.TGeoTranslation("focal_tr", 0, 0, kFocalLength + 10 * um) focal_tr.RegisterYourself() # Make a focal surface focal = ROOT.AFocalSurface("focal", focal_tube) world.AddNode(focal, 1, focal_tr) obs_tube1 = ROOT.TGeoTube("obs_tube1", 0, kFocalRad + 10 * um, 10 * um) obs_tr1 = ROOT.TGeoTranslation("obs_tr1", 0, 0, kFocalLength + 30 * um) obs_tr1.RegisterYourself() # Make a dummy obscuration behind the focal plane obs1 = ROOT.AObscuration("obs1", obs_tube1) world.AddNode(obs1, 1, obs_tr1) obs_tube2 = ROOT.TGeoTube("obs_tube2", kFocalRad, kFocalRad + 10 * um, 10 * um) obs_tr2 = ROOT.TGeoTranslation("obs_tr2", 0, 0, kFocalLength + 10 * um) obs_tr2.RegisterYourself() # Make one more obscuration surrounding the focal plane obs2 = ROOT.AObscuration("obs2", obs_tube2) world.AddNode(obs2, 1, obs_tr2) manager.CloseGeometry() world.Draw("ogl") # GL View does not work in PyROOT return manager
def testQE(self): manager = makeTheWorld() focalbox = ROOT.TGeoBBox("focalbox", 0.5 * m, 0.5 * m, 1 * mm) focal = ROOT.AFocalSurface("focal", focalbox) registerGeo((focalbox, focal)) qe_lambda = ROOT.TGraph() qe_lambda.SetPoint(0, 300 * nm, 0.0) qe_lambda.SetPoint(1, 500 * nm, 1.0) qe_angle = ROOT.TGraph() qe_angle.SetPoint(0, 0 * deg, 1.) # QE = 100% for on-axis photons qe_angle.SetPoint(1, 90 * deg, 0.) manager.GetTopVolume().AddNode(focal, 1) manager.CloseGeometry() if ROOT.gInterpreter.ProcessLine('ROOT_VERSION_CODE;') < \ ROOT.gInterpreter.ProcessLine('ROOT_VERSION(6, 2, 0);'): manager.SetMultiThread(True) manager.SetMaxThreads(4) for i in range(3): if i == 1: focal.SetQuantumEfficiency(qe_lambda) elif i == 2: focal.SetQuantumEfficiencyAngle(qe_angle) array = ROOT.ARayArray() N = 1000**2 raytr = ROOT.TGeoTranslation("raytr", 0, 0, 2 * mm) direction = ROOT.TVector3(ROOT.TMath.Cos(45 * deg), 0, -ROOT.TMath.Sin(45 * deg)) array = ROOT.ARayShooter.Square(400 * nm, 1 * mm, 1000, 0, raytr, direction) manager.TraceNonSequential(array) nfocused = array.GetFocused().GetLast() + 1 nstopped = array.GetStopped().GetLast() + 1 self.assertEqual(nfocused + nstopped, N) if i == 0: self.assertEqual(nfocused, N) elif i == 1: p = 0.5 sigma = (N * (1 - p) * p)**0.5 self.assertLess(abs(nfocused - N * p), 3 * sigma) else: p = 0.25 sigma = (N * (1 - p) * p)**0.5 self.assertLess(abs(nfocused - N * p), 3 * sigma) cleanupGeo()
def testSnellsLaw(self): manager = makeTheWorld() manager.DisableFresnelReflection(True) lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 1 * mm) lens = ROOT.ALens("lens", lensbox) idx = 1.5 ROOT.gROOT.ProcessLine( 'refidx = std::make_shared<ARefractiveIndex>(%.1f);' % idx) lens.SetRefractiveIndex(ROOT.refidx) manager.GetTopVolume().AddNode(lens, 1) focalbox = ROOT.TGeoBBox("focalbox", 0.5 * m, 0.5 * m, 0.1 * mm) focal = ROOT.AFocalSurface("focal", focalbox) registerGeo((lensbox, lens, focalbox, focal)) lens.AddNode(focal, 1) manager.CloseGeometry() theta = 30 * deg sint = ROOT.TMath.Sin(theta) cost = ROOT.TMath.Cos(theta) ray = ROOT.ARay(0, 400 * nm, 0 * m, 0 * m, 2 * mm, 0, sint, 0, -cost) arr = ROOT.ARayArray() #arr.Add(ray) ## calling TraceNonSequential(ARay*) causes a seg fault... manager.TraceNonSequential(ray) p = array.array("d", [0, 0, 0, 0]) ray.GetDirection(p) px = p[0] py = p[1] pz = p[2] self.assertAlmostEqual(px, sint / idx) self.assertAlmostEqual(py, 0) cleanupGeo()
def testSnellsLaw(self): manager = makeTheWorld() manager.SetLimit(1000) lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 1 * mm) lens = ROOT.ALens("lens", lensbox) idx = 1.5 lens.SetConstantRefractiveIndex(idx) manager.GetTopVolume().AddNode(lens, 1) focalbox = ROOT.TGeoBBox("focalbox", 0.5 * m, 0.5 * m, 0.1 * mm) focal = ROOT.AFocalSurface("focal", focalbox) lens.AddNode(focal, 1) manager.CloseGeometry() if ROOT.gInterpreter.ProcessLine('ROOT_VERSION_CODE') < \ ROOT.gInterpreter.ProcessLine('ROOT_VERSION(6, 2, 0)'): manager.SetMultiThread(True) manager.SetMaxThreads(4) manager.DisableFresnelReflection(True) theta = 30 * d2r sint = ROOT.TMath.Sin(theta) cost = ROOT.TMath.Cos(theta) ray = ROOT.ARay(0, 400 * nm, 0 * m, 0 * m, 2 * mm, 0, sint, 0, -cost) arr = ROOT.ARayArray() arr.Add(ray) # calling TraceNonSequential(ARay*) causes a seg fault... manager.TraceNonSequential(arr) p = array.array("d", [0, 0, 0, 0]) ray.GetDirection(p) px = p[0] py = p[1] pz = p[2] self.assertAlmostEqual(px, sint / idx) self.assertAlmostEqual(py, 0)
def testLambertian(self): manager = makeTheWorld() mirrorbox = ROOT.TGeoBBox("mirrorbox", 5 * cm, 5 * cm, 1 * um) mirror = ROOT.AMirror("mirror", mirrorbox) condition = ROOT.ABorderSurfaceCondition(manager.GetTopVolume(), mirror) registerGeo((mirrorbox, mirror, condition)) condition.EnableLambertian(True) manager.GetTopVolume().AddNode(mirror, 1) focalbox = ROOT.TGeoBBox("focalbox", 0.5 * cm, 0.5 * cm, 1 * um) focal = ROOT.AFocalSurface("focal", focalbox) registerGeo((focalbox, focal)) collimatorpgon = ROOT.TGeoPgon("focalboxcollimatorpgon", 0, 360, 4, 2) collimatorpgon.DefineSection(0, -3 * m, 0.5 * cm, 0.51 * cm) collimatorpgon.DefineSection(1, -1 * um, 0.5 * cm, 0.51 * cm) collimator = ROOT.AObscuration("collimator", collimatorpgon) registerGeo((collimatorpgon, collimator)) for i in range(90): theta = i rot = ROOT.TGeoRotation("", 0, theta, 0) rot2 = ROOT.TGeoRotation("", 0, theta, 45) cos = ROOT.TMath.Cos(theta * ROOT.TMath.Pi() / 180.) sin = ROOT.TMath.Sin(theta * ROOT.TMath.Pi() / 180.) tr = ROOT.TGeoTranslation(0, -10 * m * sin, 10 * m * cos) registerGeo((rot, rot2, tr)) manager.GetTopVolume().AddNode(focal, i + 1, ROOT.TGeoCombiTrans(tr, rot)) manager.GetTopVolume().AddNode(collimator, i + 1, ROOT.TGeoCombiTrans(tr, rot2)) manager.CloseGeometry() manager.GetTopVolume().Draw("ogl") h = ROOT.TH1D('h', ';Viewing Angle (deg);Number of Photons', 90, 0, 90) for j in range(-500, 501): rot = ROOT.TGeoRotation("", 0, 180, 0) dy = j * mm / 10. tr = ROOT.TGeoTranslation(0, dy, 2 * um) array = ROOT.ARayShooter.RandomSquare(400 * nm, 2 * cm, 1000000, rot, tr) manager.TraceNonSequential(array) objarray = ROOT.TObjArray() objarray.Add(array) # to delete ARayArray inside C++ objarray.SetOwner(True) focused = array.GetFocused() for i in range(focused.GetLast() + 1): ray = focused[i] history = ray.GetNodeHistory() angle = int( history.At( history.GetLast()).GetName().split('_')[1]) - 0.5 h.Fill(angle) if i < 1000 and j == 0: pol = ray.MakePolyLine3D() pol.SetLineColor(2) pol.SetLineWidth(2) pol.Draw() registerGeo((pol, )) ROOT.gPad.Modified() ROOT.gPad.Update() del objarray can = ROOT.TCanvas() h.Draw() h.Fit('pol0', '', '', 0, 50)