pept.scanners.modular_camera API documentation

# Module `pept.scanners.modular_camera`

Source code

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-

    # File   : __init__.py
    # License: License: GNU v3.0
    # Author : Sam Manger <s.manger@bham.ac.uk>
    # Date   : 20.08.2019

    from    .modular_camera    import  ModularCamera

    __all__ = [
        'ModularCamera'
    ]

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

## Sub-modules

`pept.scanners.modular_camera.extensions`
`pept.scanners.modular_camera.modular_camera`

## Classes

`class ModularCamera (dataFile, sample_size=200, overlap=0, filtered=[], verbose=True)`

  A subclass of `LineData` that reads PEPT data from the modular camera DAQ.

  Provides the same functionality as the `LineData` class while initialising `line_data` from a given file. This is a helper class for PEPT using the modular camera.

  Can read data from a `.da_1` file or equivalent. The file must contain the standard datawords from the modular camera output. This will then be automatically transformed into the standard `_line_data` format with every row being `[time, x1, y1, z1, x2, y2, z2]`, where the geometry is derived from the C-extension. The current useable geometry is a square layout with 4 stacks for 4 modules, separated by 250 mm.

  ## Parameters

  `dataFile` :`str`
    A string with the (absolute or relative) path to the data file from which the PEPT data will be read. It should include the full file name, along with the extension (.da_1)
  `sample_size` :`int`, optional
    An `int`` that defines the number of lines that should be returned when iterating over`_line_data`. A`sample_size` of 0 yields all the data as one single sample. (Default is 200)
  `overlap` :`int`, optional
    An `int` that defines the overlap between two consecutive samples that are returned when iterating over `_line_data`. An overlap of 0 means consecutive samples, while an overlap of (`sample_size` - 1) means incrementing the samples by one. A negative overlap means skipping values between samples. An error is raised if `overlap` is larger than or equal to `sample_size`. (Default is 0)
  `filtered` :`list`, optional
    A list of 'int's of module pair numbers that will be filtered from the PEPT data. For use when noisy data affects tracking. (Default is [])
  `verbose` :`bool`, optional
    An option that enables printing the time taken for the initialisation of an instance of the class. Useful when reading large files (10gb files for PEPT data is not unheard of). (Default is True)

  ## Attributes

  `_line_data` : (`N`, `7`) `numpy.ndarray`
    An (N, 7) numpy array that stores the PEPT LoRs as time and cartesian (3D) coordinates of two points defining a line, in mm. Each row is then `[time, x1, y1, z1, x2, y2, z2]`.
  `sample_size` :`int`
    An `int` that defines the number of lines that should be returned when iterating over `_line_data`. (Default is 200)
  `overlap` :`int`
    An `int` that defines the overlap between two consecutive samples that are returned when iterating over `_line_data`. An overlap of 0 means consecutive samples, while an overlap of (`sample_size` - 1) means incrementing the samples by one. A negative overlap means skipping values between samples. It has to be smaller than `sample_size`. (Default is 0)
  `numberOfLines` :`int`
    An `int` that corresponds to len(`_line_data`), or the number of LoRs stored by `_line_data`.

  ## Raises

  `ValueError`
    If `overlap` >= `sample_size`. Overlap has to be smaller than `sample_size`. Note that it can also be negative.
  `ValueError`
    If the data file does not have (N, 7) shape.

  ## Notes

  The class saves `line_data` as a contiguous numpy array for efficient access in C functions. It should not be changed after instantiating the class.

  Source code

      class ModularCamera(LineData):
              '''A subclass of `LineData` that reads PEPT data from the modular camera DAQ.

              Provides the same functionality as the `LineData` class while
              initialising `line_data` from a given file. This is a helper class
              for **PEPT using the modular camera**.

              Can read data from a `.da_1` file or equivalent. The file must contain
              the standard datawords from the modular camera output. This will then
              be automatically transformed into the standard `_line_data` format
              with every row being `[time, x1, y1, z1, x2, y2, z2]`, where the geometry
              is derived from the C-extension. The current useable geometry is a square
              layout with 4 stacks for 4 modules, separated by 250 mm.

              Parameters
              ----------
              dataFile : str
                      A string with the (absolute or relative) path to the data file
                      from which the PEPT data will be read. It should include the
                      full file name, along with the extension (.da_1)
              sample_size : int, optional
                      An `int`` that defines the number of lines that should be
                      returned when iterating over `_line_data`. A `sample_size` of 0
                      yields all the data as one single sample. (Default is 200)
              overlap : int, optional
                      An `int` that defines the overlap between two consecutive
                      samples that are returned when iterating over `_line_data`.
                      An overlap of 0 means consecutive samples, while an overlap
                      of (`sample_size` - 1) means incrementing the samples by one.
                      A negative overlap means skipping values between samples. An
                      error is raised if `overlap` is larger than or equal to
                      `sample_size`. (Default is 0)
              filtered : list, optional
                      A list of 'int's of module pair numbers that will be filtered
                      from the PEPT data. For use when noisy data affects tracking.
                      (Default is [])
              verbose : bool, optional
                      An option that enables printing the time taken for the
                      initialisation of an instance of the class. Useful when
                      reading large files (10gb files for PEPT data is not unheard
                      of). (Default is True)

              Attributes
              ----------
              _line_data : (N, 7) numpy.ndarray
                      An (N, 7) numpy array that stores the PEPT LoRs as time and
                      cartesian (3D) coordinates of two points defining a line, **in mm**.
                      Each row is then `[time, x1, y1, z1, x2, y2, z2]`.
              sample_size : int
                      An `int` that defines the number of lines that should be
                      returned when iterating over `_line_data`. (Default is 200)
              overlap : int
                      An `int` that defines the overlap between two consecutive
                      samples that are returned when iterating over `_line_data`.
                      An overlap of 0 means consecutive samples, while an overlap
                      of (`sample_size` - 1) means incrementing the samples by one.
                      A negative overlap means skipping values between samples. It
                      has to be smaller than `sample_size`. (Default is 0)
              numberOfLines : int
                      An `int` that corresponds to len(`_line_data`), or the number of
                      LoRs stored by `_line_data`.

              Raises
              ------
              ValueError
                      If `overlap` >= `sample_size`. Overlap has to be smaller than
                      `sample_size`. Note that it can also be negative.
              ValueError
                      If the data file does not have (N, 7) shape.

              Notes
              -----
              The class saves `line_data` as a **contiguous** numpy array for
              efficient access in C functions. It should not be changed after
              instantiating the class.

              '''

              def __init__(self,
                                       dataFile,
                                       sample_size = 200,
                                       overlap = 0,
                                       filtered =[],
                                       verbose = True):

                      if verbose:
                              start = time.time()

                      if sample_size != 0 and overlap >= sample_size:
                              raise ValueError('\n[ERROR]: overlap = {} must be smaller than sample_size = {}\n'.format(overlap, sample_size))

                      self._index = 0
                      self._sample_size = sample_size
                      self._overlap = overlap

                      self.dataFile = dataFile
                      self.filtered = []

                      x = 10

                      header_buffer_size = 1000

                      self.n_events = 0

                      if sample_size == 0:
                              sample_size = int( (os.path.getsize(self.dataFile) - header_buffer_size) /4 ) # Set the sample size to the expected number of events
                              self.overlap = -1

                      # Modular camera data reader requires 'itag' for timing. We will drop this column at the end of initialisation
                      # Row: [itag, itime, X1, Y1, Z1, X2, Y2, Z2]

                      self._line_data = np.zeros([sample_size, 8])

                      with open(self.dataFile,"rb") as f:

                              # Skip over the header and handshake word

                              f.seek(header_buffer_size)

                              word = f.read(4)

                              if word.hex() == 'cefacefa':
                                      # Skip two words
                                      word = f.read(4)
                                      word = f.read(4)

                              itime = 0
                              itag = 0

                              BufTime = 0
                              nBuf = 0

                              while word != b'' and (self.n_events < sample_size):

                                      word = f.read(4)

                                      if word.hex() == 'cefacefa': # Handshake word
                                              # Skip two words
                                              word = f.read(4)
                                              word = f.read(4)

                                      if word!=b'':
                                              word = int.from_bytes(word, "little")

                                              self._line_data[self.n_events,:] = get_pept_LOR(word,itag,itime) # C function

                                              itag  = self._line_data[self.n_events,1]
                                              itime = self._line_data[self.n_events,1]

                                              self.n_events = self.n_events + 1

                                              if (self.n_events % x) == 0:
                                                      print("Got ", self.n_events,"\n")
                                                      x = x * 10

                      # Remove 'zero' lines
                      self._line_data = self._line_data[np.all(self._line_data,axis=1)]

                      # Drop itag column
                      self._line_data = np.delete(self._line_data, 0, axis=1)

                      self._number_of_lines = len(self._line_data)

                      if verbose:
                              end = time.time()
                              print("Initialising the PEPT data took {} seconds\n".format(end - start))

  ### Ancestors

  - LineData

  ### Inherited members

  - `LineData`:
    - `line_data`
    - `lines_trace`
    - `number_of_lines`
    - `number_of_samples`
    - `overlap`
    - `plot_all_lines`
    - `plot_all_lines_alt_axes`
    - `plot_lines_sample_n`
    - `plot_lines_sample_n_alt_axes`
    - `sample_n`
    - `sample_size`
    - `to_csv`