**********************
Programming Languages
**********************


In this section, we show how to interface the Time Tagger and perform measurements using the supported
programming environments. The *Time Tagger* API is implemented in C++ and exposed to several higher-level
languages via wrapper libraries (Python, MATLAB, LabVIEW, .NET).
More details about the software interface are covered by the API documentation in the :doc:`/api/index` chapter.

Before you begin, ensure the Time Tagger software is installed; if not, see :doc:`/gettingStarted/installation`.
Also make sure your Time Tagger device is connected to your computer and not in use by other applications
(e.g., close |ttlab-name|).


.. _examples:

Python
------

#. Make sure a Python distribution is available. We provide full support for `actively supported Python versions <https://devguide.python.org/versions/>_,`.
   Older versions, while untested, might still work.

    - On **Unix/Linux** systems, a system-supported installation of Python should already be present.
    - On **Windows** systems, you can install Python by following `these instructions <https://docs.python.org/3/using/windows.html>`_.
      We recommend the default installation ("Install Now"), as it includes all standard libraries and pip.
#. Make sure to install the required Python package (`NumPy <https://numpy.org/install/>`_)
   as well as the recommended ones (`Matplotlib <https://matplotlib.org/stable/install/index.html>`_, and `ipython <https://ipython.org/install/>`_).

#. Open a command shell and navigate to the ``.\examples\python\1-Quickstart`` folder in your *Time Tagger* installation directory.
#. Start an ipython shell with plotting support by entering ``ipython --pylab``.
#. Run the `hello_world` script by entering ``run hello_world``.

The `hello_world` executes a simple yet useful measurement that demonstrates many essential features of the *Time Tagger* programming interface:

#. Connects your Time Tagger.
#. Starts the built-in test signal (~0.8 MHz square wave) and apply it to channels 1 and 2.
#. Controls the trigger level of your inputs - although it is not necessary here.
#. Initializes a standard measurement (:ref:`api.Correlation`) in order to find the delay of the test signal between channel 1 and 2.
#. Shows how to control the delay of different inputs programmatically.

You are encouraged to open and read the `hello_world` file in an editor to understand what it does.
With this basic knowledge, you can explore the other examples in the ``1-Quickstart`` folder:


