def write_event(self, pyev): "Write an event.Event object to the ROOT tree as a ROOT.Event object." self.ev.id = pyev.id if pyev.primary_vertex is not None: self.ev.primary_vertex.particle_name = \ pyev.primary_vertex.particle_name self.ev.primary_vertex.pos.SetXYZ(*pyev.primary_vertex.pos) self.ev.primary_vertex.dir.SetXYZ(*pyev.primary_vertex.dir) if pyev.primary_vertex.pol is not None: self.ev.primary_vertex.pol.SetXYZ(*pyev.primary_vertex.pol) self.ev.primary_vertex.ke = pyev.primary_vertex.ke self.ev.primary_vertex.t0 = pyev.primary_vertex.t0 if pyev.photons_beg is not None: photons = pyev.photons_beg ROOT.fill_photons(self.ev.photons_beg, len(photons.pos), photons.pos.ravel(), photons.dir.ravel(), photons.pol.ravel(), photons.wavelengths, photons.t, photons.last_hit_triangles, photons.flags) if pyev.photons_end is not None: photons = pyev.photons_end ROOT.fill_photons(self.ev.photons_end, len(photons.pos), photons.pos.ravel(), photons.dir.ravel(), photons.pol.ravel(), photons.wavelengths, photons.t, photons.last_hit_triangles, photons.flags) self.ev.vertices.resize(0) if pyev.vertices is not None: self.ev.vertices.resize(len(pyev.vertices)) for i, vertex in enumerate(pyev.vertices): self.ev.vertices[i].particle_name = vertex.particle_name self.ev.vertices[i].pos.SetXYZ(*vertex.pos) self.ev.vertices[i].dir.SetXYZ(*vertex.dir) if vertex.pol is not None: self.ev.vertices[i].pol.SetXYZ(*vertex.pol) self.ev.vertices[i].ke = vertex.ke self.ev.vertices[i].t0 = vertex.t0 if pyev.channels is not None: nhit = count_nonzero(pyev.channels.hit) if nhit > 0: ROOT.fill_channels(self.ev, nhit, np.arange(len(pyev.channels.t))[pyev.channels.hit].astype(np.uint32), pyev.channels.t, pyev.channels.q, pyev.channels.flags, len(pyev.channels.hit)) else: self.ev.nhit = 0 self.ev.channels.resize(0) self.ev.nchannels = len(pyev.channels.hit) else: self.ev.nhit = 0 self.ev.channels.resize(0) self.ev.nchannels = 0 self.T.Fill()
def setup_pdf_eval(self, event_hit, event_time, event_charge, min_twidth, trange, min_qwidth, qrange, min_bin_content=10, time_only=True): """Setup GPU arrays to compute PDF values for the given event. The pdf_eval calculation allows the PDF to be evaluated at a single point for each channel as the Monte Carlo is run. The effective bin size will be as small as (`min_twidth`, `min_qwidth`) around the point of interest, but will be large enough to ensure that `min_bin_content` Monte Carlo events fall into the bin. event_hit: ndarray Hit or not-hit status for each channel in the detector. event_time: ndarray Hit time for each channel in the detector. If channel not hit, the time will be ignored. event_charge: ndarray Integrated charge for each channel in the detector. If channel not hit, the charge will be ignored. min_twidth: float Minimum bin size in the time dimension trange: (float, float) Range of time dimension in PDF min_qwidth: float Minimum bin size in charge dimension qrange: (float, float) Range of charge dimension in PDF min_bin_content: int The bin will be expanded to include at least this many events time_only: bool If True, only the time observable will be used in the PDF. """ self.event_nhit = count_nonzero(event_hit) # Define a mapping from an array of len(event_hit) to an array of length event_nhit self.map_hit_offset_to_channel_id = np.where(event_hit)[0].astype(np.uint32) self.map_hit_offset_to_channel_id_gpu = ga.to_gpu(self.map_hit_offset_to_channel_id) self.map_channel_id_to_hit_offset = np.maximum(0, event_hit.cumsum() - 1).astype(np.uint32) self.map_channel_id_to_hit_offset_gpu = ga.to_gpu(self.map_channel_id_to_hit_offset) self.event_hit_gpu = ga.to_gpu(event_hit.astype(np.uint32)) self.event_time_gpu = ga.to_gpu(event_time.astype(np.float32)) self.event_charge_gpu = ga.to_gpu(event_charge.astype(np.float32)) self.eval_hitcount_gpu = ga.zeros(len(event_hit), dtype=np.uint32) self.eval_bincount_gpu = ga.zeros(len(event_hit), dtype=np.uint32) self.nearest_mc_gpu = ga.empty(shape=self.event_nhit * min_bin_content, dtype=np.float32) self.nearest_mc_gpu.fill(1e9) self.min_twidth = min_twidth self.trange = trange self.min_qwidth = min_qwidth self.qrange = qrange self.min_bin_content = min_bin_content assert time_only # Only support time right now self.time_only = time_only
def testAbort(self): '''Photons that hit a triangle at normal incidence should not abort. Photons that hit a triangle at exactly normal incidence can sometimes produce a dot product that is outside the range allowed by acos(). Trigger these with axis aligned photons in a box. ''' # Setup geometry cube = Geometry(vacuum) cube.add_solid(Solid(box(100, 100, 100), vacuum, vacuum)) geo = create_geometry_from_obj(cube, update_bvh_cache=False) # Initialize simulation (without geant4) sim = Simulation(geo, geant4_processes=0) # Create initial photons nphotons = 5 pos = np.tile([0, 0, 0], (nphotons, 1)).astype(np.float32) dir = np.tile([0, 0, 1], (nphotons, 1)).astype(np.float32) pol = np.zeros_like(pos) phi = np.random.uniform(0, 2 * np.pi, nphotons).astype(np.float32) pol[:, 0] = np.cos(phi) pol[:, 1] = np.sin(phi) t = np.zeros(nphotons, dtype=np.float32) wavelengths = np.empty(nphotons, np.float32) wavelengths.fill(400.0) photons = Photons(pos=pos, dir=dir, pol=pol, t=t, wavelengths=wavelengths) # First make one step to check for strangeness photons_end = sim.simulate([photons], keep_photons_end=True, max_steps=1).next().photons_end print "FIRST STEP" print photons_end.pos[0:10] self.assertFalse(np.isnan(photons_end.pos).any()) self.assertFalse(np.isnan(photons_end.dir).any()) self.assertFalse(np.isnan(photons_end.pol).any()) self.assertFalse(np.isnan(photons_end.t).any()) self.assertFalse(np.isnan(photons_end.wavelengths).any()) # Now let it run the usual ten steps photons_end = sim.simulate([photons], keep_photons_end=True, max_steps=10).next().photons_end aborted = (photons_end.flags & (1 << 31)) > 0 print 'aborted photon fracttion: %1.1f' % ( float(count_nonzero(aborted)) / nphotons) self.assertFalse(aborted.any()) print "LAST STEPS" print photons_end.pos[0:10]
def testAbort(self): '''Photons that hit a triangle at normal incidence should not abort. Photons that hit a triangle at exactly normal incidence can sometimes produce a dot product that is outside the range allowed by acos(). Trigger these with axis aligned photons in a box. ''' # Setup geometry cube = Geometry(vacuum) cube.add_solid(Solid(box(100,100,100), vacuum, vacuum)) geo = create_geometry_from_obj(cube, update_bvh_cache=False) sim = Simulation(geo, geant4_processes=0) # Create initial photons nphotons = 10000 pos = np.tile([0,0,0], (nphotons,1)).astype(np.float32) dir = np.tile([0,0,1], (nphotons,1)).astype(np.float32) pol = np.zeros_like(pos) phi = np.random.uniform(0, 2*np.pi, nphotons).astype(np.float32) pol[:,0] = np.cos(phi) pol[:,1] = np.sin(phi) t = np.zeros(nphotons, dtype=np.float32) wavelengths = np.empty(nphotons, np.float32) wavelengths.fill(400.0) photons = Photons(pos=pos, dir=dir, pol=pol, t=t, wavelengths=wavelengths) # First make one step to check for strangeness photons_end = sim.simulate([photons], keep_photons_end=True, max_steps=1).next().photons_end self.assertFalse(np.isnan(photons_end.pos).any()) self.assertFalse(np.isnan(photons_end.dir).any()) self.assertFalse(np.isnan(photons_end.pol).any()) self.assertFalse(np.isnan(photons_end.t).any()) self.assertFalse(np.isnan(photons_end.wavelengths).any()) # Now let it run the usual ten steps photons_end = sim.simulate([photons], keep_photons_end=True, max_steps=10).next().photons_end aborted = (photons_end.flags & (1 << 31)) > 0 print 'aborted photons: %1.1f' % \ (float(count_nonzero(aborted)) / nphotons) self.assertFalse(aborted.any())
def write_event(self, pyev): "Write an event.Event object to the ROOT tree as a ROOT.Event object." self.ev.id = pyev.id if pyev.photons_beg is not None: photons = pyev.photons_beg ROOT.fill_photons(self.ev.photons_beg, len(photons.pos), photons.pos.ravel(), photons.dir.ravel(), photons.pol.ravel(), photons.wavelengths, photons.t, photons.last_hit_triangles, photons.flags) if pyev.photons_end is not None: photons = pyev.photons_end ROOT.fill_photons(self.ev.photons_end, len(photons.pos), photons.pos.ravel(), photons.dir.ravel(), photons.pol.ravel(), photons.wavelengths, photons.t, photons.last_hit_triangles, photons.flags) self.ev.vertices.resize(0) if pyev.vertices is not None: self.ev.vertices.resize(len(pyev.vertices)) for i, vertex in enumerate(pyev.vertices): python_vertex_to_root_vertex(vertex, self.ev.vertices[i]) if pyev.channels is not None: nhit = count_nonzero(pyev.channels.hit) if nhit > 0: ROOT.fill_channels( self.ev, nhit, np.arange(len(pyev.channels.t))[pyev.channels.hit].astype( np.uint32), pyev.channels.t, pyev.channels.q, pyev.channels.flags, len(pyev.channels.hit)) else: self.ev.nhit = 0 self.ev.channels.resize(0) self.ev.nchannels = len(pyev.channels.hit) else: self.ev.nhit = 0 self.ev.channels.resize(0) self.ev.nchannels = 0 self.T.Fill()
def write_event(self, pyev): "Write an event.Event object to the ROOT tree as a ROOT.Event object." self.ev.id = pyev.id if pyev.photons_beg is not None: photons = pyev.photons_beg ROOT.fill_photons(self.ev.photons_beg, len(photons.pos), photons.pos.ravel(), photons.dir.ravel(), photons.pol.ravel(), photons.wavelengths, photons.t, photons.last_hit_triangles, photons.flags) if pyev.photons_end is not None: photons = pyev.photons_end ROOT.fill_photons(self.ev.photons_end, len(photons.pos), photons.pos.ravel(), photons.dir.ravel(), photons.pol.ravel(), photons.wavelengths, photons.t, photons.last_hit_triangles, photons.flags) self.ev.vertices.resize(0) if pyev.vertices is not None: self.ev.vertices.resize(len(pyev.vertices)) for i, vertex in enumerate(pyev.vertices): python_vertex_to_root_vertex(vertex,self.ev.vertices[i]) if pyev.channels is not None: nhit = count_nonzero(pyev.channels.hit) if nhit > 0: ROOT.fill_channels(self.ev, nhit, np.arange(len(pyev.channels.t))[pyev.channels.hit].astype(np.uint32), pyev.channels.t, pyev.channels.q, pyev.channels.flags, len(pyev.channels.hit)) else: self.ev.nhit = 0 self.ev.channels.resize(0) self.ev.nchannels = len(pyev.channels.hit) else: self.ev.nhit = 0 self.ev.channels.resize(0) self.ev.nchannels = 0 self.T.Fill()
from chroma.demo import detector as build_detector from chroma.sim import Simulation from chroma.generator import constant_particle_gun from chroma import tools import time tools.enable_debug_on_crash() detector = build_detector() sim = Simulation(detector, seed=0) event = sim.simulate( islice(constant_particle_gun('e-', (0, 0, 0), (1, 0, 0), 100.0), 1)).next() print 'nhit = %i' % count_nonzero(event.channels.hit) likelihood = Likelihood(sim, event) x = np.linspace(-10.0, 10.0, 100) l = [] for pos in izip(x, repeat(0), repeat(0)): t0 = time.time() ev_vertex_iter = constant_particle_gun('e-', pos, (1, 0, 0), 100.0) l.append(likelihood.eval(ev_vertex_iter, 1000)) elapsed = time.time() - t0 print '(%.1f, %.1f, %.1f), %s (%1.1f sec)' % \ (pos[0], pos[1], pos[2], tools.ufloat_to_str(l[-1]), elapsed)
if __name__ == '__main__': from chroma.demo import detector as build_detector from chroma.sim import Simulation from chroma.generator import constant_particle_gun from chroma import tools import time tools.enable_debug_on_crash() detector = build_detector() sim = Simulation(detector, seed=0) event = sim.simulate(islice(constant_particle_gun('e-',(0,0,0),(1,0,0),100.0), 1)).next() print 'nhit = %i' % count_nonzero(event.channels.hit) likelihood = Likelihood(sim, event) x = np.linspace(-10.0, 10.0, 100) l = [] for pos in izip(x, repeat(0), repeat(0)): t0 = time.time() ev_vertex_iter = constant_particle_gun('e-',pos,(1,0,0),100.0) l.append(likelihood.eval(ev_vertex_iter, 1000)) elapsed = time.time() - t0 print '(%.1f, %.1f, %.1f), %s (%1.1f sec)' % \ (pos[0], pos[1], pos[2], tools.ufloat_to_str(l[-1]), elapsed)