Beispiel #1
0
def equilateral_prism(width=1.0,
                      height=1.0,
                      parent=None,
                      transform=None,
                      material=None):

    half_width = width / 2
    mid_point = half_width * tan(60 / 180 * pi) / 2

    centre = Box(Point3D(-half_width * 1.001, 0, 0),
                 Point3D(half_width * 1.001, height, width))

    left = Box(Point3D(0, -height * 0.001, -width * 0.001),
               Point3D(width, height * 1.001, 2 * width),
               transform=translate(half_width, 0, 0) * rotate(30, 0, 0))

    right = Box(Point3D(-width, -height * 0.001, -width * 0.001),
                Point3D(0.0, height * 1.001, 2 * width),
                transform=translate(-half_width, 0, 0) * rotate(-30, 0, 0))

    csg_prism = Subtract(Subtract(centre, left),
                         right,
                         parent=parent,
                         transform=transform * translate(0, 0, -mid_point),
                         material=material)

    return csg_prism
Beispiel #2
0
    def csg_aperture(self, value):

        if value is True:
            width = max(self.dx, self.dy)
            face = Box(Point3D(-width, -width, -self.dz/2), Point3D(width, width, self.dz/2))
            slit = Box(lower=Point3D(-self.dx/2, -self.dy/2, -self.dz/2 - self.dz*0.1),
                       upper=Point3D(self.dx/2, self.dy/2, self.dz/2 + self.dz*0.1))
            self._csg_aperture = Subtract(face, slit, parent=self,
                                          material=AbsorbingSurface(), name=self.name+' - CSG Aperture')

        else:
            if isinstance(self._csg_aperture, Primitive):
                self._csg_aperture.parent = None
            self._csg_aperture = None
Beispiel #3
0
def light_box(parent, transform=None):

    # Notice that this function is creating and returning a parent node which holds references
    # to the underlying primitives.
    node = Node(parent=parent, transform=transform)

    outer = Box(Point3D(-0.01, 0, -0.05), Point3D(0.01, 0.15, 0.0))
    slit = Box(Point3D(-0.0015, 0.03, -0.045), Point3D(0.0015, 0.12, 0.0001))

    Subtract(outer, slit, parent=node, material=Lambert(reflectivity=ConstantSF(0.1)))

    Box(Point3D(-0.0015, 0.03, -0.045),
        Point3D(0.0015, 0.12, -0.04),
        parent=node,
        material=UniformSurfaceEmitter(d65_white, 250))

    return node
Beispiel #4
0
 def __init__(self, radius_outer, height, n_radius, n_height, radius_inner=0, n_polar=0, period=360., step=None, voxel_map=None, mask=None,
              parent=None, transform=None):
     grid_shape = (n_radius, n_polar, n_height) if n_polar else (n_radius, n_height)
     if n_polar:
         if not 0 < period <= 360.:
             raise ValueError('period must be > 0 and <= 360')
     dr = (radius_outer - radius_inner) / n_radius
     dz = height / n_height
     dphi = period / n_polar if n_polar else 0
     grid_steps = (dr, dphi, dz) if n_polar else (dr, dz)
     eps_r = 1.e-5 * dr
     eps_z = 1.e-5 * dz
     step = step or 0.1 * min(dr, dz)
     material = CylindricalRayTransferEmitter(grid_shape, grid_steps, mask=mask, voxel_map=voxel_map,
                                              integrator=CylindricalRayTransferIntegrator(step), rmin=radius_inner, period=period)
     primitive = Subtract(Cylinder(radius_outer - eps_r, height - eps_z), Cylinder(radius_inner + eps_r, height - eps_z),
                          material=material, parent=parent, transform=transform)
     super().__init__(primitive)
