> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mangrovesystems.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Build accounting models

> A model represents a discrete set of calculations and data associations to generate production accounting. There are 2 main types of models in Mangrove: production models, and quantification models.

## Building models

Models can be edited by Admin users in the Model Editor using a YAML-based scripting language.

* Open the **Model Editor** by clicking on **Edit/Test** besides the model name

The YAML script constructs carbon accounting models using a tree of interconnected nodes, where each node performs a calculation or holds a value. These nodes are organized in a hierarchical structure.

```mermaid theme={null}
  graph LR
    B1[Intermediate Calc A<br>operator: #123;#123; #125;#125; ] --> A[Output Node<br>operator: #123;#123; #125;#125;]
    B2[Intermediate Calc B<br>operator:  #123;#123; #125;#125;] --> A
    C1[Data Input 1 <br><b>datapoints</b>] --> B1
    C2[Input Node 2 <br><b>constant</b>] --> B1
    C3[Input Node 3 <br><b>static input</b>] --> B2
    C4[Input Node 4 <br><b>datapoints</b>] --> B2
    
    style A fill:#57BECE,stroke:#333,stroke-width:2px,color:black
    style B1 fill:#98A2B3,stroke:#333,stroke-width:1.5px,color:black
    style B2 fill:#98A2B3,stroke:#333,stroke-width:1.5px,color:black
    style C1 fill:#F9FAFB,color:black
    style C2 fill:#F9FAFB,color:black
    style C3 fill:#F9FAFB,color:black
    style C4 fill:#F9FAFB,color:black
    
    B1:::opA
    B2:::opB
  
    classDef opA fill:#e0f7fa,stroke:#00796b,stroke-width:1px,color:black;
    classDef opB fill:#e0f7fa,stroke:#00796b,stroke-width:1px,color:black;
```

```yaml Example Model [expandable] theme={null}
nexus_nodes_attributes:
- name: Output Node
  operator: summation
  data_point_type: output-slug
  nexus_nodes_attributes:
  - name: Intermediate Calc A
    operator: summation
    nexus_nodes_attributes:
    - name: Data Input 1
      data_point_type: data-point-slug
    - name: Constant
      constant: 100
  - name: Intermediate Calc B
    operator: difference
    nexus_nodes_attributes:
    - name: Static Input
      order: 0
      data_point_type: static-input-slug
    - name: Data Input 2
      order: 1
      data_point_type: data-point-2-slug
```

This is the equivalent of writing the following equation:

$(Datapoint1 + 100) + (\alpha  - Datapoint2) = Output$

As a best practice, **Validate** the model you have built, and check the results in the Console before saving the model.

### Editing models

Saving the model updates its version.

New model versions do not affect the calculations of past accounting batches, only new calculations run after the version has been activated.

## Model versioning

Each model on a ledger can have multiple versions. Only one version per ledger is **active** at a time — the active version is the one Mangrove uses when generating new batches. All other versions are kept as inactive drafts.

### Creating a new draft version

Use draft versions to iterate on a model without disrupting live accounting.

* Open the model and make your edits in the Model Editor
* Click **Save**
* In the save dialog, enter a **version label** to describe the change (e.g. `2026 Emissions Update`)
* Leave the **Set as active version** option unchecked to save the edits as an inactive draft — the previously active version continues to drive batch generation
* Check **Set as active version** on save to activate the new version in one step

You can keep iterating on an inactive draft: adjust nodes, test calculations, and validate the model before promoting it.

### Activating a version

* Open the **version dropdown** on the model to see all versions for the ledger
* Click the **edit icon** next to the version you want to pin
* Update the **version label** if needed and click **Activate**
* Mangrove atomically switches the active version — the previously active version becomes inactive and the newly activated version is used for subsequent batch generation

<Note>
  A version must validate successfully before it can be activated. Activation is blocked if the model has validation errors.
</Note>

### Deleting versions

The currently active model version cannot be deleted. To remove an active version, first activate a different version on the same ledger, then delete the now-inactive one.

### How versions interact with batches

* Previously generated batches continue to reference the version that produced them, so historical accounting is unaffected by activating a new version.
* Newly generated batches default to whichever version is active at the time of generation.
* You can override the model version at batch generation time to run batches against a specific draft — useful for previewing how a draft will calculate before you activate it. See [Generate batches](/production-accounting/generate-batches).
* The model header and model cards display the active version's number and label so you can see at a glance which version a project is running.

## Defining new nodes

Nodes can be added to the model to represent specific variables in the accounting equations. Each node can:

* Receive a value from a data source (data\_point\_type)
* Use a constant/mapped value from a library, or
* Have its value calculated from child nodes through the defined operator

