Utilities: recovering the energies of muons at depth¶
Muons are ranged particles, so both their position and energy are a function of
time. The position is easy enough to represent in an I3Particle
;
by dint of special relativity, the position be approximated by speed-of-light
displacement along the muon’s initial direction from an arbitrary reference
point. Information about a muon’s true energy at any given moment, however, is
scattered in multiple locations in each frame. These are:
The initial energy at the reference point, stored in the
I3Particle
that represents the muon itselfThe energy the muon has when it enters and exits the MMC simulation volume (typically a 1600 x 800 meter upright cylinder), stored in the
I3MMCTrack
corresponding to the muon.The sizes of the stochastic energy losses inside the MMC simulation volume. These are stored as
I3Particle
attached as daughters of theI3Particle
represending the muon in the I3MCTree
While it is in principle straightforward to recover the energy of a simulated
muon at any point along its path inside the MMC simulation volume from these
scattered data structures, it is also extremely tedious. MuonGun includes
a utility class, Track
, to automate this task.
- class icecube.MuonGun.Track
A subclass of I3Particle that includes the particle’s energy losses
- classmethod harvest(frame)
Assemble a collection of
Track
from theMMCTrackList
and I3MCTree in frame
- get_energy(displacement)
Get the energy of the muon displacement meters from its starting position
This class can be used, for example, to find the total energy losses (stochastic and continuous) of all muons within some volume:
from icecube import MuonGun, simclasses
# A surface approximating the actual detector (make it smaller if you only care e.g. about DeepCore)
surface = MuonGun.Cylinder(1000,500)
edep = 0
for track in MuonGun.Track.harvest(frame['I3MCTree'], frame['MMCTrackList']):
# Find distance to entrance and exit from sampling volume
intersections = surface.intersection(track.pos, track.dir)
# Get the corresponding energies
e0, e1 = track.get_energy(intersections.first), track.get_energy(intersections.second)
# Accumulate
edep += (e0-e1)
There is also a convenience function, muons_at_surface()
, that uses
Track
to “shift” all the muons in a frame forward so that their
positions, times, and energies correspond to their intersections with a given
surface.
- icecube.MuonGun.muons_at_surface(frame, surface)
- Parameters:
frame – an I3Frame
surface – a
Surface
- Returns:
a list of I3Particles with positions, times, and energies that correspond to their intersection with surface. Muons that range out before reaching surface are not included.
This can be used to quickly obtain the true multiplicity of a muon bundle when it enters the detector:
surface = MuonGun.Cylinder(1000,500)
multiplicity = len(MuonGun.muons_at_surface(frame, surface))