예제 #1
0
def get_curved_surf_triangle_centers(vtx,
                                     rad,
                                     detector_r=1.0,
                                     focal_length=1.0,
                                     nsteps=10,
                                     b_pxl=4):
    #Changed the rotation matrix to try and keep the curved surface towards the interior
    #Make sure diameter, etc. are set properly
    curved_surf_triangle_centers = []
    mesh_surf, ring = curved_surface2(detector_r,
                                      diameter=2 * rad,
                                      nsteps=nsteps,
                                      base_pxl=b_pxl,
                                      ret_arr=True)
    initial_curved_surf = mh.rotate(
        mesh_surf,
        make_rotation_matrix(-np.pi / 2,
                             (1, 0, 0)))  #-np.pi with curved_surface2
    triangles_per_surface = initial_curved_surf.triangles.shape[0]
    phi, axs = rot_axis([0, 0, 1], vtx)
    for vx, ph, ax in zip(vtx, -phi, axs):
        curved_surf_triangle_centers.extend(
            mh.shift(
                mh.rotate(initial_curved_surf,
                          make_rotation_matrix(ph, ax)), -normalize(vx) *
                (np.linalg.norm(vx) + focal_length)).get_triangle_centers())
    return np.asarray(
        curved_surf_triangle_centers), triangles_per_surface, ring
예제 #2
0
def build_detector():
    """Returns a cubic detector made of cubic photodetectors."""
    g = Geometry(water)
    for pos, dir in iter_box(nx,ny,nz,spacing):
        # convert to arrays
        pos, dir = np.array(pos), np.array(dir)

        # we need to figure out what rotation matrix to apply to each
        # photodetector so that the photosensitive surface will be facing
        # `dir`.
        if tuple(dir) == (0,0,1):
            rotation = None
        elif tuple(dir) == (0,0,-1):
            rotation = make_rotation_matrix(np.pi,(1,0,0))
        else:
            rotation = make_rotation_matrix(np.arccos(dir.dot((0,0,1))),
                                            np.cross(dir,(0,0,1)))
        # add the photodetector
        g.add_solid(build_pd(size,glass_thickness),rotation=rotation,
                    displacement=pos)

    world = Solid(make.box(spacing*nx,spacing*ny,spacing*nz),water,vacuum,
                  color=0x33ffffff)
    g.add_solid(world)

    return g
예제 #3
0
 def build_rotation_matrices(self):
     rotation_matrices = np.empty((20, 3, 3))
     for k in range(20):
         rotation_matrices[k] = np.dot(
             make_rotation_matrix(self.spin_angle[k], self.direction[k]),
             make_rotation_matrix(self.angle[k], self.axis[k]))
     return rotation_matrices
예제 #4
0
def build_detector():
    """Returns a cubic detector made of cubic photodetectors."""
    g = Geometry(water)
    for pos, dir in iter_box(nx, ny, nz, spacing):
        # convert to arrays
        pos, dir = np.array(pos), np.array(dir)

        # we need to figure out what rotation matrix to apply to each
        # photodetector so that the photosensitive surface will be facing
        # `dir`.
        if tuple(dir) == (0, 0, 1):
            rotation = None
        elif tuple(dir) == (0, 0, -1):
            rotation = make_rotation_matrix(np.pi, (1, 0, 0))
        else:
            rotation = make_rotation_matrix(np.arccos(dir.dot((0, 0, 1))),
                                            np.cross(dir, (0, 0, 1)))
        # add the photodetector
        g.add_solid(build_pd(size, glass_thickness),
                    rotation=rotation,
                    displacement=pos)

    world = Solid(make.box(spacing * nx, spacing * ny, spacing * nz),
                  water,
                  vacuum,
                  color=0x33ffffff)
    g.add_solid(world)

    return g
예제 #5
0
def detector(pmt_radius=14000.0, sphere_radius=14500.0, spiral_step=350.0):
    pmt = build_8inch_pmt_with_lc()
    geo = Detector(water)

    geo.add_solid(Solid(sphere(sphere_radius,nsteps=200), 
                        water, water, 
                        surface=black_surface,
                        color=0xBBFFFFFF))

    for position in spherical_spiral(pmt_radius, spiral_step):
        direction = -normalize(position)

        # Orient PMT that starts facing Y axis
        y_axis = np.array((0.0,1.0,0.0))
        axis = np.cross(direction, y_axis)
        angle = np.arccos(np.dot(y_axis, direction))
        rotation = make_rotation_matrix(angle, axis)

        # Place PMT (note that position is front face of PMT)
        geo.add_pmt(pmt, rotation, position)
        
    
    time_rms = 1.5 # ns
    charge_mean = 1.0
    charge_rms = 0.1 # Don't I wish!
    
    geo.set_time_dist_gaussian(time_rms, -5 * time_rms, 5*time_rms)
    geo.set_charge_dist_gaussian(charge_mean, charge_rms, 0.0, charge_mean + 5*charge_rms)

    logger.info('Demo detector: %d PMTs' % geo.num_channels())
    logger.info('               %1.1f ns time RMS' % time_rms)
    logger.info('               %1.1f%% charge RMS' % (100.0*charge_rms/charge_mean))
    return geo
