.. _schema:

*****************
Data Model Schema
*****************

This describes the required and optional components of the data model and how to describe them in JSON.
The top level JSON object can be given a name by the user.
For example:

.. code-block:: json

    {
      "VTK_Cartesian_grid": {
      }
    }

The following sections describe the objects are placed inside this top-level object.

Data Sources
============

The ``data_sources`` object is required and must have at least 1 data source specified.
A data source corresponds to an ADIOS engine output.
If you write all of your data using one engine (e.g., single BP file or stream), then you'll only need one data source.
Some simulations write the mesh to a different file from the field data, so in this case, you would set up two data sources.


The following example shows a single data source being defined. The ``name`` is any name you want to give it and is the name
Fides uses to track the data source.
In most cases ``filename_mode`` will be ``input``. In this case, the specific filename is not given, and you will need to give the name to Fides in your code.

.. code-block:: json

    "data_sources": [
      {
      "name": "source",
      "filename_mode": "input"
      }
    ]

The following example shows two data sources being defined, one for the mesh and one for the fields.
The ``filename_mode`` is set to ``relative``, which means that ``filename`` is now required.
Filename is the actual name of the BP file/stream. The path is not necessary, as that will be passed at runtime to Fides.

.. code-block:: json

    "data_sources": [
      {
        "name": "mesh",
        "filename_mode": "relative",
        "filename": "mesh.bp"
      },
      {
        "name": "fields",
        "filename_mode": "relative",
        "filename": "fields.bp"
      }
    ]


Coordinate System
=================

The ``coordinate_system`` object will map your ADIOS Variable(s) to the appropriate VTK-m coordinate system.
For any coordinate system, there is an ``array`` object that specifies the ``array_type``.
Possible values are ``basic``, ``uniform_point_coordinates``, ``cartesian_product``, or ``composite``.

The following example describes a coordinate system with uniform point coordinates:

.. code-block:: json

    "coordinate_system": {
      "array" : {
        "array_type": "uniform_point_coordinates",
        "dimensions": {
          "source": "variable_dimensions",
          "data_source": "source",
          "variable": "density"
        },
        "origin": {
          "source": "array",
          "values": [0.0, 0.0, 0.0]
        },
        "spacing": {
          "source": "array",
          "values": [0.1, 0.1, 0.1]
        }
      }
    }

``dimensions`` uses an ADIOS Variable to determine the dimensions of the coordinate system, so
``data_source`` should name the appropriate data source, while ``variable`` is the name of the ADIOS Variable.
In this case ``source`` should always be ``variable_dimensions``.

The ``source`` for the ``origin`` and ``spacing`` should always be ``array`` as it specifies that you will specify an
array for the ``values``.


The following example describes a coordinate system with a cartesian product for coordinates:

.. code-block:: json

    "coordinate_system": {
      "array" : {
        "array_type": "cartesian_product",
        "x_array": {
          "array_type": "basic",
          "data_source": "source",
          "variable": "x"
        },
        "y_array": {
          "array_type": "basic",
          "data_source": "source",
          "variable": "y"
        },
        "z_array": {
          "array_type": "basic",
          "data_source": "source",
          "variable": "z"
        }
      }
    }

In this case, you need to specify your x, y, and z arrays as shown in the example.
The ``array_type`` should be set to ``basic`` for the x, y, and z arrays.
Again, ``data_source`` should name the appropriate data source.

The ``composite`` ``array_type`` is similar to ``cartesian_product``, except that instead of performing a cartesian product
on the arrays, the array values are zipped together to form points (x0, y0, z0), (x1, y1, z1), ..., (xn, yn, zn).

The final ``array_type`` of ``basic`` for the coordinate system is shown in the following example:

.. code-block:: json

    "coordinate_system": {
      "array" : {
        "array_type": "basic",
        "data_source": "source",
        "variable": "points"
      }
    }

This is useful for an unstructured grid, where your points are all explicitly written out in a variable.

Cell Set
========

The ``cell_set`` object will map your ADIOS Variable(s) to the appropriate VTK-m cell set.
You must specify the ``cell_set_type``, which can be one of the following values:
``structured``, ``single_type``, or ``explicit``.

The following example describes a structured cell set:

.. code-block:: json

    "cell_set": {
      "cell_set_type": "structured",
      "dimensions": {
        "source": "variable_dimensions",
        "data_source": "source",
        "variable": "density"
      }
    }

The dimensions are determined from an ADIOS Variable, in this case ``density`` from the
data source named ``source``.

For an explicit cell set, but with only a single type of cells, you can do the following:

.. code-block:: json

    "cell_set": {
      "cell_set_type": "single_type",
      "cell_type": "triangle",
      "data_source": "source",
      "variable": "connectivity"
    }

``cell_type`` must be one of: ``vertex``, ``line``, ``triangle``, ``quad``, ``tetrahedron``, ``hexahedron``, ``wedge``, ``pyramid``.
Then you must specify the variable containing the connectivity.

The following shows an example of an explicit cell set, where different types of cells may be used.

.. code-block:: json

    "cell_set": {
      "cell_set_type": "explicit",
      "connectivity": {
        "array_type": "basic",
        "data_source": "source",
        "variable": "connectivity"
      },
      "cell_types": {
        "array_type": "basic",
        "data_source": "source",
        "variable": "cell_types"
      },
      "number_of_vertices": {
        "array_type": "basic",
        "data_source": "source",
        "variable": "num_verts"
      }
    }

In this case, you'll need to specify 3 ADIOS variables, one each for the connectivity, cell types, and number of vertices of each cell.

Fields
======

The ``fields`` section is optional and describes each ADIOS variable that should be read as a Field.
For example:

.. code-block:: json

    "fields": [
      {
        "name": "density",
        "association": "points",
        "array": {
          "array_type": "basic",
          "data_source": "source",
          "variable": "density"
        }
      }
    ]

``name`` allows you to specify a different name for the field (or you can choose the same name as it's called in ADIOS).
``association`` should be either ``points`` or ``cells``.
``array`` is similar to array definitions in other places described earlier, where you need to specify the data source name and the name of the variable in ADIOS.

Each field that should be read in must be specified here, or you can use :ref:`wildcard-fields`.


Step Information
================

The ``step_information`` section is optional. If defined, the ``data_source`` is required, while ``variable`` is optional.
By specifying a data source, Fides will use that data source for step information (e.g., number of steps available in the dataset).
If you add the ``variable``, Fides will use the chosen ADIOS variable to give the time value for each time step, which is useful
when using ParaView/VTK to visualize your data.


.. code-block:: json

    "step_information": {
      "data_source": "source",
      "variable": "time"
    }