Beispiel #5
0
 def test_evaluate_function_2d(self):
     """
     Unlike test_integration_2d() in TestRayTransferCylinder here we test how
     CylindricalRayTransferEmitter works with NumericalIntegrator in axysimmetric case.
     Testing against ToroidalVoxelGrid.
     """
     world = World()
     material = CylindricalRayTransferEmitter(
         (2, 2), (1., 1.), rmin=2., integrator=NumericalIntegrator(0.0001))
     primitive = Subtract(Cylinder(3.999999, 1.999999),
                          Cylinder(2.0, 1.999999),
                          material=material,
                          parent=world)
     ray = Ray(origin=Point3D(4., 1., 2.),
               direction=Vector3D(-4., -1., -2.) / np.sqrt(21.),
               min_wavelength=500.,
               max_wavelength=501.,
               bins=4)
     spectrum = ray.trace(world)
     world = World()
     vertices = []
     for rv in [2., 3.]:
         for zv in [0., 1.]:
             vertices.append([
                 Point2D(rv, zv + 1.),
                 Point2D(rv + 1., zv + 1.),
                 Point2D(rv + 1., zv),
                 Point2D(rv, zv)
             ])
     tvg = ToroidalVoxelGrid(vertices,
                             parent=world,
                             primitive_type='csg',
                             active='all')
     tvg.set_active('all')
     spectrum_test = ray.trace(world)
     self.assertTrue(
         np.allclose(spectrum_test.samples, spectrum.samples, atol=0.001))
Beispiel #6
0
 def test_evaluate_function_3d(self):
     """
     Unlike test_integration_3d() in TestRayTransferCylinder here we test how
     CylindricalRayTransferEmitter works with NumericalIntegrator in 3D case.
     """
     world = World()
     material = CylindricalRayTransferEmitter(
         (2, 3, 2), (1., 30., 1.),
         period=90.,
         integrator=NumericalIntegrator(0.0001))
     primitive = Subtract(Cylinder(1.999999, 1.999999),
                          Cylinder(0.000001, 1.999999),
                          material=material,
                          parent=world)
     ray = Ray(origin=Point3D(np.sqrt(2.), np.sqrt(2.), 2.),
               direction=Vector3D(-1., -1., -np.sqrt(2.)) / 2.,
               min_wavelength=500.,
               max_wavelength=501.,
               bins=12)
     spectrum = ray.trace(world)
     spectrum_test = np.zeros(12)
     spectrum_test[2] = spectrum_test[9] = np.sqrt(2.)
     self.assertTrue(
         np.allclose(spectrum_test, spectrum.samples, atol=0.001))
Beispiel #7
0
def mask_corners(element):
    """
    Support detectors with rounded corners, by producing a mask to cover
    the corners.

    The mask is produced by placing thin rectangles of side
    element.curvature_radius at each corner, and then cylinders of
    radius element.curvature_radius centred on the inner vertex of
    those rectangles. Then each corner of the mask is the part of the
    rectangle not covered by the cylinder.

    The curvature radius should be given in units of metres.
    """
    # Make the mask very (but not infinitely) thin, so that raysect
    # can actually detect that it's there. We'll work in the local
    # coordinate system of the element, with dx=width, dy=height,
    # dz=depth.
    dz = 1e-6
    rc = element.curvature_radius  # Shorthand
    try:
        dx = element.x_width
        dy = element.y_width
    except AttributeError:
        dx = element.dx
        dy = element.dy

    # Create a box and a cylinder of the appropriate size.
    # Then position copies of these at each corner.
    box_template = Box(Point3D(0, 0, 0), Point3D(rc, rc, dz))
    cylinder_template = Cylinder(rc, dz)

    top_left_box = box_template.instance(
        transform=translate(-dx / 2, dy / 2 - rc, 0),
    )
    top_left_cylinder = cylinder_template.instance(
        transform=translate(-dx / 2 + rc, dy / 2 - rc, 0),
    )
    top_left_mask = Subtract(top_left_box,
                             Intersect(top_left_box, top_left_cylinder))

    top_right_box = box_template.instance(
        transform=translate(dx / 2 - rc, dy / 2 - rc, 0),
    )
    top_right_cylinder = cylinder_template.instance(
        transform=translate(dx / 2 - rc, dy / 2 - rc, 0),
    )
    top_right_mask = Subtract(top_right_box,
                              Intersect(top_right_box, top_right_cylinder))

    bottom_right_box = box_template.instance(
        transform=translate(dx / 2 - rc, -dy / 2, 0),
    )
    bottom_right_cylinder = cylinder_template.instance(
        transform=translate(dx / 2 - rc, -dy / 2 + rc, 0),
    )
    bottom_right_mask = Subtract(bottom_right_box,
                                 Intersect(bottom_right_box, bottom_right_cylinder))

    bottom_left_box = box_template.instance(
        transform=translate(-dx / 2, -dy / 2, 0),
    )
    bottom_left_cylinder = cylinder_template.instance(
        transform=translate(-dx / 2 + rc, -dy / 2 + rc, 0),
    )
    bottom_left_mask = Subtract(bottom_left_box,
                                Intersect(bottom_left_box, bottom_left_cylinder))

    # The foil mask is the sum of all 4 of these corner shapes
    mask = functools.reduce(Union, (top_left_mask, top_right_mask,
                                    bottom_right_mask, bottom_left_mask))
    mask.material = AbsorbingSurface()
    mask.transform = translate(0, 0, dz)
    mask.name = element.name + ' - rounded edges mask'
    mask.parent = element