예제 #6
0
def get_lens_triangle_centers(vtx,
                              rad,
                              diameter_ratio,
                              thickness_ratio,
                              half_EPD,
                              blockers=True,
                              blocker_thickness_ratio=1.0 / 1000,
                              light_confinement=False,
                              focal_length=1.0,
                              lens_system_name=None):
    """input edge length of icosahedron 'edge_length', the number of small triangles in the base of each face 'base',
	   the ratio of the diameter of each lens to the maximum diameter possible 'diameter_ratio' (or the fraction of the default such ratio,
	   if a curved detector lens system), the ratio of the thickness of the lens to the chosen (not maximum) diameter 'thickness_ratio',
	   the radius of the blocking entrance pupil 'half_EPD', and the ratio of the thickness of the blockers to that of the lenses 'blocker_thickness_ratio'
	   to return the icosahedron of lenses in kabamland. Light_confinment=True adds cylindrical shells behind each lens that
	   absorb all the light that touches them, so that light doesn't overlap between lenses.
	   If lens_system_name is a string that matches one of the lens systems in lenssystem.py, the corresponding lenses and detectors will be built.
	   Otherwise, a default simple lens will be built, with parameters hard-coded below."""
    # Get the list of lens meshes from the appropriate lens system as well as the lens material
    scale_rad = rad * diameter_ratio
    lenses = lenssystem.get_lens_mesh_list(lens_system_name, scale_rad)
    lens_mesh = None
    for lns in lenses:  # Add all the lenses for the first lens system to solid 'face'
        if not lens_mesh:
            lens_mesh = lns
        else:
            lens_mesh += lns
    X, Y, Z = get_assembly_xyz(lens_mesh)
    lens_centers = np.asarray([np.mean(X), np.mean(Y), np.mean(Z)])
    lns_center_arr = []
    phi, axs = rot_axis([0, 0, 1], vtx)
    for vx, ph, ax in zip(vtx, -phi, axs):
        lns_center_arr.append(
            np.dot(make_rotation_matrix(ph, ax), lens_centers) - vx)
    return np.asarray(lns_center_arr)
예제 #7
0
    def render_particle_track(self):
        x = 10.0
        h = x * np.sqrt(3) / 2
        pyramid = make.linear_extrude([-x / 2, 0, x / 2],
                                      [-h / 2, h / 2, -h / 2], h, [0] * 3,
                                      [0] * 3)
        marker = Solid(pyramid, vacuum, vacuum)

        if self.photon_display_mode == 'beg':
            photons = self.ev.photons_beg
        else:
            photons = self.ev.photons_end

        geometry = Geometry()
        sample_factor = max(1, len(photons.pos) / 10000)
        for pos in photons.pos[::sample_factor]:
            geometry.add_solid(marker,
                               displacement=pos,
                               rotation=make_rotation_matrix(
                                   np.random.uniform(0, 2 * np.pi),
                                   uniform_sphere()))

        geometry = create_geometry_from_obj(geometry)
        gpu_geometry = gpu.GPUGeometry(geometry)

        self.gpu_geometries = [self.gpu_geometry, gpu_geometry]
