.. toctree::
   :maxdepth: 1

Working with data
=================

Storing data is one thing, but we want to work with it. The following examples illustrate reading of data from *DataArray*, *Tag* and *MultiTag* entities. We will use the dummy dataset already used in the :doc:`tagging <./tagging>` example. The figure below shows what is stored in the dataset. 

.. figure:: ./images/tag1.png
   :alt: a system's response to a stimulus

At some instance in time a system was exposed to a stimulus that leads to the system's response. The response has been recorded and stored in a *DataArray*, a *Tag* is used to highlight the "stimulus-on" segment of the data.

.. literalinclude:: examples/tagging_example.py
    :caption: :download:`example code <examples/tagging_example.py>`
    :lines: 78 - 90 

In this example we know the interesting entities by name, i.e. the
*DataArray* is called **response** and the *Tag* is called **stimulus**.
In cases in which we have no clue about the names, we just have to
browse the file or `search <./finding_things.md>`__ by name or type.

Reading data
------------

The first and maybe most common problem is to read the data stored in a
*DataArray*.

Reading all data
~~~~~~~~~~~~~~~~

In *NIX* when you open a *DataArray* the stored data is **not** automatically read from file. This keeps the object lightweight and easy to create. To read the data you can simply access it in a numpy style:

.. literalinclude:: examples/tagging_example.py
    :caption: :download:`example code <examples/tagging_example.py>`
    :lines: 71 - 73 

There are a few noteworthy things:

-  We use some previous knowledge here. For one, we know the names of the entities. Further, we know that the data is 1-D and the single dimension is a ``SampledDimension``. If these things are not known, the NIX library offers the necessary functions to get this information.
-  ``DataArray.shape`` returns a tuple with the data shape.
-  ``DataArray.dtype`` returns the data type.
-  To find out the ``DimensionType``, we need to access the dimension:

.. code-block:: python

    for dim in data_array.dimensions:
        print(dim.dimension_type)


Reading partial data
~~~~~~~~~~~~~~~~~~~~

In other instances it might be wanted to read only parts of the data.
Reading slices of the data is straight forward using the numpy style.

.. literalinclude:: examples/tagging_example.py
    :caption: :download:`example code <examples/tagging_example.py>`
    :lines: 98-101

An alternative approach is to use the ``DataArray.get_slice`` method which by default works with indices but can also work in data coordinates. E.g. we know that the data is 1-D and covers a span of 3.5s and we want to have the data in the interval 0.5s through 1.75s. The method returns a ``nixio.DataView`` object. The actual reading is done by accessing the data.

.. literalinclude:: examples/tagging_example.py
    :caption: :download:`example code <examples/tagging_example.py>`
    :lines: 103-106
    :emphasize-lines: 3

The arguments ``positions`` and ``extents`` are passed as lists. There must be one entry for each dimension of the data. In this case, since the data is 1-D, positions and extents are 1-element lists.
Note: the slice is defined by the starting point(s) and the *extent(s)*, not with start and end points.

Reading tagged data
~~~~~~~~~~~~~~~~~~~

*Tag* and *MultiTag* tag single or multiple points or regions in data stored in the referenced *DataArrays* (see `tagging <./tagging.md>`__ for more information and the example data created in the `example <#mtag_regions>`__  will be used in the following code snippets).

.. figure:: ./images/multiple_regions.png
    :alt: tagging multiple segments

    Plot of the data created by this :download:`example <examples/multiple_regions.py>` on tagging multiple regions in data. 

In order to read the data that belongs to the highlighted region(s) *Tag* and *MultiTag* define the ``tagged_data`` methods which return ``nixio.DataView`` objects from which the data is read as shown above. The following code snippet shows how to use these function:

.. literalinclude:: examples/multiple_regions.py
   :lines: 86 - 97
   :emphasize-lines: 10
   :caption: Reading data segments tagged by the *Tag* or *MultiTag* can be done using the ``tagged_data`` method (:download:`example code <examples/multiple_regions.py>`).

The *MultiTag* version of the ``tagged_data`` method takes two arguments. The first is the index of the tagged region (0 for the first), the second argument is the name of the referenced *DataArray* (you can also use the index or the id). Since the *Tag* tags only a single region, it takes only one argument, i.e. the name (id, index) of the referenced *DataArray*.

.. figure:: ./images/reading_tagged_data.png
   :alt: reading tagged data
   

Analogously, the feature data attached to the *Tag* or *MultiTag* can be
obtained using the ``feature_data`` methods.

.. literalinclude:: examples/multiple_regions.py
   :lines: 69 - 76
   :emphasize-lines: 6, 7
   :caption: ``feature_data`` works analogously, the first argument is the index of the tagged region, the second the name (or id or index) of the feature. Here the feature stores a single number, i.e. the frequency of the stimulus for each tagged region which is plotted below the highlighted regions in the figure above (:download:`example code <examples/multiple_regions.py>`). 