Beispiel #8
0
enclosure_thickness = 0.001 + padding
glass_thickness = 0.003

light_box = Node(parent=world)

enclosure_outer = Box(
    Point3D(-0.10 - enclosure_thickness, -0.02 - enclosure_thickness,
            -0.10 - enclosure_thickness),
    Point3D(0.10 + enclosure_thickness, 0.0, 0.10 + enclosure_thickness))

enclosure_inner = Box(
    Point3D(-0.10 - padding, -0.02 - padding, -0.10 - padding),
    Point3D(0.10 + padding, 0.001, 0.10 + padding))

enclosure = Subtract(enclosure_outer,
                     enclosure_inner,
                     material=Lambert(ConstantSF(0.2)),
                     parent=light_box)

glass_outer = Box(Point3D(-0.10, -0.02, -0.10), Point3D(0.10, 0.0, 0.10))

glass_inner = Box(
    Point3D(-0.10 + glass_thickness, -0.02 + glass_thickness,
            -0.10 + glass_thickness),
    Point3D(0.10 - glass_thickness, 0.0 - glass_thickness,
            0.10 - glass_thickness))

glass = Subtract(glass_outer,
                 glass_inner,
                 material=schott("N-BK7"),
                 parent=light_box)
Beispiel #9
0
            Point3D(1000, 0, 1000),
            parent=world,
            material=Lambert())

# construct prism from utility method
prism = equilateral_prism(0.06,
                          0.15,
                          parent=world,
                          material=schott("SF11"),
                          transform=translate(0, 0.0 + 1e-6, -0.01))

# Curved target screen for collecting rainbow light
stand = Intersect(
    Box(Point3D(-10, -10, -10), Point3D(10, 10, 0)),
    Subtract(Cylinder(0.21, 0.15),
             Cylinder(0.20, 0.16, transform=translate(0, 0, -0.005)),
             transform=rotate(0, 90, 0)),
    transform=translate(0.0, 1e-6, 0.0),
    parent=world,
    material=schott("N-BK7")  # RoughIron(0.25)
)

