Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions source/_static/theme_overrides.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@
overflow: visible !important;
}
}

/* add breathing room between numbered list items */
.rst-content ol.arabic > li {
margin-bottom: 1em;
}
53 changes: 30 additions & 23 deletions source/best_practices.rst
Original file line number Diff line number Diff line change
@@ -1,40 +1,47 @@
Best Practices
==============

When writing schema using the HDMF Schema Language, including extensions, the HDMF development team provides a few best
practices to ensure correct behavior from the HDMF reference API and other APIs that we are aware of (e.g., MatNWB).

1. Do not create schema that the HDMF reference API does not yet support. See `hdmf_support`_ for details.

2. Define new data types (``data_type_def``) at the root of the schema rather than nested within another data type
definition. Nested type definitions may in some cases lead to errors in HDMF. See `hdmf#511`_ and `hdmf#73`_.
definition. Nested type definitions may in some cases lead to errors in HDMF. See `hdmf#511`_ and `hdmf#73`_.

3. Use the ``quantity`` key not in the data type definition but in the group/dataset spec where the type is included.
When the data type is included within another data type via ``data_type_inc``, if the ``quantity`` key is omitted, the
default value of 1 would be used. This makes the ``quantity`` defined in the data type definition meaningless
and confusing.
When the data type is included within another data type via ``data_type_inc``, if the ``quantity`` key is omitted,
the default value of 1 would be used. This makes the ``quantity`` defined in the data type definition meaningless
and confusing.

4. Use the ``name`` key not in the data type definition but in the group/dataset spec where the type is included,
unless you really want to require that all instances of the data type have that name. Mismatch between the name
defined on the data type definition and where it is included can lead to unexpected behavior in the APIs.

5. Create a new data type when adding attributes/datasets/groups/links to an existing data type. See
`hdmf-schema-language#13`_ for details. Adding attributes/datasets/groups/links to an existing data type using
``data_type_inc`` is partially supported by the APIs (for example, the validator may not check these added fields),
so this is discouraged until full, tested support is added.

6. Modifying the dtype, shape, or quantity of a data type when using ``data_type_inc`` should only restrict the values
from their original definitions. This ensures that the data types follow the object-oriented programming principle of
inheritance. For example, if type A has ``dtype: text`` and type B extends type A
(``data_type_def: B, data_type_inc: A``), then type B should not redefine ``dtype`` to be ``int``
which is incompatible with the ``dtype`` of type A. The same idea holds if type A is included in another type
and a new type is not defined (just ``data_type_inc: A``).
In other words, all children types should be valid against the parent type. See `hdmf#321`_.
unless you really want to require that all instances of the data type have that name. Mismatch between the name
defined on the data type definition and where it is included can lead to unexpected behavior in the APIs.

5. When adding attributes, datasets, groups, or links to an existing data type, create a new data type that extends
it (using both ``data_type_def`` and ``data_type_inc``) rather than adding those fields to an included instance of
the type (i.e., a group/dataset that uses only ``data_type_inc: X`` without a ``data_type_def``). For example, if
a group includes a named dataset with ``data_type_inc: VectorData`` and adds a ``resolution`` attribute to that
dataset, the added attribute is tied to that specific included location rather than to a reusable data type, and
is only partially supported by the APIs (for example, the validator may not check these added fields). Instead,
define a new type that extends ``VectorData`` with the ``resolution`` attribute, and include that type. See
`hdmf-schema-language#13`_ for details.

6. Modifying the dtype, shape, or quantity of a data type when using ``data_type_inc`` should only restrict the
values from their original definitions. This ensures that the data types follow the object-oriented programming
principle of inheritance. For example, if type A has ``dtype: text`` and type B extends type A
(``data_type_def: B, data_type_inc: A``), then type B should not redefine ``dtype`` to be ``int``
which is incompatible with the ``dtype`` of type A. The same idea holds if type A is included in another type
and a new type is not defined (just ``data_type_inc: A``).
In other words, all children types should be valid against the parent type. See `hdmf#321`_.

7. The use of list values for the ``value`` and ``default_value`` keys, e.g., ``value: [0, 1, 2]`` is not fully
supported in the official APIs, so this is discouraged until full, tested support is added.
supported in the official APIs, so this is discouraged until full, tested support is added.

8. The names of data types or objects should use only characters in the sets ``a-z``, ``A-Z``, ``0-9``, ``-``, ``_``,
``.``. This helps ensure consistent behavior in the APIs across different storage backends and operating systems.
For example, writing a group that contains ":" to a Zarr backend on a Windows machine is not allowed by Windows.
See `pynwb#1421`_ and `hdmf-zarr#219`_ for examples.
``.``. This helps ensure consistent behavior in the APIs across different storage backends and operating systems.
For example, writing a group that contains ":" to a Zarr backend on a Windows machine is not allowed by Windows.
See `pynwb#1421`_ and `hdmf-zarr#219`_ for examples.


.. _hdmf#511: https://github.com/hdmf-dev/hdmf/issues/511
Expand Down