Source code for spine.data.larcv.crt

"""Module with a data class object which represents CRT information.

This copies the internal structure of :class:`larcv.CRTHit`.
"""

from dataclasses import dataclass, field

import numpy as np

from spine.data.base import PosDataBase
from spine.data.decorator import stored_property
from spine.data.field import FieldMetadata

__all__ = ["CRTHit"]


[docs] @dataclass(eq=False, repr=False) class CRTHit(PosDataBase): """CRT hit information. Attributes ---------- id : int Index of the CRT hit in the list plane : int Index of the CRT tagger that registered the hit tagger : str Name of the CRT tagger that registered the hit feb_id : np.ndarray Address of the FEB board stored as a list of bytes (uint8) ts0_s : int Absolute time from White Rabbit (seconds component) ts0_ns : float Absolute time from White Rabbit (nanoseconds component) ts0_s_corr : float Unclear in the documentation, placeholder at this point ts0_ns_corr : float Unclear in the documentation, placeholder at this point ts1_ns : float Time relative to the trigger (nanoseconds component) time : float Alias for ts1_ns, but scaled to microseconds total_pe : float Total number of PE in the CRT hit center : np.ndarray Barycenter of the CRT hit in detector coordinates width : np.ndarray Uncertainty on the barycenter of the CRT hit in detector coordinates units : str Units in which the position attributes are expressed """ # Index attributes id: int = field(default=-1, metadata=FieldMetadata(index=True)) # Scalar attributes plane: int = -1 ts0_s: int = field( default=-1, metadata=FieldMetadata(units="s") ) # Integer to match LArCV ts0_ns: float = field(default=np.nan, metadata=FieldMetadata(units="ns")) ts0_s_corr: float = field(default=np.nan, metadata=FieldMetadata(units="s")) ts0_ns_corr: float = field(default=np.nan, metadata=FieldMetadata(units="ns")) ts1_ns: float = field(default=np.nan, metadata=FieldMetadata(units="ns")) total_pe: float = np.nan tagger: str = "" units: str = "cm" # Vector attributes feb_id: np.ndarray = field( default_factory=lambda: np.empty(0, dtype=np.ubyte), metadata=FieldMetadata(dtype=np.ubyte), ) center: np.ndarray = field( default_factory=lambda: np.full(3, np.nan, dtype=np.float32), metadata=FieldMetadata( length=3, dtype=np.float32, position=True, units="instance", ), ) width: np.ndarray = field( default_factory=lambda: np.full(3, np.nan, dtype=np.float32), metadata=FieldMetadata( length=3, dtype=np.float32, vector=True, units="instance", ), ) @property @stored_property(units="us") def time(self) -> float: """Time w.r.t. to the trigger in microseconds. Returns ------- float Time of the CRT hit w.r.t. to the trigger in microseconds. """ return self.ts1_ns / 1000.0
[docs] @classmethod def from_larcv(cls, crthit): """Builds and returns a CRTHit object from a LArCV CRTHit object. Parameters ---------- crthit : larcv.CRTHit LArCV-format CRT hit Returns ------- CRTHit CRT hit object """ # Get the physical center and width of the CRT hit center = np.array( [getattr(crthit, f"{a}_pos")() for a in cls._axes], dtype=np.float32 ) width = np.array( [getattr(crthit, f"{a}_err")() for a in cls._axes], dtype=np.float32 ) # Convert the FEB address to a list of bytes feb_id = np.array([ord(c) for c in crthit.feb_id()], dtype=np.ubyte) return cls( id=crthit.id(), plane=crthit.plane(), tagger=crthit.tagger(), feb_id=feb_id, ts0_s=crthit.ts0_s(), ts0_ns=crthit.ts0_ns(), ts0_s_corr=crthit.ts0_s_corr(), ts0_ns_corr=crthit.ts0_ns_corr(), ts1_ns=crthit.ts1_ns(), total_pe=crthit.peshit(), center=center, width=width, )