surface = Intersect(Box(Point3D(-10, -10, -10), Point3D(10, 10, -0.015)),
                    Subtract(Cylinder(0.1999,
                                      0.12,
                                      transform=translate(0, 0, 0.015)),
                             Cylinder(0.1998,
                                      0.13,
                                      transform=translate(0, 0, 0.010)),
                             transform=rotate(0, 90, 0)),
                    parent=stand,
Beispiel #10
0
# construct diffuse floor surface
floor = Box(Point3D(-1000, -0.1, -1000), Point3D(1000, 0, 1000),
            parent=world, material=Lambert())


# construct prism from utility method
prism = equilateral_prism(0.06, 0.15, parent=world,
                          material=schott("SF11"), transform=translate(0, 0.0 + 1e-6, 0))


# Curved target screen for collecting rainbow light
screen = Intersect(
    Box(Point3D(-10, -10, -10), Point3D(10, 10, 0)),
    Subtract(Cylinder(0.22, 0.15),
             Cylinder(0.20, 0.16, transform=translate(0, 0, -0.005)),
             transform=rotate(0, 90, 0)),
    parent=world,
    material=Lambert()
)


# construct main collimated light source
prism_light = light_box(parent=world,
                        transform=rotate(-35.5, 0, 0) * translate(0.10, 0, 0) * rotate(90, 0, 0))


# background light source
top_light = Sphere(0.5, parent=world, transform=translate(0, 2, -1),
                   material=UniformSurfaceEmitter(d65_white, scale=2))
Beispiel #11
0
green_glass = Dielectric(index=Sellmeier(1.03961212, 0.231792344, 1.01046945, 6.00069867e-3, 2.00179144e-2, 1.03560653e2),
                         transmission=InterpolatedSF([300, 490, 510, 590, 610, 800], array([0.0, 0.0, 1.0, 1.0, 0.0, 0.0])*0.7))

blue_glass = Dielectric(index=Sellmeier(1.03961212, 0.231792344, 1.01046945, 6.00069867e-3, 2.00179144e-2, 1.03560653e2),
                        transmission=InterpolatedSF([300, 490, 510, 590, 610, 800], array([1.0, 1.0, 0.0, 0.0, 0.0, 0.0])*0.7))

world = World()

cyl_x = Cylinder(1, 4.2, transform=rotate(90, 0, 0)*translate(0, 0, -2.1))
cyl_y = Cylinder(1, 4.2, transform=rotate(0, 90, 0)*translate(0, 0, -2.1))
cyl_z = Cylinder(1, 4.2, transform=rotate(0, 0, 0)*translate(0, 0, -2.1))
cube = Box(Point3D(-1.5, -1.5, -1.5), Point3D(1.5, 1.5, 1.5))
sphere = Sphere(2.0)

Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world, translate(-2.1,2.1,2.5)*rotate(30, -20, 0), schott("N-LAK9"))
Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world, translate(2.1,2.1,2.5)*rotate(-30, -20, 0), schott("SF6"))
Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world, translate(2.1,-2.1,2.5)*rotate(-30, 20, 0), schott("LF5G19"))
Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world, translate(-2.1,-2.1,2.5)*rotate(30, 20, 0), schott("N-BK7"))

s1 = Sphere(1.0, transform=translate(0, 0, 1.0-0.01))
s2 = Sphere(0.5, transform=translate(0, 0, -0.5+0.01))
Intersect(s1, s2, world, translate(0,0,-3.6)*rotate(50,50,0), schott("N-BK7"))

Box(Point3D(-50, -50, 50), Point3D(50, 50, 50.1), world, material=Checkerboard(4, d65_white, d65_white, 0.4, 0.8))
Box(Point3D(-100, -100, -100), Point3D(100, 100, 100), world, material=UniformSurfaceEmitter(d65_white, 0.1))

ion()

# create and setup the camera
rgb = RGBPipeline2D()
Beispiel #12
0
s1 = Sphere(0.5, transform=translate(-0.25, 0, 0), name='s1')
s2 = Sphere(0.5, transform=translate(0.25, 0, 0), name='s2')

world = World()
Union(s1, s2, parent=world)
visualise_scenegraph(world)
input('pause...')

world = World()
Intersect(s1, s2, parent=world)
visualise_scenegraph(world)
input('pause...')

