Helper classes
==============

.. _api.CustomMeasurement:

CustomMeasurement
-----------------

.. py:class:: CustomMeasurement(tagger)

   Python and C# wrapper for :cpp:class:`CustomMeasurementBase`.

   :param TimeTaggerBase tagger: Time Tagger object instance.

   .. py:method:: process(incoming_tags, begin_time, end_time)

      Override this method to implement the measurement logic.
      The method is called whenever a new chunk of time tags is available.

      :param incoming_tags:
         Chunk of incoming time tags for this call.

      :param int begin_time:
         Begin timestamp of the processed chunk.

      :param int end_time:
         End timestamp of the processed chunk.

      This method is executed on the Time Tagger backend thread and is the
      performance-critical part of a custom measurement.
      The ``incoming_tags`` buffer is only valid during the current call and may be overwritten by the
      next one. If you need to store tags, create a copy. In Python, it is usually
      advisable to use :func:`numpy.array` and vectorized NumPy operations, or compiled code such as
      `Numba <https://numba.pydata.org/>`_ if explicit iteration over the tags is
      required.

      .. note::
         In Python, the `incoming_tags` are a :ref:`structured Numpy array <numpy:structured_arrays>`.
         You can access single tags as well as arrays of tag entries directly:

         .. code:: python

            first_tag = incoming_tags[0]
            all_timestamps = incoming_tags['time']

   .. py:attribute:: mutex

        Context manager object (see :ref:`python:typecontextmanager`) that locks the mutex when used and automatically unlocks it when the code block exits.
        For example, it is intended for use with Python's :ref:`"with" keyword <python:with>` as

        .. code-block:: python

            class MyMeasurement(CustomMeasurement):

                def getData(self):
                    # Acquire a lock for this instance to guarantee that
                    # self.data is not modified in other parallel threads.
                    # This ensures to return a consistent data.
                    with self.mutex:
                        return self.data.copy()

   .. note::
      You can find an example of how to use the ``CustomMeasurement`` in the
      installation folder. Further custom measurement examples are available in the
      `Time-Tagger-Custom-Measurements <https://github.com/swabianinstruments/Time-Tagger-Custom-Measurements>`_ repository.

.. doxygenclass:: CustomMeasurementBase


.. _api.SynchronizedMeasurements:

SynchronizedMeasurements
------------------------

.. doxygenclass:: SynchronizedMeasurements