예제 #8
0
 def build_detector(self, detector=None, volume_classifier=_default_volume_classifier):
     '''
     Add the meshes defined by this GDML to the detector. If detector is not
     specified, a new detector will be created.
     
     The volume_classifier should be a function that returns a classification
     of the volume ('pmt','solid','omit') and kwargs passed to the Solid
     constructor for that volume: material1, material2, color, surface
     
     The different classifications have different behaviors:
     'pmt' should specify channel_type in the kwargs to identify the channel, calls add_pmt
     'solid' will add a normal solid to the Chroma geometry, calls add_solid
     'omit' will not add the Solid to the Chroma geometry
     '''
     if detector is None:
         detector = Detector(vacuum)
     q = deque()
     q.append([self.world, np.zeros(3), np.identity(3), None])
     while len(q):
         v, pos, rot, parent_material_ref = q.pop()
         for child, c_pos, c_rot in zip(v.children, v.child_pos, v.child_rot):
             c_pos = self.get_vals(c_pos) if c_pos is not None else np.zeros(3)
             c_rot = self.get_vals(c_rot) if c_rot is not None else np.identity(3)
             c_pos = np.matmul(c_pos,rot)+pos
             x_rot = make_rotation_matrix(c_rot[0], [1, 0, 0])
             y_rot = make_rotation_matrix(c_rot[1], [0, 1, 0])
             z_rot = make_rotation_matrix(c_rot[2], [0, 0, 1])
             c_rot = np.matmul(rot, np.matmul(x_rot, np.matmul(y_rot, z_rot))) #FIXME verify this order
             q.append([child, c_pos, c_rot, v.material_ref])
         m = self.get_mesh(v.solid_ref)
         mesh = Mesh(m.vertices, m.faces) # convert PyMesh mesh to Chroma mesh
         classification, kwargs = volume_classifier(v.name, v.material_ref, parent_material_ref)
         if classification == 'pmt':
             channel_type = kwargs.pop('channel_type',None)
             solid = Solid(mesh, **kwargs)
             detector.add_pmt(solid, displacement=pos, rotation=rot, channel_type=channel_type)   
         elif classification == 'solid':
             solid = Solid(mesh, **kwargs)
             detector.add_solid(solid, displacement=pos, rotation=rot)   
         elif classification == 'omit':
             pass
         else:
             raise Exception('Unknown volume classification: '+classification)
     return detector
예제 #9
0
파일: camera.py 프로젝트: wcgillis01/chroma
def gen_rot(a, b):
    '''Construct a matrix to rotate vector a to vector b'''
    a = a / np.linalg.norm(a)
    b = b / np.linalg.norm(b)
    if (a == b).all():
        return np.diag([1., 1., 1.])
    if (a == -b).all():
        return np.diag([-1., -1., -1.])
    v = np.cross(a, b)
    c = np.arccos(-np.dot(a, b))
    return make_rotation_matrix(c, v)
예제 #10
0
def BuildBlocker(radius, height):
    nsteps = 50
    x_value = np.linspace(radius, radius + 200, nsteps)
    y_value = [1] * nsteps

    blocker = make.rotate_extrude(x_value, y_value, nsteps)

    blocker = mh.rotate(blocker, make_rotation_matrix(+np.pi / 2, (1, 0, 0)))
    blocker = mh.shift(blocker, (0, 0, height))

    return blocker
예제 #11
0
def build_curvedsurface_icosahedron(kabamland,
                                    vtx,
                                    rad,
                                    diameter_ratio,
                                    focal_length=1.0,
                                    detector_r=1.0,
                                    nsteps=10,
                                    b_pxl=4):
    initial_curved_surf = mh.rotate(
        curved_surface2(detector_r,
                        diameter=rad * 2,
                        nsteps=nsteps,
                        base_pxl=b_pxl),
        make_rotation_matrix(-np.pi / 2, (1, 0, 0)))
    face = Solid(initial_curved_surf, kabamland.detector_material,
                 kabamland.detector_material, lm.fulldetect, 0x0000FF)
    phi, axs = rot_axis([0, 0, 1], vtx)
    for vx, ph, ax in zip(vtx, -phi, axs):
        kabamland.add_solid(face,
                            rotation=make_rotation_matrix(ph, ax),
                            displacement=-normalize(vx) *
                            (np.linalg.norm(vx) + focal_length))
예제 #12
0
def build_pmt_icosahedron(kabamland, vtx, focal_length=1.0):
    offset = 1.2 * (vtx + focal_length)
    angles = np.linspace(np.pi / 4, 2 * np.pi + np.pi / 4, 4, endpoint=False)
    square = make.linear_extrude(offset * np.sqrt(2) * np.cos(angles),
                                 offset * np.sqrt(2) * np.sin(angles), 2.0)
    vrs = np.eye(3)
    for vr in vrs:
        if np.array_equal(vr, [0, 0, 1]):
            kabamland.add_pmt(Solid(square, glass, kabamland.detector_material,
                                    lm.fullabsorb, 0xBBFFFFFF),
                              displacement=offset * vr)
            kabamland.add_pmt(Solid(square, glass, kabamland.detector_material,
                                    lm.fullabsorb, 0xBBFFFFFF),
                              displacement=-offset * vr)
        else:
            trasl = np.cross(vr, [0, 0, 1])
            kabamland.add_pmt(Solid(square, glass, kabamland.detector_material,
                                    lm.fullabsorb, 0xBBFFFFFF),
                              rotation=make_rotation_matrix(np.pi / 2, vr),
                              displacement=offset * trasl)
            kabamland.add_pmt(Solid(square, glass, kabamland.detector_material,
                                    lm.fullabsorb, 0xBBFFFFFF),
                              rotation=make_rotation_matrix(np.pi / 2, vr),
                              displacement=-offset * trasl)
