def propagate(gpu_detector, number=10, nphotons=500000, nthreads_per_block=64, max_blocks=1024): "Returns the average number of photons propagated on the GPU per second." rng_states = gpu.get_rng_states(nthreads_per_block * max_blocks) run_times = [] for i in tools.progress(list(range(number))): pos = np.zeros((nphotons, 3)) dir = sample.uniform_sphere(nphotons) reorder = tools.argsort_direction(dir) dir = dir[reorder] pol = normalize(np.cross(sample.uniform_sphere(nphotons), dir)) wavelengths = np.random.uniform(400, 800, size=nphotons) photons = event.Photons(pos, dir, pol, wavelengths) gpu_photons = gpu.GPUPhotons(photons) t0 = time.time() gpu_photons.propagate(gpu_detector, rng_states, nthreads_per_block, max_blocks) cuda.Context.get_current().synchronize() elapsed = time.time() - t0 if i > 0: # first kernel call incurs some driver overhead run_times.append(elapsed) return nphotons / ufloat((np.mean(run_times), np.std(run_times)))
def constant_photons(pos, n): #constructs photons at one location with random propagation directions points = np.empty((n, 3)) points[:] = pos pos = points dir = uniform_sphere(n) pol = np.cross(dir, uniform_sphere(n)) #300 nm is roughly the pseudocumene scintillation wavelength wavelengths = np.repeat(300.0, n) return Photons(pos, dir, pol, wavelengths)
def gaussian_sphere(pos, sigma, n): points = np.empty((n, 3)) points[:, 0] = np.random.normal(0.0, sigma, n) + pos[0] points[:, 1] = np.random.normal(0.0, sigma, n) + pos[1] points[:, 2] = np.random.normal(0.0, sigma, n) + pos[2] pos = points dir = uniform_sphere(n) pol = np.cross(dir, uniform_sphere(n)) #300 nm is roughly the pseudocumene scintillation wavelength wavelengths = np.repeat(300.0, n) return Photons(pos, dir, pol, wavelengths)
def uniform_photons(inscribed_radius, n): #constructs photons uniformly throughout the detector inside of the inscribed sphere. radius_root = inscribed_radius * np.power(np.random.rand(n), 1.0 / 3.0) theta = np.arccos(np.random.uniform(-1.0, 1.0, n)) phi = np.random.uniform(0.0, 2 * np.pi, n) points = np.empty((n, 3)) points[:, 0] = radius_root * np.sin(theta) * np.cos(phi) points[:, 1] = radius_root * np.sin(theta) * np.sin(phi) points[:, 2] = radius_root * np.cos(theta) pos = points dir = uniform_sphere(n) pol = np.cross(dir, uniform_sphere(n)) #300 nm is roughly the pseudocumene scintillation wavelength wavelengths = np.repeat(300.0, n) return Photons(pos, dir, pol, wavelengths)
def intersect(gpu_geometry, number=100, nphotons=500000, nthreads_per_block=64, max_blocks=1024): "Returns the average number of ray intersections per second." distances_gpu = ga.empty(nphotons, dtype=np.float32) module = gpu.get_cu_module('mesh.h', options=('--use_fast_math', )) gpu_funcs = gpu.GPUFuncs(module) run_times = [] for i in tools.progress(list(range(number))): pos = ga.zeros(nphotons, dtype=ga.vec.float3) dir = sample.uniform_sphere(nphotons) reorder = tools.argsort_direction(dir) dir = ga.to_gpu(gpu.to_float3(dir[reorder])) t0 = time.time() gpu_funcs.distance_to_mesh(np.int32(pos.size), pos, dir, gpu_geometry.gpudata, distances_gpu, block=(nthreads_per_block, 1, 1), grid=(pos.size // nthreads_per_block + 1, 1)) cuda.Context.get_current().synchronize() elapsed = time.time() - t0 if i > 0: # first kernel call incurs some driver overhead run_times.append(elapsed) return nphotons / ufloat((np.mean(run_times), np.std(run_times)))
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]
def load_photons(number=100, nphotons=500000): """Returns the average number of photons moved to the GPU device memory per second.""" pos = np.zeros((nphotons, 3)) dir = sample.uniform_sphere(nphotons) pol = normalize(np.cross(sample.uniform_sphere(nphotons), dir)) wavelengths = np.random.uniform(400, 800, size=nphotons) photons = event.Photons(pos, dir, pol, wavelengths) run_times = [] for i in tools.progress(list(range(number))): t0 = time.time() gpu_photons = gpu.GPUPhotons(photons) cuda.Context.get_current().synchronize() elapsed = time.time() - t0 if i > 0: # first kernel call incurs some driver overhead run_times.append(elapsed) return nphotons / ufloat((np.mean(run_times), np.std(run_times)))
def photon_angle(rep, pos=[0, 0, 0]): off = 200 photon_pos = np.zeros((rep, 3)) upshift = 800 for i in range(5): photon_pos[i, :] = [ pos[0] - i * 100 + off - 100, pos[1] + off + 400, pos[2] + upshift ] photon_pos[5, :] = [-800, 600, 800] photon_dir = np.tile(np.array([0.2, -0.55, -1]), (rep, 1)) pol = np.cross(photon_dir, uniform_sphere(rep)) wavelength = np.repeat(300.0, rep) return Photons(photon_pos, photon_dir, pol, wavelength), photon_pos
def isotropic(): while True: yield uniform_sphere()
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)
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]
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)