Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/parameterisations/Par04/training/utils/observables.py

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /examples/extended/parameterisations/Par04/training/utils/observables.py (Version 11.3.0) and /examples/extended/parameterisations/Par04/training/utils/observables.py (Version 11.2.2)


  1 from dataclasses import dataclass                   1 from dataclasses import dataclass
  2 from enum import Enum                               2 from enum import Enum
  3                                                     3 
  4 import numpy as np                                  4 import numpy as np
  5                                                     5 
  6 from core.constants import N_CELLS_Z, N_CELLS_      6 from core.constants import N_CELLS_Z, N_CELLS_R, SIZE_Z, SIZE_R
  7                                                     7 
  8                                                     8 
  9 @dataclass                                          9 @dataclass
 10 class Observable:                                  10 class Observable:
 11     """ An abstract class defining interface o     11     """ An abstract class defining interface of all observables.
 12                                                    12 
 13     Do not use this class directly.                13     Do not use this class directly.
 14                                                    14 
 15     Attributes:                                    15     Attributes:
 16           _input: A numpy array with shape = (     16           _input: A numpy array with shape = (NE, R, PHI, Z), where NE stays for number of events.
 17     """                                            17     """
 18     _input: np.ndarray                             18     _input: np.ndarray
 19                                                    19 
 20                                                    20 
 21 class ProfileType(Enum):                           21 class ProfileType(Enum):
 22     """ Enum class of various profile types.       22     """ Enum class of various profile types.
 23                                                    23 
 24     """                                            24     """
 25     LONGITUDINAL = 0                               25     LONGITUDINAL = 0
 26     LATERAL = 1                                    26     LATERAL = 1
 27                                                    27 
 28                                                    28 
 29 @dataclass                                         29 @dataclass
 30 class Profile(Observable):                         30 class Profile(Observable):
 31     """ An abstract class describing behaviour     31     """ An abstract class describing behaviour of LongitudinalProfile and LateralProfile.
 32                                                    32 
 33     Do not use this class directly. Use Longit     33     Do not use this class directly. Use LongitudinalProfile or LateralProfile instead.
 34                                                    34 
 35     """                                            35     """
 36                                                    36 
 37     def calc_profile(self) -> np.ndarray:          37     def calc_profile(self) -> np.ndarray:
 38         pass                                       38         pass
 39                                                    39 
 40     def calc_first_moment(self) -> np.ndarray:     40     def calc_first_moment(self) -> np.ndarray:
 41         pass                                       41         pass
 42                                                    42 
 43     def calc_second_moment(self) -> np.ndarray     43     def calc_second_moment(self) -> np.ndarray:
 44         pass                                       44         pass
 45                                                    45 
 46                                                    46 
 47 @dataclass                                         47 @dataclass
 48 class LongitudinalProfile(Profile):                48 class LongitudinalProfile(Profile):
 49     """ A class defining observables related t     49     """ A class defining observables related to LongitudinalProfile.
 50                                                    50 
 51     Attributes:                                    51     Attributes:
 52         _energies_per_event: A numpy array wit     52         _energies_per_event: A numpy array with shape = (NE, Z) where NE stays for a number of events. An
 53             element [i, j] is a sum of energie     53             element [i, j] is a sum of energies detected in all cells located in a jth layer for an ith event.
 54         _total_energy_per_event: A numpy array     54         _total_energy_per_event: A numpy array with shape = (NE, ). An element [i] is a sum of energies detected in all
 55             cells for an ith event.                55             cells for an ith event.
 56         _w: A numpy array = [0, 1, ..., Z - 1]     56         _w: A numpy array = [0, 1, ..., Z - 1] which represents weights used in computation of first and second moment.
 57                                                    57 
 58     """                                            58     """
 59                                                    59 
 60     def __post_init__(self):                       60     def __post_init__(self):
 61         self._energies_per_event = np.sum(self     61         self._energies_per_event = np.sum(self._input, axis=(1, 2))
 62         self._total_energy_per_event = np.sum(     62         self._total_energy_per_event = np.sum(self._energies_per_event, axis=1)
 63         self._w = np.arange(N_CELLS_Z)             63         self._w = np.arange(N_CELLS_Z)
 64                                                    64 
 65     def calc_profile(self) -> np.ndarray:          65     def calc_profile(self) -> np.ndarray:
 66         """ Calculates a longitudinal profile.     66         """ Calculates a longitudinal profile.
 67                                                    67 
 68         A longitudinal profile for a given lay     68         A longitudinal profile for a given layer l (l = 0, ..., Z - 1) is defined as:
 69         sum_{i = 0}^{NE - 1} energy_per_event[     69         sum_{i = 0}^{NE - 1} energy_per_event[i, l].
 70                                                    70 
 71         Returns:                                   71         Returns:
 72             A numpy array of longitudinal prof     72             A numpy array of longitudinal profiles for each layer with a shape = (Z, ).
 73                                                    73 
 74         """                                        74         """
 75         return np.sum(self._energies_per_event     75         return np.sum(self._energies_per_event, axis=0)
 76                                                    76 
 77     def calc_first_moment(self) -> np.ndarray:     77     def calc_first_moment(self) -> np.ndarray:
 78         """ Calculates a first moment of profi     78         """ Calculates a first moment of profile.
 79                                                    79 
 80         A first moment of a longitudinal profi     80         A first moment of a longitudinal profile for a given event e (e = 0, ..., NE - 1) is defined as:
 81         FM[e] = alpha * (sum_{i = 0}^{Z - 1} e     81         FM[e] = alpha * (sum_{i = 0}^{Z - 1} energies_per_event[e, i] * w[i]) / total_energy_per_event[e], where
 82         w = [0, 1, 2, ..., Z - 1],                 82         w = [0, 1, 2, ..., Z - 1],
 83         alpha = SIZE_Z defined in core/constan     83         alpha = SIZE_Z defined in core/constants.py.
 84                                                    84 
 85         Returns:                                   85         Returns:
 86             A numpy array of first moments of      86             A numpy array of first moments of longitudinal profiles for each event with a shape = (NE, ).
 87                                                    87 
 88         """                                        88         """
 89         return SIZE_Z * np.dot(self._energies_     89         return SIZE_Z * np.dot(self._energies_per_event, self._w) / self._total_energy_per_event
 90                                                    90 
 91     def calc_second_moment(self) -> np.ndarray     91     def calc_second_moment(self) -> np.ndarray:
 92         """ Calculates a second moment of a lo     92         """ Calculates a second moment of a longitudinal profile.
 93                                                    93 
 94         A second moment of a longitudinal prof     94         A second moment of a longitudinal profile for a given event e (e = 0, ..., NE - 1) is defined as:
 95         SM[e] = (sum_{i = 0}^{Z - 1} (w[i] - a     95         SM[e] = (sum_{i = 0}^{Z - 1} (w[i] - alpha - FM[e])^2 * energies_per_event[e, i]) total_energy_per_event[e],
 96         where                                      96         where
 97         w = [0, 1, 2, ..., Z - 1],                 97         w = [0, 1, 2, ..., Z - 1],
 98         alpha = SIZE_Z defined in ochre/consta     98         alpha = SIZE_Z defined in ochre/constants.py
 99                                                    99 
100         Returns:                                  100         Returns:
101             A numpy array of second moments of    101             A numpy array of second moments of longitudinal profiles for each event with a shape = (NE, ).
102         """                                       102         """
103         first_moment = self.calc_first_moment(    103         first_moment = self.calc_first_moment()
104         first_moment = np.expand_dims(first_mo    104         first_moment = np.expand_dims(first_moment, axis=1)
105         w = np.expand_dims(self._w, axis=0)       105         w = np.expand_dims(self._w, axis=0)
106         # w has now a shape = [1, Z] and first    106         # w has now a shape = [1, Z] and first moment has a shape = [NE, 1]. There is a broadcasting in the line
107         # below how that one create an array w    107         # below how that one create an array with a shape = [NE, Z]
108         return np.sum(np.multiply(np.power(w *    108         return np.sum(np.multiply(np.power(w * SIZE_Z - first_moment, 2), self._energies_per_event),
109                       axis=1) / self._total_en    109                       axis=1) / self._total_energy_per_event
110                                                   110 
111                                                   111 
112 @dataclass                                        112 @dataclass
113 class LateralProfile(Profile):                    113 class LateralProfile(Profile):
114     """ A class defining observables related t    114     """ A class defining observables related to LateralProfile.
115                                                   115 
116     Attributes:                                   116     Attributes:
117         _energies_per_event: A numpy array wit    117         _energies_per_event: A numpy array with shape = (NE, R) where NE stays for a number of events. An
118             element [i, j] is a sum of energie    118             element [i, j] is a sum of energies detected in all cells located in a jth layer for an ith event.
119         _total_energy_per_event: A numpy array    119         _total_energy_per_event: A numpy array with shape = (NE, ). An element [i] is a sum of energies detected in all
120             cells for an ith event.               120             cells for an ith event.
121         _w: A numpy array = [0, 1, ..., R - 1]    121         _w: A numpy array = [0, 1, ..., R - 1] which represents weights used in computation of first and second moment.
122                                                   122 
123     """                                           123     """
124                                                   124 
125     def __post_init__(self):                      125     def __post_init__(self):
126         self._energies_per_event = np.sum(self    126         self._energies_per_event = np.sum(self._input, axis=(2, 3))
127         self._total_energy_per_event = np.sum(    127         self._total_energy_per_event = np.sum(self._energies_per_event, axis=1)
128         self._w = np.arange(N_CELLS_R)            128         self._w = np.arange(N_CELLS_R)
129                                                   129 
130     def calc_profile(self) -> np.ndarray:         130     def calc_profile(self) -> np.ndarray:
131         """ Calculates a lateral profile.         131         """ Calculates a lateral profile.
132                                                   132 
133         A lateral profile for a given layer l     133         A lateral profile for a given layer l (l = 0, ..., R - 1) is defined as:
134         sum_{i = 0}^{NE - 1} energy_per_event[    134         sum_{i = 0}^{NE - 1} energy_per_event[i, l].
135                                                   135 
136         Returns:                                  136         Returns:
137             A numpy array of longitudinal prof    137             A numpy array of longitudinal profiles for each layer with a shape = (R, ).
138                                                   138 
139         """                                       139         """
140         return np.sum(self._energies_per_event    140         return np.sum(self._energies_per_event, axis=0)
141                                                   141 
142     def calc_first_moment(self) -> np.ndarray:    142     def calc_first_moment(self) -> np.ndarray:
143         """ Calculates a first moment of profi    143         """ Calculates a first moment of profile.
144                                                   144 
145         A first moment of a lateral profile fo    145         A first moment of a lateral profile for a given event e (e = 0, ..., NE - 1) is defined as:
146         FM[e] = alpha * (sum_{i = 0}^{R - 1} e    146         FM[e] = alpha * (sum_{i = 0}^{R - 1} energies_per_event[e, i] * w[i]) / total_energy_per_event[e], where
147         w = [0, 1, 2, ..., R - 1],                147         w = [0, 1, 2, ..., R - 1],
148         alpha = SIZE_R defined in core/constan    148         alpha = SIZE_R defined in core/constants.py.
149                                                   149 
150         Returns:                                  150         Returns:
151             A numpy array of first moments of     151             A numpy array of first moments of lateral profiles for each event with a shape = (NE, ).
152                                                   152 
153         """                                       153         """
154         return SIZE_R * np.dot(self._energies_    154         return SIZE_R * np.dot(self._energies_per_event, self._w) / self._total_energy_per_event
155                                                   155 
156     def calc_second_moment(self) -> np.ndarray    156     def calc_second_moment(self) -> np.ndarray:
157         """ Calculates a second moment of a la    157         """ Calculates a second moment of a lateral profile.
158                                                   158 
159         A second moment of a lateral profile f    159         A second moment of a lateral profile for a given event e (e = 0, ..., NE - 1) is defined as:
160         SM[e] = (sum_{i = 0}^{R - 1} (w[i] - a    160         SM[e] = (sum_{i = 0}^{R - 1} (w[i] - alpha - FM[e])^2 * energies_per_event[e, i]) total_energy_per_event[e],
161         where                                     161         where
162         w = [0, 1, 2, ..., R - 1],                162         w = [0, 1, 2, ..., R - 1],
163         alpha = SIZE_R defined in ochre/consta    163         alpha = SIZE_R defined in ochre/constants.py
164                                                   164 
165         Returns:                                  165         Returns:
166             A numpy array of second moments of    166             A numpy array of second moments of lateral profiles for each event with a shape = (NE, ).
167         """                                       167         """
168         first_moment = self.calc_first_moment(    168         first_moment = self.calc_first_moment()
169         first_moment = np.expand_dims(first_mo    169         first_moment = np.expand_dims(first_moment, axis=1)
170         w = np.expand_dims(self._w, axis=0)       170         w = np.expand_dims(self._w, axis=0)
171         # w has now a shape = [1, R] and first    171         # w has now a shape = [1, R] and first moment has a shape = [NE, 1]. There is a broadcasting in the line
172         # below how that one create an array w    172         # below how that one create an array with a shape = [NE, R]
173         return np.sum(np.multiply(np.power(w *    173         return np.sum(np.multiply(np.power(w * SIZE_R - first_moment, 2), self._energies_per_event),
174                       axis=1) / self._total_en    174                       axis=1) / self._total_energy_per_event
175                                                   175 
176                                                   176 
177 @dataclass                                        177 @dataclass
178 class Energy(Observable):                         178 class Energy(Observable):
179     """ A class defining observables total ene    179     """ A class defining observables total energy per event and cell energy.
180                                                   180 
181     """                                           181     """
182                                                   182 
183     def calc_total_energy(self):                  183     def calc_total_energy(self):
184         """ Calculates total energy detected i    184         """ Calculates total energy detected in an event.
185                                                   185 
186         Total energy for a given event e (e =     186         Total energy for a given event e (e = 0, ..., NE - 1) is defined as a sum of energies detected in all cells
187         for this event.                           187         for this event.
188                                                   188 
189         Returns:                                  189         Returns:
190             A numpy array of total energy valu    190             A numpy array of total energy values with shape = (NE, ).
191         """                                       191         """
192         return np.sum(self._input, axis=(1, 2,    192         return np.sum(self._input, axis=(1, 2, 3))
193                                                   193 
194     def calc_cell_energy(self):                   194     def calc_cell_energy(self):
195         """ Calculates cell energy.               195         """ Calculates cell energy.
196                                                   196 
197         Cell energy for a given event (e = 0,     197         Cell energy for a given event (e = 0, ..., NE - 1) is defined by an array with shape (R * PHI * Z) storing
198         values of energy in particular cells.     198         values of energy in particular cells.
199                                                   199 
200         Returns:                                  200         Returns:
201             A numpy array of cell energy value    201             A numpy array of cell energy values with shape = (NE * R * PHI * Z, ).
202                                                   202 
203         """                                       203         """
204         return np.copy(self._input).reshape(-1    204         return np.copy(self._input).reshape(-1)
205                                                   205 
206     def calc_energy_per_layer(self):              206     def calc_energy_per_layer(self):
207         """ Calculates total energy detected i    207         """ Calculates total energy detected in a particular layer.
208                                                   208 
209         Energy per layer for a given event (e     209         Energy per layer for a given event (e = 0, ..., NE - 1) is defined by an array with shape (Z, ) storing
210         values of total energy detected in a p    210         values of total energy detected in a particular layer
211                                                   211 
212         Returns:                                  212         Returns:
213             A numpy array of cell energy value    213             A numpy array of cell energy values with shape = (NE, Z).
214                                                   214 
215         """                                       215         """
216         return np.sum(self._input, axis=(1, 2)    216         return np.sum(self._input, axis=(1, 2))