diff options
| -rw-r--r-- | __init__.py | 6 | ||||
| -rw-r--r-- | color/chromaticity.py (renamed from chromaticity.py) | 1 | ||||
| -rw-r--r-- | color/ciexyz64_1.csv (renamed from ciexyz64_1.csv) | 0 | ||||
| -rw-r--r-- | color/sbrgb10w.csv (renamed from sbrgb10w.csv) | 0 | ||||
| -rw-r--r-- | detectors/lbne.py | 72 | ||||
| -rw-r--r-- | geometry.py | 158 | ||||
| -rw-r--r-- | make.py | 14 | ||||
| -rw-r--r-- | materials/OPTICS.ratdb (renamed from OPTICS.ratdb) | 0 | ||||
| -rw-r--r-- | materials/__init__.py (renamed from materials.py) | 43 | ||||
| -rw-r--r-- | materials/ratdb.py (renamed from ratdb.py) | 0 | ||||
| -rw-r--r-- | solid.py | 49 | ||||
| -rw-r--r-- | solids/__init__.py | 1 | ||||
| -rw-r--r-- | solids/r7081.py | 29 | ||||
| -rw-r--r-- | stl.py (renamed from mesh.py) | 31 | ||||
| -rwxr-xr-x | view.py | 19 | ||||
| -rw-r--r-- | viewpmt.py | 30 | 
16 files changed, 203 insertions, 250 deletions
| diff --git a/__init__.py b/__init__.py index f6d25eb..e69de29 100644 --- a/__init__.py +++ b/__init__.py @@ -1,6 +0,0 @@ -import geometry -import materials -import transform -import stl -import photon -import likelihood diff --git a/chromaticity.py b/color/chromaticity.py index 4080496..6229b51 100644 --- a/chromaticity.py +++ b/color/chromaticity.py @@ -1,6 +1,5 @@  import numpy as np -#f = open('ciexyz64_1.csv')  f = open('sbrgb10w.csv')  color_map = [] diff --git a/ciexyz64_1.csv b/color/ciexyz64_1.csv index f437db7..f437db7 100644 --- a/ciexyz64_1.csv +++ b/color/ciexyz64_1.csv diff --git a/sbrgb10w.csv b/color/sbrgb10w.csv index b654ad3..b654ad3 100644 --- a/sbrgb10w.csv +++ b/color/sbrgb10w.csv diff --git a/detectors/lbne.py b/detectors/lbne.py index a439682..7f1bb41 100644 --- a/detectors/lbne.py +++ b/detectors/lbne.py @@ -6,13 +6,12 @@ dir = os.path.split(os.path.realpath(__file__))[0]  sys.path.append(dir + '/..')  import models -from mesh import mesh_from_stl -from solid import Solid -from geometry import Geometry +from geometry import * +from materials import * +from solids import *  from transform import rotate, make_rotation_matrix  from itertools import product -from materials import * -from make import cylinder +import make  endcap_spacing = .485 @@ -27,46 +26,19 @@ class LBNE(Geometry):          super(LBNE, self).__init__()          # outer cylinder -        cylinder_solid = Solid(0, cylinder(radius, height+height/(pmts_per_string-1)), material1=lightwater_sno, material2=vacuum, surface=black_surface, color=0x0000ff) +        cylinder_mesh = \ +            make.cylinder(radius, height+height/(pmts_per_string-1)) +        cylinder_solid = Solid(cylinder_mesh, lightwater_sno, vacuum, black_surface, 0x0000ff)          self.add_solid(cylinder_solid) -        pmt_inner_mesh = \ -            mesh_from_stl(models.dir + '/hamamatsu_12inch_inner.stl') -        pmt_outer_mesh = \ -            mesh_from_stl(models.dir + '/hamamatsu_12inch_outer.stl') - -        photocathode_triangles = np.mean(pmt_inner_mesh[:], axis=1)[:,1] > 0 - -        inner_color = np.empty(len(pmt_inner_mesh.triangles), np.uint32) -        inner_color[photocathode_triangles] = 0xff0000 -        inner_color[~photocathode_triangles] = 0x00ff00 - -        outer_color = np.empty(len(pmt_outer_mesh.triangles), np.uint32) -        outer_color[:] = 0xffffff - -        inner_surface = np.empty(len(pmt_inner_mesh.triangles), np.object) -        inner_surface[photocathode_triangles] = black_surface -        inner_surface[~photocathode_triangles] = shiny_surface - -        self.pmtids = [1] +        self.pmtids = []          # construct the barrel          for i in range(pmts_per_string):              for j in range(nstrings):                  rotation = make_rotation_matrix(j*2*np.pi/nstrings, (0,0,1))                  displacement = rotate((0,-radius,-height/2+i*height/(pmts_per_string-1)), j*2*np.pi/nstrings, (0,0,1)) -                self.add_solid(Solid(self.pmtids[-1], pmt_inner_mesh, -                                     rotation, displacement, -                                     material1=vacuum, -                                     material2=glass, -                                     surface=inner_surface, -                                     color=inner_color)) -                self.add_solid(Solid(self.pmtids[-1], pmt_outer_mesh, -                                     rotation, displacement, -                                     material1=glass, -                                     material2=lightwater_sno, -                                     color=outer_color)) -                self.pmtids += [self.pmtids[-1]+1] +                self.pmtids.append(self.add_solid(r7081, rotation, displacement))          # construct the top endcap          for x, y in np.array(tuple(product(\ @@ -75,18 +47,7 @@ class LBNE(Geometry):              if np.sqrt(x**2 + y**2) <= radius:                  rotation = make_rotation_matrix(+np.pi/2, (1,0,0))                  displacement = (x,y,+height/2+height/(pmts_per_string-1)/2) -                self.add_solid(Solid(self.pmtids[-1], pmt_inner_mesh, -                                     rotation, displacement, -                                     material1=vacuum, -                                     material2=glass, -                                     surface=inner_surface, -                                     color=inner_color)) -                self.add_solid(Solid(self.pmtids[-1], pmt_outer_mesh, -                                     rotation, displacement, -                                     material1=glass, -                                     material2=lightwater_sno, -                                     color=outer_color)) -                self.pmtids += [self.pmtids[-1]+1] +                self.pmtids.append(self.add_solid(r7081, rotation, displacement))          # construct the bottom endcap          for x, y in np.array(tuple(product(\ @@ -95,15 +56,4 @@ class LBNE(Geometry):              if np.sqrt(x**2 + y**2) <= radius:                  rotation = make_rotation_matrix(-np.pi/2, (1,0,0))                  displacement = (x,y,-height/2-height/(pmts_per_string-1)/2) -                self.add_solid(Solid(self.pmtids[-1], pmt_inner_mesh, -                                     rotation, displacement, -                                     material1=vacuum, -                                     material2=glass, -                                     surface=inner_surface, -                                     color=inner_color)) -                self.add_solid(Solid(self.pmtids[-1], pmt_outer_mesh, -                                     rotation, displacement, -                                     material1=glass, -                                     material2=lightwater_sno, -                                     color=outer_color)) -                self.pmtids += [self.pmtids[-1]+1] +                self.pmtids.append(self.add_solid(r7081, rotation, displacement)) diff --git a/geometry.py b/geometry.py index 5cd1bf2..be31e4b 100644 --- a/geometry.py +++ b/geometry.py @@ -1,9 +1,117 @@  import numpy as np -import numpy.ma as ma  import pycuda.driver as cuda  from pycuda import gpuarray -from mesh import Mesh -from materials import standard_wavelengths + +# all material/surface properties are interpolated at these +# wavelengths when they are sent to the gpu +standard_wavelengths = np.arange(200, 810, 20).astype(np.float32) + +class Mesh(object): +    def __init__(self, vertices, triangles): +        vertices = np.asarray(vertices, dtype=np.float32) +        triangles = np.asarray(triangles, dtype=np.int32) + +        if len(vertices.shape) != 2 or vertices.shape[1] != 3: +            raise ValueError('shape mismatch') + +        if len(triangles.shape) != 2 or triangles.shape[1] != 3: +            raise ValueError('shape mismatch') + +        if (triangles < 0).any(): +            raise ValueError('indices in `triangles` must be positive.') + +        if (triangles >= len(vertices)).any(): +            raise ValueError('indices in `triangles` must be less than the ' +                             'length of the vertex array.') + +        self.vertices = vertices +        self.triangles = triangles + +    def build(self): +        return self.vertices[self.triangles] + +    def __getitem__(self, key): +        return self.vertices[self.triangles[key]] + +    def __len__(self): +        return len(self.triangles) + +    def __add__(self, other): +        return Mesh(np.concatenate((self.vertices, other.vertices)), np.concatenate((self.triangles, other.triangles + len(self.vertices)))) + +class Solid(object): +    def __init__(self, mesh, material1=None, material2=None, surface=None, color=0xffffffff): +        self.mesh = mesh + +        if np.iterable(material1): +            if len(material1) != len(mesh): +                raise ValueError('shape mismatch') +            self.material1 = np.array(material1, dtype=np.object) +        else: +            self.material1 = np.tile(material1, len(self.mesh)) + +        if np.iterable(material2): +            if len(material2) != len(mesh): +                raise ValueError('shape mismatch') +            self.material2 = np.array(material2, dtype=np.object) +        else: +            self.material2 = np.tile(material2, len(self.mesh)) + +        if np.iterable(surface): +            if len(surface) != len(mesh): +                raise ValueError('shape mismatch') +            self.surface = np.array(surface, dtype=np.object) +        else: +            self.surface = np.tile(surface, len(self.mesh)) + +        if np.iterable(color): +            if len(color) != len(mesh): +                raise ValueError('shape mismatch') +            self.color = np.array(color, dtype=np.uint32) +        else: +            self.color = np.tile(color, len(self.mesh)).astype(np.uint32) + +    def __len__(self): +        return len(self.mesh) + +    def __add__(self, other): +        return Solid(self.mesh + other.mesh, np.concatenate((self.material1, other.material1)), np.concatenate((self.material2, other.material2)), np.concatenate((self.surface, other.surface)), np.concatenate((self.color, other.color))) + +class Material(object): +    """Material optical properties.""" +    def __init__(self, name='none'): +        self.name = name + +        self.refractive_index = None +        self.absorption_length = None +        self.scattering_length = None + +    def set(self, name, value, wavelengths=standard_wavelengths): +        if np.iterable(value): +            if len(value) != len(wavelengths): +                raise ValueError('shape mismatch') +        else: +            value = np.tile(value, len(wavelengths)) + +        self.__dict__[name] = np.array(zip(wavelengths, value), dtype=np.float32) + +class Surface(object): +    """Surface optical properties.""" +    def __init__(self, name='none'): +        self.name = name + +        self.absorption = None +        self.reflection_diffuse = None +        self.reflection_specular = None + +    def set(self, name, value, wavelengths=standard_wavelengths): +        if np.iterable(value): +            if len(value) != len(wavelengths): +                raise ValueError('shape mismatch') +        else: +            value = np.tile(value, len(wavelengths)) + +        self.__dict__[name] = np.array(zip(wavelengths, value), dtype=np.float32)  def interleave(arr, bits):      """ @@ -51,15 +159,30 @@ def morton_order(mesh, bits):      return interleave(mean_positions, bits)  class Geometry(object): -    def __init__(self, solids=None): -        if solids is not None: -            self.solids = list(solids) -        else: -            self.solids = [] +    def __init__(self): +        self.solids = [] +        self.solid_rotations = [] +        self.solid_displacements = [] + +    def add_solid(self, solid, rotation=np.identity(3), displacement=(0,0,0)): +        rotation = np.asarray(rotation, dtype=np.float32) + +        if rotation.shape != (3,3): +            raise ValueError('shape mismatch') + +        self.solid_rotations.append(rotation.astype(np.float32)) + +        displacement = np.asarray(displacement, dtype=np.float32) + +        if displacement.shape != (3,): +            raise ValueError('shape mismatch') + +        self.solid_displacements.append(displacement) -    def add_solid(self, solid):          self.solids.append(solid) +        return len(self.solids)-1 +      def build(self, bits=8):          offsets = [ (0,0) ]          for solid in self.solids: @@ -69,15 +192,14 @@ class Geometry(object):          vertices = np.zeros(shape=(offsets[-1][0], 3), dtype=np.float32)          triangles = np.zeros(shape=(offsets[-1][1],3), dtype=np.int32) -        for solid, (vertex_offset, triangle_offset) in zip(self.solids, offsets[:-1]): +        for i, (solid, (vertex_offset, triangle_offset)) in \ +                enumerate(zip(self.solids, offsets[:-1])):              triangles[triangle_offset:triangle_offset+len(solid.mesh.triangles),:] = \                  solid.mesh.triangles + vertex_offset -            vertices[vertex_offset:vertex_offset + len(solid.mesh.vertices),:] = \ -                np.inner(solid.mesh.vertices, solid.rotation) + solid.displacement +            vertices[vertex_offset:vertex_offset+len(solid.mesh.vertices),:] = \ +                np.inner(solid.mesh.vertices, self.solid_rotations[i]) + self.solid_displacements[i]          self.mesh = Mesh(vertices, triangles) -        #del vertices -        #del triangles          zvalues_mesh = morton_order(self.mesh[:], bits)          reorder = np.argsort(zvalues_mesh) @@ -121,10 +243,12 @@ class Geometry(object):              else:                  self.surface_index[i] = -1 -        self.colors = np.concatenate([solid.color for solid in self.solids])[reorder] +        self.colors = \ +            np.concatenate([solid.color for solid in self.solids])[reorder] -        self.solid_id = np.concatenate([np.tile(solid.id, len(solid.mesh)) \ -                                            for solid in self.solids])[reorder] +        self.solid_id = \ +            np.concatenate([np.tile(i, len(solid.mesh)) for i, solid in \ +                                enumerate(self.solids)])[reorder]          unique_zvalues = np.unique(zvalues_mesh)          zvalues = np.empty(unique_zvalues.size, dtype=np.uint64) @@ -1,5 +1,5 @@  import numpy as np -from mesh import Mesh +from geometry import Mesh  def cylinder(radius=1.0, height=1.0, theta=np.pi/32):      angles = np.arange(0, 2*np.pi, theta) @@ -41,15 +41,3 @@ def cylinder(radius=1.0, height=1.0, theta=np.pi/32):          np.roll(np.arange(len(angles)),1)      return Mesh(vertices, triangles) - -if __name__ == '__main__': -    from solid import Solid -    from geometry import Geometry -    from view import view - -    cylinder_mesh = cylinder() -    cylinder_solid = Solid(0, cylinder_mesh) -    geometry = Geometry([cylinder_solid]) -    geometry.build(bits=8) - -    view(geometry) diff --git a/OPTICS.ratdb b/materials/OPTICS.ratdb index c7551a5..c7551a5 100644 --- a/OPTICS.ratdb +++ b/materials/OPTICS.ratdb diff --git a/materials.py b/materials/__init__.py index 9feb866..d2644ad 100644 --- a/materials.py +++ b/materials/__init__.py @@ -1,43 +1,12 @@ +import os +import sys  import numpy as np  from ratdb import load -standard_wavelengths = np.arange(200, 810, 20).astype(np.float32) +dir = os.path.split(os.path.realpath(__file__))[0] +sys.path.append(dir + '/..') -class Material(object): -    """Material optical properties.""" -    def __init__(self, name='none'): -        self.name = name - -        self.refractive_index = None -        self.absorption_length = None -        self.scattering_length = None - -    def set(self, name, value, wavelengths=standard_wavelengths): -        if np.iterable(value): -            if len(value) != len(wavelengths): -                raise ValueError('shape mismatch') -        else: -            value = np.tile(value, len(wavelengths)) - -        self.__dict__[name] = np.array(zip(wavelengths, value), dtype=np.float32) - -class Surface(object): -    """Surface optical properties.""" -    def __init__(self, name='none'): -        self.name = name - -        self.absorption = None -        self.reflection_diffuse = None -        self.reflection_specular = None - -    def set(self, name, value, wavelengths=standard_wavelengths): -        if np.iterable(value): -            if len(value) != len(wavelengths): -                raise ValueError('shape mismatch') -        else: -            value = np.tile(value, len(wavelengths)) - -        self.__dict__[name] = np.array(zip(wavelengths, value), dtype=np.float32) +from geometry import Material, Surface  vacuum = Material('vacuum')  vacuum.set('refractive_index', 1) @@ -59,7 +28,7 @@ shiny_surface.set('absorption', 0)  shiny_surface.set('reflection_specular', 1)  shiny_surface.set('reflection_diffuse', 0) -db = load(open('OPTICS.ratdb'))['OPTICS'] +db = load(open(dir + '/OPTICS.ratdb'))['OPTICS']  glass = Material('pmt_glass')  glass.set('refractive_index', db['glass']['RINDEX_value2'], db['glass']['RINDEX_value1']) diff --git a/ratdb.py b/materials/ratdb.py index 2b14761..2b14761 100644 --- a/ratdb.py +++ b/materials/ratdb.py diff --git a/solid.py b/solid.py deleted file mode 100644 index 707a786..0000000 --- a/solid.py +++ /dev/null @@ -1,49 +0,0 @@ -import numpy as np - -class Solid(object): -    def __init__(self, id, mesh, rotation=np.identity(3), displacement=(0,0,0), material1=None, material2=None, surface=None, color=0xffffffff): -        self.id = id -        self.mesh = mesh - -        if rotation.shape != (3,3): -            raise ValueError('shape mismatch') - -        self.rotation = rotation.astype(np.float32) - -        displacement = np.asarray(displacement, dtype=np.float32) - -        if displacement.shape != (3,): -            raise ValueError('shape mismatch') - -        self.displacement = displacement - -        if np.iterable(material1): -            if len(material1) != len(mesh): -                raise ValueError('shape mismatch') -            self.material1 = np.array(material1, dtype=np.object) -        else: -            self.material1 = np.tile(material1, len(self.mesh)) - -        if np.iterable(material2): -            if len(material2) != len(mesh): -                raise ValueError('shape mismatch') -            self.material2 = np.array(material2, dtype=np.object) -        else: -            self.material2 = np.tile(material2, len(self.mesh)) - -        if np.iterable(surface): -            if len(surface) != len(mesh): -                raise ValueError('shape mismatch') -            self.surface = np.array(surface, dtype=np.object) -        else: -            self.surface = np.tile(surface, len(self.mesh)) - -        if np.iterable(color): -            if len(color) != len(mesh): -                raise ValueError('shape mismatch') -            self.color = np.array(color, dtype=np.uint32) -        else: -            self.color = np.tile(color, len(self.mesh)).astype(np.uint32) - -    def __len__(self): -        return len(self.mesh) diff --git a/solids/__init__.py b/solids/__init__.py new file mode 100644 index 0000000..f01d97f --- /dev/null +++ b/solids/__init__.py @@ -0,0 +1 @@ +from r7081 import r7081 diff --git a/solids/r7081.py b/solids/r7081.py new file mode 100644 index 0000000..f91c2ab --- /dev/null +++ b/solids/r7081.py @@ -0,0 +1,29 @@ +import os +import sys +import numpy as np + +dir = os.path.split(os.path.realpath(__file__))[0] +sys.path.append(dir + '/..') + +import models +from mesh import mesh_from_stl +from geometry import * +from materials import * + +r7081_outer_mesh = mesh_from_stl(models.dir + '/hamamatsu_12inch_outer.stl') +r7081_inner_mesh = mesh_from_stl(models.dir + '/hamamatsu_12inch_inner.stl') + +photocathode_triangles = np.mean(r7081_inner_mesh[:], axis=1)[:,1] > 0 + +inner_color = np.empty(len(r7081_inner_mesh.triangles), np.uint32) +inner_color[photocathode_triangles] = 0xff0000 +inner_color[~photocathode_triangles] = 0x00ff00 + +inner_surface = np.empty(len(r7081_inner_mesh.triangles), np.object) +inner_surface[photocathode_triangles] = black_surface +inner_surface[~photocathode_triangles] = shiny_surface + +r7081_inner_solid = Solid(r7081_inner_mesh, vacuum, glass, inner_surface, color=inner_color) +r7081_outer_solid = Solid(r7081_outer_mesh, glass, lightwater_sno) + +r7081 = r7081_inner_solid + r7081_outer_solid @@ -1,36 +1,7 @@  import numpy as np  import string  import struct - -class Mesh(object): -    def __init__(self, vertices, triangles): -        vertices = np.asarray(vertices, dtype=np.float32) -        triangles = np.asarray(triangles, dtype=np.int32) - -        if len(vertices.shape) != 2 or vertices.shape[1] != 3: -            raise ValueError('shape mismatch') - -        if len(triangles.shape) != 2 or triangles.shape[1] != 3: -            raise ValueError('shape mismatch') - -        if (triangles < 0).any(): -            raise ValueError('indices in `triangles` must be positive.') - -        if (triangles >= len(vertices)).any(): -            raise ValueError('indices in `triangles` must be less than the ' -                             'length of the vertex array.') - -        self.vertices = vertices -        self.triangles = triangles - -    def build(self): -        return self.vertices[self.triangles] - -    def __getitem__(self, key): -        return self.vertices[self.triangles[key]] - -    def __len__(self): -        return len(self.triangles) +from geometry import Mesh  def mesh_from_stl(filename):      f = open(filename) @@ -6,7 +6,6 @@ from pygame.locals import *  import src  from camera import * -from solid import *  from geometry import *  from transform import * @@ -182,6 +181,8 @@ if __name__ == '__main__':      import optparse      from mesh import * + +    import solids      import detectors      parser = optparse.OptionParser('%prog filename.stl') @@ -197,20 +198,26 @@ if __name__ == '__main__':      if ext.lower() == '.stl':          geometry = Geometry() -        geometry.add_solid(Solid(0, mesh_from_stl(args[0]))) +        geometry.add_solid(Solid(mesh_from_stl(args[0])))          geometry.build(options.bits)          view(geometry, tail)      else:          import inspect -        members = dict(inspect.getmembers(detectors)) +        members = dict(inspect.getmembers(detectors) + inspect.getmembers(solids))          if args[0] in members: -            if issubclass(members[args[0]], Geometry): +            if type(members[args[0]]) is type and \ +                    issubclass(members[args[0]], Geometry):                  geometry = members[args[0]]()                  geometry.build(options.bits)                  view(geometry, args[0]) +            elif isinstance(members[args[0]], Solid): +                geometry = Geometry() +                geometry.add_solid(members[args[0]]) +                geometry.build(options.bits) +                view(geometry, args[0])              else: -                sys.exit("%s doesn't inherit from a Geometry object" % args[0]) +                sys.exit("can't display %s" % args[0])          else: -            sys.exit("couldn't find a geometry with name %s" % args[0]) +            sys.exit("couldn't find object %s" % args[0]) diff --git a/viewpmt.py b/viewpmt.py deleted file mode 100644 index 474b6d8..0000000 --- a/viewpmt.py +++ /dev/null @@ -1,30 +0,0 @@ -import numpy as np -from solid import Solid -from mesh import mesh_from_stl -from geometry import Geometry -from view import view -import models - -pmt_inner_mesh = \ -    mesh_from_stl(models.dir + '/hamamatsu_12inch_inner.stl') -pmt_outer_mesh = \ -    mesh_from_stl(models.dir + '/hamamatsu_12inch_outer.stl') - -pmt_outer_mesh.triangles = \ -    pmt_outer_mesh.triangles[np.mean(pmt_outer_mesh[:], axis=1)[:,0] > 0] - -photocathode_triangles = np.mean(pmt_inner_mesh[:], axis=1)[:,1] > 0 - -inner_color = np.empty(len(pmt_inner_mesh.triangles), np.uint32) -inner_color[photocathode_triangles] = 0xff0000 -inner_color[~photocathode_triangles] = 0x00ff00 - -outer_color = np.empty(len(pmt_outer_mesh.triangles), np.uint32) -outer_color[:] = 0xffffff - -geometry = Geometry([Solid(0, pmt_inner_mesh, color=inner_color), -                     Solid(1, pmt_outer_mesh, color=outer_color)]) - -geometry.build(bits=8) - -view(geometry) | 
