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
def build_dom(): """Returns a simple photodetector Solid. The photodetector is a sphere of size `size` constructed out of a glass envelope with a photosensitive face on the inside of the glass envelope.""" glass_thickness = 10 #mm size = 100 #mm # outside of the glass envelope outside_mesh = make.sphere(size) # inside of the glass envelope inside_mesh = make.sphere(size-glass_thickness) # outside solid with ice on the outside, and glass on the inside outside_solid = Solid(outside_mesh,glass,ice) inside_surface = r7081hqe_photocathode inside_color = 0x00ff00 # 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 build_checkerboard_scene(checkers_per_side=10, squares_per_checker=50): x = np.linspace(-5000.0, 5000.0, checkers_per_side*squares_per_checker+1) y = np.linspace(-5000.0, 5000.0, checkers_per_side*squares_per_checker+1) vertices = np.array(tuple(product(x,y,[0]))) triangles = [] for j in range(y.size-1): for i in range(x.size-1): triangles.append([j*len(x)+i, (j+1)*len(x)+i,(j+1)*len(x)+i+1]) triangles.append([j*len(x)+i, j*len(x)+i+1,(j+1)*len(x)+i+1]) checkerboard_mesh = Mesh(vertices, triangles, remove_duplicate_vertices=True) checkerboard_color_line1 = take(checkers_per_side*squares_per_checker*2, cycle([0]*2*squares_per_checker + [0xffffff]*2*squares_per_checker))*squares_per_checker checkerboard_color_line2 = take(checkers_per_side*squares_per_checker*2, cycle([0xffffff]*2*squares_per_checker + [0]*2*squares_per_checker))*squares_per_checker checkerboard_color = take(len(checkerboard_mesh.triangles), cycle(checkerboard_color_line1 + checkerboard_color_line2)) checkerboard_surface_line1 = take(checkers_per_side*squares_per_checker*2, cycle([black_surface]*2*squares_per_checker + [lambertian_surface]*2*squares_per_checker))*squares_per_checker checkerboard_surface_line2 = take(checkers_per_side*squares_per_checker*2, cycle([lambertian_surface]*2*squares_per_checker + [black_surface]*2*squares_per_checker))*squares_per_checker checkerboard_surface = take(len(checkerboard_mesh.triangles), cycle(checkerboard_surface_line1 + checkerboard_surface_line2)) checkerboard = Solid(checkerboard_mesh, vacuum, vacuum, surface=checkerboard_surface, color=checkerboard_color) sphere1 = Solid(sphere(1000.0, nsteps=512), water, vacuum) sphere2 = Solid(sphere(1000.0, nsteps=512), vacuum, vacuum, surface=shiny_surface) sphere3 = Solid(sphere(1000.0, nsteps=512), vacuum, vacuum, surface=lambertian_surface) checkerboard_scene = Geometry() checkerboard_scene.add_solid(checkerboard, displacement=(0,0,-1500.0)) checkerboard_scene.add_solid(sphere1, displacement=(2000.0,-2000.0,0)) checkerboard_scene.add_solid(sphere2, displacement=(-2000.0,-2000.0,0)) checkerboard_scene.add_solid(sphere3, displacement=(0.0,2000.0,0)) return checkerboard_scene
def testBulkReemission(self): '''Test bulk reemission Start a bunch of monoenergetic photons at the center of a wavelength- shifting sphere, forcing reemission, and check that the final wavelength distribution matches the wls spectrum. ''' import scipy.stats nphotons = 1e5 # set up detector -- a sphere of 'scintillator' surrounded by a # detecting sphere scint = Material('scint') scint.set('refractive_index', 1) scint.set('absorption_length', 1.0) scint.set('scattering_length', 1e7) scint.set('reemission_prob', 1) x = np.arange(0,1000,10) norm = scipy.stats.norm(scale=50, loc=600) pdf = 10 * norm.pdf(x) cdf = norm.cdf(x) scint.reemission_cdf = np.array(zip(x, cdf)) detector = Surface('detector') detector.set('detect', 1) world = Geometry(vacuum) world.add_solid(Solid(sphere(1000), vacuum, vacuum, surface=detector)) world.add_solid(Solid(sphere(500), scint, vacuum)) w = create_geometry_from_obj(world, update_bvh_cache=False) sim = Simulation(w, geant4_processes=0) # initial photons -- isotropic 250 nm at the origin pos = np.tile([0,0,0], (nphotons,1)).astype(np.float32) dir = np.random.rand(nphotons, 3).astype(np.float32) * 2 - 1 dir /= np.sqrt(dir[:,0]**2 + dir[:,1]**2 + dir[:,2]**2)[:,np.newaxis] pol = np.zeros_like(pos) t = np.zeros(nphotons, dtype=np.float32) wavelengths = np.ones(nphotons).astype(np.float32) * 250 photons = Photons(pos=pos, dir=dir, pol=pol, t=t, wavelengths=wavelengths) # run simulation and extract final wavelengths event = sim.simulate([photons], keep_photons_end=True).next() mask = (event.photons_end.flags & SURFACE_DETECT) > 0 final_wavelengths = event.photons_end.wavelengths[mask] # compare wavelength distribution to scintillator's reemission pdf hist, edges = np.histogram(final_wavelengths, bins=x) print 'detected', hist.sum(), 'of', nphotons, 'photons' hist_norm = 1.0 * hist / (1.0 * hist.sum() / 1000) pdf /= (1.0 * pdf.sum() / 1000) chi2 = scipy.stats.chisquare(hist_norm, pdf[:-1])[1] print 'chi2 =', chi2 # show histogram comparison #plt.figure(1) #width = edges[1] - edges[0] #plt.bar(left=edges, height=pdf, width=width, color='red') #plt.bar(left=edges[:-1], height=hist_norm, width=width) #plt.show() self.assertTrue(chi2 > 0.75)
def build_checkerboard_scene(checkers_per_side=10, squares_per_checker=50): x = np.linspace(-5000.0, 5000.0, checkers_per_side * squares_per_checker + 1) y = np.linspace(-5000.0, 5000.0, checkers_per_side * squares_per_checker + 1) vertices = np.array(tuple(product(x, y, [0]))) triangles = [] for j in range(y.size - 1): for i in range(x.size - 1): triangles.append([ j * len(x) + i, (j + 1) * len(x) + i, (j + 1) * len(x) + i + 1 ]) triangles.append( [j * len(x) + i, j * len(x) + i + 1, (j + 1) * len(x) + i + 1]) checkerboard_mesh = Mesh(vertices, triangles, remove_duplicate_vertices=True) checkerboard_color_line1 = take( checkers_per_side * squares_per_checker * 2, cycle([0] * 2 * squares_per_checker + [0xffffff] * 2 * squares_per_checker)) * squares_per_checker checkerboard_color_line2 = take( checkers_per_side * squares_per_checker * 2, cycle([0xffffff] * 2 * squares_per_checker + [0] * 2 * squares_per_checker)) * squares_per_checker checkerboard_color = take( len(checkerboard_mesh.triangles), cycle(checkerboard_color_line1 + checkerboard_color_line2)) checkerboard_surface_line1 = take( checkers_per_side * squares_per_checker * 2, cycle([black_surface] * 2 * squares_per_checker + [lambertian_surface] * 2 * squares_per_checker)) * squares_per_checker checkerboard_surface_line2 = take( checkers_per_side * squares_per_checker * 2, cycle([lambertian_surface] * 2 * squares_per_checker + [black_surface] * 2 * squares_per_checker)) * squares_per_checker checkerboard_surface = take( len(checkerboard_mesh.triangles), cycle(checkerboard_surface_line1 + checkerboard_surface_line2)) checkerboard = Solid(checkerboard_mesh, vacuum, vacuum, surface=checkerboard_surface, color=checkerboard_color) sphere1 = Solid(sphere(1000.0, nsteps=512), water, vacuum) sphere2 = Solid(sphere(1000.0, nsteps=512), vacuum, vacuum, surface=shiny_surface) sphere3 = Solid(sphere(1000.0, nsteps=512), vacuum, vacuum, surface=lambertian_surface) checkerboard_scene = Geometry() checkerboard_scene.add_solid(checkerboard, displacement=(0, 0, -1500.0)) checkerboard_scene.add_solid(sphere1, displacement=(2000.0, -2000.0, 0)) checkerboard_scene.add_solid(sphere2, displacement=(-2000.0, -2000.0, 0)) checkerboard_scene.add_solid(sphere3, displacement=(0.0, 2000.0, 0)) return checkerboard_scene