world = World()
Subtract(s1, s2, parent=world)
visualise_scenegraph(world)
input('pause...')

########################################################################################################################
# Cubes

b1 = Box(Point3D(0, 0, 0), Point3D(1, 1, 1))
b2 = Box(Point3D(0, 0, 0),
         Point3D(1, 1, 1),
         transform=translate(0.6, 0.6, 0.6))

world = World()
Union(b1, b2, parent=world)
visualise_scenegraph(world)
input('pause...')
Beispiel #13
0
              transform=translate(0, 4, -3.5) * rotate(0, -48, 180))

# b = BiConvex(0.0508, 0.0036, 1.0295, 1.0295, parent=camera, transform=translate(0, 0, 0.1), material=schott("N-BK7"))
# b = BiConvex(0.0508, 0.0062, 0.205, 0.205, parent=camera, transform=translate(0, 0, 0.05), material=schott("N-BK7"))
lens = BiConvex(0.0508,
                0.0144,
                0.0593,
                0.0593,
                parent=camera,
                transform=translate(0, 0, 0.0536),
                material=schott("N-BK7"))

body = Subtract(Subtract(
    Cylinder(0.0260, 0.07, transform=translate(0, 0, 0)),
    Cylinder(0.0255, 0.06, transform=translate(0, 0, 0.005))),
                Cylinder(0.015, 0.007, transform=translate(0, 0, 0.064)),
                parent=camera,
                transform=translate(0, 0, -0.01),
                material=AbsorbingSurface())

aperture = Cylinder(0.016,
                    0.0009,
                    parent=camera,
                    transform=translate(0, 0, 0.064),
                    material=NullMaterial())

rgb = RGBPipeline2D(display_unsaturated_fraction=0.98, name="sRGB")
bayer = BayerPipeline2D(ciexyz_x,
                        ciexyz_y,
                        ciexyz_z,
                        display_unsaturated_fraction=0.98,
Beispiel #14
0
from raysect.core import Point3D, Vector3D, rotate_basis, translate, Ray as CoreRay
from raysect.core.math.sampler import DiskSampler3D, RectangleSampler3D, TargettedHemisphereSampler
from raysect.optical import World
from raysect.primitive import Box, Cylinder, Subtract
from raysect.optical.material import AbsorbingSurface, NullMaterial

R_2_PI = 1 / (2 * np.pi)

world = World()

# Setup pinhole
target_plane = Box(Point3D(-10, -10, -0.000001), Point3D(10, 10, 0.000001))
hole = Cylinder(0.001, 0.001, transform=translate(0, 0, -0.0005))
pinhole = Subtract(target_plane,
                   hole,
                   parent=world,
                   material=AbsorbingSurface())

target = Cylinder(0.0012,
                  0.001,
                  transform=translate(0, 0, -0.0011),
                  parent=world,
                  material=NullMaterial())


def analytic_etendue(area_det, area_slit, distance, alpha, gamma):

    return area_det * area_slit * np.cos(alpha / 360 * (2 * np.pi)) * np.cos(
        gamma / 360 * (2 * np.pi)) / distance**2

Beispiel #15
0
import numpy as np
from matplotlib import pyplot as plt

from raysect.primitive import Cylinder, Subtract
from raysect.optical import World, translate, rotate
from raysect.optical.observer import PinholeCamera, FullFrameSampler2D

from cherab.tools.raytransfer import RayTransferPipeline2D, RayTransferCylinder
from cherab.tools.raytransfer import RoughNickel

world = World()

# creating the scene
cylinder_inner = Cylinder(radius=80., height=140.)
cylinder_outer = Cylinder(radius=220., height=140.)
wall = Subtract(cylinder_outer, cylinder_inner, material=RoughNickel(0.1), parent=world,
                transform=translate(0, 0, -70.))

# creating ray transfer cylinder with 200 (m) outer radius, 100 (m) inner radius, 140 (m) height
# for axisymmetric cylindrical emission profile defined on a 100 x 100 (R, Z) gird
rtc = RayTransferCylinder(200., 100., 100, 100, radius_inner=100.)
# n_polar=0 by default (axisymmetric case)
rtc.parent = world
rtc.transform = translate(0, 0, -50.)

# unlike the demo with a mask, here we not only cut out a circle but also
# create 50 ring-shaped light sources using the voxel map
rad_circle = 50.
xsqr = np.linspace(-49.5, 49.5, 100) ** 2
rad = np.sqrt(xsqr[:, None] + xsqr[None, :])
voxel_map = np.zeros((100, 100), dtype=np.int)
voxel_map[rad > 50.] = -1  # removing the area outside the circle
Beispiel #16
0
blue_glass = Dielectric(
    index=Sellmeier(1.03961212, 0.231792344, 1.01046945, 6.00069867e-3,
                    2.00179144e-2, 1.03560653e2),
    transmission=InterpolatedSF([300, 490, 510, 590, 610, 800],
                                array([1.0, 1.0, 0.0, 0.0, 0.0, 0.0]) * 0.7))

world = World()

cyl_x = Cylinder(1, 4.2, transform=rotate(90, 0, 0) * translate(0, 0, -2.1))
cyl_y = Cylinder(1, 4.2, transform=rotate(0, 90, 0) * translate(0, 0, -2.1))
cyl_z = Cylinder(1, 4.2, transform=rotate(0, 0, 0) * translate(0, 0, -2.1))
cube = Box(Point3D(-1.5, -1.5, -1.5), Point3D(1.5, 1.5, 1.5))
sphere = Sphere(2.0)

Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world,
          translate(-2.1, 2.1, 2.5) * rotate(30, -20, 0), schott("N-LAK9"))
Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world,
          translate(2.1, 2.1, 2.5) * rotate(-30, -20, 0), schott("SF6"))
Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world,
          translate(2.1, -2.1, 2.5) * rotate(-30, 20, 0), schott("LF5G19"))
