pept.utilities.traverse API documentation

# Module `pept.utilities.traverse`

Source code

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    # File   : __init__.py
    # License: GNU v3.0
    # Author : Andrei Leonard Nicusan <a.l.nicusan@bham.ac.uk>
    # Date   : 14.01.2020

    from    .traverse2d     import  traverse2d
    from    .traverse3d     import  traverse3d

    __all__ = [
        "traverse2d",
        "traverse3d",
    ]

    __author__ =        "Andrei Leonard Nicusan"
    __credits__ =       ["Andrei Leonard Nicusan", "Kit Windows-Yule", "Sam Manger"]
    __license__ =       "GNU v3.0"
    __maintainer__ =    "Andrei Leonard Nicusan"
    __email__ =         "a.l.nicusan@bham.ac.uk"
    __status__ =        "Development"

## Functions

`def traverse2d(...)`

  Fast voxel traversal for 2D lines (or LoRs).

  Function Signature: traverse3d( long[:, :] pixels, # Initialised to zero! double[:, :] lines, # Has exactly 7 columns! double[:] grid_x, # Has pixels.shape[0] + 1 elements! double[:] grid_y, # Has pixels.shape[1] + 1 elements! )

  This function computes the number of lines that passes through each pixel, saving the result in `pixels`. It does so in an efficient manner, in which for every line, only the pixels that it passes through are traversed.

  As it is highly optimised, this function does not perform any checks on the validity of the input data. Please check the parameters before calling `traverse2d()`, as it WILL segfault on wrong input data. Details are given below, along with an example call.

  ## Parameters

      pixels : numpy.ndarray(dtype = numpy.int64, ndim = 2)
          The `pixels` parameter is a numpy.ndarray of shape (X, Y) that
          has been initialised to zeros before the function call. The values
          will be modified in-place in the function to reflect the number of
          lines that pass through each pixel.
      lines : numpy.ndarray(dtype = numpy.float64, ndim = 2)
          The `lines` parameter is a numpy.ndarray of shape(N, 5), where each
          row is formatted as [time, x1, y1, x2, y2]. Only indices 1:5
          will be used as the two points P1 = [x1, y1] and P2 = [x2, y2]
          defining the line (or LoR).
      grid_x : numpy.ndarray(dtype = numpy.float64, ndim = 1)
          The grid_x parameter is a one-dimensional grid that delimits the
          pixels in the x-dimension. It must be *sorted* in ascending order
          with *equally-spaced* numbers and length X + 1 (pixels.shape[0] + 1).
      grid_y : numpy.ndarray(dtype = numpy.float64, ndim = 1)
          The grid_y parameter is a one-dimensional grid that delimits the
          pixels in the y-dimension. It must be *sorted* in ascending order
          with *equally-spaced* numbers and length Y + 1 (pixels.shape[1] + 1).

  ## Example usage

  The input parameters can be easily generated using numpy before calling the function. For example, if a plane of 300 x 400 is split into 30 x 40 pixels, a possible code would be:

      >>> import numpy as np
      >>> from pept.utilities.traverse import traverse2d
      >>>
      >>> plane = [300, 400]
      >>> number_of_pixels = [30, 40]
      >>> pixels = np.zeros(number_of_pixels)

  The grid has one extra element than the number of pixels. For example, 5 pixels between 0 and 5 would be delimited by the grid [0, 1, 2, 3, 4, 5] which has 6 elements (see off-by-one errors - story of my life).

      >>> grid_x = np.linspace(0, plane[0], number_of_pixels[0] + 1)
      >>> grid_y = np.linspace(0, plane[1], number_of_pixels[1] + 1)
      >>>
      >>> random_lines = np.random.random((100, 5)) * 100

  Calling `traverse2d()` will modify `pixels` in-place.

      >>> traverse2d(pixels, random_lines, grid_x, grid_y)

  ## Note

  This function is an adaptation of a widely-used algorithm [1], optimised for PEPT LoRs traversal.

  .. [1] Amanatides J, Woo A. A fast voxel traversal algorithm for ray tracing. InEurographics 1987 Aug 24 (Vol. 87, No. 3, pp. 3-10)..

`def traverse3d(...)`

  Fast voxel traversal for 3D lines (or LoRs).

  Function Signature: traverse3d( long[:, :, :] voxels, # Initialised to zero! double[:, :] lines, # Has exactly 7 columns! double[:] grid_x, # Has voxels.shape[0] + 1 elements! double[:] grid_y, # Has voxels.shape[1] + 1 elements! double[:] grid_z # Has voxels.shape[2] + 1 elements! )

  This function computes the number of lines that passes through each voxel, saving the result in `voxels`. It does so in an efficient manner, in which for every line, only the voxels that is passes through are traversed.

  As it is highly optimised, this function does not perform any checks on the validity of the input data. Please check the parameters before calling `traverse3d()`, as it WILL segfault on wrong input data. Details are given below, along with an example call.

  ## Parameters

      voxels : numpy.ndarray(dtype = numpy.int64, ndim = 3)
          The `voxels` parameter is a numpy.ndarray of shape (X, Y, Z) that
          has been initialised to zeros before the function call. The values
          will be modified in-place in the function to reflect the number of
          lines that pass through each voxel.
      lines : numpy.ndarray(dtype = numpy.float64, ndim = 2)
          The `lines` parameter is a numpy.ndarray of shape(N, 7), where each
          row is formatted as [time, x1, y1, z1, x2, y2, z2]. Only indices 1:7
          will be used as the two points P1 = [x1, y1, z2] and P2 = [x2, y2, z2]
          defining the line (or LoR).
      grid_x : numpy.ndarray(dtype = numpy.float64, ndim = 1)
          The grid_x parameter is a one-dimensional grid that delimits the
          voxels in the x-dimension. It must be *sorted* in ascending order
          with *equally-spaced* numbers and length X + 1 (voxels.shape[0] + 1).
      grid_y : numpy.ndarray(dtype = numpy.float64, ndim = 1)
          The grid_y parameter is a one-dimensional grid that delimits the
          voxels in the y-dimension. It must be *sorted* in ascending order
          with *equally-spaced* numbers and length Y + 1 (voxels.shape[1] + 1).
      grid_z : numpy.ndarray(dtype = numpy.float64, ndim = 1)
          The grid_z parameter is a one-dimensional grid that delimits the
          voxels in the z-dimension. It must be *sorted* in ascending order
          with *equally-spaced* numbers and length Z + 1 (voxels.shape[2] + 1).

  ## Example usage

  The input parameters can be easily generated using numpy before calling the function. For example, if a volume of 300 x 400 x 500 is split into 30 x 40 x 50 voxels, a possible code would be:

      >>> import numpy as np
      >>> from pept.utilities.traverse import traverse3d
      >>>
      >>> volume = [300, 400, 500]
      >>> number_of_voxels = [30, 40, 50]
      >>> voxels = np.zeros(number_of_voxels)

  The grid has one extra element than the number of voxels. For example, 5 voxels between 0 and 5 would be delimited by the grid [0, 1, 2, 3, 4, 5] which has 6 elements (see off-by-one errors - story of my life).

      >>> grid_x = np.linspace(0, volume[0], number_of_voxels[0] + 1)
      >>> grid_y = np.linspace(0, volume[1], number_of_voxels[1] + 1)
      >>> grid_z = np.linspace(0, volume[2], number_of_voxels[2] + 1)
      >>>
      >>> random_lines = np.random.random((100, 7)) * 300

  Calling `traverse3d()` will modify `voxels` in-place.

      >>> traverse3d(voxels, random_lines, grid_x, grid_y, grid_z)

  ## Note

  This function is an adaptation of a widely-used algorithm [1], optimised for PEPT LoRs traversal.

  .. [1] Amanatides J, Woo A. A fast voxel traversal algorithm for ray tracing. InEurographics 1987 Aug 24 (Vol. 87, No. 3, pp. 3-10)..