예제 #13
0
파일: camera.py 프로젝트: wcgillis01/chroma
    def render_vertex(
        self,
        geometry,
        vertex,
        children=2,
        sz=5.0,
        colors={
            'mu+': 0x50E0FF,
            'mu-': 0xFFE050,
            'e+': 0x0000FF,
            'e-': 0xFF0000,
            'gamma': 0x00FF00
        }):
        steps = np.vstack((vertex.steps.x, vertex.steps.y, vertex.steps.z)).T
        for index in range(len(steps) - 1):
            vec = steps[index + 1] - steps[index]
            mag = np.linalg.norm(vec)
            u = vec / mag
            axis = np.cross(u, [0, 0, 1])
            ang = np.arccos(np.dot(u, [0, 0, 1]))
            rotmat = make_rotation_matrix(ang, axis)
            x = sz / 2
            y = x * np.sqrt(3) / 2
            segment = make.linear_extrude([-x, 0, x], [-y, y, -y], mag,
                                          [0, 0, 0], [0, 0, 0])
            segment.vertices[:, 2] += mag / 2.0
            marker = Solid(segment,
                           vacuum,
                           vacuum,
                           color=colors[vertex.particle_name]
                           if vertex.particle_name in colors else 0xAAAAAA)
            geometry.add_solid(marker,
                               displacement=steps[index],
                               rotation=rotmat)

        if children and vertex.children:
            for child in vertex.children:
                if isinstance(children, bool):
                    self.render_vertex(geometry, child, children)
                else:
                    self.render_vertex(geometry, child, children - 1)
예제 #14
0
def PlotBlocker(radius, height):
    nsteps = 30
    x_value = np.linspace(radius, radius + 200, nsteps)
    y_value = [0] * nsteps

    blocker = make.rotate_extrude(x_value, y_value, nsteps)
    blocker = mh.rotate(blocker, make_rotation_matrix(+np.pi / 2, (1, 0, 0)))
    blocker = mh.shift(blocker, (0, 0, height))

    blocker_triangles = blocker.get_triangle_centers()
    blocker_vertices = blocker.assemble()

    X = blocker_vertices[:, :, 0].flatten()
    Y = blocker_vertices[:, :, 1].flatten()
    Z = blocker_vertices[:, :, 2].flatten()

    trianglesblocker = [[3 * ii, 3 * ii + 1, 3 * ii + 2]
                        for ii in range(len(X) / 3)]
    triang = Triangulation(X, Y, trianglesblocker)

    return triang, Z
예제 #15
0
파일: camera.py 프로젝트: BenLand100/chroma
    def render_particle_track(self):
        x = 10.0
        h = x*np.sqrt(3)/2
        pyramid = make.linear_extrude([-x/2,0,x/2], [-h/2,h/2,-h/2], h,
                                      [0]*3, [0]*3)
        marker = Solid(pyramid, vacuum, vacuum)

        if self.photon_display_mode == 'beg':
            photons = self.ev.photons_beg
        else:
            photons = self.ev.photons_end

        geometry = Geometry()
        sample_factor = max(1, len(photons.pos) / 10000)
        for pos in photons.pos[::sample_factor]:
            geometry.add_solid(marker, displacement=pos, rotation=make_rotation_matrix(np.random.uniform(0,2*np.pi), uniform_sphere()))

        geometry = create_geometry_from_obj(geometry)
        gpu_geometry = gpu.GPUGeometry(geometry)

        self.gpu_geometries = [self.gpu_geometry, gpu_geometry]