+-----+---------------------------+--------------------------------------------------------------+
| No. | Topic                     | Classes & Methods                                            |
+=====+===========================+==============================================================+
| **Basic software control** (folder `1-basic_software_control`)                                 |
+-----+---------------------------+--------------------------------------------------------------+
| 1-A | Create a measurement      | :cpp:func:`createTimeTagger`,                                |
|     |                           | :cpp:func:`Counter::getData`,                                |
|     |                           |                                                              |
|     |                           | :cpp:func:`Counter::getIndex`                                |
+     +---------------------------+--------------------------------------------------------------+
|     | Count rate trace          | :cpp:class:`Counter`                                         |
+-----+---------------------------+--------------------------------------------------------------+
| 1-B | Start & stop measurements | :cpp:class:`Countrate`,                                      |
|     |                           | :cpp:func:`~IteratorBase::start`,                            |
|     |                           | :cpp:func:`~IteratorBase::stop`,                             |
|     |                           | :cpp:func:`~IteratorBase::startFor`                          |
+-----+---------------------------+--------------------------------------------------------------+
| 1-C | Synchronize measurements  | :cpp:class:`SynchronizedMeasurements`                        |
+     +---------------------------+--------------------------------------------------------------+
|     | Use different histograms  | :cpp:class:`Correlation`,                                    |
|     |                           | :cpp:class:`Histogram`,                                      |
|     |                           |                                                              |
|     |                           | :cpp:class:`StartStop`,                                      |
|     |                           | :cpp:class:`HistogramLogBins`                                |
+-----+---------------------------+--------------------------------------------------------------+
| 1-D | Virtual Channels          | :cpp:class:`DelayedChannel`,                                 |
|     |                           | :cpp:class:`Coincidence`,                                    |
|     |                           | :cpp:class:`GatedChannel`                                    |
+-----+---------------------------+--------------------------------------------------------------+
| 1-E | Logging errors            | :cpp:func:`setLogger`                                        |
+-----+---------------------------+--------------------------------------------------------------+
| 1-F | External reference clock  | :cpp:func:`TimeTaggerSource::setReferenceClock`,             |
|     |                           |                                                              |
|     |                           | :cpp:class:`FrequencyStability`                              |
+-----+---------------------------+--------------------------------------------------------------+
| **Controlling the hardware** (folder `2-controlling-the-hardware`)                             |
+-----+---------------------------+--------------------------------------------------------------+
| 2-A | Get hardware information  | :cpp:func:`scanTimeTagger`,                                  |
|     |                           | :cpp:func:`~TimeTaggerHardware::getSerial`,                  |
|     |                           |                                                              |
|     |                           | :cpp:func:`~TimeTaggerHardware::getModel`,                   |
|     |                           | :cpp:func:`~TimeTaggerHardware::getSensorData`,              |
|     |                           |                                                              |
|     |                           | :cpp:func:`~TimeTaggerBase::getConfiguration`                |
+-----+---------------------------+--------------------------------------------------------------+
| 2-B | The input trigger level   | :cpp:func:`~TimeTaggerHardware::setTriggerLevel`,            |
|     |                           | :cpp:func:`~TimeTaggerHardware::getTriggerLevelRange`        |
+-----+---------------------------+--------------------------------------------------------------+
| 2-C | Filter tags on hardware   | :cpp:func:`~TimeTaggerSource::setConditionalFilter`,         |
|     |                           |                                                              |
|     |                           | :cpp:func:`~TimeTaggerSource::setEventDivider`               |
+-----+---------------------------+--------------------------------------------------------------+
| 2-D | Control input delays      | :cpp:func:`~TimeTaggerSource::setInputDelay`,                |
|     |                           | :cpp:class:`Histogram2D`                                     |
+-----+---------------------------+--------------------------------------------------------------+
| 2-E | Overflows                 | :cpp:func:`~TimeTaggerSource::getOverflows`,                 |
|     |                           |                                                              |
|     |                           | :cpp:func:`~TimeTaggerHardware::setTestSignalDivider`        |
+-----+---------------------------+--------------------------------------------------------------+
| 2-F | HighRes mode              | :cpp:func:`createTimeTagger`,                                |
|     |                           | :cpp:class:`TimeDifferences`                                 |
+-----+---------------------------+--------------------------------------------------------------+
| **Dump and re-analyze time-tags** (folder `3-dump-and-reanalyze-time-tags`)                    |
+-----+---------------------------+--------------------------------------------------------------+
| 3-A | Dump tags by FileWriter   | :cpp:class:`FileWriter`                                      |
+-----+---------------------------+--------------------------------------------------------------+
| 3-B | The Time Tagger Virtual   | :cpp:func:`createTimeTaggerVirtual`,                         |
|     |                           | :cpp:class:`TimeTaggerVirtual`                               |
+-----+---------------------------+--------------------------------------------------------------+
| **Working with raw time-tags** (folder `4-working-with-raw-time-tags`)                         |
+-----+---------------------------+--------------------------------------------------------------+
| 4-A | The FileReader            | :cpp:class:`FileReader`,                                     |
|     |                           | :cpp:class:`TimeTagStreamBuffer`                             |
+-----+---------------------------+--------------------------------------------------------------+
| 4-B | Streaming raw time-tags   | :cpp:class:`TimeTagStream`                                   |
+-----+---------------------------+--------------------------------------------------------------+
| 4-C | Custom Measurements       | :class:`CustomMeasurement`                                   |
+-----+---------------------------+--------------------------------------------------------------+

LabVIEW (via .NET)
------------------

In LabVIEW, you can access and program your Time Tagger through .NET interoperability.

    .. figure::  ../images/LV_dotNET_interop.png
        :width: 100%
        :align: center

A set of examples is provided in ``.\examples\LabVIEW\`` for LabVIEW 2014 and higher (32 and 64 bit).


MATLAB (wrapper for .NET)
-------------------------

Wrapper classes are also provided for MATLAB.
The *Time Tagger* toolbox is automatically installed during the setup. If the `TimeTagger` is not available in your MATLAB
environment try to reinstall the toolbox from ``.\driver\Matlab\TimeTaggerMatlab.mltbx``.

The following changes in respect to the .NET library have been made:

* Static functions are available through the `TimeTagger` class.
* All classes except for ``TimeTagger``, ``TimeTaggerNetwork``, and ``TimeTaggerVirtual``
  have a ``TT`` prefix (e.g. ``TTCountrate``) to prevent conflict with any variables/classes in your MATLAB environment.

Several examples demonstrating how to use the Time Tagger with MATLAB are provided in the ``.\examples\Matlab\`` folder.
The ``1-Quickstart`` directory has the same structure of the Python one (see Table above).
These examples cover core topics such as basic measurements, hardware control, and postprocessing,
providing a one-to-one correspondence between MATLAB and Python usage.

.NET
----

