def create_event(self): """ Generate a neutrino event in the ice volume. Creates a neutrino with a random vertex in the volume, a random direction, and an energy based on ``get_energy``. Particle type is randomly chosen, and its interaction type is also randomly chosen based on the branching ratio. Weights the particles according to their survival probability through the Earth and their probability of interacting in the ice at their vertex. If Earth shadowing has been turned on then particles which don't survive transit through the Earth are skipped, and surviving particles are given a survival weight of 1. Currently each `Event` returned consists of only a single `Particle`. Returns ------- Event Random neutrino event not shadowed by the Earth. See Also -------- pyrex.Event : Class for storing a tree of `Particle` objects representing an event. pyrex.Particle : Class for storing particle attributes. """ self.count += 1 vtx = self.get_vertex() u = self.get_direction() E = self.get_energy() particle_id = self.get_particle_type() particle = Particle(particle_id=particle_id, vertex=vtx, direction=u, energy=E, interaction_model=self.interaction_model) weights = self.get_weights(particle) if not self.shadow: particle.survival_weight = weights[0] particle.interaction_weight = weights[1] logger.debug( "Successfully created %s with survival weight %d and " + "interaction weight %d", particle, weights[0], weights[1]) return Event(particle) elif np.random.rand() < weights[0]: particle.survival_weight = 1 particle.interaction_weight = weights[1] logger.debug( "Successfully created %s with survival weight %d and " + "interaction weight %d", particle, weights[0], weights[1]) return Event(particle) else: # Particle was shadowed by the earth. Try again logger.debug("Particle creation shadowed by the Earth") return self.create_event()
def _load_events(self): """ Pulls the next chunk of events into memory. Reads events up to the ``slice_range`` into memory from the current file. If the current file is exhausted, loads the next file. Returns ------- list List of `Event` objects read from the current file. Raises ------ StopIteration If the end of the last file in the file list has been reached. """ if self._file_index < 0 or self._event_index >= len(self._file): self._next_file() start = self._event_index stop = self._event_index + self.slice_range self._event_index += self.slice_range if stop > len(self._file): stop = len(self._file) self._events = [] self._event_counts = [] for file_event in self._file[start:stop]: info = file_event.get_particle_info() particles = [] for p in info: part = Particle(particle_id=p['particle_id'], vertex=(p['vertex_x'], p['vertex_y'], p['vertex_z']), direction=(p['direction_x'], p['direction_y'], p['direction_z']), energy=p['energy'], interaction_model=self.interaction_model, interaction_type=p['interaction_kind']) part.interaction.inelasticity = p['interaction_inelasticity'] part.interaction.em_frac = p['interaction_em_frac'] part.interaction.had_frac = p['interaction_had_frac'] part.survival_weight = p['survival_weight'] part.interaction_weight = p['interaction_weight'] particles.append(part) self._events.append(Event(particles)) self._event_counts.append(file_event.total_events_thrown)