# Workflow Layers

The `WorkflowCalculationLayer` and `WorkflowCalculationSchema` offer an abstract base implementation for any calculation layers (and their associated schemas) which will perform their calculations using the built-in workflow engine.

The `WorkflowCalculationLayer` takes as input from its calculation schema one `WorkflowSchema` object for each type of property to be estimated by this layer. These schemas must at a minimum provide both the schemas of the protocols in the workflow, and have the `final_value_source` attribute set to the value of the calculated observable. In addition, the layer fully supports schemas which provide gradient information (see the `gradients_sources` attribute), as well as storing any generated dataclasses (see the `outputs_to_store` attribute) to the available storage backend.

This layer implements three key methods which are available to be overridden by any subclass implementations:

- `_get_workflow_metadata()`: a method which returns the dictionary of metadata which will be made available to the workflow (see the default metadata section for details).

- `_build_workflow_graph()`: the method which will construct the workflow graph to execute using the input workflow schemas and the metadata generated by the layer.

- `workflow_to_layer_result()`: a method which will map any `WorkflowResult` objects generated by the workflow graph into the `CalculationLayerResult` objects which the layer requires.

The workflow layer will by default tag each property estimated using it (or one of its derivatives) with a `CalculationSource` with the `fidelity` attribute set to the name of the layer, and the `provenance` attribute set to the schema of the workflow used to generate the property.

## Default Metadata

The metadata provided to the workflows generated by this layer is generated on a per property to estimate basis mainly using the `generate_default_metadata()` function. It includes:

Key | Type | Description
--- | --- | ---
`thermodynamic_state` | `ThermodynamicState` | The state at which the to perform any calculations .
`substance` | `Substance` | The substance to use in any calculations.
`components` | [`Substance`] | The components present in the main `substance`.
`target_uncertainty` | `Quantity` | The target uncertainty of any calculations defined by the calculation schema.
`per_component_uncertainty` | `Quantity` | The `target_uncertainty` divided by `sqrt(substance.n_components + 1)`
`force_field_path` | `str` | A file path to the force field parameters to use.
`parameter_gradient_keys` | [`ParameterGradientKey`] | The parameters to differentiate any observables with respect to (if any).