diff options
author | Anthony LaTorre <devnull@localhost> | 2013-01-01 19:08:43 -0600 |
---|---|---|
committer | tlatorre <tlatorre@uchicago.edu> | 2021-05-09 08:42:39 -0700 |
commit | 07dcc0971c435f7e0068a6c28dbeaf14349e1beb (patch) | |
tree | 14ecb96278023ab66e72529ed6cf4bf354d06440 /doc/source | |
parent | ac4bdcae5a79a239f5e6086d998ce41ba202457e (diff) | |
download | chroma-07dcc0971c435f7e0068a6c28dbeaf14349e1beb.tar.gz chroma-07dcc0971c435f7e0068a6c28dbeaf14349e1beb.tar.bz2 chroma-07dcc0971c435f7e0068a6c28dbeaf14349e1beb.zip |
add a simple example script to produce a detector and simulate some events.
Diffstat (limited to 'doc/source')
-rw-r--r-- | doc/source/example_detector.py | 152 | ||||
-rw-r--r-- | doc/source/examples.rst | 7 | ||||
-rw-r--r-- | doc/source/index.rst | 1 |
3 files changed, 160 insertions, 0 deletions
diff --git a/doc/source/example_detector.py b/doc/source/example_detector.py new file mode 100644 index 0000000..d2026b8 --- /dev/null +++ b/doc/source/example_detector.py @@ -0,0 +1,152 @@ +from chroma import make, view +from chroma.geometry import Solid, Geometry +from chroma.transform import make_rotation_matrix +from chroma.demo.optics import glass, water, vacuum, r7081hqe_photocathode +from chroma.demo.optics import black_surface +import numpy as np + +def build_pd(size, glass_thickness): + """Returns a simple photodetector Solid. The photodetector is a cube of + size `size` constructed out of a glass envelope with a photosensitive + face on the inside of the glass envelope facing up.""" + # outside of the glass envelope + outside_mesh = make.cube(size) + # inside of the glass envelope + inside_mesh = make.cube(size-glass_thickness*2) + + # outside solid with water on the outside, and glass on the inside + outside_solid = Solid(outside_mesh,glass,water) + + # now we need to determine the triangles which make up + # the top face of the inside mesh, because we are going to place + # the photosensitive surface on these triangles + # do this by seeing which triangle centers are at the maximum z + # coordinate + z = inside_mesh.get_triangle_centers()[:,2] + top = z == max(z) + + # see np.where() documentation + # Here we make the photosensitive surface along the top face of the inside + # mesh. The rest of the inside mesh is perfectly absorbing. + inside_surface = np.where(top,r7081hqe_photocathode,black_surface) + inside_color = np.where(top,0x00ff00,0x33ffffff) + + # construct the inside solid + inside_solid = Solid(inside_mesh,vacuum,glass,surface=inside_surface, + color=inside_color) + + # you can add solids and meshes! + return outside_solid + inside_solid + +def iter_box(nx,ny,nz,spacing): + """Yields (position, direction) tuple for a series of points along the + boundary of a box. Will yield nx points along the x axis, ny along the y + axis, and nz along the z axis. `spacing` is the spacing between the points. + """ + dx, dy, dz = spacing*(np.array([nx,ny,nz])-1) + + # sides + for z in np.linspace(-dz/2,dz/2,nz): + for x in np.linspace(-dx/2,dx/2,nx): + yield (x,-dy/2,z), (0,1,0) + for y in np.linspace(-dy/2,dy/2,ny): + yield (dx/2,y,z), (-1,0,0) + for x in np.linspace(dx/2,-dx/2,nx): + yield (x,dy/2,z), (0,-1,0) + for y in np.linspace(dy/2,-dy/2,ny): + yield (-dx/2,y,z), (1,0,0) + + # bottom and top + for x in np.linspace(-dx/2,dx/2,nx)[1:-1]: + for y in np.linspace(-dy/2,dy/2,ny)[1:-1]: + # bottom + yield (x,y,-dz/2), (0,0,1) + # top + yield (x,y,dz/2), (0,0,-1) + +size = 100 +glass_thickness = 10 + +nx, ny, nz = 20, 20, 20 + +spacing = size*2 + +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 + +if __name__ == '__main__': + from chroma.sim import Simulation + from chroma.sample import uniform_sphere + from chroma.event import Photons + from chroma.loader import load_bvh + from chroma.generator import vertex + import matplotlib.pyplot as plt + + g = build_detector() + g.flatten() + g.bvh = load_bvh(g) + + sim = Simulation(g) + + # photon bomb from center + def photon_bomb(n,wavelength,pos): + pos = np.tile(pos,(n,1)) + dir = uniform_sphere(n) + pol = np.cross(dir,uniform_sphere(n)) + wavelengths = np.repeat(wavelength,n) + return Photons(pos,dir,pol,wavelengths) + + # write it to a root file + from chroma.io.root import RootWriter + f = RootWriter('test.root') + + # sim.simulate() always returns an iterator even if we just pass + # a single photon bomb + for ev in sim.simulate([photon_bomb(1000,400,(0,0,0))], + keep_photons_beg=True,keep_photons_end=True, + run_daq=False,max_steps=100): + # write the python event to a root file + f.write_event(ev) + + # simulate some electrons! + gun = vertex.particle_gun(['e-']*10, + vertex.constant((0,0,0)), + vertex.isotropic(), + vertex.flat(500,1000)) + + for ev in sim.simulate(gun,keep_photons_beg=True,keep_photons_end=True, + run_daq=False,max_steps=100): + f.write_event(ev) + + detected = (ev.photons_end.flags & (0x1 << 2)).astype(bool) + + plt.hist(ev.photons_end.t[detected],100) + plt.xlabel('Time (ns)') + plt.title('Photon Hit Times') + plt.show() + + f.close() diff --git a/doc/source/examples.rst b/doc/source/examples.rst new file mode 100644 index 0000000..0b7827b --- /dev/null +++ b/doc/source/examples.rst @@ -0,0 +1,7 @@ +Examples +======== + +Building a Simple Detector +-------------------------- + +.. literalinclude:: example_detector.py diff --git a/doc/source/index.rst b/doc/source/index.rst index 1e5686c..34bf38d 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -50,6 +50,7 @@ Subscribe to the mailing list for update announcements! render simulation likelihood + examples Authors ------- |