Source code for km3pipe.mc

# Filename: mc.py
# pylint: disable=C0103
"""
Monte Carlo related things.

"""
from __future__ import absolute_import, print_function, division

import numpy as np

from .logger import get_logger

__author__ = "Tamas Gal and Moritz Lotze"
__copyright__ = "Copyright 2016, Tamas Gal and the KM3NeT collaboration."
__credits__ = []
__license__ = "MIT"
__maintainer__ = "Tamas Gal and Moritz Lotze"
__email__ = "tgal@km3net.de"
__status__ = "Development"

[docs]log = get_logger(__name__) # pylint: disable=C0103
[docs]def geant2pdg(geant_code): """Convert GEANT particle ID to PDG""" conversion_table = { 1: 22, # photon 2: -11, # positron 3: 11, # electron 5: -13, # muplus 6: 13, # muminus 7: 111, # pi0 8: 211, # piplus 9: -211, # piminus 10: 130, # k0long 11: 321, # kplus 12: -321, # kminus 13: 2112, # neutron 14: 2212, # proton 16: 310, # kaon0short 17: 221, # eta } try: return conversion_table[geant_code] except KeyError: return 0
_PDG2NAME = { 1: 'd', 2: 'u', 3: 's', 4: 'c', 5: 'b', 6: 't', 11: 'e-', -11: 'e+', 12: 'nu_e', -12: 'anu_e', 13: 'mu-', -13: 'mu+', 14: 'nu_mu', -14: 'anu_mu', 15: 'tau-', -15: 'tau+', 16: 'nu_tau', -16: 'anu_tau', 22: 'photon', 111: 'pi0', 130: 'K0L', 211: 'pi-', -211: 'pi+', 310: 'K0S', 311: 'K0', 321: 'K+', -321: 'K-', 2112: 'n', 2212: 'p', -2212: 'p-', } _NAME2PDG = {val: key for key, val in _PDG2NAME.items()} # noqa
[docs]def pdg2name(pdg_id): """Convert PDG ID to human readable names""" # pylint: disable=C0330 try: return _PDG2NAME[pdg_id] except KeyError: return "N/A"
[docs]def name2pdg(name): try: return _NAME2PDG[name] except KeyError: return 0
[docs]def most_energetic(df): """Grab most energetic particle from mc_tracks dataframe.""" idx = df.groupby(['event_id'])['energy'].transform(max) == df['energy'] return df[idx].reindex()
[docs]def leading_particle(df): """Grab leading particle (neutrino, most energetic bundle muon). Note: selecting the most energetic mc particle does not always select the neutrino! In some sub-percent cases, the post-interaction secondaries can have more energy than the incoming neutrino! aanet convention: mc_tracks[0] = neutrino so grab the first row if the first row is not unique (neutrinos are unique), it's a muon bundle grab the most energetic then """ leading = df.groupby('event_id', as_index=False).first() unique = leading.type.unique() if len(unique) == 1 and unique[0] == 0: leading = most_energetic(df) return leading
[docs]def get_flavor(pdg_types): """Build a 'flavor' from the 'type' column.""" import pandas as pd return pd.Series(pdg_types).apply(pdg2name)
def _p_eq_nu(pdg_type): return np.abs(pdg_type) in {12, 14, 16} def _p_eq_mu(pdg_type): return pdg_type == -13
[docs]def is_neutrino(pdg_types): """flavor string -> is_neutrino""" import pandas as pd return pd.Series(pdg_types).apply(_p_eq_nu)
[docs]def is_muon(pdg_types): """flavor string -> is_neutrino""" import pandas as pd return pd.Series(pdg_types).apply(_p_eq_mu)