import numpy as np from chroma.sample import uniform_sphere class Photons(object): def __init__(self, positions, directions, wavelengths, polarizations=None, times=None, last_hit_triangles=None, histories=None): self.positions = positions nphotons = len(positions) assert len(directions) == nphotons self.directions = directions assert len(wavelengths) == nphotons self.wavelengths = wavelengths if polarizations is not None: self.polarizations = polarizations else: # polarizations are isotropic in plane perpendicular # to the direction vectors polarizations = np.cross(directions, uniform_sphere(nphotons)) # normalize polarization vectors polarizations /= np.tile(np.apply_along_axis(np.linalg.norm,1,polarizations),[3,1]).transpose() self.polarizations = np.asarray(polarizations, order='C') self.times = times self.last_hit_triangles = last_hit_triangles self.histories = histories def concatenate_photons(photons): '''Merge a list of Photons objects into one long list of photons''' return Photons(positions=np.concatenate([p.positions for p in photons]), directions=np.concatenate([p.directions for p in photons]), polarizations=np.concatenate([p.polarizations for p in photons]), times=np.concatenate([p.times for p in photons]), wavelengths=np.concatenate([p.wavelengths for p in photons])) class Channels(object): def __init__(self, hit, t, q, histories=None): self.hit = hit self.t = t self.q = q self.histories=histories def hit_channels(self): return self.hit.nonzero(), self.t[self.hit], self.q[self.hit] class Subtrack(object): def __init__(self, particle_name, position, direction, start_time, total_energy): self.particle_name = particle_name self.position = position self.direction = direction self.start_time = start_time self.total_energy = total_energy class Event(object): def __init__(self, event_id, particle_name=None, gen_position=None, gen_direction=None, gen_total_energy=None, ): self.event_id = event_id self.particle_name = particle_name self.gen_position = gen_position self.gen_direction = gen_direction self.gen_total_energy = gen_total_energy self.subtracks = [] self.nphoton = 0 self.photon_start = None self.photon_stop = None self.channels = None