We provide a .NET class library (32, 64 bit and CIL) which can be used to access the TimeTagger from many high-level languages.
Please consider the following notes:

* Namespace: ``SwabianInstruments.TimeTagger``.
* The corresponding library ``.\driver\xxx\SwabianInstruments.TimeTagger.dll`` is registered in the Global Assembly Cache (GAC).
* Static functions (e.g. to create an instance of a TimeTagger) are accessible via ``SwabianInstruments.TimeTagger.TT``.


C#
---

A sample Visual Studio C# project provided in the ``.\examples\csharp\Quickstart``
directory covers the basics of how to use the Time Tagger .NET API.
An example of creating a custom measurement is also included.

Please copy the project folder to a directory within the user environment such that files can be written within the directory.

An example suite is provided in the ``.\examples\csharp\ExampleSuite`` directory.
`ExampleSuite` is an interactive application that demonstrates various measurements that can be performed with the Time Tagger.
Reference source code to setup and plot (with OxyPlot) each measurement is also provided within the application.
Additionally, the application contains examples for creating and using *Virtual channels*, *Filtering* and *Accessing the raw time tags*.

.. note:: Running the Example Suite requires '.NET Core 3.1 Desktop Runtime (v3.1.10)'.


C++
----

The provided Visual Studio C++ project can be found in ``.\examples\cpp\``.
Using the C++ interface supports writing custom measurement classes with no overhead.

.. note::

    * the C++ headers are stored in the ``.\driver\include\`` folder.
    * the final assembly must link ``.\driver\xYZ\TimeTagger.lib``.
    * the library ``.\driver\xYZ\TimeTagger.dll`` is linked with the shared v142 or newer Visual Studio runtime (``/MD``).
    * use ``TimeTaggerD.lib`` and ``TimeTaggerD.dll`` for the Visual Studio debug runtime (``/MDd``).
    * use ``libTimeTagger.dll`` and ``libTimeTagger.a`` for the MinGW C++ ABI for the `MINGW32 and UCRT64 environment <https://www.msys2.org/docs/environments/>`_.

Debug and Release Builds
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The choice of build type can have a great effect on the code performance. 
In Visual Studio, the default compiler flags for ``Debug`` builds are ``/MDd``,  ``/O0``, and  ``/Zi``. For  ``Release`` builds these are  ``/MD``, ``/O2``, and ``/DNDEBUG``.
It is crucial that you understand these flags and their implications on performance. 

* ``/O0`` vs ``/O2``
    This flag controls the general optimization level. ``/O0`` means no optimization, so every instruction is surrounded by ``load_from_memory`` and ``store_to_memory``.
    This is a significant waste of CPU resources, but guarantees that every local variable can be inspected at all times.
    We suggest the use of the default optimization level ``/O2`` and to overwrite it only for required methods using pragmas (see the `MSVC optimize pragma <https://learn.microsoft.com/en-us/cpp/preprocessor/optimize?view=msvc-170>`_).

* ``/MDd`` vs ``/MD``
    This flag selects which (incompatible) runtime C++ ABI you want to use for the whole project.
    The debug runtime ``/MDd`` has additional fields and checks for e.g. better range checking.
    It is good practice to run your code with them at least once before each commit.
    As they are incompatible with each other, **all linked C++ libraries must use the same runtime**.
    This flag is the only difference between our debug ``TimeTaggerD.dll`` and non-debug ``TimeTagger.dll`` library.
    We suggest using ``/MD`` even for debug builds, otherwise the debug runtime will incur significant performance costs, including in the internals of the Time Tagger library.

* ``/Zi``
    This flag tells the compiler to generate a ``*.pdb`` symbol file.
    This is used by the debugger to map e.g. the assembly to the C++ code and the stack to the local variable.
    As this has no performance overhead, we recommend using this flag for all internal builds.

* ``/DNDEBUG``
    The macro ``NDEBUG`` is the C way to disable ``assert()``. Asserts are usually good at catching logic errors without much overhead.

The relevant choice is thus not whether to build using ``Debug`` or ``Release``, but rather which set of flags to use. Please select each of them carefully based on your target.

Code Sanitizers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

We recommend the use of code sanitizers. Switching your Visual Studio compiler to CLANG allows you to use its undefined behavior, address, and thread sanitizers.
Microsoft has also recently announced the MSVC compiler now ships with an address sanitizer, which finds out-of-bounds accesses, use-after-free and similar issues. Please consult the documentation for the `AddressSanitizer (ASan) for Windows with MSVC <https://devblogs.microsoft.com/cppblog/addresssanitizer-asan-for-windows-with-msvc/>`_.
