YAML Data File Specification ============================ This file constitutes the official specification for the YAML data files used to store the data for an :term:`instrument`. Spec ---- The data must be stored in a YAML format file with the following structure: .. parsed-code-block:: yaml :emphasize-lines: 1,2,3,5,8,9,10,15,17 :ref:`name`: :iref:target:`"instrument_name"` :ref:`default_version`: :iref:target:`"version1"` :ref:`version`\ :iref:target:`:` version1: :ref:`default_model`: :iref:target:`"model1"` :ref:`models`\ :iref:target:`:` model1: "model1_v1" model1_v1: :ref:`function`: :iref:target:`"model_function_name"` :ref:`citation`: ["citation1", :iref:target:`"citation2"`] :ref:`parameters`\ :iref:target:`:` :ref:`defaults`\ :iref:target:`:` setting1: 1 setting2: "value1" :ref:`restrictions`\ :iref:target:`:` setting1: [1, 100, 5] setting2: !!set {"value1", "value2", "value3"} setting3: [0, 2000] parameter1: "value1" parameter2: 2 parameter3: 3.14 parameter4: [1, 2, 3, 4] :ref:`configurations`\ :iref:target:`:` configuration1: :ref:`default_option`: :iref:target:`"option1"` option1: parameter5: "value2" parameter6: 56.1687 The highlighted lines contain keys with **preset names** that **must not** be changed. The names of the remaining keys as well as the values can and should be changed appropriately. Further, these freeform keys are free to have multiples of (e.g. `version1`, `version2`, see :ref:`spec-example`), given that their substructure is kept. .. _spec-name: name ^^^^ This key (:iref:ref:`see in spec`) specifies the name of the :term:`instrument`, set as a string (`"instrument_name"`). This *should* be the public, official name that *should* be used everywhere else in ResINS. This is the name that :py:attr:`resins.instrument.Instrument.name` is set to and that will be shown when printing ``Instrument``, i.e. ``print(instrument)``. *This* name does *not* have to be unique, but since it is recommended to match the other uses of the same instrument in ResINS, it **should** be globally unique. .. _spec-default-version: default_version ^^^^^^^^^^^^^^^ This key (:iref:ref:`see in spec`) specifies the name of the :term:`version` that will be used by default for this :term:`instrument` when user does not specify which :term:`version` they want to use, i.e. calling :py:meth:`~resins.instrument.Instrument.from_default` with only one argument, e.g. ``Instrument.from_default('TOSCA')``. The value of this key, specified as a string, **must** match one of the version keys (see :ref:`version`). .. _spec-version: version ^^^^^^^ This key (:iref:ref:`see in spec`) contains all the data for all the :term:`versions`. It must be a (YAML) dictionary in which each key is the name of an :term:`instrument` :term:`version` and its corresponding value is another dictionary with the associated data. .. warning:: All of the entries in this dictionary **will** be interpreted as :term:`versions` - no other data is permissible in this section. If anything not following the below guidelines is placed in the dictionary, it will lead to errors. All the subkeys (:term:`version` names) must be mutually unique, but none has to be globally unique, though it is recommended, if possible. Regardless, though, each of the subkeys *must not* be arbitrary - it should represent an official name for the given :term:`version`. Each value for the subkey (:term:`version` name) in the dictionary **must** be a correctly formatted data for an :term:`instrument` :term:`version` in the form of a (YAML) dictionary. That said, though, this inner dictionary has less strict specification - the only requirement is that it contains a key called :ref:`models`. In fact, this space is encouraged to be used for storing shared data (see :ref:`spec-yaml-magic`). .. _spec-default-model: default_model ^^^^^^^^^^^^^ This key (:iref:ref:`see in spec`), found inside the (YAML) dictionary corresponding to a particular :term:`instrument` :term:`version` (see the :ref:`version key`), specifies the name of the :term:`model` that will be used by default when the user does not specify which :term:`model` they want to use, e.g. when calling :py:meth:`resins.instrument.Instrument.get_resolution_function`. The value of this key, specified as a string, **must** match one of the model keys (see :ref:`version`). .. _spec-models: models ^^^^^^ This key (:iref:ref:`see in spec`), found inside the (YAML) dictionary corresponding to a particular :term:`instrument` :term:`version` (see the :ref:`version key`), contains all the data for all the :term:`models`. Its value must be a (YAML) dictionary in which each key is the name of a :term:`model` and its corresponding value is either: * Another dictionary with the associated data * In this case, the key (:term:`model` name) **must** include a version number in the form ``{model_name}_v{version_number}``, e.g. ``PyChop_fit_v1``, where the ``version_number`` is an integer. * A string whose value matches one of the keys *whose value is a dictionary*. Chaining *will* lead to errors. * In this case, the key (:term:`model` name) **must not** include a version number. .. warning:: All of the entries in this inner dictionary **will** be interpreted as :term:`models` - no other data is permissible in this section. If anything not following the below guidelines is placed in the dictionary, it will lead to errors. All the subkeys (:term:`model` names) must be mutually unique, but none has to be globally unique - in fact, if a model is applicable to multiple :term:`instruments` or :term:`versions`, it is recommended that the same name is used for that :term:`model` in each YAML file. Regardless, though, each of the subkeys *must not* be arbitrary - it should represent an official name for the given :term:`model`. Each value for the subkey (:term:`model` name) in the dictionary **must** be a correctly formatted data for a :term:`model` in the form of a (YAML) dictionary. That said, though, this inner dictionary has less strict specification - the only requirement is that it *must* contain the following keys: * :ref:`function` * :ref:`citation` * :ref:`parameters` * :ref:`configurations` Otherwise, other entries for the dictionary are not defined and may similarly be used for storing shared data (see :ref:`spec-yaml-magic`), so long as they do not clash with the names above. .. _spec-function: function ^^^^^^^^ This key (:iref:ref:`see in spec`), found inside the (YAML) dictionary corresponding to a particular :term:`model`, (see the :ref:`model key`), specifies the exact ResINS :term:`model` object that will be instantiated when a user wants to use the particular :term:`model`. The value for this key is a string. .. important:: The value for this key **must** correspond to one of the keys in :py:data:`resins.models.MODELS` (and therefore must be globally unique. For creating a new model, see :doc:`../howtos/add_model`. .. _spec-citation: citation ^^^^^^^^ This key (:iref:ref:`see in spec`), found inside the (YAML) dictionary corresponding to a particular :term:`model`, (see the :ref:`model key`), specifies the citations/references associated with the particular :term:`model` of the particular :term:`instrument`. These are exposed to the user as-is via ``ModelData.citation`` and ``InstrumentModel.citation``. The value corresponding to this key must be a list of strings, where each string is a shortened citation (only initials and last name, no paper title, etc.). There is no requirement for citation style beyond that, though the DOI should be included if there is one. .. _spec-parameters: parameters ^^^^^^^^^^ This key (:iref:ref:`see in spec`), found inside the (YAML) dictionary corresponding to a particular :term:`model`, (see the :ref:`model key`), specifies all the parameters required by the particular :term:`model`. Its value must be a (YAML) dictionary in which each key is the name of a parameter of that model, and the value is a valid value for that parameter of that model. The only intrinsic restrictions on this dictionary are that it must contain the :ref:`defaults` and :ref:`restrictions` key-value pairs. Otherwise, the only requirement is that it must contain **exactly** the parameters required by the ResINS model specified by the :ref:`function value`. There can be no missing or extra parameters, though please note that some of the parameters required by the model may be stored in the :ref:`configurations dictionary`. The values must match the arguments expected by the associated ``ModelData`` subclass, which means that the type of each parameter could be anything - ``int``, ``float``, ``string``, ``list``, ``dict`` - as long as the ``ModelData`` expects it. In fact, when :doc:`creating new models<../howtos/add_model>`, it is encouraged to further structure the data if there are many parameters. .. _spec-defaults: defaults ^^^^^^^^ This key (:iref:ref:`see in spec`), found inside the :ref:`parameters` (YAML) dictionary, specifies the default values for the :term:`settings` of a particular :term:`model`. This key is required and its value must be a (YAML) dictionary in which each key is the name of a :term:`setting` of that model, and the value is the default value that will be used if user does not provide a value for that setting. .. note:: This (defaults) key is allowed to be an empty dictionary and also may specify only *some* of the settings for the model. I.e., it is allowed to have settings with no default values. Each key inside the dictionary **must** correspond to a :term:`setting` of that model, and its value must match the type. Additionally, if a default value is provided, it must be a valid value for that model: * It must be within the associated :ref:`restrictions` * If the model has other failure states (e.g. the PyChop model has a ``NoTransmissionError`` at certain values), the use of the default values must not result in any of the failure states arising. .. _spec-restrictions: restrictions ^^^^^^^^^^^^ This key (:iref:ref:`see in spec`), found inside the :ref:`parameters` (YAML) dictionary, specifies the restrictions on the values for the :term:`settings` of a particular :term:`model`. This key is required and its value must be a (YAML) dictionary in which each key is the name of a :term:`setting` of that model, and the value is the specification of the restrictions on the values for that setting. I.e., if the user provides a value that lies outside the restrictions (allowed values) an exception will be raised. .. note:: This (restrictions) key is allowed to be an empty dictionary and also may specify only *some* of the settings for the model. I.e., it is allowed to have settings with no restrictions. Each key inside the dictionary **must** correspond to a :term:`setting` of that model, and its value must be one of the following: * A set (``!!set {}``) - in this case, all the allowed values must be listed - a value not in the set will raise an error. * A list (``[]``): * Length-2 list (e.g. ``[1, 100]``) - in this case, the two values specify the lower and upper bound for the allowed values (included, i.e. above example is <1, 100>) * Length-3 list (e.g. ``[1, 100, 10]``) - in this case, the three values are arguments to the ``range`` function (i.e. ``range(1, 100, 10)``), the result of which is treated as the ``set`` case (list of all allowed values). Any other values for a key inside the dictionary is not valid and will be treated as a bug. .. note:: If a setting is not bounded from exactly one side, the ``!!float inf`` construct may be used to specify an infinity as one of the bounds. However, if there is no restriction on a setting, please leave out the key rather than specifying the bounds as +inf and -inf. .. _spec-configurations: configurations ^^^^^^^^^^^^^^ This key (:iref:ref:`see in spec`), found inside the (YAML) dictionary corresponding to a particular :term:`model`, (see the :ref:`model key`), specifies all the :term:`configurations` available to the particular :term:`model`. Its value must be a (YAML) dictionary in which each key is the name of a :term:`configuration`, and the corresponding value is the data associated with the :term:`configuration`. This data consists of two different things: * The :ref:`default_option` key * The various :term:`options