Пример #1
0
    def testMirrorScattaring(self):
        manager = makeTheWorld()

        mirrorbox = ROOT.TGeoBBox("mirrorbox", 0.5 * m, 0.5 * m, 0.5 * m)
        mirror = ROOT.AMirror("mirror", mirrorbox)

        condition = ROOT.ABorderSurfaceCondition(manager.GetTopVolume(),
                                                 mirror)
        registerGeo((mirrorbox, mirror, condition))

        sigma = 1
        condition.SetGaussianRoughness(sigma * deg)

        manager.GetTopVolume().AddNode(mirror, 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)

        exited = rays.GetExited()

        h2 = ROOT.TH2D("h2", "h2", 40, -10 * sigma, 10 * sigma, 40,
                       -10 * sigma, 10 * sigma)

        for i in range(N):
            ray = exited.At(i)
            p = array.array("d", [0, 0, 0, 0])
            ray.GetDirection(p)
            px = p[0]
            py = p[1]
            pz = p[2]
            h2.Fill(px * rad / deg, py * rad / deg)

        f2 = ROOT.TF2("f2", "[0]*exp(-(x*x + y*y)/(2*[1]*[1]))", -10 * sigma,
                      10 * sigma, -10 * sigma, 10 * sigma)
        f2.SetParameter(0, 1000)
        f2.SetParLimits(1, 0, 10)
        f2.SetParameter(1, sigma)
        h2.Draw("lego")
        ROOT.gPad.Update()
        h2.Fit("f2", "l")
        p = f2.GetParameter(1)
        e = f2.GetParError(1)

        self.assertGreater(2 * sigma,
                           p - 3 * e)  # reflected angle is 2 times larger
        self.assertLess(2 * sigma, p + 3 * e)

        cleanupGeo()
Пример #2
0
    def testLensBoundaryMultilayer(self):
        manager = makeTheWorld()

        lensbox = ROOT.TGeoBBox("lensbox", 0.5 * m, 0.5 * m, 0.5 * m)
        lens = ROOT.AMirror("lens", lensbox)

        condition = ROOT.ABorderSurfaceCondition(manager.GetTopVolume(), lens)
        registerGeo((lensbox, lens, condition))

        ROOT.gROOT.ProcessLine(
            'auto lens_layer = std::make_shared<AMultilayer>(air, Si)')
        ROOT.lens_layer.InsertLayer(ROOT.SiO2, 2000 * nm)
        ROOT.lens_layer.InsertLayer(ROOT.Si3N4, 33 * nm)

        condition.SetMultilayer(ROOT.lens_layer)

        manager.GetTopVolume().AddNode(lens, 1)
        manager.CloseGeometry()

        N = 100000

        for wl in range(300, 600, 50):
            rays = ROOT.ARayArray()
            for i in range(N):
                ray = ROOT.ARay(i, wl * nm, 0, 0, 0.51 * m, 0, 1, 0, -1)
                rays.Add(ray)
                manager.TraceNonSequential(rays)

            n_exited = rays.GetExited().GetEntries()
            n_absorbed = rays.GetAbsorbed().GetEntries()
            self.assertEqual(n_exited + n_absorbed, N)

            reflectance = ctypes.c_double()
            transmittance = ctypes.c_double()
            ROOT.lens_layer.CoherentTMMMixed(
                ROOT.std.complex(ROOT.double)(45 * deg), wl * nm, reflectance,
                transmittance)

            expected = N * reflectance.value
            e = expected**0.5
            self.assertGreater(n_exited, expected - 3 * e)
            self.assertLess(n_exited, expected + 3 * e)

        cleanupGeo()
Пример #3
0
    def testMirrorBoundaryMultilayer(self):
        manager = makeTheWorld()

        mirrorbox = ROOT.TGeoBBox("mirrorbox", 0.5 * m, 0.5 * m, 0.5 * m)
        mirror = ROOT.AMirror("mirror", mirrorbox)

        condition = ROOT.ABorderSurfaceCondition(manager.GetTopVolume(),
                                                 mirror)
        ROOT.gROOT.ProcessLine(
            'auto mirror_layer = std::make_shared<AMultilayer>(air, Al)')
        ROOT.mirror_layer.InsertLayer(ROOT.SiO2, 25.4 * nm)

        condition.SetMultilayer(ROOT.mirror_layer)

        manager.GetTopVolume().AddNode(mirror, 1)
        manager.CloseGeometry()

        N = 100000

        for wl in range(300, 1100, 100):
            rays = ROOT.ARayArray()
            for i in range(N):
                ray = ROOT.ARay(i, wl * nm, 0, 0, 0.51 * m, 0, 1, 0, -1)
                rays.Add(ray)
                manager.TraceNonSequential(rays)

            n_exited = rays.GetExited().GetEntries()
            n_absorbed = rays.GetAbsorbed().GetEntries()
            self.assertEqual(n_exited + n_absorbed, N)

            reflectance = ROOT.double()
            transmittance = ROOT.double()
            ROOT.mirror_layer.CoherentTMMMixed(
                ROOT.std.complex(ROOT.double)(45 * deg), wl * nm, reflectance,
                transmittance)

            expected = N * reflectance
            e = expected**0.5
            self.assertGreater(n_exited, expected - 3 * e)
            self.assertLess(n_exited, expected + 3 * e)
            print(wl, n_exited, n_absorbed)
Пример #4
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)