Intersect(sphere, Subtract(cube, Union(Union(cyl_x, cyl_y), cyl_z)), world,
          translate(-2.1, -2.1, 2.5) * rotate(30, 20, 0), schott("N-BK7"))

s1 = Sphere(1.0, transform=translate(0, 0, 1.0 - 0.01))
s2 = Sphere(0.5, transform=translate(0, 0, -0.5 + 0.01))
Intersect(s1, s2, world,
          translate(0, 0, -3.6) * rotate(50, 50, 0), schott("N-BK7"))

Box(Point3D(-50, -50, 50),
    Point3D(50, 50, 50.1),
              mm(20.4942),
              parent=l2,
              transform=translate(0, 0, mm(-7.949)),
              material=schott("N-LAK9"))
image_plane = Node(parent=l3, transform=translate(0, 0, mm(
    -41.5)))  # tweaked position gives a sharper image (original: 41.10346 mm)

# disable importance sampling of the lenses (enabled by default for dielectrics and emitters)
l1.material.importance = 0.0
l2.material.importance = 0.0
l3.material.importance = 0.0

# cylinder body holding the lenses and CCD
body = Subtract(Cylinder(mm(26), mm(80.0), transform=translate(0, 0, mm(-63))),
                Cylinder(mm(25), mm(79.1), transform=translate(0, 0, mm(-62))),
                parent=camera,
                transform=translate(0, 0, 0),
                material=AbsorbingSurface())

# L1 lens mount
l1_mount = Subtract(Cylinder(mm(25.5),
                             mm(5.0),
                             transform=translate(0, 0, mm(0))),
                    Cylinder(mm(21 / 2 + 0.01),
                             mm(5.1),
                             transform=translate(0, 0, mm(-0.05))),
                    parent=l1,
                    transform=translate(0, 0, mm(0)),
                    material=AbsorbingSurface())

# L2 lens mount