<CodeGroup>
  ```yaml Input nodes theme={null}
      - name: Input Node
        data_point_type: {{input-data-point-slug}}
      - name: Static Input Node
        data_point_type: {{static-input-slug}}
      - name: Constant Node
        constant: {{value}}
  ```

  ```yaml Intermediate calculated node theme={null}
      - name: Calculated Node
        operator: summation
        nexus_nodes_attributes:
        - name: Child Node 1
          data_point_type: {{child-data-point-slug}}
        - name: Child Node 2
          data_point_type: {{child-data-point-slug2}}
  ```

  ```yaml Output node theme={null}
  - name: Output Node
    operator: summation
    data_point_type: output-slug
    nexus_nodes_attributes:
    - name: Intermediate Calc A
      ...
    - name: Intermediate Calc B
      ...
  }
  ```
</CodeGroup>

See **Reference** below for the full list of parameters that can be defined on each node.

### Units

Units are not always required to be defined on nodes, but are *very* helpful for legibility especially when data is run through operator expressions. Use `output_unit` to define the expected result unit:

```yaml Example with units [expandable] theme={null}
nexus_nodes_attributes:
- name: Calculated EF
  output_unit: tCO2e/tonne
  operator: quotient
  nexus_nodes_attributes:
  - name: Emissions
    order: 0
    output_unit: kgCO2e  // note that Mangrove supports unit conversion above
    data_point_type: emissions-datapoint-slug
  - name: Mass
    order: 1
    output_unit: U.S. ton  // note that Mangrove supports unit conversion above
    data_point_type: mass-datapoint-slug
```

<Note>
  See **Reference** below: units have to conform to the supported syntax from the Unitwise library. Mismatched units between inputs on the same tier of nodes can result in errors unless explicitly converted upstream.
</Note>

## Testing models

Models can be tested by running them with a set of inputs to confirm the calculations.

How to test the models:

* Open the **Model Editor** by clicking on **Edit/Test** besides the model name
* Switch to **Test Model**
* Define a time range (this is necessary for certain calculations that consider duration), enter values for the model's required inputs, and **Run Test**
* Review the output calculations in the Console

## Reference

Below is the full list of fields that can be configured on nodes within a model.

<ParamField body="name" required>
  Name of the variable
</ParamField>

<ParamField body="output_unit">
  Unit. We use the Unitwise library to interpret units. Here's a list of [library-supported units](https://github.com/joshwlewis/unitwise/blob/master/data/derived_unit.yaml).
</ParamField>

<ParamField body="ghg">
  Specifies whether the values of that node represent a type of GHG calculation. Possible values: `co2e`
</ParamField>

<ParamField body="order">
  Specifies the node’s order in the parent node’s equation
</ParamField>

<ParamField body="nexus_nodes_attributes">
  Defines a new tier of child nodes.
</ParamField>

<ParamField body="data_point_type">
  Specifies the datapoint slug that the nodes is associated with, defining the node as either an input node that expects incoming data, or an input node tied to a Static Input.
</ParamField>

<ParamField body="operator">
  Operation performed on the child nodes. A detailed guide to operations can be found [here](/production-accounting/model-expressions).

  | Operator                | Function                                                                                                                                                |
  | :---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | Keisan expressions      | Mathematical expressions using the Keisan library. See the [Model Expressions guide](/production-accounting/model-expressions) for syntax and examples. |
  | summation               | Sums all child node values                                                                                                                              |
  | difference              | Subtracts subsequent values from the first. Child nodes have to be set in the right `order`.                                                            |
  | product                 | Multiplies all child node values                                                                                                                        |
  | quotient                | Divides subsequent values from the first. Child nodes have to be set in the right `order`.                                                              |
  | max                     | Finds the maximum value across all child node values                                                                                                    |
  | min                     | Finds the minimum value across all child node values                                                                                                    |
  | average                 | Finds the average of all child node values                                                                                                              |
  | count                   | Returns the count of child node values                                                                                                                  |
  | data\_point\_proportion | Special operator used to extract the allocation proportion from an allocated node                                                                       |
  | duration                | Special operator used to convert the time range of the incoming datapoint into a duration                                                               |
  | map                     | Maps a value from a linked library                                                                                                                      |
</ParamField>

<ParamField body="constant">
  Sets a constant value on the node.
</ParamField>

<ParamField body="should_aggregate" default="true">
  If set to `false`, the node's computation behaviour will change such that it will always return an array in which the computation is applied to each element of the input. If the node is using data points as input, the array will have the same length as the number of data points found for that data flow. If the node is using multiple child nodes as input, the operator is applied piece-wise across each child's output array to derive one output array.
</ParamField>

## Further Reading

<Card title="Model Operators" icon="function" href="/production-accounting/model-expressions">
  Read more on how to write mathematical and logical expressions in Mangrove models.
</Card>
