From 46145c946397e82431dac3ffd78113a1c6bc02fd Mon Sep 17 00:00:00 2001 From: Johannes Schumann <johannes.schumann@fau.de> Date: Fri, 2 Apr 2021 00:44:38 +0200 Subject: [PATCH] First layout of detector geometry classes --- km3buu/detector.py | 108 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 km3buu/detector.py diff --git a/km3buu/detector.py b/km3buu/detector.py new file mode 100644 index 0000000..5d32478 --- /dev/null +++ b/km3buu/detector.py @@ -0,0 +1,108 @@ +# Filename: detector.py +""" +Detector geometry related functionalities +""" + +__author__ = "Johannes Schumann" +__copyright__ = "Copyright 2021, Johannes Schumann and the KM3NeT collaboration." +__credits__ = [] +__license__ = "MIT" +__maintainer__ = "Johannes Schumann" +__email__ = "jschumann@km3net.de" +__status__ = "Development" + +import numpy as np +from abc import ABC, abstractmethod + +class DetectorGeometry(ABC): + """ + Detector geometry class + """ + def __init__(self) + self._volume = -1.0 + + @abstractmethod + def random_pos(self): + """ + Generate a random position in the detector volume based on a uniform + event distribution + + Returns + ------- + tuple [m] (x, y, z) + """ + pass + + @property + def volume(self): + """ + Returns + ------- + float [m^3] + The detector volume + """ + return self._volume + + +class Can(DetectorGeometry): + """ + Cylindrical detector geometry + + Parameters + ---------- + radius: float [m] (default: 403.5) + Cylinder radius given in metres + zmin: float [m] (default: 0.0) + Cylinder bottom z position + zmax: float [m] (default: 476.5) + Cylinder top z position + """ + def __init__(self, radius=403.4, zmin=0.0, zmax=476.5): + super().__init__() + self._radius = radius + self._zmin = zmin + self._zmax = zmax + self._volume = self._calc_volume() + + def _calc_volume(self): + return np.pi * (self._zmax - self.zmax) * np.power(self._radius, 2) + + def random_pos(self): + r = self._radius * np.sqrt(np.random.uniform(0, 1)) + phi = np.random.uniform(0, 2 * np.pi) + pos_x = r * np.cos(phi) + pos_y = r * np.sin(phi) + pos_z = np.random.uniform(self._zmin, self._zmax) + return (pos_x, pos_y, pos_z) + + +class Sphere(DetectorGeometry): + """ + Spherical detector geometry + + Parameters + ---------- + radius: float [m] + The radius of the sphere + center: tuple [m] + Coordinate center of the sphere + (x, y, z) + """ + def __init__(self, radius, center=(0, 0, 0)): + super().__init__() + self._radius = radius + self._center = center + self._volume = self._calc_volume() + + def _calc_volume(self): + return 4/3 * np.pi * np.power(self._radius) + + def random_pos(self): + r = np.power(self._radius, 1/3) + phi = np.random.uniform(0, np.pi) + cosTheta = np.random.uniform(-1,1) + pos_x = r * np.cos(phi) * np.sqrt(1-np.power(cosTheta,2)) + pos_y = r * np.sin(phi) * np.sqrt(1-np.power(cosTheta,2)) + pos_z = r * cosTheta + pos = (pos_x, pos_y, pos_z) + return tuple(np.add(center, pos)) -- GitLab