Source code for cavendish_particle_tracks.analysis

from dataclasses import dataclass, field

import numpy as np

CHAMBER_DEPTH = 31.6  # cm

FIDUCIAL_FRONT = {
    "C'": [0.0, 0.0],
    "F'": [14.97, -8.67],
    "B'": [15.00, 8.66],
    "D'": [29.91, -0.07],
}  # cm
FIDUCIAL_BACK = {
    "C": [-0.02, 0.01],
    "F": [14.95, -8.63],
    "B": [14.92, 8.67],
    "D": [29.90, 0.02],
    "E": [-14.96, -8.62],
    "A": [-15.00, 8.68],
}  # cm

VIEW_NAMES = ["view1", "view2", "view3"]

EXPECTED_PARTICLES = [
    "New particle",
    "Σ⁺ ⇨ p + π⁰",
    "Σ⁺ ⇨ n + π⁺",
    "Σ⁻ ⇨ n + π⁻",
    "Λ⁰ ⇨ p + π⁻",
    "Λ⁰ ⇨ n + π⁰",
]


[docs] @dataclass class Fiducial: name: str = "" x: float = -1.0e6 y: float = -1.0e6 def __str__(self): return f"Fiducial(name={self.name}; x={self.x}; y={self.y})" @property def xy(self): return np.array([self.x, self.y]) @xy.setter def xy(self, point): self.x = point[0] self.y = point[1]
[docs] @dataclass class StereoshiftInfo: name: str = "" _sf1: list[float] = field(default_factory=lambda: [0.0, 0.0]) _sf2: list[float] = field(default_factory=lambda: [0.0, 0.0]) _sp1: list[float] = field(default_factory=lambda: [0.0, 0.0]) _sp2: list[float] = field(default_factory=lambda: [0.0, 0.0]) shift_fiducial: float = 0.0 shift_point: float = 0.0 stereoshift: float = -1.0 depth_cm: float = -1.0 @property def spoints(self): return [self._sf1, self._sf2, self._sp1, self._sp2] @spoints.setter def spoints(self, values): for i, point in enumerate(self.spoints): point[0] = values[i][0] point[1] = values[i][1] def __str__(self): mystring = f"StereoshiftInfo(name={self.name}; " for name, point in zip( ["sf1", "sf2", "sp1", "sp2"], [self._sf1, self._sf2, self._sp1, self._sp2] ): x, y = point mystring += f"{name}=[{x} {y}]; " mystring += f"shift_fiducial={self.shift_fiducial}; " mystring += f"shift_point={self.shift_point}; " mystring += f"stereoshift={self.stereoshift}; " mystring += f"depth_cm={self.depth_cm})" return mystring
# Idea is to save a list of ParticleDecays as we go along, and then pandas.DataFrame(list_of_particles) does all the magic
[docs] @dataclass class ParticleDecay: name: str = "" index: int = 0 event_number: int = -1 view_number: int = -1 _r1: list[float] = field(default_factory=lambda: [0.0, 0.0]) _r2: list[float] = field(default_factory=lambda: [0.0, 0.0]) _r3: list[float] = field(default_factory=lambda: [0.0, 0.0]) radius_px: float = -1.0 radius_cm: float = -1.0 _d1: list[float] = field(default_factory=lambda: [0.0, 0.0]) _d2: list[float] = field(default_factory=lambda: [0.0, 0.0]) decay_length_px: float = -1.0 decay_length_cm: float = -1.0 magnification_a: float = -1.0 magnification_b: float = 0.0 origin_vertex_stereoshift_info: StereoshiftInfo = field( default_factory=StereoshiftInfo ) decay_vertex_stereoshift_info: StereoshiftInfo = field( default_factory=StereoshiftInfo ) phi_proton: float = -100 phi_pion: float = -100
[docs] def vars_to_show(self, calibrated=False): if calibrated: return [ "event_number", "name", "radius_cm", "decay_length_cm", "origin_vertex_depth_cm", "decay_vertex_depth_cm", "magnification", "phi_proton", "phi_pion", ] else: return [ "event_number", "name", "radius_px", "decay_length_px", "origin_vertex_depth_cm", "decay_vertex_depth_cm", "magnification", "phi_proton", "phi_pion", ]
[docs] def vars_to_save(self): """Variable to save in the output file, all for the moment""" vars_to_save = [var for var in self.__dict__ if var[0] != "_"] vars_to_save += ["origin_vertex_depth_cm", "decay_vertex_depth_cm"] vars_to_save += ["rpoints", "dpoints"] return vars_to_save
@property def rpoints(self): return [self._r1, self._r2, self._r3] @rpoints.setter def rpoints(self, values): for i, point in enumerate(self.rpoints): point[0] = values[i][0] point[1] = values[i][1] @property def dpoints(self): return [self._d1, self._d2] @dpoints.setter def dpoints(self, values): for i, point in enumerate(self.dpoints): point[0] = values[i][0] point[1] = values[i][1] @property def origin_vertex_depth_cm(self): return self.origin_vertex_stereoshift_info.depth_cm @property def decay_vertex_depth_cm(self): return self.decay_vertex_stereoshift_info.depth_cm @property def average_depth_cm(self): return self.origin_vertex_stereoshift_info.depth_cm @property def magnification(self): return self.magnification_a + self.magnification_b * self.average_depth_cm
[docs] def calibrate(self) -> None: self.radius_cm = self.magnification * self.radius_px self.decay_length_cm = self.magnification * self.decay_length_px
[docs] def to_csv(self): mystring = "" for var in self.vars_to_save(): if var in ["rpoints", "dpoints"]: mystring += "[" for point in getattr(self, var): x, y = point mystring += f"[{x} {y}]; " mystring = mystring[0:-2] + "]," else: mystring += str(getattr(self, var)) + "," return mystring[0:-1] + "\n"