pymchelper.detector module

class pymchelper.detector.Detector[source]

Bases: object

Detector data including scoring mesh description.

This class handles in universal way data generated with MC code. It includes data (data and data_raw fields) and optinal errors (error and error_raw). Detector holds also up to 3 binning axis (x, y and z fields). Scored quantity can be assigned a name (i.e. dose) and unit (i.e. Gy). Several other fields are also used:

  • nstat: number of simulated histories
  • counter: number of files read to construct detector object
  • corename: common core part of input files defining a name of detector
  • error_type: none, stderr or stddev - error type

Detector data can be either read from the file (see fromfile method in io module or constructed directly:

>>> d = Detector()
>>> d.x = MeshAxis(n=2, min_val=0.0, max_val=10.0, name="X", unit="cm", binning=MeshAxis.BinningType.linear)
>>> d.x.data
array([ 2.5,  7.5])
>>> d.y = MeshAxis(n=3, min_val=0.0, max_val=150.0, name="Y", unit="cm", binning=MeshAxis.BinningType.linear)
>>> d.y.data
array([  25.,   75.,  125.])
>>> d.z = MeshAxis(n=1, min_val=0.0, max_val=1.0, name="Z", unit="cm", binning=MeshAxis.BinningType.linear)
>>> d.z.data
array([ 0.5])
>>> d.data_raw = np.arange(6)
>>> d.data.shape
(2, 3, 1)
>>> d.data
array([[[0],
        [1],
        [2]],
       [[3],
        [4],
        [5]]])
axis(id)[source]

Mesh axis selector method based on integer id’s.

Instead of getting mesh axis data by calling d.x, d.y or d.z (assuming d an object of Detector class) we can get that data by calling d.axis(0), d.axis(1) or d.axis(2). See for example: >>> d = Detector() >>> d.x = MeshAxis(n=2, min_val=0.0, max_val=10.0, name=”X”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.y = MeshAxis(n=3, min_val=0.0, max_val=150.0, name=”Y”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.z = MeshAxis(n=1, min_val=0.0, max_val=1.0, name=”Z”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.axis(1) MeshAxis(n=3, min_val=0.0, max_val=150.0, name=’Y’, unit=’cm’, binning=<BinningType.linear: 0>)

Parameters:id – axis id (0, 1 or 2)
Returns:MeshAxis object
data

3-D view of detector data.

Detector data are stored originally in data_raw 1-D array. This property provides efficient view of detector data, suitable for numpy-like indexing.

>>> d = Detector()
>>> d.x = MeshAxis(n=2, min_val=0.0, max_val=10.0, name="X", unit="cm", binning=MeshAxis.BinningType.linear)
>>> d.y = MeshAxis(n=3, min_val=0.0, max_val=150.0, name="Y", unit="cm", binning=MeshAxis.BinningType.linear)
>>> d.z = MeshAxis(n=1, min_val=0.0, max_val=1.0, name="Z", unit="cm", binning=MeshAxis.BinningType.linear)
>>> d.data_raw = np.arange(6)
>>> d.data.shape
(2, 3, 1)
>>> d.data[1, 2, 0]
5
Returns:reshaped view of data_raw
dimension

Let’s take again detector d with YZ scoring. >>> d = Detector() >>> d.x = MeshAxis(n=1, min_val=0.0, max_val=1.0, name=”X”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.y = MeshAxis(n=3, min_val=0.0, max_val=150.0, name=”Y”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.z = MeshAxis(n=2, min_val=0.0, max_val=2.0, name=”Z”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.dimension 2

Returns:number of axes which have more than one point
error

3-D view of detector error

For more details see data property. :return:

plot_axis(id)[source]

Calculate new order of detector axis, axis with data (n>1) comes first Axes with constant value goes last.

Let’s take a detector d with YZ scoring. >>> d = Detector() >>> d.x = MeshAxis(n=1, min_val=0.0, max_val=1.0, name=”X”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.y = MeshAxis(n=3, min_val=0.0, max_val=150.0, name=”Y”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> d.z = MeshAxis(n=2, min_val=0.0, max_val=2.0, name=”Z”, unit=”cm”, binning=MeshAxis.BinningType.linear)

First axis for plotting will be Y (as X axis holds only one bin): >>> d.plot_axis(0) MeshAxis(n=3, min_val=0.0, max_val=150.0, name=’Y’, unit=’cm’, binning=<BinningType.linear: 0>)

Second axis for plotting will be Z (its the next after Y with n > 1 bins) >>> d.plot_axis(1) MeshAxis(n=2, min_val=0.0, max_val=2.0, name=’Z’, unit=’cm’, binning=<BinningType.linear: 0>)

Finally the third axis will be X, but it cannot be used for plotting as it has only one bin. >>> d.plot_axis(2) MeshAxis(n=1, min_val=0.0, max_val=1.0, name=’X’, unit=’cm’, binning=<BinningType.linear: 0>)

Parameters:id – axis number (0, 1 or 2)
Returns:axis object
class pymchelper.detector.ErrorEstimate[source]

Bases: enum.IntEnum

An enumeration.

none = 0
stddev = 2
stderr = 1
class pymchelper.detector.MeshAxis[source]

Bases: pymchelper.detector.MeshAxis

Scoring mesh axis data.

It can represent an axis variety of scorers: x,y or z in cartesian scoring, r, rho or z in cylindrical. An axis represents a sequence of n numbers, defining linear or logarithmic binning. This sequence of numbers is not stored in the memory, but can be generated using data property method. min_val is lowest bin left edge, max_val is highest bin right edge name can be used to define physical quantity (i.e. position, energy, angle). unit gives physical units (i.e. cm, MeV, mrad).

MeshAxis is constructed as immutable data structure, thus it is possible to set field values only upon object creation. Later they are available for read only.

>>> x = MeshAxis(n=10, min_val=0.0, max_val=30.0, name="Position", unit="cm", binning=MeshAxis.BinningType.linear)
>>> x.n, x.min_val, x.max_val
(10, 0.0, 30.0)
>>> x.n = 5
Traceback (most recent call last):
...
AttributeError: can't set attribute

binning field (use internal BinningType.linear or BinningType.logarithmic) can distinguish log from linear binning

class BinningType[source]

Bases: enum.IntEnum

type of axis generator

linear = 0
logarithmic = 1
data

Generates linear or logarithmic sequence of n numbers.

These numbers are middle points of the bins defined by n, min_val and max_val parameters.

>>> x = MeshAxis(n=10, min_val=0.0, max_val=10.0, name="X", unit="cm", binning=MeshAxis.BinningType.linear)
>>> x.data
array([ 0.5,  1.5,  2.5,  3.5,  4.5,  5.5,  6.5,  7.5,  8.5,  9.5])

Binning may also consist of one bin: >>> x = MeshAxis(n=1, min_val=0.0, max_val=5.0, name=”X”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> x.data array([ 2.5])

Logarithmic binning works as well, middle bin points are calculated as geometrical mean. Here we define 3 bins: [1,4], [4,16], [16,64]. >>> x = MeshAxis(n=3, min_val=1.0, max_val=64.0, name=”X”, unit=”cm”, binning=MeshAxis.BinningType.logarithmic) >>> x.data array([ 2., 8., 32.])

For the same settings as below linear scale gives as expected different sequence: >>> x = MeshAxis(n=3, min_val=1.0, max_val=64.0, name=”X”, unit=”cm”, binning=MeshAxis.BinningType.linear) >>> x.data array([ 11.5, 32.5, 53.5])

For logarithmic axis min_val has to be positive: >>> x = MeshAxis(n=3, min_val=-2.0, max_val=64.0, name=”X”, unit=”cm”, binning=MeshAxis.BinningType.logarithmic) >>> x.data Traceback (most recent call last): … Exception: Left edge of first bin (-2) is not positive

Returns:
pymchelper.detector.average_with_nan(detector_list, error_estimate=<ErrorEstimate.stderr: 1>)[source]

Calculate average detector object, excluding malformed data (NaN) from averaging. :param detector_list: :param error_estimate: :return: