# Noting the origin of data

In cases in which we want to store where the data originates from Source entities can be used. Almost all entities of the NIX-model can have Sources. For example, if the recorded data originates from experiments done with one specific experimental subject.

Sources have a name and a type and can have some definition and link to further metadata.

Sources are used to note the origin of the data (`example code`).

        subject = block.create_source('subject A', 'nix.experimental_subject')
        subject.definition = 'The experimental subject used in this experiment'

        data_from_subject = block.create_data_array("subject data", "nix.sampled.time_series", data=np.random.randn(100))
        data_from_subject.append_sampled_dimension(1, unit="s", label="time")
        data_from_subject.sources.append(subject)

Sources may depend on other Sources. For example, in an electrophysiological experiment we record from different cells in the same brain region of the same animal. To represent this hierarchy, Sources can be nested, create a tree-like structure.

Sources are used to note the origin of the data (`example code`).

        brain_region = subject.create_source('hippocampus', 'nix.experimental_subject.subject')

        cell_a = brain_region.create_source('Cell 1', 'nix.experimental_subject.cell')
        cell_b = brain_region.create_source('Cell 2', 'nix.experimental_subject.cell')

        data_from_cell_a.sources.append(cell_a)
        data_from_cell_b.sources.append(cell_b)

As mentioned above the Sources build a tree. The block (as the root of the tree) at the moment has only a single source attached to it

        print("block sources:", block.sources)
        print("subject sources:", subject.sources)
        print("brain region sources:", brain_region.sources)

The output should yield:

    block sources: [Source: {name = subject A, type = nix.experimental_subject}]
    subject sources: [Source: {name = hippocampus, type = nix.experimental_subject.subject}]
    brain region sources: [Source: {name = Cell 1, type = nix.experimental_subject.cell}, Source: {name = Cell 2, type = nix.experimental_subject.cell}]

## Search and find

In a data-centered search we can then ask the DataArray for it’s Source to get information about the cell and get the linked metadata. A DataArray may have several sources attached to it. To make sure we get the right one (with the cell information) we perform a search on the sources using the type information.

        print("Source:", src)
        print("Source metadata:")
        src.metadata.pprint()

The output should give

    Source: Source: {name = Cell 1, type = nix.experimental_subject.cell}
    Source metadata:
    Cell 1 [odml.cell]
        |- Type: ('pyramidal',)
        |- BrainSubregion: ('CA1',)
        |- BaselineRate: (15,)Hz
        |- Layer: ('4',)

In a source-centered search we can ask for the DataArrays that link to a source.

        print(cell_a.referring_data_arrays)

This should return a list with a single entry:

    [DataArray: {name = cell a data, type = nix.sampled.time_series}]