예제 #16
0
def build_kabamland(kabamland, configname):
    # focal_length sets dist between lens plane and PMT plane (or back of curved detecting surface);
    #(need not equal true lens focal length)
    config = detectorconfig.configdict(configname)

    _, lens = kb.get_lens_triangle_centers(
        config.edge_length,
        config.base,
        config.diameter_ratio,
        config.thickness_ratio,
        config.half_EPD,
        config.blockers,
        blocker_thickness_ratio=config.blocker_thickness_ratio,
        light_confinement=config.light_confinement,
        focal_length=config.focal_length,
        lens_system_name=config.lens_system_name)
    surf = mh.rotate(
        kb.curved_surface2(config.detector_r,
                           diameter=2 *
                           kb.find_max_radius(config.edge_length, config.base),
                           nsteps=9),
        make_rotation_matrix(-np.pi / 2, (1, 0, 0)))
    surf = mh.shift(surf, (0, 0, -config.focal_length))
    kabamland.add_solid(Solid(surf, lm.ls, lm.ls, lm.fulldetect, 0x0000FF),
                        rotation=None,
                        displacement=(0, 0, 0))
    kabamland.add_solid(Solid(lens, lm.lensmat, lm.ls),
                        rotation=None,
                        displacement=None)

    blocker = BuildBlocker(
        np.max(lens.assemble()[:, :, 0].flatten()),
        lens.assemble()[:, :,
                        2].flatten()[np.argmax(lens.assemble()[:, :,
                                                               0].flatten())])
    kabamland.add_solid(Solid(blocker, lm.ls, lm.ls, lm.fullabsorb, 0x0000FF),
                        rotation=None,
                        displacement=(0, 0, 0))
    kabamland.channel_index_to_channel_id = [1]
    return lens, surf
예제 #17
0
def build_lens_icosahedron(kabamland,
                           vtx,
                           rad,
                           diameter_ratio,
                           thickness_ratio,
                           half_EPD,
                           blockers=True,
                           blocker_thickness_ratio=1.0 / 1000,
                           light_confinement=False,
                           focal_length=1.0,
                           lens_system_name=None):
    """input edge length of icosahedron 'edge_length',
       the number of small triangles in the base of each face 'base',
       the ratio of the diameter of each lens to the maximum diameter possible 'diameter_ratio' (or the fraction of the default such ratio,
       if a curved detector lens system), the ratio of the thickness of the lens to the chosen (not maximum) diameter 'thickness_ratio',
       the radius of the blocking entrance pupil 'half_EPD',
       and the ratio of the thickness of the blockers to that of the lenses 'blocker_thickness_ratio'
       to return the icosahedron of lenses in kabamland. Light_confinment=True adds cylindrical shells behind each lens that absorb all the light that touches them,
       so that light doesn't overlap between lenses. If lens_system_name is a string that matches one of the lens systems in lenssystem.py,
       the corresponding lenses and detectors will be built. Otherwise, a default simple lens will be built, with parameters hard-coded below.
    """
    # Get the list of lens meshes from the appropriate lens system as well as the lens material'''
    scale_rad = rad * diameter_ratio  #max_radius->rad of the lens assembly
    lenses = lenssystem.get_lens_mesh_list(lens_system_name, scale_rad)
    lensmat = lenssystem.get_lens_material(lens_system_name)
    face = None
    for lns in lenses:
        #lns = mh.rotate(lns,make_rotation_matrix(ph,ax))
        if not face:
            face = Solid(lns, lensmat, kabamland.detector_material)
        else:
            face += Solid(lns, lensmat, kabamland.detector_material)

    if light_confinement:
        shield = mh.rotate(
            cylindrical_shell(rad * (1 - 0.001), rad, focal_length, 32),
            make_rotation_matrix(np.pi / 2.0, (1, 0, 0)))
        baffle = Solid(shield, lensmat, kabamland.detector_material,
                       black_surface, 0xff0000)

    if blockers:
        blocker_thickness = 2 * rad * blocker_thickness_ratio
        if half_EPD < rad:
            c1 = lenssystem.get_lens_sys(
                lens_system_name).c1 * lenssystem.get_scale_factor(
                    lens_system_name, scale_rad)
            offset = [0, 0, c1 - np.sqrt(c1 * c1 - rad * rad)]
            anulus_blocker = mh.shift(
                mh.rotate(
                    cylindrical_shell(half_EPD, rad, blocker_thickness, 32),
                    make_rotation_matrix(np.pi / 2.0, (1, 0, 0))), offset)
            face += Solid(anulus_blocker, lensmat, kabamland.detector_material,
                          black_surface, 0xff0000)
    phi, axs = rot_axis([0, 0, 1], vtx)
    for vx, ph, ax in zip(vtx, -phi, axs):
        kabamland.add_solid(face,
                            rotation=make_rotation_matrix(ph, ax),
                            displacement=-vx)
        if light_confinement:
            kabamland.add_solid(baffle,
                                rotation=make_rotation_matrix(ph, ax),
                                displacement=-normalize(vx) *
                                (np.linalg.norm(vx) + focal_length / 2.0))