def testFresnelReflection(self): manager = makeTheWorld() manager.DisableFresnelReflection(False) # enable lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 0.5 * m) lens = ROOT.ALens("lens", lensbox) lens.SetConstantAbsorptionLength(1 * um) idx = 3. lens.SetConstantRefractiveIndex(idx) manager.GetTopVolume().AddNode(lens, 1) manager.CloseGeometry() if ROOT.gInterpreter.ProcessLine('ROOT_VERSION_CODE') < \ ROOT.gInterpreter.ProcessLine('ROOT_VERSION(6, 2, 0)'): manager.SetMultiThread(True) manager.SetMaxThreads(4) N = 10000 rays = ROOT.ARayArray() for i in range(N): ray = ROOT.ARay(i, 400 * nm, 0, 0, 0.8 * m, 0, 0, 0, -1) rays.Add(ray) manager.TraceNonSequential(rays) n = rays.GetExited().GetLast() + 1 ref = (idx - 1)**2 / (idx + 1)**2 self.assertGreater(ref, (n - n**0.5 * 3) / N) self.assertLess(ref, (n + n**0.5 * 3) / N)
def testAbsorptionLength(self): manager = makeTheWorld() lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 0.5 * m) lens = ROOT.ALens("lens", lensbox) registerGeo((lensbox, lens)) manager.GetTopVolume().AddNode(lens, 1) manager.CloseGeometry() if ROOT.gInterpreter.ProcessLine('ROOT_VERSION_CODE;') < \ ROOT.gInterpreter.ProcessLine('ROOT_VERSION(6, 2, 0);'): manager.SetMultiThread(True) manager.SetMaxThreads(4) # test absorption length evaluated from a TGraph wl = 400 * nm absl = 1 * mm ROOT.gROOT.ProcessLine( 'refidx = std::make_shared<ARefractiveIndex>();') ROOT.gROOT.ProcessLine('graph = std::make_shared<TGraph>();') ROOT.graph.SetPoint(0, wl, 1) ROOT.refidx.SetRefractiveIndex(ROOT.graph) ROOT.gROOT.ProcessLine('graph = std::make_shared<TGraph>();') k = ROOT.ARefractiveIndex.AbsorptionLengthToExtinctionCoefficient( absl, wl) ROOT.graph.SetPoint(0, wl, k) ROOT.refidx.SetExtinctionCoefficient(ROOT.graph) lens.SetRefractiveIndex(ROOT.refidx) rays = ROOT.ARayShooter.RandomSphere(400 * nm, 10000) manager.TraceNonSequential(rays) h = ROOT.TH1D("h", "h", 1000, 0, 10) absorbed = rays.GetAbsorbed() for i in range(absorbed.GetLast() + 1): ray = absorbed.At(i) p = array.array("d", [0, 0, 0, 0]) ray.GetLastPoint(p) d = (p[0] * p[0] + p[1] * p[1] + p[2] * p[2])**0.5 h.Fill(d / mm) h.Draw() h.Fit("expo", "l") ROOT.gPad.Update() expo = h.GetFunction("expo") p = -expo.GetParameter(1) e = expo.GetParError(1) self.assertGreater(1, p - 3 * e) self.assertLess(1, p + 3 * e) cleanupGeo()
def testRefractiveIndex(self): manager = makeTheWorld() lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 1 * mm) lens = ROOT.ALens("lens", lensbox) graph = ROOT.TGraph() graph.SetPoint(0, 400 * nm, 1.6) graph.SetPoint(1, 500 * nm, 1.5) lens.SetRefractiveIndex(graph) n = lens.GetRefractiveIndex(450 * nm) self.assertEqual(n, 1.55)
def testRefractiveIndex(self): lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 1 * mm) lens = ROOT.ALens("lens", lensbox) ROOT.gROOT.ProcessLine('graph = std::make_shared<TGraph>();') ROOT.graph.SetPoint(0, 400 * nm, 1.6) ROOT.graph.SetPoint(1, 500 * nm, 1.5) ROOT.gROOT.ProcessLine( 'refidx = std::make_shared<ARefractiveIndex>();') ROOT.refidx.SetRefractiveIndex(ROOT.graph) lens.SetRefractiveIndex(ROOT.refidx) n = lens.GetRefractiveIndex(450 * nm) self.assertEqual(n, 1.55)
def testAbsorptionLength(self): manager = makeTheWorld() lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 0.5 * m) lens = ROOT.ALens("lens", lensbox) manager.GetTopVolume().AddNode(lens, 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 j in range(2): if j == 0: # test a constant absorption length lens.SetConstantAbsorptionLength(1 * mm) else: # test absorption length evaluated from a TGraph graph = ROOT.TGraph() graph.SetPoint(0, 300 * nm, 0.5 * mm) # 1 mm at 400 nm graph.SetPoint(1, 500 * nm, 1.5 * mm) lens.SetAbsorptionLength(graph) rays = ROOT.ARayShooter.RandomSphere(400 * nm, 10000) manager.TraceNonSequential(rays) h = ROOT.TH1D("h", "h", 1000, 0, 10) absorbed = rays.GetAbsorbed() for i in range(absorbed.GetLast() + 1): ray = absorbed.At(i) p = array.array("d", [0, 0, 0, 0]) ray.GetLastPoint(p) d = (p[0] * p[0] + p[1] * p[1] + p[2] * p[2])**0.5 h.Fill(d / mm) h.Draw() h.Fit("expo", "l") ROOT.gPad.Update() expo = h.GetFunction("expo") p = -expo.GetParameter(1) e = expo.GetParError(1) self.assertGreater(1, p - 3 * e) self.assertLess(1, p + 3 * e)
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 testFresnelReflection(self): manager = makeTheWorld() manager.DisableFresnelReflection(False) # enable lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 0.5 * m) lens = ROOT.ALens("lens", lensbox) wl = 400 * nm absl = 1 * um idx = 3. ROOT.gROOT.ProcessLine('double idx, k;') ROOT.idx = idx ROOT.k = ROOT.ARefractiveIndex.AbsorptionLengthToExtinctionCoefficient( absl, wl) ROOT.gROOT.ProcessLine( 'refidx = std::make_shared<ARefractiveIndex>(idx, k);') lens.SetRefractiveIndex(ROOT.refidx) manager.GetTopVolume().AddNode(lens, 1) manager.CloseGeometry() if ROOT.gInterpreter.ProcessLine('ROOT_VERSION_CODE;') < \ ROOT.gInterpreter.ProcessLine('ROOT_VERSION(6, 2, 0);'): manager.SetMultiThread(True) manager.SetMaxThreads(4) N = 100000 rays = ROOT.ARayArray() for i in range(N): ray = ROOT.ARay(i, wl, 0, 0, 0.8 * m, 0, 0, 0, -1) rays.Add(ray) manager.TraceNonSequential(rays) n = rays.GetExited().GetLast() + 1 ref = (idx - 1)**2 / (idx + 1)**2 self.assertGreater(ref, (n - n**0.5 * 3) / N) self.assertLess(ref, (n + n**0.5 * 3) / N) layer = ROOT.AMultilayer(ROOT.air, ROOT.TiO2) angle = ROOT.std.complex(ROOT.double)(45 * deg) for wl in (200 * nm, 800 * nm): ref, trans = ctypes.c_double(), ctypes.c_double() layer.CoherentTMMMixed(angle, wl, ref, trans) lens.SetRefractiveIndex(ROOT.TiO2) rays = ROOT.ARayArray() z, dy, dz = 0.51 * m, 1 / 2**0.5, -1 / 2**0.5 for i in range(N): ray = ROOT.ARay(i, wl, 0, 0, z, 0, 0, dy, dz) rays.Add(ray) manager.SetLimit( 3) # stop tracking of photons that entered the lens manager.TraceNonSequential(rays) n = rays.GetExited().GetLast() + 1 self.assertGreater(ref.value, (n - n**0.5 * 3) / N) self.assertLess(ref.value, (n + n**0.5 * 3) / N)