Repository: silvxlabs/quicfire-tools (language: python)

Issue:
Integrate Pydantic BaseModels into inputs module

26 add docs to cicd

Add QFire_Advanced_User_Inputs.inp to inputs module
- [x] Class object
- [x] Template file
- [x] documentation json
- [x] docstring
- [x] tests


Discussion / hints:

Fix patch:
diff --git a/.flake8 b/.flake8
new file mode 100644
index 0000000..b58c978
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,8 @@
+[flake8]
+ignore =
+    # E501: line too long (we rely on black for this)
+    E501,
+    # Whitespace before ':'. flake8 is wrong when inside slice expressions.
+    E203,
+    # Line break before binary operator. flake8 is wrong and goes against PEP8.
+    W503,
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
new file mode 100644
index 0000000..c0ec3a7
--- /dev/null
+++ b/.github/workflows/build-docs.yml
@@ -0,0 +1,16 @@
+name: build mkdocs
+
+on:
+  release:
+    types: [published]
+
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-python@v4
+        with:
+          python-version: 3.x
+      - run: pip install mkdocs mkdocstrings mkdocstrings-python mkdocs-material
+      - run: mkdocs gh-deploy --force --clean --verbose
diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
new file mode 100644
index 0000000..4556b88
--- /dev/null
+++ b/.github/workflows/pre-commit.yaml
@@ -0,0 +1,16 @@
+name: Linting and Formatting
+on:
+  push:
+  pull_request:
+  workflow_dispatch:
+
+jobs:
+  pre-commit:
+    name: Run pre-commit
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v3
+        with:
+          python-version: "3.10"
+      - uses: pre-commit/action@v3.0.0
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index da51b6d..3eb9745 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -29,4 +29,4 @@ jobs:
         TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
       run: |
         python setup.py sdist bdist_wheel
-        twine upload dist/*
\ No newline at end of file
+        twine upload dist/*
diff --git a/.gitignore b/.gitignore
index 613f744..eb08009 100644
--- a/.gitignore
+++ b/.gitignore
@@ -130,8 +130,8 @@ dmypy.json
 
 # IDE
 *.code-workspace
-.vscode/*
-.idea/*
+.vscode
+.idea
 
 # Development
 dev/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..6d5d07b
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,17 @@
+exclude: 'tests/data/'
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.4.0
+    hooks:
+      - id: check-yaml
+      - id: end-of-file-fixer
+      - id: trailing-whitespace
+  - repo: https://github.com/psf/black
+    rev: 23.1.0
+    hooks:
+    - id: black
+    - id: black-jupyter
+  - repo: https://github.com/PyCQA/flake8
+    rev: 6.0.0
+    hooks:
+      - id: flake8
diff --git a/README.md b/README.md
index f5275fd..81c0529 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,38 @@
 # quicfire-tools
-Input and output tools for working with QUIC-Fire
+
+## Quick-Links
+
+[Documentation](https://silvxlabs.github.io/quicfire-tools/) - [PyPi Package](https://pypi.org/project/quicfire-tools/)
+
+## What is quicfire-tools?
+
+quicfire-tools is a Python package that provides a convenient interface for programmatically creating and managing
+QUIC-Fire input file decks and processing QUIC-Fire output files into standard Python array data structures.
+
+The goals of quicfire-tools are to:
+
+1. Make it easy to write Python code to work with QUIC-Fire input and output files.
+2. Unify code, scripts, and workflows across the QUIC-Fire ecosystem into a single package to support the development of
+   new QUIC-Fire tools and applications.
+3. Provide a platform for collaboration among QUIC-Fire developers and users.
+
+
+## Installation
+
+quicfire-tools can be installed using `pip` or `conda`.
+
+### pip
+
+```bash
+pip install quicfire-tools
+```
+
+### conda
+
+Conda support is coming soon!
+
+
+## Issues
+
+If you encounter any issues with the quicfire-tools package, please submit an issue on the quicfire-tools GitHub
+repository [issues page](https://github.com/silvxlabs/fastfuels-sdk-python/issues).
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..e89fcd3
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,34 @@
+# Welcome to the quicfire-tools Documentation!
+
+## What is quicfire-tools?
+
+quicfire-tools is a Python package that provides a convenient interface for programmatically creating and managing
+QUIC-Fire input file decks and processing QUIC-Fire output files into standard Python array data structures.
+
+The goals of quicfire-tools are to:
+
+1. Make it easy to write Python code to work with QUIC-Fire input and output files.
+2. Unify code, scripts, and workflows across the QUIC-Fire ecosystem into a single package to support the development of
+   new QUIC-Fire tools and applications.
+3. Provide a platform for collaboration among QUIC-Fire developers and users.
+
+
+## Installation
+
+quicfire-tools can be installed using `pip` or `conda`.
+
+### pip
+
+```bash
+pip install quicfire-tools
+```
+
+### conda
+
+Conda support is coming soon!
+
+
+## Issues
+
+If you encounter any issues with the FastFuels Python SDK, please submit an
+issue on the [GitHub repository](https://github.com/silvxlabs/fastfuels-sdk-python/issues).
diff --git a/docs/reference.md b/docs/reference.md
new file mode 100644
index 0000000..24d7285
--- /dev/null
+++ b/docs/reference.md
@@ -0,0 +1,9 @@
+::: quicfire_tools.inputs
+
+::: quicfire_tools.ignitions
+
+::: quicfire_tools.topography
+
+::: quicfire_tools.outputs
+
+::: quicfire_tools.examples
diff --git a/examples/data/blue_mtn_100m.geojson b/examples/data/blue_mtn_100m.geojson
new file mode 100644
index 0000000..648b109
--- /dev/null
+++ b/examples/data/blue_mtn_100m.geojson
@@ -0,0 +1,8 @@
+{
+"type": "FeatureCollection",
+"name": "blue_mtn_100m",
+"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::5070" } },
+"features": [
+{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -1378810.119193073827773, 2781532.062650748062879 ], [ -1378810.119193073827773, 2781632.062650748062879 ], [ -1378710.119193073827773, 2781632.062650748062879 ], [ -1378710.119193073827773, 2781532.062650748062879 ], [ -1378810.119193073827773, 2781532.062650748062879 ] ] ] } }
+]
+}
diff --git a/examples/rechunking.ipynb b/examples/rechunking.ipynb
new file mode 100644
index 0000000..66bf153
--- /dev/null
+++ b/examples/rechunking.ipynb
@@ -0,0 +1,4063 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "fee353ea48913bdd",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:05.750343Z",
+     "start_time": "2023-10-11T12:19:05.674073Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import sys\n",
+    "\n",
+    "sys.path.append(\"../\")\n",
+    "from quicfire_tools import outputs\n",
+    "from quicfire_tools.parameters import SimulationParameters"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "initial_id",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:05.841321Z",
+     "start_time": "2023-10-11T12:19:05.836270Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import zarr\n",
+    "import numpy as np\n",
+    "import xarray as xr\n",
+    "import dask.array as da\n",
+    "from rechunker import rechunk\n",
+    "from pathlib import Path\n",
+    "from IPython.display import display, HTML"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "b1d8f6f257e053b",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:06.117877Z",
+     "start_time": "2023-10-11T12:19:06.112191Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "TMP_PATH = Path(\"../tests/tmp\")\n",
+    "DATA_PATH = Path(\"../tests/data\")\n",
+    "SIMULATION_PATH = DATA_PATH / \"crazy-canyon-simulation\"\n",
+    "OUTPUT_PATH = SIMULATION_PATH / \"Output\"\n",
+    "DRAWFIRE_PATH = OUTPUT_PATH / \"drawfire\"\n",
+    "\n",
+    "# Create simulation parameters object\n",
+    "SIM_PARAMS = SimulationParameters(\n",
+    "    nx=100,\n",
+    "    ny=100,\n",
+    "    nz=56,\n",
+    "    dx=1,\n",
+    "    dy=1,\n",
+    "    dz=1,\n",
+    "    wind_speed=6.5,\n",
+    "    wind_direction=270,\n",
+    "    sim_time=600,\n",
+    "    auto_kill=0,\n",
+    "    num_cpus=4,\n",
+    "    fuel_flag=4,\n",
+    "    ignition_flag=1,\n",
+    "    output_time=100,\n",
+    "    topo_flag=0,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "6dddacaf2eab2038",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:06.482318Z",
+     "start_time": "2023-10-11T12:19:06.474791Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "sim_outputs = outputs.SimulationOutputs(OUTPUT_PATH, SIM_PARAMS)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "13d3bb0f4bd15177",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:07.459945Z",
+     "start_time": "2023-10-11T12:19:07.375150Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "zarr_simulation_outputs = sim_outputs.to_zarr(TMP_PATH / \"test.zarr\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "f7659b86d5859b16",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:07.985539Z",
+     "start_time": "2023-10-11T12:19:07.979729Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "/\n",
+      " ├── fire-energy_to_atmos (2, 100, 100, 57) float64\n",
+      " ├── fire-reaction_rate (2, 100, 100, 57) float64\n",
+      " ├── fuels-dens (2, 100, 100, 57) float64\n",
+      " ├── fuels-moist (2, 100, 100, 57) float64\n",
+      " ├── groundfuelheight (1, 100, 100, 1) float64\n",
+      " ├── mburnt_integ (2, 100, 100, 1) float64\n",
+      " ├── thermaldose (2, 100, 100, 57) float64\n",
+      " ├── thermalradiation (2, 100, 100, 57) float64\n",
+      " └── windu (2, 100, 100, 57) float64\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(zarr_simulation_outputs.tree())"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "455ff33034e7caf",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "source": [
+    "# Xarray rechunking"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "755e9c58ab1f7654",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "source": [
+    "### All arrays in a dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "5af1506169e74c01",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:09.465792Z",
+     "start_time": "2023-10-11T12:19:09.309560Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "ds_3d = xr.open_zarr(\n",
+    "    TMP_PATH / \"test.zarr\",\n",
+    "    drop_variables=[\"groundfuelheight\", \"mburnt_integ\"],\n",
+    "    consolidated=False,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "8f13307ddd520b92",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:09.920935Z",
+     "start_time": "2023-10-11T12:19:09.913330Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<xarray.Dataset>\n",
+      "Dimensions:               (time: 2, y: 100, x: 100, z: 57)\n",
+      "Dimensions without coordinates: time, y, x, z\n",
+      "Data variables:\n",
+      "    fire-energy_to_atmos  (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 57), meta=np.ndarray>\n",
+      "    fire-reaction_rate    (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 57), meta=np.ndarray>\n",
+      "    fuels-dens            (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 57), meta=np.ndarray>\n",
+      "    fuels-moist           (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 57), meta=np.ndarray>\n",
+      "    thermaldose           (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 57), meta=np.ndarray>\n",
+      "    thermalradiation      (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 57), meta=np.ndarray>\n",
+      "    windu                 (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 57), meta=np.ndarray>\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ds_3d)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "cfb204c40dedfd45",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:12.200147Z",
+     "start_time": "2023-10-11T12:19:12.181551Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;fuels-dens&#x27; (time: 2, y: 100, x: 100, z: 57)&gt;\n",
+       "dask.array&lt;open_dataset-fuels-dens, shape=(2, 100, 100, 57), dtype=float64, chunksize=(1, 100, 100, 57), chunktype=numpy.ndarray&gt;\n",
+       "Dimensions without coordinates: time, y, x, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'fuels-dens'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span>y</span>: 100</li><li><span>x</span>: 100</li><li><span>z</span>: 57</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-52895b38-46fe-490c-b0ab-8a29c1c383ec' class='xr-array-in' type='checkbox' checked><label for='section-52895b38-46fe-490c-b0ab-8a29c1c383ec' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(1, 100, 100, 57), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 8.70 MiB </td>\n",
+       "                        <td> 4.35 MiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 57) </td>\n",
+       "                        <td> (1, 100, 100, 57) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 2 chunks in 2 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"386\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"14\" y1=\"0\" x2=\"14\" y2=\"25\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"167\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"167\" y1=\"0\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 167.4,0.0 237.98823529411766,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"237\" y1=\"70\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 237.98823529411766,70.58823529411765 237.98823529411766,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"203.788235\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >57</text>\n",
+       "  <text x=\"257.988235\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,257.988235,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-11fa81b7-1144-40fc-899b-769491451a2f' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-11fa81b7-1144-40fc-899b-769491451a2f' class='xr-section-summary'  title='Expand/collapse section'>Coordinates: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-e6302c5a-5c61-44e9-bc32-d392b7215ef3' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-e6302c5a-5c61-44e9-bc32-d392b7215ef3' class='xr-section-summary'  title='Expand/collapse section'>Indexes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-2707e23c-7f28-46f7-b776-112c1ad9b5bf' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-2707e23c-7f28-46f7-b776-112c1ad9b5bf' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'fuels-dens' (time: 2, y: 100, x: 100, z: 57)>\n",
+       "dask.array<open_dataset-fuels-dens, shape=(2, 100, 100, 57), dtype=float64, chunksize=(1, 100, 100, 57), chunktype=numpy.ndarray>\n",
+       "Dimensions without coordinates: time, y, x, z"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ds_3d[\"fuels-dens\"]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "d2787fb3df8932d1",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:16.723881Z",
+     "start_time": "2023-10-11T12:19:16.715271Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Rechunk the full dataset along the time dimension\n",
+    "ds_3d_rechunked = ds_3d.chunk({\"time\": 2})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "21a348b1ede3dc62",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:17.311521Z",
+     "start_time": "2023-10-11T12:19:17.294825Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<xarray.Dataset>\n",
+      "Dimensions:               (time: 2, y: 100, x: 100, z: 57)\n",
+      "Dimensions without coordinates: time, y, x, z\n",
+      "Data variables:\n",
+      "    fire-energy_to_atmos  (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 57), meta=np.ndarray>\n",
+      "    fire-reaction_rate    (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 57), meta=np.ndarray>\n",
+      "    fuels-dens            (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 57), meta=np.ndarray>\n",
+      "    fuels-moist           (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 57), meta=np.ndarray>\n",
+      "    thermaldose           (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 57), meta=np.ndarray>\n",
+      "    thermalradiation      (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 57), meta=np.ndarray>\n",
+      "    windu                 (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 57), meta=np.ndarray>\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ds_3d_rechunked)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "6768cce5-bfac-45f2-998b-78b4958bcbb1",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:19:45.189258Z",
+     "start_time": "2023-10-11T12:19:45.166651Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;fuels-dens&#x27; (time: 2, y: 100, x: 100, z: 57)&gt;\n",
+       "dask.array&lt;rechunk-merge, shape=(2, 100, 100, 57), dtype=float64, chunksize=(2, 100, 100, 57), chunktype=numpy.ndarray&gt;\n",
+       "Dimensions without coordinates: time, y, x, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'fuels-dens'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span>y</span>: 100</li><li><span>x</span>: 100</li><li><span>z</span>: 57</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-611588d5-2032-4dfd-9310-cc7812987915' class='xr-array-in' type='checkbox' checked><label for='section-611588d5-2032-4dfd-9310-cc7812987915' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(2, 100, 100, 57), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 8.70 MiB </td>\n",
+       "                        <td> 8.70 MiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 57) </td>\n",
+       "                        <td> (2, 100, 100, 57) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 1 chunks in 3 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"386\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"167\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"167\" y1=\"0\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 167.4,0.0 237.98823529411766,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"237\" y1=\"70\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 237.98823529411766,70.58823529411765 237.98823529411766,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"203.788235\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >57</text>\n",
+       "  <text x=\"257.988235\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,257.988235,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-6004d3f9-e517-483c-8706-783ec02f3f97' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-6004d3f9-e517-483c-8706-783ec02f3f97' class='xr-section-summary'  title='Expand/collapse section'>Coordinates: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-d54aaf55-2b85-43c5-b395-98ec19b8d7fc' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-d54aaf55-2b85-43c5-b395-98ec19b8d7fc' class='xr-section-summary'  title='Expand/collapse section'>Indexes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-968c63b7-e590-42fb-b8da-e055d4c97aa3' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-968c63b7-e590-42fb-b8da-e055d4c97aa3' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'fuels-dens' (time: 2, y: 100, x: 100, z: 57)>\n",
+       "dask.array<rechunk-merge, shape=(2, 100, 100, 57), dtype=float64, chunksize=(2, 100, 100, 57), chunktype=numpy.ndarray>\n",
+       "Dimensions without coordinates: time, y, x, z"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ds_3d_rechunked[\"fuels-dens\"]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "31073048608b5ef8",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "source": [
+    "### Rechunk a single data array in the dataset "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "3b6151985d5f7bbd",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.546416Z",
+     "start_time": "2023-10-10T20:14:19.525964Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;fuels-dens&#x27; (time: 2, y: 100, x: 100, z: 57)&gt;\n",
+       "dask.array&lt;open_dataset-fuels-dens, shape=(2, 100, 100, 57), dtype=float64, chunksize=(1, 100, 100, 57), chunktype=numpy.ndarray&gt;\n",
+       "Dimensions without coordinates: time, y, x, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'fuels-dens'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span>y</span>: 100</li><li><span>x</span>: 100</li><li><span>z</span>: 57</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-cb0a6930-92e7-436f-84c9-b4b24097c165' class='xr-array-in' type='checkbox' checked><label for='section-cb0a6930-92e7-436f-84c9-b4b24097c165' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(1, 100, 100, 57), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 8.70 MiB </td>\n",
+       "                        <td> 4.35 MiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 57) </td>\n",
+       "                        <td> (1, 100, 100, 57) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 2 chunks in 2 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"386\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"14\" y1=\"0\" x2=\"14\" y2=\"25\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"167\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"167\" y1=\"0\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 167.4,0.0 237.98823529411766,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"237\" y1=\"70\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 237.98823529411766,70.58823529411765 237.98823529411766,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"203.788235\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >57</text>\n",
+       "  <text x=\"257.988235\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,257.988235,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-53e10127-24da-4d02-9f23-283798442948' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-53e10127-24da-4d02-9f23-283798442948' class='xr-section-summary'  title='Expand/collapse section'>Coordinates: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-30c10958-0314-41ea-9144-9535ed727ffd' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-30c10958-0314-41ea-9144-9535ed727ffd' class='xr-section-summary'  title='Expand/collapse section'>Indexes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-f37db88b-15db-4f60-8c1b-63a96adfca22' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-f37db88b-15db-4f60-8c1b-63a96adfca22' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'fuels-dens' (time: 2, y: 100, x: 100, z: 57)>\n",
+       "dask.array<open_dataset-fuels-dens, shape=(2, 100, 100, 57), dtype=float64, chunksize=(1, 100, 100, 57), chunktype=numpy.ndarray>\n",
+       "Dimensions without coordinates: time, y, x, z"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "da_fuels_dens = ds_3d[\"fuels-dens\"]\n",
+    "da_fuels_dens"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "8c783c388d760107",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.547594Z",
+     "start_time": "2023-10-10T20:14:19.538418Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;fuels-dens&#x27; (time: 2, y: 100, x: 100, z: 57)&gt;\n",
+       "dask.array&lt;rechunk-merge, shape=(2, 100, 100, 57), dtype=float64, chunksize=(1, 10, 10, 10), chunktype=numpy.ndarray&gt;\n",
+       "Dimensions without coordinates: time, y, x, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'fuels-dens'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span>y</span>: 100</li><li><span>x</span>: 100</li><li><span>z</span>: 57</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-919df37e-e422-4fbe-8241-72164c663309' class='xr-array-in' type='checkbox' checked><label for='section-919df37e-e422-4fbe-8241-72164c663309' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(1, 10, 10, 10), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 8.70 MiB </td>\n",
+       "                        <td> 7.81 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 57) </td>\n",
+       "                        <td> (1, 10, 10, 10) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 1200 chunks in 3 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"386\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"14\" y1=\"0\" x2=\"14\" y2=\"25\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"12\" x2=\"169\" y2=\"82\" />\n",
+       "  <line x1=\"99\" y1=\"24\" x2=\"169\" y2=\"94\" />\n",
+       "  <line x1=\"99\" y1=\"36\" x2=\"169\" y2=\"106\" />\n",
+       "  <line x1=\"99\" y1=\"48\" x2=\"169\" y2=\"118\" />\n",
+       "  <line x1=\"99\" y1=\"60\" x2=\"169\" y2=\"130\" />\n",
+       "  <line x1=\"99\" y1=\"72\" x2=\"169\" y2=\"142\" />\n",
+       "  <line x1=\"99\" y1=\"84\" x2=\"169\" y2=\"154\" />\n",
+       "  <line x1=\"99\" y1=\"96\" x2=\"169\" y2=\"166\" />\n",
+       "  <line x1=\"99\" y1=\"108\" x2=\"169\" y2=\"178\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"106\" y1=\"7\" x2=\"106\" y2=\"127\" />\n",
+       "  <line x1=\"113\" y1=\"14\" x2=\"113\" y2=\"134\" />\n",
+       "  <line x1=\"120\" y1=\"21\" x2=\"120\" y2=\"141\" />\n",
+       "  <line x1=\"127\" y1=\"28\" x2=\"127\" y2=\"148\" />\n",
+       "  <line x1=\"134\" y1=\"35\" x2=\"134\" y2=\"155\" />\n",
+       "  <line x1=\"141\" y1=\"42\" x2=\"141\" y2=\"162\" />\n",
+       "  <line x1=\"148\" y1=\"49\" x2=\"148\" y2=\"169\" />\n",
+       "  <line x1=\"155\" y1=\"56\" x2=\"155\" y2=\"176\" />\n",
+       "  <line x1=\"162\" y1=\"63\" x2=\"162\" y2=\"183\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"167\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"106\" y1=\"7\" x2=\"174\" y2=\"7\" />\n",
+       "  <line x1=\"113\" y1=\"14\" x2=\"181\" y2=\"14\" />\n",
+       "  <line x1=\"120\" y1=\"21\" x2=\"188\" y2=\"21\" />\n",
+       "  <line x1=\"127\" y1=\"28\" x2=\"195\" y2=\"28\" />\n",
+       "  <line x1=\"134\" y1=\"35\" x2=\"202\" y2=\"35\" />\n",
+       "  <line x1=\"141\" y1=\"42\" x2=\"209\" y2=\"42\" />\n",
+       "  <line x1=\"148\" y1=\"49\" x2=\"216\" y2=\"49\" />\n",
+       "  <line x1=\"155\" y1=\"56\" x2=\"223\" y2=\"56\" />\n",
+       "  <line x1=\"162\" y1=\"63\" x2=\"230\" y2=\"63\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"111\" y1=\"0\" x2=\"181\" y2=\"70\" />\n",
+       "  <line x1=\"123\" y1=\"0\" x2=\"193\" y2=\"70\" />\n",
+       "  <line x1=\"135\" y1=\"0\" x2=\"205\" y2=\"70\" />\n",
+       "  <line x1=\"147\" y1=\"0\" x2=\"217\" y2=\"70\" />\n",
+       "  <line x1=\"159\" y1=\"0\" x2=\"229\" y2=\"70\" />\n",
+       "  <line x1=\"167\" y1=\"0\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 167.4,0.0 237.98823529411766,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"237\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"82\" x2=\"237\" y2=\"82\" />\n",
+       "  <line x1=\"169\" y1=\"94\" x2=\"237\" y2=\"94\" />\n",
+       "  <line x1=\"169\" y1=\"106\" x2=\"237\" y2=\"106\" />\n",
+       "  <line x1=\"169\" y1=\"118\" x2=\"237\" y2=\"118\" />\n",
+       "  <line x1=\"169\" y1=\"130\" x2=\"237\" y2=\"130\" />\n",
+       "  <line x1=\"169\" y1=\"142\" x2=\"237\" y2=\"142\" />\n",
+       "  <line x1=\"169\" y1=\"154\" x2=\"237\" y2=\"154\" />\n",
+       "  <line x1=\"169\" y1=\"166\" x2=\"237\" y2=\"166\" />\n",
+       "  <line x1=\"169\" y1=\"178\" x2=\"237\" y2=\"178\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"181\" y1=\"70\" x2=\"181\" y2=\"190\" />\n",
+       "  <line x1=\"193\" y1=\"70\" x2=\"193\" y2=\"190\" />\n",
+       "  <line x1=\"205\" y1=\"70\" x2=\"205\" y2=\"190\" />\n",
+       "  <line x1=\"217\" y1=\"70\" x2=\"217\" y2=\"190\" />\n",
+       "  <line x1=\"229\" y1=\"70\" x2=\"229\" y2=\"190\" />\n",
+       "  <line x1=\"237\" y1=\"70\" x2=\"237\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 237.98823529411766,70.58823529411765 237.98823529411766,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"203.788235\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >57</text>\n",
+       "  <text x=\"257.988235\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,257.988235,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-f58936e8-e57f-4817-9ca6-7bb84befc426' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-f58936e8-e57f-4817-9ca6-7bb84befc426' class='xr-section-summary'  title='Expand/collapse section'>Coordinates: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-4ae5849c-c130-48cc-aafd-c3e6e66b95ae' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-4ae5849c-c130-48cc-aafd-c3e6e66b95ae' class='xr-section-summary'  title='Expand/collapse section'>Indexes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-e7849754-e3dd-4b9b-bf0b-258652a30d7e' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-e7849754-e3dd-4b9b-bf0b-258652a30d7e' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'fuels-dens' (time: 2, y: 100, x: 100, z: 57)>\n",
+       "dask.array<rechunk-merge, shape=(2, 100, 100, 57), dtype=float64, chunksize=(1, 10, 10, 10), chunktype=numpy.ndarray>\n",
+       "Dimensions without coordinates: time, y, x, z"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "da_fuels_dens_rechunked = da_fuels_dens.chunk({\"x\": 10, \"y\": 10, \"z\": 10})\n",
+    "da_fuels_dens_rechunked"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a2a35a175a94afd8",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "source": [
+    "### Just the mburnt_integ array in a dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "823cfd7f3b9811b7",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.549612Z",
+     "start_time": "2023-10-10T20:14:19.543234Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "output_name = \"mburnt_integ\"\n",
+    "dropped_variables = [var for var in zarr_simulation_outputs if var != output_name]\n",
+    "ds_2d = xr.open_zarr(\n",
+    "    TMP_PATH / \"test.zarr\",\n",
+    "    drop_variables=dropped_variables,\n",
+    "    consolidated=False,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "d0305f56b1163064",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.555524Z",
+     "start_time": "2023-10-10T20:14:19.548853Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<xarray.Dataset>\n",
+      "Dimensions:       (time: 2, y: 100, x: 100, z: 1)\n",
+      "Dimensions without coordinates: time, y, x, z\n",
+      "Data variables:\n",
+      "    mburnt_integ  (time, y, x, z) float64 dask.array<chunksize=(1, 100, 100, 1), meta=np.ndarray>\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ds_2d)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "29294d19fd60b919",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.557376Z",
+     "start_time": "2023-10-10T20:14:19.552766Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;mburnt_integ&#x27; (time: 2, y: 100, x: 100, z: 1)&gt;\n",
+       "dask.array&lt;open_dataset-mburnt_integ, shape=(2, 100, 100, 1), dtype=float64, chunksize=(1, 100, 100, 1), chunktype=numpy.ndarray&gt;\n",
+       "Dimensions without coordinates: time, y, x, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'mburnt_integ'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span>y</span>: 100</li><li><span>x</span>: 100</li><li><span>z</span>: 1</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-378accbb-8e03-4220-b253-17fe055ba38a' class='xr-array-in' type='checkbox' checked><label for='section-378accbb-8e03-4220-b253-17fe055ba38a' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(1, 100, 100, 1), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                        <td> (1, 100, 100, 1) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 2 chunks in 2 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"344\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"14\" y1=\"0\" x2=\"14\" y2=\"25\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"124\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"124\" y1=\"0\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 124.41261651458248,0.0 195.00085180870013,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"195\" y1=\"70\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 195.00085180870013,70.58823529411765 195.00085180870013,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"182.294544\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1</text>\n",
+       "  <text x=\"215.000852\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,215.000852,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-19711506-fa8a-4f88-8a1e-ec3a085f311d' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-19711506-fa8a-4f88-8a1e-ec3a085f311d' class='xr-section-summary'  title='Expand/collapse section'>Coordinates: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-3fd50aaa-ffbc-4cc2-aa40-5d0714aacf1a' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-3fd50aaa-ffbc-4cc2-aa40-5d0714aacf1a' class='xr-section-summary'  title='Expand/collapse section'>Indexes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-46181f6c-3684-433e-bdc5-a25293144297' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-46181f6c-3684-433e-bdc5-a25293144297' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'mburnt_integ' (time: 2, y: 100, x: 100, z: 1)>\n",
+       "dask.array<open_dataset-mburnt_integ, shape=(2, 100, 100, 1), dtype=float64, chunksize=(1, 100, 100, 1), chunktype=numpy.ndarray>\n",
+       "Dimensions without coordinates: time, y, x, z"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ds_2d[\"mburnt_integ\"]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "id": "36646c4116efba2c",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.585052Z",
+     "start_time": "2023-10-10T20:14:19.558042Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Rechunk the ds along the time dimension\n",
+    "ds_2d_rechunked = ds_2d.chunk({\"time\": -1})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "41a940cc3df96ac8",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.585357Z",
+     "start_time": "2023-10-10T20:14:19.560593Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<xarray.Dataset>\n",
+      "Dimensions:       (time: 2, y: 100, x: 100, z: 1)\n",
+      "Dimensions without coordinates: time, y, x, z\n",
+      "Data variables:\n",
+      "    mburnt_integ  (time, y, x, z) float64 dask.array<chunksize=(2, 100, 100, 1), meta=np.ndarray>\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ds_2d_rechunked)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "id": "af784a18cf705a3e",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.586310Z",
+     "start_time": "2023-10-10T20:14:19.563523Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;mburnt_integ&#x27; (time: 2, y: 100, x: 100, z: 1)&gt;\n",
+       "dask.array&lt;rechunk-merge, shape=(2, 100, 100, 1), dtype=float64, chunksize=(2, 100, 100, 1), chunktype=numpy.ndarray&gt;\n",
+       "Dimensions without coordinates: time, y, x, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'mburnt_integ'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span>y</span>: 100</li><li><span>x</span>: 100</li><li><span>z</span>: 1</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-58f088f1-7e95-42d6-90f1-2b2ab33b59e9' class='xr-array-in' type='checkbox' checked><label for='section-58f088f1-7e95-42d6-90f1-2b2ab33b59e9' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(2, 100, 100, 1), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 1 chunks in 3 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"344\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"124\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"124\" y1=\"0\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 124.41261651458248,0.0 195.00085180870013,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"195\" y1=\"70\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 195.00085180870013,70.58823529411765 195.00085180870013,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"182.294544\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1</text>\n",
+       "  <text x=\"215.000852\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,215.000852,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-d6bfbde1-9d1a-4df2-87e7-d05f6d3043c3' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-d6bfbde1-9d1a-4df2-87e7-d05f6d3043c3' class='xr-section-summary'  title='Expand/collapse section'>Coordinates: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-d4b817c2-20fc-4699-9239-0e7739f069cc' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-d4b817c2-20fc-4699-9239-0e7739f069cc' class='xr-section-summary'  title='Expand/collapse section'>Indexes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-03f1b337-7912-4814-8f00-98f0bfaa5366' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-03f1b337-7912-4814-8f00-98f0bfaa5366' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'mburnt_integ' (time: 2, y: 100, x: 100, z: 1)>\n",
+       "dask.array<rechunk-merge, shape=(2, 100, 100, 1), dtype=float64, chunksize=(2, 100, 100, 1), chunktype=numpy.ndarray>\n",
+       "Dimensions without coordinates: time, y, x, z"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ds_2d_rechunked[\"mburnt_integ\"]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "59434f75f9561fe3",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "source": [
+    "# Dask rechunking"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "bc72404ca51b22e0",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.586409Z",
+     "start_time": "2023-10-10T20:14:19.568803Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "dask_array = sim_outputs.to_dask(\"mburnt_integ\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "id": "509038d94f672d47",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.587106Z",
+     "start_time": "2023-10-10T20:14:19.575829Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                        <td> (1, 100, 100, 1) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 2 chunks in 3 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"344\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"14\" y1=\"0\" x2=\"14\" y2=\"25\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"124\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"124\" y1=\"0\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 124.41261651458248,0.0 195.00085180870013,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"195\" y1=\"70\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 195.00085180870013,70.58823529411765 195.00085180870013,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"182.294544\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1</text>\n",
+       "  <text x=\"215.000852\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,215.000852,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table>"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "display(HTML(dask_array._repr_html_()))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "id": "e1f5d8ead65b6b12",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.587182Z",
+     "start_time": "2023-10-10T20:14:19.579203Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "dask_array_rechunked = dask_array.rechunk((2, 100, 100, 57))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "id": "6ef05fe8-c5b6-429c-8d75-2e8b4c3063ed",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:14:19.601391Z",
+     "start_time": "2023-10-10T20:14:19.582099Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 1 chunks in 4 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"344\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"124\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"124\" y1=\"0\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 124.41261651458248,0.0 195.00085180870013,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"195\" y1=\"70\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 195.00085180870013,70.58823529411765 195.00085180870013,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"182.294544\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1</text>\n",
+       "  <text x=\"215.000852\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,215.000852,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table>"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "display(HTML(dask_array_rechunked._repr_html_()))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "56e729f41d86c7f9",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "source": [
+    "# Zarr rechunking with rechunker"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f63ccea55b5fd6b",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "source": [
+    "### Rechunk group"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "1215e2e2-6f7c-41ba-8011-3906286fbb54",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:22:28.448840Z",
+     "start_time": "2023-10-10T20:22:28.338776Z"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<h2>Rechunked</h2>\n",
+       "        <details>\n",
+       "          <summary><b>Source</b></summary>\n",
+       "          <p><code>&lt;zarr.hierarchy.Group &#x27;/&#x27;&gt;</code></p>\n",
+       "        </details>\n",
+       "        <details>\n",
+       "<summary><b>Intermediate</b></summary>\n",
+       "<p><code>&lt;zarr.hierarchy.Group &#x27;/&#x27;&gt;</code></p>\n",
+       "</details>\n",
+       "\n",
+       "        <details>\n",
+       "          <summary><b>Target</b></summary>\n",
+       "          <p><code>&lt;zarr.hierarchy.Group &#x27;/&#x27;&gt;</code></p>\n",
+       "        </details>\n"
+      ],
+      "text/plain": [
+       "<Rechunked>\n",
+       "* Source      : <zarr.hierarchy.Group '/'>\n",
+       "\n",
+       "* Intermediate: <zarr.hierarchy.Group '/'>\n",
+       "\n",
+       "* Target      : <zarr.hierarchy.Group '/'>"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "zarr_group = sim_outputs.to_zarr(TMP_PATH / \"test.zarr\", dimensions=True)\n",
+    "target_chunks = {\n",
+    "    \"fire-energy_to_atmos\": (2, 100, 100, 57),\n",
+    "    \"fire-reaction_rate\": (2, 100, 100, 57),\n",
+    "    \"fuels-dens\": (2, 100, 100, 57),\n",
+    "    \"fuels-moist\": (2, 100, 100, 57),\n",
+    "    \"groundfuelheight\": (1, 100, 100, 1),\n",
+    "    \"mburnt_integ\": (2, 100, 100, 1),\n",
+    "    \"thermaldose\": (2, 100, 100, 57),\n",
+    "    \"thermalradiation\": (2, 100, 100, 57),\n",
+    "    \"windu\": (2, 100, 100, 57),\n",
+    "}\n",
+    "max_mem = \"100MB\"\n",
+    "array_plan = rechunk(\n",
+    "    zarr_group,\n",
+    "    target_chunks,\n",
+    "    max_mem,\n",
+    "    target_store=TMP_PATH / \"test_group_rechunked.zarr\",\n",
+    "    temp_store=TMP_PATH / \"test_group_tmp.zarr\",\n",
+    ")\n",
+    "array_plan"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "id": "e0e22d388a7f40d5",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:21:33.795413Z",
+     "start_time": "2023-10-10T20:21:33.785959Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "rechunked = array_plan.execute()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "id": "a633c15f",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<zarr.hierarchy.Group '/'>\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(rechunked)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "id": "89830a51fe21310c",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-10T20:21:34.656145Z",
+     "start_time": "2023-10-10T20:21:34.630661Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "/\n",
+      " ├── fire-energy_to_atmos (2, 100, 100, 57) float64\n",
+      " ├── fire-reaction_rate (2, 100, 100, 57) float64\n",
+      " ├── fuels-dens (2, 100, 100, 57) float64\n",
+      " ├── fuels-moist (2, 100, 100, 57) float64\n",
+      " ├── groundfuelheight (1, 100, 100, 1) float64\n",
+      " ├── mburnt_integ (2, 100, 100, 1) float64\n",
+      " ├── thermaldose (2, 100, 100, 57) float64\n",
+      " ├── thermalradiation (2, 100, 100, 57) float64\n",
+      " └── windu (2, 100, 100, 57) float64\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(rechunked.tree())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "63548ed8ec218b28",
+   "metadata": {
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(2, 100, 100, 57)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(rechunked[\"fuels-dens\"].chunks)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "77ebba7b",
+   "metadata": {},
+   "source": [
+    "### Rechunk single Store"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "19c5cf78",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<h2>Rechunked</h2>\n",
+       "        <details>\n",
+       "          <summary><b>Source</b></summary>\n",
+       "          <p><code>&lt;zarr.core.Array (2, 100, 100, 57) float64&gt;</code></p>\n",
+       "        </details>\n",
+       "        \n",
+       "        <details>\n",
+       "          <summary><b>Target</b></summary>\n",
+       "          <p><code>&lt;zarr.core.Array (2, 100, 100, 57) float64&gt;</code></p>\n",
+       "        </details>\n"
+      ],
+      "text/plain": [
+       "<Rechunked>\n",
+       "* Source      : <zarr.core.Array '/fuels-dens' (2, 100, 100, 57) float64>\n",
+       "\n",
+       "* Target      : <zarr.core.Array (2, 100, 100, 57) float64>"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "zarr_group = sim_outputs.to_zarr(TMP_PATH / \"test.zarr\", dimensions=True)\n",
+    "source_array = zarr_group[\"fuels-dens\"]\n",
+    "target_chunks = (2, 100, 100, 57)\n",
+    "max_mem = \"100MB\"\n",
+    "array_plan = rechunk(\n",
+    "    source_array,\n",
+    "    target_chunks,\n",
+    "    max_mem,\n",
+    "    target_store=TMP_PATH / \"test_store_rechunked.zarr\",\n",
+    "    temp_store=TMP_PATH / \"test_store_tmp.zarr\",\n",
+    ")\n",
+    "array_plan"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "id": "d058a61a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "rechunked = array_plan.execute()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "id": "f0ea79e3",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<zarr.core.Array (2, 100, 100, 57) float64>\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(rechunked)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "id": "b0b03030",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(2, 100, 100, 57)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(rechunked.chunks)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/rioxarray.ipynb b/examples/rioxarray.ipynb
new file mode 100644
index 0000000..849996c
--- /dev/null
+++ b/examples/rioxarray.ipynb
@@ -0,0 +1,2666 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "3dd9929975b8b998",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:18.836776Z",
+     "start_time": "2023-10-11T12:45:18.473535Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import sys\n",
+    "\n",
+    "sys.path.append(\"..\")\n",
+    "from quicfire_tools import outputs\n",
+    "from quicfire_tools.parameters import SimulationParameters"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "initial_id",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.553257Z",
+     "start_time": "2023-10-11T12:45:18.838501Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import zarr\n",
+    "import numpy as np\n",
+    "import xarray as xr\n",
+    "import rasterio as rio\n",
+    "import rioxarray as rxr\n",
+    "import geopandas as gpd\n",
+    "import matplotlib.pyplot as plt\n",
+    "import matplotlib.lines as mlines\n",
+    "from pathlib import Path"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "c0e8fd6f2db3ffe0",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.559622Z",
+     "start_time": "2023-10-11T12:45:19.554620Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "TMP_PATH = Path(\"../tests/tmp\")\n",
+    "DATA_PATH = Path(\"../tests/data\")\n",
+    "SIMULATION_PATH = DATA_PATH / \"crazy-canyon-simulation\"\n",
+    "OUTPUT_PATH = SIMULATION_PATH / \"Output\"\n",
+    "DRAWFIRE_PATH = OUTPUT_PATH / \"drawfire\"\n",
+    "\n",
+    "# Create simulation parameters object\n",
+    "SIM_PARAMS = SimulationParameters(\n",
+    "    nx=100,\n",
+    "    ny=100,\n",
+    "    nz=56,\n",
+    "    dx=1,\n",
+    "    dy=1,\n",
+    "    dz=1,\n",
+    "    wind_speed=6.5,\n",
+    "    wind_direction=270,\n",
+    "    sim_time=600,\n",
+    "    auto_kill=0,\n",
+    "    num_cpus=4,\n",
+    "    fuel_flag=4,\n",
+    "    ignition_flag=1,\n",
+    "    output_time=100,\n",
+    "    topo_flag=0,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "57438dca3a14e176",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.585299Z",
+     "start_time": "2023-10-11T12:45:19.557948Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Initialize the SimulationOutputs object\n",
+    "sim_outputs = outputs.SimulationOutputs(OUTPUT_PATH, SIM_PARAMS)\n",
+    "zarr_simulation_outputs = sim_outputs.to_zarr(\n",
+    "    TMP_PATH / \"test.zarr\", outputs=\"mburnt_integ\"\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "7a0728f366350a64",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.591674Z",
+     "start_time": "2023-10-11T12:45:19.586951Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "94.49690246582031"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "zarr_simulation_outputs[\"mburnt_integ\"][1, 50, 50, 0]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "41a0a44d8d7e1c3a",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.629598Z",
+     "start_time": "2023-10-11T12:45:19.591865Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;mburnt_integ&#x27; (time: 2, y: 100, x: 100, z: 1)&gt;\n",
+       "dask.array&lt;open_dataset-mburnt_integ, shape=(2, 100, 100, 1), dtype=float64, chunksize=(1, 100, 100, 1), chunktype=numpy.ndarray&gt;\n",
+       "Dimensions without coordinates: time, y, x, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'mburnt_integ'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span>y</span>: 100</li><li><span>x</span>: 100</li><li><span>z</span>: 1</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-eb5c61a9-9ad1-4372-9e6e-561a5777374e' class='xr-array-in' type='checkbox' checked><label for='section-eb5c61a9-9ad1-4372-9e6e-561a5777374e' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(1, 100, 100, 1), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                        <td> (1, 100, 100, 1) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 2 chunks in 2 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"344\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"14\" y1=\"0\" x2=\"14\" y2=\"25\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"124\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"124\" y1=\"0\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 124.41261651458248,0.0 195.00085180870013,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"195\" y1=\"70\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 195.00085180870013,70.58823529411765 195.00085180870013,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"182.294544\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1</text>\n",
+       "  <text x=\"215.000852\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,215.000852,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-39f84926-2199-4cb5-be12-88e809450c03' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-39f84926-2199-4cb5-be12-88e809450c03' class='xr-section-summary'  title='Expand/collapse section'>Coordinates: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-945f4b88-c885-4678-8300-8210d0695c57' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-945f4b88-c885-4678-8300-8210d0695c57' class='xr-section-summary'  title='Expand/collapse section'>Indexes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'></ul></div></li><li class='xr-section-item'><input id='section-7d3af38c-064e-44a5-8986-f40aa6c60d95' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-7d3af38c-064e-44a5-8986-f40aa6c60d95' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'mburnt_integ' (time: 2, y: 100, x: 100, z: 1)>\n",
+       "dask.array<open_dataset-mburnt_integ, shape=(2, 100, 100, 1), dtype=float64, chunksize=(1, 100, 100, 1), chunktype=numpy.ndarray>\n",
+       "Dimensions without coordinates: time, y, x, z"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Load the QUIC-Fire mburnt_integ output into an xarray DataArray\n",
+    "da = xr.open_zarr(TMP_PATH / \"test.zarr\", consolidated=False)[\"mburnt_integ\"]\n",
+    "da"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "124072ca10c5db2e",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.650362Z",
+     "start_time": "2023-10-11T12:45:19.612230Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "EPSG:5070\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Load a pretend shapefile of the area of interest\n",
+    "roi = gpd.read_file(\"data/blue_mtn_100m.geojson\")\n",
+    "print(roi.crs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "cbd12c12df3721",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.663440Z",
+     "start_time": "2023-10-11T12:45:19.660427Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "CRS.from_epsg(5070)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# Set the CRS of the DataArray\n",
+    "da = da.rio.write_crs(roi.crs)\n",
+    "da.rio.crs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "82548995118fd1f",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.669140Z",
+     "start_time": "2023-10-11T12:45:19.662632Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Set the transform of the DataArray\n",
+    "west = roi.total_bounds[0]\n",
+    "north = roi.total_bounds[3]\n",
+    "transform = rio.transform.from_origin(west, north, SIM_PARAMS.dx, SIM_PARAMS.dy)\n",
+    "da = da.rio.write_transform(transform)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "44ac147257d76019",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.669363Z",
+     "start_time": "2023-10-11T12:45:19.666679Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<bound method XRasterBase.transform of <rioxarray.raster_array.RasterArray object at 0x159fa1090>>\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(da.rio.transform)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "7738c02e225780c9",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.690899Z",
+     "start_time": "2023-10-11T12:45:19.671267Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Assign coordinates to the DataArray\n",
+    "da = da.assign_coords(\n",
+    "    x=da.x.values * SIM_PARAMS.dx + west,\n",
+    "    y=da.y.values * -SIM_PARAMS.dy + north,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "da738f265e84c28a",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.692417Z",
+     "start_time": "2023-10-11T12:45:19.675694Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;mburnt_integ&#x27; (time: 2, y: 100, x: 100, z: 1)&gt;\n",
+       "dask.array&lt;open_dataset-mburnt_integ, shape=(2, 100, 100, 1), dtype=float64, chunksize=(1, 100, 100, 1), chunktype=numpy.ndarray&gt;\n",
+       "Coordinates:\n",
+       "    spatial_ref  int64 0\n",
+       "  * x            (x) float64 -1.379e+06 -1.379e+06 ... -1.379e+06 -1.379e+06\n",
+       "  * y            (y) float64 2.782e+06 2.782e+06 ... 2.782e+06 2.782e+06\n",
+       "Dimensions without coordinates: time, z</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'mburnt_integ'</div><ul class='xr-dim-list'><li><span>time</span>: 2</li><li><span class='xr-has-index'>y</span>: 100</li><li><span class='xr-has-index'>x</span>: 100</li><li><span>z</span>: 1</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-03d537a5-c5cf-4e98-8382-12bf52807f20' class='xr-array-in' type='checkbox' checked><label for='section-03d537a5-c5cf-4e98-8382-12bf52807f20' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(1, 100, 100, 1), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 156.25 kiB </td>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (2, 100, 100, 1) </td>\n",
+       "                        <td> (1, 100, 100, 1) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 2 chunks in 2 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"344\" height=\"240\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"29\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"25\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"14\" y1=\"0\" x2=\"14\" y2=\"25\" />\n",
+       "  <line x1=\"29\" y1=\"0\" x2=\"29\" y2=\"25\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 29.030629010473877,0.0 29.030629010473877,25.412616514582485 0.0,25.412616514582485\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"14.515315\" y=\"45.412617\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >2</text>\n",
+       "  <text x=\"49.030629\" y=\"12.706308\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(0,49.030629,12.706308)\">1</text>\n",
+       "\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"99\" y1=\"120\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"99\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 169.58823529411765,70.58823529411765 169.58823529411765,190.58823529411765 99.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"124\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"99\" y1=\"0\" x2=\"169\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"124\" y1=\"0\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"99.0,0.0 124.41261651458248,0.0 195.00085180870013,70.58823529411765 169.58823529411765,70.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"195\" y2=\"70\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"169\" y1=\"190\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"169\" y1=\"70\" x2=\"169\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"195\" y1=\"70\" x2=\"195\" y2=\"190\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"169.58823529411765,70.58823529411765 195.00085180870013,70.58823529411765 195.00085180870013,190.58823529411765 169.58823529411765,190.58823529411765\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"182.294544\" y=\"210.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >1</text>\n",
+       "  <text x=\"215.000852\" y=\"130.588235\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,215.000852,130.588235)\">100</text>\n",
+       "  <text x=\"124.294118\" y=\"175.294118\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(45,124.294118,175.294118)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-90c80067-0d30-440c-a44e-0ede6ba0a799' class='xr-section-summary-in' type='checkbox'  checked><label for='section-90c80067-0d30-440c-a44e-0ede6ba0a799' class='xr-section-summary' >Coordinates: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>spatial_ref</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0</div><input id='attrs-6ffaab3b-6df7-4105-997c-e4e880f9418a' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-6ffaab3b-6df7-4105-997c-e4e880f9418a' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-17ec1a21-ea29-49b6-a77c-a2565b1b3f82' class='xr-var-data-in' type='checkbox'><label for='data-17ec1a21-ea29-49b6-a77c-a2565b1b3f82' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>crs_wkt :</span></dt><dd>PROJCS[&quot;NAD83 / Conus Albers&quot;,GEOGCS[&quot;NAD83&quot;,DATUM[&quot;North_American_Datum_1983&quot;,SPHEROID[&quot;GRS 1980&quot;,6378137,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4269&quot;]],PROJECTION[&quot;Albers_Conic_Equal_Area&quot;],PARAMETER[&quot;latitude_of_center&quot;,23],PARAMETER[&quot;longitude_of_center&quot;,-96],PARAMETER[&quot;standard_parallel_1&quot;,29.5],PARAMETER[&quot;standard_parallel_2&quot;,45.5],PARAMETER[&quot;false_easting&quot;,0],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;5070&quot;]]</dd><dt><span>semi_major_axis :</span></dt><dd>6378137.0</dd><dt><span>semi_minor_axis :</span></dt><dd>6356752.314140356</dd><dt><span>inverse_flattening :</span></dt><dd>298.257222101</dd><dt><span>reference_ellipsoid_name :</span></dt><dd>GRS 1980</dd><dt><span>longitude_of_prime_meridian :</span></dt><dd>0.0</dd><dt><span>prime_meridian_name :</span></dt><dd>Greenwich</dd><dt><span>geographic_crs_name :</span></dt><dd>NAD83</dd><dt><span>horizontal_datum_name :</span></dt><dd>North American Datum 1983</dd><dt><span>projected_crs_name :</span></dt><dd>NAD83 / Conus Albers</dd><dt><span>grid_mapping_name :</span></dt><dd>albers_conical_equal_area</dd><dt><span>standard_parallel :</span></dt><dd>(29.5, 45.5)</dd><dt><span>latitude_of_projection_origin :</span></dt><dd>23.0</dd><dt><span>longitude_of_central_meridian :</span></dt><dd>-96.0</dd><dt><span>false_easting :</span></dt><dd>0.0</dd><dt><span>false_northing :</span></dt><dd>0.0</dd><dt><span>spatial_ref :</span></dt><dd>PROJCS[&quot;NAD83 / Conus Albers&quot;,GEOGCS[&quot;NAD83&quot;,DATUM[&quot;North_American_Datum_1983&quot;,SPHEROID[&quot;GRS 1980&quot;,6378137,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4269&quot;]],PROJECTION[&quot;Albers_Conic_Equal_Area&quot;],PARAMETER[&quot;latitude_of_center&quot;,23],PARAMETER[&quot;longitude_of_center&quot;,-96],PARAMETER[&quot;standard_parallel_1&quot;,29.5],PARAMETER[&quot;standard_parallel_2&quot;,45.5],PARAMETER[&quot;false_easting&quot;,0],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;5070&quot;]]</dd><dt><span>GeoTransform :</span></dt><dd>-1378810.1191930738 1.0 0.0 2781632.062650748 0.0 -1.0</dd></dl></div><div class='xr-var-data'><pre>array(0)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-1.379e+06 ... -1.379e+06</div><input id='attrs-037de339-62be-4087-ba6e-13d15089dfab' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-037de339-62be-4087-ba6e-13d15089dfab' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-d175cdc0-0bad-4f39-99bb-ef022a97d247' class='xr-var-data-in' type='checkbox'><label for='data-d175cdc0-0bad-4f39-99bb-ef022a97d247' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([-1378810.119193, -1378809.119193, -1378808.119193, -1378807.119193,\n",
+       "       -1378806.119193, -1378805.119193, -1378804.119193, -1378803.119193,\n",
+       "       -1378802.119193, -1378801.119193, -1378800.119193, -1378799.119193,\n",
+       "       -1378798.119193, -1378797.119193, -1378796.119193, -1378795.119193,\n",
+       "       -1378794.119193, -1378793.119193, -1378792.119193, -1378791.119193,\n",
+       "       -1378790.119193, -1378789.119193, -1378788.119193, -1378787.119193,\n",
+       "       -1378786.119193, -1378785.119193, -1378784.119193, -1378783.119193,\n",
+       "       -1378782.119193, -1378781.119193, -1378780.119193, -1378779.119193,\n",
+       "       -1378778.119193, -1378777.119193, -1378776.119193, -1378775.119193,\n",
+       "       -1378774.119193, -1378773.119193, -1378772.119193, -1378771.119193,\n",
+       "       -1378770.119193, -1378769.119193, -1378768.119193, -1378767.119193,\n",
+       "       -1378766.119193, -1378765.119193, -1378764.119193, -1378763.119193,\n",
+       "       -1378762.119193, -1378761.119193, -1378760.119193, -1378759.119193,\n",
+       "       -1378758.119193, -1378757.119193, -1378756.119193, -1378755.119193,\n",
+       "       -1378754.119193, -1378753.119193, -1378752.119193, -1378751.119193,\n",
+       "       -1378750.119193, -1378749.119193, -1378748.119193, -1378747.119193,\n",
+       "       -1378746.119193, -1378745.119193, -1378744.119193, -1378743.119193,\n",
+       "       -1378742.119193, -1378741.119193, -1378740.119193, -1378739.119193,\n",
+       "       -1378738.119193, -1378737.119193, -1378736.119193, -1378735.119193,\n",
+       "       -1378734.119193, -1378733.119193, -1378732.119193, -1378731.119193,\n",
+       "       -1378730.119193, -1378729.119193, -1378728.119193, -1378727.119193,\n",
+       "       -1378726.119193, -1378725.119193, -1378724.119193, -1378723.119193,\n",
+       "       -1378722.119193, -1378721.119193, -1378720.119193, -1378719.119193,\n",
+       "       -1378718.119193, -1378717.119193, -1378716.119193, -1378715.119193,\n",
+       "       -1378714.119193, -1378713.119193, -1378712.119193, -1378711.119193])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>y</span></div><div class='xr-var-dims'>(y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>2.782e+06 2.782e+06 ... 2.782e+06</div><input id='attrs-798c8168-d64c-49d9-a33e-d74d601d1e81' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-798c8168-d64c-49d9-a33e-d74d601d1e81' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-3a80b22d-e822-42eb-844a-71a74fb44231' class='xr-var-data-in' type='checkbox'><label for='data-3a80b22d-e822-42eb-844a-71a74fb44231' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([2781632.062651, 2781631.062651, 2781630.062651, 2781629.062651,\n",
+       "       2781628.062651, 2781627.062651, 2781626.062651, 2781625.062651,\n",
+       "       2781624.062651, 2781623.062651, 2781622.062651, 2781621.062651,\n",
+       "       2781620.062651, 2781619.062651, 2781618.062651, 2781617.062651,\n",
+       "       2781616.062651, 2781615.062651, 2781614.062651, 2781613.062651,\n",
+       "       2781612.062651, 2781611.062651, 2781610.062651, 2781609.062651,\n",
+       "       2781608.062651, 2781607.062651, 2781606.062651, 2781605.062651,\n",
+       "       2781604.062651, 2781603.062651, 2781602.062651, 2781601.062651,\n",
+       "       2781600.062651, 2781599.062651, 2781598.062651, 2781597.062651,\n",
+       "       2781596.062651, 2781595.062651, 2781594.062651, 2781593.062651,\n",
+       "       2781592.062651, 2781591.062651, 2781590.062651, 2781589.062651,\n",
+       "       2781588.062651, 2781587.062651, 2781586.062651, 2781585.062651,\n",
+       "       2781584.062651, 2781583.062651, 2781582.062651, 2781581.062651,\n",
+       "       2781580.062651, 2781579.062651, 2781578.062651, 2781577.062651,\n",
+       "       2781576.062651, 2781575.062651, 2781574.062651, 2781573.062651,\n",
+       "       2781572.062651, 2781571.062651, 2781570.062651, 2781569.062651,\n",
+       "       2781568.062651, 2781567.062651, 2781566.062651, 2781565.062651,\n",
+       "       2781564.062651, 2781563.062651, 2781562.062651, 2781561.062651,\n",
+       "       2781560.062651, 2781559.062651, 2781558.062651, 2781557.062651,\n",
+       "       2781556.062651, 2781555.062651, 2781554.062651, 2781553.062651,\n",
+       "       2781552.062651, 2781551.062651, 2781550.062651, 2781549.062651,\n",
+       "       2781548.062651, 2781547.062651, 2781546.062651, 2781545.062651,\n",
+       "       2781544.062651, 2781543.062651, 2781542.062651, 2781541.062651,\n",
+       "       2781540.062651, 2781539.062651, 2781538.062651, 2781537.062651,\n",
+       "       2781536.062651, 2781535.062651, 2781534.062651, 2781533.062651])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-b90443a5-b10a-4967-9b24-bdfff009c086' class='xr-section-summary-in' type='checkbox'  ><label for='section-b90443a5-b10a-4967-9b24-bdfff009c086' class='xr-section-summary' >Indexes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>x</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-78cd433f-0fcf-4eb1-afd8-b5174fda1b3e' class='xr-index-data-in' type='checkbox'/><label for='index-78cd433f-0fcf-4eb1-afd8-b5174fda1b3e' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([-1378810.1191930738, -1378809.1191930738, -1378808.1191930738,\n",
+       "       -1378807.1191930738, -1378806.1191930738, -1378805.1191930738,\n",
+       "       -1378804.1191930738, -1378803.1191930738, -1378802.1191930738,\n",
+       "       -1378801.1191930738, -1378800.1191930738, -1378799.1191930738,\n",
+       "       -1378798.1191930738, -1378797.1191930738, -1378796.1191930738,\n",
+       "       -1378795.1191930738, -1378794.1191930738, -1378793.1191930738,\n",
+       "       -1378792.1191930738, -1378791.1191930738, -1378790.1191930738,\n",
+       "       -1378789.1191930738, -1378788.1191930738, -1378787.1191930738,\n",
+       "       -1378786.1191930738, -1378785.1191930738, -1378784.1191930738,\n",
+       "       -1378783.1191930738, -1378782.1191930738, -1378781.1191930738,\n",
+       "       -1378780.1191930738, -1378779.1191930738, -1378778.1191930738,\n",
+       "       -1378777.1191930738, -1378776.1191930738, -1378775.1191930738,\n",
+       "       -1378774.1191930738, -1378773.1191930738, -1378772.1191930738,\n",
+       "       -1378771.1191930738, -1378770.1191930738, -1378769.1191930738,\n",
+       "       -1378768.1191930738, -1378767.1191930738, -1378766.1191930738,\n",
+       "       -1378765.1191930738, -1378764.1191930738, -1378763.1191930738,\n",
+       "       -1378762.1191930738, -1378761.1191930738, -1378760.1191930738,\n",
+       "       -1378759.1191930738, -1378758.1191930738, -1378757.1191930738,\n",
+       "       -1378756.1191930738, -1378755.1191930738, -1378754.1191930738,\n",
+       "       -1378753.1191930738, -1378752.1191930738, -1378751.1191930738,\n",
+       "       -1378750.1191930738, -1378749.1191930738, -1378748.1191930738,\n",
+       "       -1378747.1191930738, -1378746.1191930738, -1378745.1191930738,\n",
+       "       -1378744.1191930738, -1378743.1191930738, -1378742.1191930738,\n",
+       "       -1378741.1191930738, -1378740.1191930738, -1378739.1191930738,\n",
+       "       -1378738.1191930738, -1378737.1191930738, -1378736.1191930738,\n",
+       "       -1378735.1191930738, -1378734.1191930738, -1378733.1191930738,\n",
+       "       -1378732.1191930738, -1378731.1191930738, -1378730.1191930738,\n",
+       "       -1378729.1191930738, -1378728.1191930738, -1378727.1191930738,\n",
+       "       -1378726.1191930738, -1378725.1191930738, -1378724.1191930738,\n",
+       "       -1378723.1191930738, -1378722.1191930738, -1378721.1191930738,\n",
+       "       -1378720.1191930738, -1378719.1191930738, -1378718.1191930738,\n",
+       "       -1378717.1191930738, -1378716.1191930738, -1378715.1191930738,\n",
+       "       -1378714.1191930738, -1378713.1191930738, -1378712.1191930738,\n",
+       "       -1378711.1191930738],\n",
+       "      dtype=&#x27;float64&#x27;, name=&#x27;x&#x27;))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>y</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-80baf5f7-733d-4848-a78c-2480b4eb89cc' class='xr-index-data-in' type='checkbox'/><label for='index-80baf5f7-733d-4848-a78c-2480b4eb89cc' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([2781632.062650748, 2781631.062650748, 2781630.062650748,\n",
+       "       2781629.062650748, 2781628.062650748, 2781627.062650748,\n",
+       "       2781626.062650748, 2781625.062650748, 2781624.062650748,\n",
+       "       2781623.062650748, 2781622.062650748, 2781621.062650748,\n",
+       "       2781620.062650748, 2781619.062650748, 2781618.062650748,\n",
+       "       2781617.062650748, 2781616.062650748, 2781615.062650748,\n",
+       "       2781614.062650748, 2781613.062650748, 2781612.062650748,\n",
+       "       2781611.062650748, 2781610.062650748, 2781609.062650748,\n",
+       "       2781608.062650748, 2781607.062650748, 2781606.062650748,\n",
+       "       2781605.062650748, 2781604.062650748, 2781603.062650748,\n",
+       "       2781602.062650748, 2781601.062650748, 2781600.062650748,\n",
+       "       2781599.062650748, 2781598.062650748, 2781597.062650748,\n",
+       "       2781596.062650748, 2781595.062650748, 2781594.062650748,\n",
+       "       2781593.062650748, 2781592.062650748, 2781591.062650748,\n",
+       "       2781590.062650748, 2781589.062650748, 2781588.062650748,\n",
+       "       2781587.062650748, 2781586.062650748, 2781585.062650748,\n",
+       "       2781584.062650748, 2781583.062650748, 2781582.062650748,\n",
+       "       2781581.062650748, 2781580.062650748, 2781579.062650748,\n",
+       "       2781578.062650748, 2781577.062650748, 2781576.062650748,\n",
+       "       2781575.062650748, 2781574.062650748, 2781573.062650748,\n",
+       "       2781572.062650748, 2781571.062650748, 2781570.062650748,\n",
+       "       2781569.062650748, 2781568.062650748, 2781567.062650748,\n",
+       "       2781566.062650748, 2781565.062650748, 2781564.062650748,\n",
+       "       2781563.062650748, 2781562.062650748, 2781561.062650748,\n",
+       "       2781560.062650748, 2781559.062650748, 2781558.062650748,\n",
+       "       2781557.062650748, 2781556.062650748, 2781555.062650748,\n",
+       "       2781554.062650748, 2781553.062650748, 2781552.062650748,\n",
+       "       2781551.062650748, 2781550.062650748, 2781549.062650748,\n",
+       "       2781548.062650748, 2781547.062650748, 2781546.062650748,\n",
+       "       2781545.062650748, 2781544.062650748, 2781543.062650748,\n",
+       "       2781542.062650748, 2781541.062650748, 2781540.062650748,\n",
+       "       2781539.062650748, 2781538.062650748, 2781537.062650748,\n",
+       "       2781536.062650748, 2781535.062650748, 2781534.062650748,\n",
+       "       2781533.062650748],\n",
+       "      dtype=&#x27;float64&#x27;, name=&#x27;y&#x27;))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-719af257-0b79-42c9-ae25-121b6d7720fc' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-719af257-0b79-42c9-ae25-121b6d7720fc' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'mburnt_integ' (time: 2, y: 100, x: 100, z: 1)>\n",
+       "dask.array<open_dataset-mburnt_integ, shape=(2, 100, 100, 1), dtype=float64, chunksize=(1, 100, 100, 1), chunktype=numpy.ndarray>\n",
+       "Coordinates:\n",
+       "    spatial_ref  int64 0\n",
+       "  * x            (x) float64 -1.379e+06 -1.379e+06 ... -1.379e+06 -1.379e+06\n",
+       "  * y            (y) float64 2.782e+06 2.782e+06 ... 2.782e+06 2.782e+06\n",
+       "Dimensions without coordinates: time, z"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "da"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "a1fd69ffc1bdf4bd",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:46:16.621156Z",
+     "start_time": "2023-10-11T12:46:16.600623Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;mburnt_integ&#x27; (y: 100, x: 100)&gt;\n",
+       "dask.array&lt;getitem, shape=(100, 100), dtype=float64, chunksize=(100, 100), chunktype=numpy.ndarray&gt;\n",
+       "Coordinates:\n",
+       "    spatial_ref  int64 0\n",
+       "  * x            (x) float64 -1.379e+06 -1.379e+06 ... -1.379e+06 -1.379e+06\n",
+       "  * y            (y) float64 2.782e+06 2.782e+06 ... 2.782e+06 2.782e+06</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'mburnt_integ'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>y</span>: 100</li><li><span class='xr-has-index'>x</span>: 100</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-648dc9d3-8bd2-484e-bf3a-e52470c049bb' class='xr-array-in' type='checkbox' checked><label for='section-648dc9d3-8bd2-484e-bf3a-e52470c049bb' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(100, 100), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (100, 100) </td>\n",
+       "                        <td> (100, 100) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 1 chunks in 3 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"170\" height=\"170\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"120\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"120\" x2=\"120\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"120\" y1=\"0\" x2=\"120\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 120.0,0.0 120.0,120.0 0.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"60.000000\" y=\"140.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >100</text>\n",
+       "  <text x=\"140.000000\" y=\"60.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,140.000000,60.000000)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-082b807b-918b-4bcc-b115-b0c89f8da6d0' class='xr-section-summary-in' type='checkbox'  checked><label for='section-082b807b-918b-4bcc-b115-b0c89f8da6d0' class='xr-section-summary' >Coordinates: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>spatial_ref</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0</div><input id='attrs-f74ffbf2-7c3e-44f5-806d-c993a20ac25f' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-f74ffbf2-7c3e-44f5-806d-c993a20ac25f' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-857b8fd1-dc17-49fd-94be-5cd3c2679fe0' class='xr-var-data-in' type='checkbox'><label for='data-857b8fd1-dc17-49fd-94be-5cd3c2679fe0' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>crs_wkt :</span></dt><dd>PROJCS[&quot;NAD83 / Conus Albers&quot;,GEOGCS[&quot;NAD83&quot;,DATUM[&quot;North_American_Datum_1983&quot;,SPHEROID[&quot;GRS 1980&quot;,6378137,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4269&quot;]],PROJECTION[&quot;Albers_Conic_Equal_Area&quot;],PARAMETER[&quot;latitude_of_center&quot;,23],PARAMETER[&quot;longitude_of_center&quot;,-96],PARAMETER[&quot;standard_parallel_1&quot;,29.5],PARAMETER[&quot;standard_parallel_2&quot;,45.5],PARAMETER[&quot;false_easting&quot;,0],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;5070&quot;]]</dd><dt><span>semi_major_axis :</span></dt><dd>6378137.0</dd><dt><span>semi_minor_axis :</span></dt><dd>6356752.314140356</dd><dt><span>inverse_flattening :</span></dt><dd>298.257222101</dd><dt><span>reference_ellipsoid_name :</span></dt><dd>GRS 1980</dd><dt><span>longitude_of_prime_meridian :</span></dt><dd>0.0</dd><dt><span>prime_meridian_name :</span></dt><dd>Greenwich</dd><dt><span>geographic_crs_name :</span></dt><dd>NAD83</dd><dt><span>horizontal_datum_name :</span></dt><dd>North American Datum 1983</dd><dt><span>projected_crs_name :</span></dt><dd>NAD83 / Conus Albers</dd><dt><span>grid_mapping_name :</span></dt><dd>albers_conical_equal_area</dd><dt><span>standard_parallel :</span></dt><dd>(29.5, 45.5)</dd><dt><span>latitude_of_projection_origin :</span></dt><dd>23.0</dd><dt><span>longitude_of_central_meridian :</span></dt><dd>-96.0</dd><dt><span>false_easting :</span></dt><dd>0.0</dd><dt><span>false_northing :</span></dt><dd>0.0</dd><dt><span>spatial_ref :</span></dt><dd>PROJCS[&quot;NAD83 / Conus Albers&quot;,GEOGCS[&quot;NAD83&quot;,DATUM[&quot;North_American_Datum_1983&quot;,SPHEROID[&quot;GRS 1980&quot;,6378137,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4269&quot;]],PROJECTION[&quot;Albers_Conic_Equal_Area&quot;],PARAMETER[&quot;latitude_of_center&quot;,23],PARAMETER[&quot;longitude_of_center&quot;,-96],PARAMETER[&quot;standard_parallel_1&quot;,29.5],PARAMETER[&quot;standard_parallel_2&quot;,45.5],PARAMETER[&quot;false_easting&quot;,0],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;5070&quot;]]</dd><dt><span>GeoTransform :</span></dt><dd>-1378810.1191930738 1.0 0.0 2781632.062650748 0.0 -1.0</dd></dl></div><div class='xr-var-data'><pre>array(0)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-1.379e+06 ... -1.379e+06</div><input id='attrs-21e80e28-99c0-4c3e-9655-30038217f660' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-21e80e28-99c0-4c3e-9655-30038217f660' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-39c42518-e622-485e-b902-1e164f1d413c' class='xr-var-data-in' type='checkbox'><label for='data-39c42518-e622-485e-b902-1e164f1d413c' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([-1378810.119193, -1378809.119193, -1378808.119193, -1378807.119193,\n",
+       "       -1378806.119193, -1378805.119193, -1378804.119193, -1378803.119193,\n",
+       "       -1378802.119193, -1378801.119193, -1378800.119193, -1378799.119193,\n",
+       "       -1378798.119193, -1378797.119193, -1378796.119193, -1378795.119193,\n",
+       "       -1378794.119193, -1378793.119193, -1378792.119193, -1378791.119193,\n",
+       "       -1378790.119193, -1378789.119193, -1378788.119193, -1378787.119193,\n",
+       "       -1378786.119193, -1378785.119193, -1378784.119193, -1378783.119193,\n",
+       "       -1378782.119193, -1378781.119193, -1378780.119193, -1378779.119193,\n",
+       "       -1378778.119193, -1378777.119193, -1378776.119193, -1378775.119193,\n",
+       "       -1378774.119193, -1378773.119193, -1378772.119193, -1378771.119193,\n",
+       "       -1378770.119193, -1378769.119193, -1378768.119193, -1378767.119193,\n",
+       "       -1378766.119193, -1378765.119193, -1378764.119193, -1378763.119193,\n",
+       "       -1378762.119193, -1378761.119193, -1378760.119193, -1378759.119193,\n",
+       "       -1378758.119193, -1378757.119193, -1378756.119193, -1378755.119193,\n",
+       "       -1378754.119193, -1378753.119193, -1378752.119193, -1378751.119193,\n",
+       "       -1378750.119193, -1378749.119193, -1378748.119193, -1378747.119193,\n",
+       "       -1378746.119193, -1378745.119193, -1378744.119193, -1378743.119193,\n",
+       "       -1378742.119193, -1378741.119193, -1378740.119193, -1378739.119193,\n",
+       "       -1378738.119193, -1378737.119193, -1378736.119193, -1378735.119193,\n",
+       "       -1378734.119193, -1378733.119193, -1378732.119193, -1378731.119193,\n",
+       "       -1378730.119193, -1378729.119193, -1378728.119193, -1378727.119193,\n",
+       "       -1378726.119193, -1378725.119193, -1378724.119193, -1378723.119193,\n",
+       "       -1378722.119193, -1378721.119193, -1378720.119193, -1378719.119193,\n",
+       "       -1378718.119193, -1378717.119193, -1378716.119193, -1378715.119193,\n",
+       "       -1378714.119193, -1378713.119193, -1378712.119193, -1378711.119193])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>y</span></div><div class='xr-var-dims'>(y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>2.782e+06 2.782e+06 ... 2.782e+06</div><input id='attrs-6c2e0585-bfbb-42f9-8036-40752a5016a8' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-6c2e0585-bfbb-42f9-8036-40752a5016a8' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-956a3e2d-8160-46ee-9edf-e17bcf5af071' class='xr-var-data-in' type='checkbox'><label for='data-956a3e2d-8160-46ee-9edf-e17bcf5af071' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([2781632.062651, 2781631.062651, 2781630.062651, 2781629.062651,\n",
+       "       2781628.062651, 2781627.062651, 2781626.062651, 2781625.062651,\n",
+       "       2781624.062651, 2781623.062651, 2781622.062651, 2781621.062651,\n",
+       "       2781620.062651, 2781619.062651, 2781618.062651, 2781617.062651,\n",
+       "       2781616.062651, 2781615.062651, 2781614.062651, 2781613.062651,\n",
+       "       2781612.062651, 2781611.062651, 2781610.062651, 2781609.062651,\n",
+       "       2781608.062651, 2781607.062651, 2781606.062651, 2781605.062651,\n",
+       "       2781604.062651, 2781603.062651, 2781602.062651, 2781601.062651,\n",
+       "       2781600.062651, 2781599.062651, 2781598.062651, 2781597.062651,\n",
+       "       2781596.062651, 2781595.062651, 2781594.062651, 2781593.062651,\n",
+       "       2781592.062651, 2781591.062651, 2781590.062651, 2781589.062651,\n",
+       "       2781588.062651, 2781587.062651, 2781586.062651, 2781585.062651,\n",
+       "       2781584.062651, 2781583.062651, 2781582.062651, 2781581.062651,\n",
+       "       2781580.062651, 2781579.062651, 2781578.062651, 2781577.062651,\n",
+       "       2781576.062651, 2781575.062651, 2781574.062651, 2781573.062651,\n",
+       "       2781572.062651, 2781571.062651, 2781570.062651, 2781569.062651,\n",
+       "       2781568.062651, 2781567.062651, 2781566.062651, 2781565.062651,\n",
+       "       2781564.062651, 2781563.062651, 2781562.062651, 2781561.062651,\n",
+       "       2781560.062651, 2781559.062651, 2781558.062651, 2781557.062651,\n",
+       "       2781556.062651, 2781555.062651, 2781554.062651, 2781553.062651,\n",
+       "       2781552.062651, 2781551.062651, 2781550.062651, 2781549.062651,\n",
+       "       2781548.062651, 2781547.062651, 2781546.062651, 2781545.062651,\n",
+       "       2781544.062651, 2781543.062651, 2781542.062651, 2781541.062651,\n",
+       "       2781540.062651, 2781539.062651, 2781538.062651, 2781537.062651,\n",
+       "       2781536.062651, 2781535.062651, 2781534.062651, 2781533.062651])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-a02bf1f5-1a39-40d8-8664-04c0186040b5' class='xr-section-summary-in' type='checkbox'  ><label for='section-a02bf1f5-1a39-40d8-8664-04c0186040b5' class='xr-section-summary' >Indexes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>x</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-c84393cf-8215-4907-919a-ac1fcf168572' class='xr-index-data-in' type='checkbox'/><label for='index-c84393cf-8215-4907-919a-ac1fcf168572' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([-1378810.1191930738, -1378809.1191930738, -1378808.1191930738,\n",
+       "       -1378807.1191930738, -1378806.1191930738, -1378805.1191930738,\n",
+       "       -1378804.1191930738, -1378803.1191930738, -1378802.1191930738,\n",
+       "       -1378801.1191930738, -1378800.1191930738, -1378799.1191930738,\n",
+       "       -1378798.1191930738, -1378797.1191930738, -1378796.1191930738,\n",
+       "       -1378795.1191930738, -1378794.1191930738, -1378793.1191930738,\n",
+       "       -1378792.1191930738, -1378791.1191930738, -1378790.1191930738,\n",
+       "       -1378789.1191930738, -1378788.1191930738, -1378787.1191930738,\n",
+       "       -1378786.1191930738, -1378785.1191930738, -1378784.1191930738,\n",
+       "       -1378783.1191930738, -1378782.1191930738, -1378781.1191930738,\n",
+       "       -1378780.1191930738, -1378779.1191930738, -1378778.1191930738,\n",
+       "       -1378777.1191930738, -1378776.1191930738, -1378775.1191930738,\n",
+       "       -1378774.1191930738, -1378773.1191930738, -1378772.1191930738,\n",
+       "       -1378771.1191930738, -1378770.1191930738, -1378769.1191930738,\n",
+       "       -1378768.1191930738, -1378767.1191930738, -1378766.1191930738,\n",
+       "       -1378765.1191930738, -1378764.1191930738, -1378763.1191930738,\n",
+       "       -1378762.1191930738, -1378761.1191930738, -1378760.1191930738,\n",
+       "       -1378759.1191930738, -1378758.1191930738, -1378757.1191930738,\n",
+       "       -1378756.1191930738, -1378755.1191930738, -1378754.1191930738,\n",
+       "       -1378753.1191930738, -1378752.1191930738, -1378751.1191930738,\n",
+       "       -1378750.1191930738, -1378749.1191930738, -1378748.1191930738,\n",
+       "       -1378747.1191930738, -1378746.1191930738, -1378745.1191930738,\n",
+       "       -1378744.1191930738, -1378743.1191930738, -1378742.1191930738,\n",
+       "       -1378741.1191930738, -1378740.1191930738, -1378739.1191930738,\n",
+       "       -1378738.1191930738, -1378737.1191930738, -1378736.1191930738,\n",
+       "       -1378735.1191930738, -1378734.1191930738, -1378733.1191930738,\n",
+       "       -1378732.1191930738, -1378731.1191930738, -1378730.1191930738,\n",
+       "       -1378729.1191930738, -1378728.1191930738, -1378727.1191930738,\n",
+       "       -1378726.1191930738, -1378725.1191930738, -1378724.1191930738,\n",
+       "       -1378723.1191930738, -1378722.1191930738, -1378721.1191930738,\n",
+       "       -1378720.1191930738, -1378719.1191930738, -1378718.1191930738,\n",
+       "       -1378717.1191930738, -1378716.1191930738, -1378715.1191930738,\n",
+       "       -1378714.1191930738, -1378713.1191930738, -1378712.1191930738,\n",
+       "       -1378711.1191930738],\n",
+       "      dtype=&#x27;float64&#x27;, name=&#x27;x&#x27;))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>y</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-d3e16f88-fc3a-49f1-b5d6-10fb161fb12e' class='xr-index-data-in' type='checkbox'/><label for='index-d3e16f88-fc3a-49f1-b5d6-10fb161fb12e' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([2781632.062650748, 2781631.062650748, 2781630.062650748,\n",
+       "       2781629.062650748, 2781628.062650748, 2781627.062650748,\n",
+       "       2781626.062650748, 2781625.062650748, 2781624.062650748,\n",
+       "       2781623.062650748, 2781622.062650748, 2781621.062650748,\n",
+       "       2781620.062650748, 2781619.062650748, 2781618.062650748,\n",
+       "       2781617.062650748, 2781616.062650748, 2781615.062650748,\n",
+       "       2781614.062650748, 2781613.062650748, 2781612.062650748,\n",
+       "       2781611.062650748, 2781610.062650748, 2781609.062650748,\n",
+       "       2781608.062650748, 2781607.062650748, 2781606.062650748,\n",
+       "       2781605.062650748, 2781604.062650748, 2781603.062650748,\n",
+       "       2781602.062650748, 2781601.062650748, 2781600.062650748,\n",
+       "       2781599.062650748, 2781598.062650748, 2781597.062650748,\n",
+       "       2781596.062650748, 2781595.062650748, 2781594.062650748,\n",
+       "       2781593.062650748, 2781592.062650748, 2781591.062650748,\n",
+       "       2781590.062650748, 2781589.062650748, 2781588.062650748,\n",
+       "       2781587.062650748, 2781586.062650748, 2781585.062650748,\n",
+       "       2781584.062650748, 2781583.062650748, 2781582.062650748,\n",
+       "       2781581.062650748, 2781580.062650748, 2781579.062650748,\n",
+       "       2781578.062650748, 2781577.062650748, 2781576.062650748,\n",
+       "       2781575.062650748, 2781574.062650748, 2781573.062650748,\n",
+       "       2781572.062650748, 2781571.062650748, 2781570.062650748,\n",
+       "       2781569.062650748, 2781568.062650748, 2781567.062650748,\n",
+       "       2781566.062650748, 2781565.062650748, 2781564.062650748,\n",
+       "       2781563.062650748, 2781562.062650748, 2781561.062650748,\n",
+       "       2781560.062650748, 2781559.062650748, 2781558.062650748,\n",
+       "       2781557.062650748, 2781556.062650748, 2781555.062650748,\n",
+       "       2781554.062650748, 2781553.062650748, 2781552.062650748,\n",
+       "       2781551.062650748, 2781550.062650748, 2781549.062650748,\n",
+       "       2781548.062650748, 2781547.062650748, 2781546.062650748,\n",
+       "       2781545.062650748, 2781544.062650748, 2781543.062650748,\n",
+       "       2781542.062650748, 2781541.062650748, 2781540.062650748,\n",
+       "       2781539.062650748, 2781538.062650748, 2781537.062650748,\n",
+       "       2781536.062650748, 2781535.062650748, 2781534.062650748,\n",
+       "       2781533.062650748],\n",
+       "      dtype=&#x27;float64&#x27;, name=&#x27;y&#x27;))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-455247eb-b60b-4454-89d8-7f21dd35593f' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-455247eb-b60b-4454-89d8-7f21dd35593f' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'mburnt_integ' (y: 100, x: 100)>\n",
+       "dask.array<getitem, shape=(100, 100), dtype=float64, chunksize=(100, 100), chunktype=numpy.ndarray>\n",
+       "Coordinates:\n",
+       "    spatial_ref  int64 0\n",
+       "  * x            (x) float64 -1.379e+06 -1.379e+06 ... -1.379e+06 -1.379e+06\n",
+       "  * y            (y) float64 2.782e+06 2.782e+06 ... 2.782e+06 2.782e+06"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "da[0, ..., 0]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "5d3fd788b25c73b8",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.720884Z",
+     "start_time": "2023-10-11T12:45:19.694897Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
+       "<defs>\n",
+       "<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
+       "<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
+       "</symbol>\n",
+       "<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
+       "<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
+       "<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
+       "</symbol>\n",
+       "</defs>\n",
+       "</svg>\n",
+       "<style>/* CSS stylesheet for displaying xarray objects in jupyterlab.\n",
+       " *\n",
+       " */\n",
+       "\n",
+       ":root {\n",
+       "  --xr-font-color0: var(--jp-content-font-color0, rgba(0, 0, 0, 1));\n",
+       "  --xr-font-color2: var(--jp-content-font-color2, rgba(0, 0, 0, 0.54));\n",
+       "  --xr-font-color3: var(--jp-content-font-color3, rgba(0, 0, 0, 0.38));\n",
+       "  --xr-border-color: var(--jp-border-color2, #e0e0e0);\n",
+       "  --xr-disabled-color: var(--jp-layout-color3, #bdbdbd);\n",
+       "  --xr-background-color: var(--jp-layout-color0, white);\n",
+       "  --xr-background-color-row-even: var(--jp-layout-color1, white);\n",
+       "  --xr-background-color-row-odd: var(--jp-layout-color2, #eeeeee);\n",
+       "}\n",
+       "\n",
+       "html[theme=dark],\n",
+       "body[data-theme=dark],\n",
+       "body.vscode-dark {\n",
+       "  --xr-font-color0: rgba(255, 255, 255, 1);\n",
+       "  --xr-font-color2: rgba(255, 255, 255, 0.54);\n",
+       "  --xr-font-color3: rgba(255, 255, 255, 0.38);\n",
+       "  --xr-border-color: #1F1F1F;\n",
+       "  --xr-disabled-color: #515151;\n",
+       "  --xr-background-color: #111111;\n",
+       "  --xr-background-color-row-even: #111111;\n",
+       "  --xr-background-color-row-odd: #313131;\n",
+       "}\n",
+       "\n",
+       ".xr-wrap {\n",
+       "  display: block !important;\n",
+       "  min-width: 300px;\n",
+       "  max-width: 700px;\n",
+       "}\n",
+       "\n",
+       ".xr-text-repr-fallback {\n",
+       "  /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-header {\n",
+       "  padding-top: 6px;\n",
+       "  padding-bottom: 6px;\n",
+       "  margin-bottom: 4px;\n",
+       "  border-bottom: solid 1px var(--xr-border-color);\n",
+       "}\n",
+       "\n",
+       ".xr-header > div,\n",
+       ".xr-header > ul {\n",
+       "  display: inline;\n",
+       "  margin-top: 0;\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type,\n",
+       ".xr-array-name {\n",
+       "  margin-left: 2px;\n",
+       "  margin-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-obj-type {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-sections {\n",
+       "  padding-left: 0 !important;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 150px auto auto 1fr 20px 20px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input + label {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label {\n",
+       "  cursor: pointer;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-item input:enabled + label:hover {\n",
+       "  color: var(--xr-font-color0);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary {\n",
+       "  grid-column: 1;\n",
+       "  color: var(--xr-font-color2);\n",
+       "  font-weight: 500;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary > span {\n",
+       "  display: inline-block;\n",
+       "  padding-left: 0.5em;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label {\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in + label:before {\n",
+       "  display: inline-block;\n",
+       "  content: '►';\n",
+       "  font-size: 11px;\n",
+       "  width: 15px;\n",
+       "  text-align: center;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:disabled + label:before {\n",
+       "  color: var(--xr-disabled-color);\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label:before {\n",
+       "  content: '▼';\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked + label > span {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary,\n",
+       ".xr-section-inline-details {\n",
+       "  padding-top: 4px;\n",
+       "  padding-bottom: 4px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-inline-details {\n",
+       "  grid-column: 2 / -1;\n",
+       "}\n",
+       "\n",
+       ".xr-section-details {\n",
+       "  display: none;\n",
+       "  grid-column: 1 / -1;\n",
+       "  margin-bottom: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-section-summary-in:checked ~ .xr-section-details {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap {\n",
+       "  grid-column: 1 / -1;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 20px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-array-wrap > label {\n",
+       "  grid-column: 1;\n",
+       "  vertical-align: top;\n",
+       "}\n",
+       "\n",
+       ".xr-preview {\n",
+       "  color: var(--xr-font-color3);\n",
+       "}\n",
+       "\n",
+       ".xr-array-preview,\n",
+       ".xr-array-data {\n",
+       "  padding: 0 5px !important;\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-array-data,\n",
+       ".xr-array-in:checked ~ .xr-array-preview {\n",
+       "  display: none;\n",
+       "}\n",
+       "\n",
+       ".xr-array-in:checked ~ .xr-array-data,\n",
+       ".xr-array-preview {\n",
+       "  display: inline-block;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list {\n",
+       "  display: inline-block !important;\n",
+       "  list-style: none;\n",
+       "  padding: 0 !important;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li {\n",
+       "  display: inline-block;\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:before {\n",
+       "  content: '(';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list:after {\n",
+       "  content: ')';\n",
+       "}\n",
+       "\n",
+       ".xr-dim-list li:not(:last-child):after {\n",
+       "  content: ',';\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-has-index {\n",
+       "  font-weight: bold;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list,\n",
+       ".xr-var-item {\n",
+       "  display: contents;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > div,\n",
+       ".xr-var-item label,\n",
+       ".xr-var-item > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-even);\n",
+       "  margin-bottom: 0;\n",
+       "}\n",
+       "\n",
+       ".xr-var-item > .xr-var-name:hover span {\n",
+       "  padding-right: 5px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-list > li:nth-child(odd) > div,\n",
+       ".xr-var-list > li:nth-child(odd) > label,\n",
+       ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
+       "  background-color: var(--xr-background-color-row-odd);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name {\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dims {\n",
+       "  grid-column: 2;\n",
+       "}\n",
+       "\n",
+       ".xr-var-dtype {\n",
+       "  grid-column: 3;\n",
+       "  text-align: right;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-preview {\n",
+       "  grid-column: 4;\n",
+       "}\n",
+       "\n",
+       ".xr-index-preview {\n",
+       "  grid-column: 2 / 5;\n",
+       "  color: var(--xr-font-color2);\n",
+       "}\n",
+       "\n",
+       ".xr-var-name,\n",
+       ".xr-var-dims,\n",
+       ".xr-var-dtype,\n",
+       ".xr-preview,\n",
+       ".xr-attrs dt {\n",
+       "  white-space: nowrap;\n",
+       "  overflow: hidden;\n",
+       "  text-overflow: ellipsis;\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name:hover,\n",
+       ".xr-var-dims:hover,\n",
+       ".xr-var-dtype:hover,\n",
+       ".xr-attrs dt:hover {\n",
+       "  overflow: visible;\n",
+       "  width: auto;\n",
+       "  z-index: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  display: none;\n",
+       "  background-color: var(--xr-background-color) !important;\n",
+       "  padding-bottom: 5px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
+       ".xr-var-data-in:checked ~ .xr-var-data,\n",
+       ".xr-index-data-in:checked ~ .xr-index-data {\n",
+       "  display: block;\n",
+       "}\n",
+       "\n",
+       ".xr-var-data > table {\n",
+       "  float: right;\n",
+       "}\n",
+       "\n",
+       ".xr-var-name span,\n",
+       ".xr-var-data,\n",
+       ".xr-index-name div,\n",
+       ".xr-index-data,\n",
+       ".xr-attrs {\n",
+       "  padding-left: 25px !important;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs,\n",
+       ".xr-var-attrs,\n",
+       ".xr-var-data,\n",
+       ".xr-index-data {\n",
+       "  grid-column: 1 / -1;\n",
+       "}\n",
+       "\n",
+       "dl.xr-attrs {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  display: grid;\n",
+       "  grid-template-columns: 125px auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt,\n",
+       ".xr-attrs dd {\n",
+       "  padding: 0;\n",
+       "  margin: 0;\n",
+       "  float: left;\n",
+       "  padding-right: 10px;\n",
+       "  width: auto;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt {\n",
+       "  font-weight: normal;\n",
+       "  grid-column: 1;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dt:hover span {\n",
+       "  display: inline-block;\n",
+       "  background: var(--xr-background-color);\n",
+       "  padding-right: 10px;\n",
+       "}\n",
+       "\n",
+       ".xr-attrs dd {\n",
+       "  grid-column: 2;\n",
+       "  white-space: pre-wrap;\n",
+       "  word-break: break-all;\n",
+       "}\n",
+       "\n",
+       ".xr-icon-database,\n",
+       ".xr-icon-file-text2,\n",
+       ".xr-no-icon {\n",
+       "  display: inline-block;\n",
+       "  vertical-align: middle;\n",
+       "  width: 1em;\n",
+       "  height: 1.5em !important;\n",
+       "  stroke-width: 0;\n",
+       "  stroke: currentColor;\n",
+       "  fill: currentColor;\n",
+       "}\n",
+       "</style><pre class='xr-text-repr-fallback'>&lt;xarray.DataArray &#x27;mburnt_integ&#x27; (y: 100, x: 100)&gt;\n",
+       "dask.array&lt;getitem, shape=(100, 100), dtype=float64, chunksize=(100, 100), chunktype=numpy.ndarray&gt;\n",
+       "Coordinates:\n",
+       "    spatial_ref  int64 0\n",
+       "  * x            (x) float64 -1.379e+06 -1.379e+06 ... -1.379e+06 -1.379e+06\n",
+       "  * y            (y) float64 2.782e+06 2.782e+06 ... 2.782e+06 2.782e+06</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.DataArray</div><div class='xr-array-name'>'mburnt_integ'</div><ul class='xr-dim-list'><li><span class='xr-has-index'>y</span>: 100</li><li><span class='xr-has-index'>x</span>: 100</li></ul></div><ul class='xr-sections'><li class='xr-section-item'><div class='xr-array-wrap'><input id='section-2c759408-177a-48c3-ae4e-d6652054fe8e' class='xr-array-in' type='checkbox' checked><label for='section-2c759408-177a-48c3-ae4e-d6652054fe8e' title='Show/hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-array-preview xr-preview'><span>dask.array&lt;chunksize=(100, 100), meta=np.ndarray&gt;</span></div><div class='xr-array-data'><table>\n",
+       "    <tr>\n",
+       "        <td>\n",
+       "            <table style=\"border-collapse: collapse;\">\n",
+       "                <thead>\n",
+       "                    <tr>\n",
+       "                        <td> </td>\n",
+       "                        <th> Array </th>\n",
+       "                        <th> Chunk </th>\n",
+       "                    </tr>\n",
+       "                </thead>\n",
+       "                <tbody>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Bytes </th>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                        <td> 78.12 kiB </td>\n",
+       "                    </tr>\n",
+       "                    \n",
+       "                    <tr>\n",
+       "                        <th> Shape </th>\n",
+       "                        <td> (100, 100) </td>\n",
+       "                        <td> (100, 100) </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Dask graph </th>\n",
+       "                        <td colspan=\"2\"> 1 chunks in 4 graph layers </td>\n",
+       "                    </tr>\n",
+       "                    <tr>\n",
+       "                        <th> Data type </th>\n",
+       "                        <td colspan=\"2\"> float64 numpy.ndarray </td>\n",
+       "                    </tr>\n",
+       "                </tbody>\n",
+       "            </table>\n",
+       "        </td>\n",
+       "        <td>\n",
+       "        <svg width=\"170\" height=\"170\" style=\"stroke:rgb(0,0,0);stroke-width:1\" >\n",
+       "\n",
+       "  <!-- Horizontal lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"120\" y2=\"0\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"0\" y1=\"120\" x2=\"120\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Vertical lines -->\n",
+       "  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "  <line x1=\"120\" y1=\"0\" x2=\"120\" y2=\"120\" style=\"stroke-width:2\" />\n",
+       "\n",
+       "  <!-- Colored Rectangle -->\n",
+       "  <polygon points=\"0.0,0.0 120.0,0.0 120.0,120.0 0.0,120.0\" style=\"fill:#ECB172A0;stroke-width:0\"/>\n",
+       "\n",
+       "  <!-- Text -->\n",
+       "  <text x=\"60.000000\" y=\"140.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" >100</text>\n",
+       "  <text x=\"140.000000\" y=\"60.000000\" font-size=\"1.0rem\" font-weight=\"100\" text-anchor=\"middle\" transform=\"rotate(-90,140.000000,60.000000)\">100</text>\n",
+       "</svg>\n",
+       "        </td>\n",
+       "    </tr>\n",
+       "</table></div></div></li><li class='xr-section-item'><input id='section-e2e99295-28ea-41b1-a390-1ad9682b375f' class='xr-section-summary-in' type='checkbox'  checked><label for='section-e2e99295-28ea-41b1-a390-1ad9682b375f' class='xr-section-summary' >Coordinates: <span>(3)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>spatial_ref</span></div><div class='xr-var-dims'>()</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0</div><input id='attrs-35734642-1201-41d1-a25f-67ea62855de6' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-35734642-1201-41d1-a25f-67ea62855de6' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-dea65628-d498-495e-9318-7257db95c881' class='xr-var-data-in' type='checkbox'><label for='data-dea65628-d498-495e-9318-7257db95c881' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>crs_wkt :</span></dt><dd>PROJCS[&quot;NAD83 / Conus Albers&quot;,GEOGCS[&quot;NAD83&quot;,DATUM[&quot;North_American_Datum_1983&quot;,SPHEROID[&quot;GRS 1980&quot;,6378137,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4269&quot;]],PROJECTION[&quot;Albers_Conic_Equal_Area&quot;],PARAMETER[&quot;latitude_of_center&quot;,23],PARAMETER[&quot;longitude_of_center&quot;,-96],PARAMETER[&quot;standard_parallel_1&quot;,29.5],PARAMETER[&quot;standard_parallel_2&quot;,45.5],PARAMETER[&quot;false_easting&quot;,0],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;5070&quot;]]</dd><dt><span>semi_major_axis :</span></dt><dd>6378137.0</dd><dt><span>semi_minor_axis :</span></dt><dd>6356752.314140356</dd><dt><span>inverse_flattening :</span></dt><dd>298.257222101</dd><dt><span>reference_ellipsoid_name :</span></dt><dd>GRS 1980</dd><dt><span>longitude_of_prime_meridian :</span></dt><dd>0.0</dd><dt><span>prime_meridian_name :</span></dt><dd>Greenwich</dd><dt><span>geographic_crs_name :</span></dt><dd>NAD83</dd><dt><span>horizontal_datum_name :</span></dt><dd>North American Datum 1983</dd><dt><span>projected_crs_name :</span></dt><dd>NAD83 / Conus Albers</dd><dt><span>grid_mapping_name :</span></dt><dd>albers_conical_equal_area</dd><dt><span>standard_parallel :</span></dt><dd>(29.5, 45.5)</dd><dt><span>latitude_of_projection_origin :</span></dt><dd>23.0</dd><dt><span>longitude_of_central_meridian :</span></dt><dd>-96.0</dd><dt><span>false_easting :</span></dt><dd>0.0</dd><dt><span>false_northing :</span></dt><dd>0.0</dd><dt><span>spatial_ref :</span></dt><dd>PROJCS[&quot;NAD83 / Conus Albers&quot;,GEOGCS[&quot;NAD83&quot;,DATUM[&quot;North_American_Datum_1983&quot;,SPHEROID[&quot;GRS 1980&quot;,6378137,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433,AUTHORITY[&quot;EPSG&quot;,&quot;9122&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;4269&quot;]],PROJECTION[&quot;Albers_Conic_Equal_Area&quot;],PARAMETER[&quot;latitude_of_center&quot;,23],PARAMETER[&quot;longitude_of_center&quot;,-96],PARAMETER[&quot;standard_parallel_1&quot;,29.5],PARAMETER[&quot;standard_parallel_2&quot;,45.5],PARAMETER[&quot;false_easting&quot;,0],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1],AXIS[&quot;Easting&quot;,EAST],AXIS[&quot;Northing&quot;,NORTH],AUTHORITY[&quot;EPSG&quot;,&quot;5070&quot;]]</dd><dt><span>GeoTransform :</span></dt><dd>-1378810.1191930738 1.0 0.0 2781632.062650748 0.0 -1.0</dd></dl></div><div class='xr-var-data'><pre>array(0)</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>-1.379e+06 ... -1.379e+06</div><input id='attrs-82b25656-7554-438d-a0f8-5a9e9b8c1053' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-82b25656-7554-438d-a0f8-5a9e9b8c1053' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-1bd4daa5-b5bf-40ef-9ffd-90b26cff7838' class='xr-var-data-in' type='checkbox'><label for='data-1bd4daa5-b5bf-40ef-9ffd-90b26cff7838' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([-1378810.119193, -1378809.119193, -1378808.119193, -1378807.119193,\n",
+       "       -1378806.119193, -1378805.119193, -1378804.119193, -1378803.119193,\n",
+       "       -1378802.119193, -1378801.119193, -1378800.119193, -1378799.119193,\n",
+       "       -1378798.119193, -1378797.119193, -1378796.119193, -1378795.119193,\n",
+       "       -1378794.119193, -1378793.119193, -1378792.119193, -1378791.119193,\n",
+       "       -1378790.119193, -1378789.119193, -1378788.119193, -1378787.119193,\n",
+       "       -1378786.119193, -1378785.119193, -1378784.119193, -1378783.119193,\n",
+       "       -1378782.119193, -1378781.119193, -1378780.119193, -1378779.119193,\n",
+       "       -1378778.119193, -1378777.119193, -1378776.119193, -1378775.119193,\n",
+       "       -1378774.119193, -1378773.119193, -1378772.119193, -1378771.119193,\n",
+       "       -1378770.119193, -1378769.119193, -1378768.119193, -1378767.119193,\n",
+       "       -1378766.119193, -1378765.119193, -1378764.119193, -1378763.119193,\n",
+       "       -1378762.119193, -1378761.119193, -1378760.119193, -1378759.119193,\n",
+       "       -1378758.119193, -1378757.119193, -1378756.119193, -1378755.119193,\n",
+       "       -1378754.119193, -1378753.119193, -1378752.119193, -1378751.119193,\n",
+       "       -1378750.119193, -1378749.119193, -1378748.119193, -1378747.119193,\n",
+       "       -1378746.119193, -1378745.119193, -1378744.119193, -1378743.119193,\n",
+       "       -1378742.119193, -1378741.119193, -1378740.119193, -1378739.119193,\n",
+       "       -1378738.119193, -1378737.119193, -1378736.119193, -1378735.119193,\n",
+       "       -1378734.119193, -1378733.119193, -1378732.119193, -1378731.119193,\n",
+       "       -1378730.119193, -1378729.119193, -1378728.119193, -1378727.119193,\n",
+       "       -1378726.119193, -1378725.119193, -1378724.119193, -1378723.119193,\n",
+       "       -1378722.119193, -1378721.119193, -1378720.119193, -1378719.119193,\n",
+       "       -1378718.119193, -1378717.119193, -1378716.119193, -1378715.119193,\n",
+       "       -1378714.119193, -1378713.119193, -1378712.119193, -1378711.119193])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>y</span></div><div class='xr-var-dims'>(y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>2.782e+06 2.782e+06 ... 2.782e+06</div><input id='attrs-3b2cf203-a0c5-462d-8089-4dfe189079e1' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-3b2cf203-a0c5-462d-8089-4dfe189079e1' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-92d733a0-2178-49ed-9e8b-6657e23537b8' class='xr-var-data-in' type='checkbox'><label for='data-92d733a0-2178-49ed-9e8b-6657e23537b8' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([2781632.062651, 2781631.062651, 2781630.062651, 2781629.062651,\n",
+       "       2781628.062651, 2781627.062651, 2781626.062651, 2781625.062651,\n",
+       "       2781624.062651, 2781623.062651, 2781622.062651, 2781621.062651,\n",
+       "       2781620.062651, 2781619.062651, 2781618.062651, 2781617.062651,\n",
+       "       2781616.062651, 2781615.062651, 2781614.062651, 2781613.062651,\n",
+       "       2781612.062651, 2781611.062651, 2781610.062651, 2781609.062651,\n",
+       "       2781608.062651, 2781607.062651, 2781606.062651, 2781605.062651,\n",
+       "       2781604.062651, 2781603.062651, 2781602.062651, 2781601.062651,\n",
+       "       2781600.062651, 2781599.062651, 2781598.062651, 2781597.062651,\n",
+       "       2781596.062651, 2781595.062651, 2781594.062651, 2781593.062651,\n",
+       "       2781592.062651, 2781591.062651, 2781590.062651, 2781589.062651,\n",
+       "       2781588.062651, 2781587.062651, 2781586.062651, 2781585.062651,\n",
+       "       2781584.062651, 2781583.062651, 2781582.062651, 2781581.062651,\n",
+       "       2781580.062651, 2781579.062651, 2781578.062651, 2781577.062651,\n",
+       "       2781576.062651, 2781575.062651, 2781574.062651, 2781573.062651,\n",
+       "       2781572.062651, 2781571.062651, 2781570.062651, 2781569.062651,\n",
+       "       2781568.062651, 2781567.062651, 2781566.062651, 2781565.062651,\n",
+       "       2781564.062651, 2781563.062651, 2781562.062651, 2781561.062651,\n",
+       "       2781560.062651, 2781559.062651, 2781558.062651, 2781557.062651,\n",
+       "       2781556.062651, 2781555.062651, 2781554.062651, 2781553.062651,\n",
+       "       2781552.062651, 2781551.062651, 2781550.062651, 2781549.062651,\n",
+       "       2781548.062651, 2781547.062651, 2781546.062651, 2781545.062651,\n",
+       "       2781544.062651, 2781543.062651, 2781542.062651, 2781541.062651,\n",
+       "       2781540.062651, 2781539.062651, 2781538.062651, 2781537.062651,\n",
+       "       2781536.062651, 2781535.062651, 2781534.062651, 2781533.062651])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-f77f903c-b890-455a-9e17-3215ad7f8b63' class='xr-section-summary-in' type='checkbox'  ><label for='section-f77f903c-b890-455a-9e17-3215ad7f8b63' class='xr-section-summary' >Indexes: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-index-name'><div>x</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-73579549-3649-4302-af45-c4b8b61013ea' class='xr-index-data-in' type='checkbox'/><label for='index-73579549-3649-4302-af45-c4b8b61013ea' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([-1378810.1191930738, -1378809.1191930738, -1378808.1191930738,\n",
+       "       -1378807.1191930738, -1378806.1191930738, -1378805.1191930738,\n",
+       "       -1378804.1191930738, -1378803.1191930738, -1378802.1191930738,\n",
+       "       -1378801.1191930738, -1378800.1191930738, -1378799.1191930738,\n",
+       "       -1378798.1191930738, -1378797.1191930738, -1378796.1191930738,\n",
+       "       -1378795.1191930738, -1378794.1191930738, -1378793.1191930738,\n",
+       "       -1378792.1191930738, -1378791.1191930738, -1378790.1191930738,\n",
+       "       -1378789.1191930738, -1378788.1191930738, -1378787.1191930738,\n",
+       "       -1378786.1191930738, -1378785.1191930738, -1378784.1191930738,\n",
+       "       -1378783.1191930738, -1378782.1191930738, -1378781.1191930738,\n",
+       "       -1378780.1191930738, -1378779.1191930738, -1378778.1191930738,\n",
+       "       -1378777.1191930738, -1378776.1191930738, -1378775.1191930738,\n",
+       "       -1378774.1191930738, -1378773.1191930738, -1378772.1191930738,\n",
+       "       -1378771.1191930738, -1378770.1191930738, -1378769.1191930738,\n",
+       "       -1378768.1191930738, -1378767.1191930738, -1378766.1191930738,\n",
+       "       -1378765.1191930738, -1378764.1191930738, -1378763.1191930738,\n",
+       "       -1378762.1191930738, -1378761.1191930738, -1378760.1191930738,\n",
+       "       -1378759.1191930738, -1378758.1191930738, -1378757.1191930738,\n",
+       "       -1378756.1191930738, -1378755.1191930738, -1378754.1191930738,\n",
+       "       -1378753.1191930738, -1378752.1191930738, -1378751.1191930738,\n",
+       "       -1378750.1191930738, -1378749.1191930738, -1378748.1191930738,\n",
+       "       -1378747.1191930738, -1378746.1191930738, -1378745.1191930738,\n",
+       "       -1378744.1191930738, -1378743.1191930738, -1378742.1191930738,\n",
+       "       -1378741.1191930738, -1378740.1191930738, -1378739.1191930738,\n",
+       "       -1378738.1191930738, -1378737.1191930738, -1378736.1191930738,\n",
+       "       -1378735.1191930738, -1378734.1191930738, -1378733.1191930738,\n",
+       "       -1378732.1191930738, -1378731.1191930738, -1378730.1191930738,\n",
+       "       -1378729.1191930738, -1378728.1191930738, -1378727.1191930738,\n",
+       "       -1378726.1191930738, -1378725.1191930738, -1378724.1191930738,\n",
+       "       -1378723.1191930738, -1378722.1191930738, -1378721.1191930738,\n",
+       "       -1378720.1191930738, -1378719.1191930738, -1378718.1191930738,\n",
+       "       -1378717.1191930738, -1378716.1191930738, -1378715.1191930738,\n",
+       "       -1378714.1191930738, -1378713.1191930738, -1378712.1191930738,\n",
+       "       -1378711.1191930738],\n",
+       "      dtype=&#x27;float64&#x27;, name=&#x27;x&#x27;))</pre></div></li><li class='xr-var-item'><div class='xr-index-name'><div>y</div></div><div class='xr-index-preview'>PandasIndex</div><div></div><input id='index-a087f1fb-19e3-4a6d-8f91-2fe1a72b9cb9' class='xr-index-data-in' type='checkbox'/><label for='index-a087f1fb-19e3-4a6d-8f91-2fe1a72b9cb9' title='Show/Hide index repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-index-data'><pre>PandasIndex(Index([2781632.062650748, 2781631.062650748, 2781630.062650748,\n",
+       "       2781629.062650748, 2781628.062650748, 2781627.062650748,\n",
+       "       2781626.062650748, 2781625.062650748, 2781624.062650748,\n",
+       "       2781623.062650748, 2781622.062650748, 2781621.062650748,\n",
+       "       2781620.062650748, 2781619.062650748, 2781618.062650748,\n",
+       "       2781617.062650748, 2781616.062650748, 2781615.062650748,\n",
+       "       2781614.062650748, 2781613.062650748, 2781612.062650748,\n",
+       "       2781611.062650748, 2781610.062650748, 2781609.062650748,\n",
+       "       2781608.062650748, 2781607.062650748, 2781606.062650748,\n",
+       "       2781605.062650748, 2781604.062650748, 2781603.062650748,\n",
+       "       2781602.062650748, 2781601.062650748, 2781600.062650748,\n",
+       "       2781599.062650748, 2781598.062650748, 2781597.062650748,\n",
+       "       2781596.062650748, 2781595.062650748, 2781594.062650748,\n",
+       "       2781593.062650748, 2781592.062650748, 2781591.062650748,\n",
+       "       2781590.062650748, 2781589.062650748, 2781588.062650748,\n",
+       "       2781587.062650748, 2781586.062650748, 2781585.062650748,\n",
+       "       2781584.062650748, 2781583.062650748, 2781582.062650748,\n",
+       "       2781581.062650748, 2781580.062650748, 2781579.062650748,\n",
+       "       2781578.062650748, 2781577.062650748, 2781576.062650748,\n",
+       "       2781575.062650748, 2781574.062650748, 2781573.062650748,\n",
+       "       2781572.062650748, 2781571.062650748, 2781570.062650748,\n",
+       "       2781569.062650748, 2781568.062650748, 2781567.062650748,\n",
+       "       2781566.062650748, 2781565.062650748, 2781564.062650748,\n",
+       "       2781563.062650748, 2781562.062650748, 2781561.062650748,\n",
+       "       2781560.062650748, 2781559.062650748, 2781558.062650748,\n",
+       "       2781557.062650748, 2781556.062650748, 2781555.062650748,\n",
+       "       2781554.062650748, 2781553.062650748, 2781552.062650748,\n",
+       "       2781551.062650748, 2781550.062650748, 2781549.062650748,\n",
+       "       2781548.062650748, 2781547.062650748, 2781546.062650748,\n",
+       "       2781545.062650748, 2781544.062650748, 2781543.062650748,\n",
+       "       2781542.062650748, 2781541.062650748, 2781540.062650748,\n",
+       "       2781539.062650748, 2781538.062650748, 2781537.062650748,\n",
+       "       2781536.062650748, 2781535.062650748, 2781534.062650748,\n",
+       "       2781533.062650748],\n",
+       "      dtype=&#x27;float64&#x27;, name=&#x27;y&#x27;))</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-382ac0b8-3f2d-43dc-a1f2-5c0ba24b92dd' class='xr-section-summary-in' type='checkbox' disabled ><label for='section-382ac0b8-3f2d-43dc-a1f2-5c0ba24b92dd' class='xr-section-summary'  title='Expand/collapse section'>Attributes: <span>(0)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><dl class='xr-attrs'></dl></div></li></ul></div></div>"
+      ],
+      "text/plain": [
+       "<xarray.DataArray 'mburnt_integ' (y: 100, x: 100)>\n",
+       "dask.array<getitem, shape=(100, 100), dtype=float64, chunksize=(100, 100), chunktype=numpy.ndarray>\n",
+       "Coordinates:\n",
+       "    spatial_ref  int64 0\n",
+       "  * x            (x) float64 -1.379e+06 -1.379e+06 ... -1.379e+06 -1.379e+06\n",
+       "  * y            (y) float64 2.782e+06 2.782e+06 ... 2.782e+06 2.782e+06"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "da.transpose(\"time\", \"z\", \"y\", \"x\").isel(time=1, z=0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "38491a09d0633eaa",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.830302Z",
+     "start_time": "2023-10-11T12:45:19.703724Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": [
+    "# Write the RasterArray to a GeoTIFF\n",
+    "raster = da.transpose(\"time\", \"z\", \"y\", \"x\").isel(time=1, z=0)\n",
+    "raster.rio.to_raster(TMP_PATH / \"test.tif\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "e3eab1d1ad401998",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.967835Z",
+     "start_time": "2023-10-11T12:45:19.831950Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzQAAAMWCAYAAAAnFsNKAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAADDBklEQVR4nOzdebxW4/7/8fduHjRr1khJkyKiUJQyJMMhVGaZhyIRB3FSZIqcE5lCiC8iY2XqIGMZGqgopNqimVKp/fujn+3s1ntx3fu+d/e9d6/n47EfDz5d67rWWvdaa+/rXuvzWVk5OTk5AgAAAIBCqFi6VwAAAAAA8osJDQAAAIBCiwkNAAAAgEKLCQ0AAACAQosJDQAAAIBCiwkNAAAAgEKLCQ0AAACAQosJDQAAAIBCq0S6VwAAAAAo7H777Tdt3Lgx3asRUapUKZUpUybdq1GgmNAAAAAASfjtt99UrmxZ5aR7RYxatWpp4cKFRXpSw4QGAAAASMLGjRuVI6mspKx0r8z/yJGUnZ2tjRs3MqEBAAAA8NeylFkTmh0FExoAAAAgBYopsyY0mfgIXEGgyhkAAACAQosJDQAAAIBCi0fOAAAAgBQoLh45Swfu0AAAAAAotJjQAAAAACi0eOQMAAAASAGqnKUHd2gAAAAAFFpMaAAAAAAUWjxyBgAAAKRAMWXW3YIt6V6B7SST9jkAAAAAJIQJDQAAAIBCi0fOAAAAgBQorsy6W5BJFdcKUibtcwAAAABICBMaAAAAAIUWj5wBAAAAKZBpVc52FOxzAAAAAIUWExoAAAAAhRaPnAEAAAApQJWz9MikfQ4AAAAACWFCAwAAAKDQ4pEzAAAAIAV45Cw9MmmfAwAAAEBCmNAAAAAAKLR45AwAAABIAV6smR7scwAAAACFFhMaAAAAAIUWj5wBAAAAKVBMWyudYfviDg0AAACAQosJDQAAAIBCi0fOAAAAgBTItCpnOelege0kk/Y5AAAAACSECQ0AAACAQotHzgAAAIAUKC6qnKUDd2gAAAAAFFpMaAAAAAAUWjxyBgAAAKQAj5ylB3doAAAAABRaTGgAAAAAFFo8cgYAAACkAC/WTI9M2ucAAAAAkBAmNAAAAAAKLR45AwAAAFKAKmfpwR0aAAAAAIUWExoAAAAAhRaPnAEAAAApwCNn6cEdGgAAAACFFhMaAAAAAIUWj5wBAAAAKZClzLpbsCXdK7CdZNI+BwAAAICEMKEBAAAAUGjxyBkAAACQAplW5Swn3SuwnXCHBgAK2H/+8x+NHTs2Ev/222+VlZVl/+3vJLNsst544w21a9dO5cuXV1ZWlp5//vntNvb48ePVpk0blSlTRnXq1FH//v31yy+/bLfxAQCZhzs0AFDA/vOf/2jnnXfW6aefnideu3Ztvf/++9p1113Ts2L5kJOTo169eqlp06aaOHGiypcvr9133327jP3444+rb9++Ovvss3XnnXdq3rx5uvLKKzVnzhxNnjx5u6wDACDzMKEBgDQpXbq09ttvv7Suw+bNm/X777+rdOnSQe2XLFmiFStW6Nhjj1WXLl0KeO3+tHnzZl1xxRXq1q2b7r//fknSwQcfrAoVKqhPnz569dVXdfjhh2+39QEAp5gy6/GnTFqXgrSjbCcA6KefftI555yjevXqqXTp0qpevbo6duyo119/PbdN586d1bJlS73zzjvab7/9VLZsWdWtW1fXXnutNm/enKe/G264Qe3bt1fVqlVVsWJF7bXXXnrwwQeVk/PnU8sNGzbU7NmzNXXqVGVlZSkrK0sNGzaU5B8b+/rrr3XGGWeoSZMmKleunOrWraujjjpKM2fOTHr7/xhvxIgRGjp0qBo1aqTSpUvrrbfekiR98skn6tmzp6pWraoyZcqobdu2evrpp3OXHzJkiHbZZRdJ0pVXXplnWwraBx98oKVLl+qMM87IEz/hhBO00047acKECdtlPQAAmYc7NAB2GKeccopmzJihm266SU2bNtWqVas0Y8YMLV++PE+77OxsnXTSSbrqqqt044036uWXX9bQoUO1cuVK3XPPPbntvv32W5177rmqX7++pK1/dF988cVavHixrrvuOknShAkTdPzxx6tSpUr6z3/+I0l/eTdkyZIlqlatmm6++WZVr15dK1as0COPPKL27dvr008/TcnjXXfffbeaNm2q2267TRUrVlSTJk301ltv6bDDDlP79u117733qlKlSho/frxOPPFErVu3TqeffrrOPvts7bnnnjruuON08cUXq3fv3n97Z+f3338PWqfixYsrKysr9t9nzZolSWrdunWeeMmSJdWsWbPcfwcA7HiY0ADYYbz33ns6++yz1a9fv9zY0UcfHWm3fPlyvfDCC+rZs6ckqVu3blq/fr1Gjx6tQYMG5U5gHn744dxltmzZos6dOysnJ0d33XWXrr32WmVlZalt27YqW7asKlasGPR42UEHHaSDDjoo9/83b96sI488Ui1atNB9992nO+64I9/b/4cyZcpo0qRJKlmyZG7s8MMPV4sWLfTmm2+qRImtvxq6d++un3/+WVdffbVOPfVU7bLLLrkTlPr16wdtz/+O8VcefvjhSI7R//pj0lm1atXIv1WtWlXffvtt0DgAUJCocpYePHKWDytWrNDFF1+s3XffXeXKlVP9+vV1ySWXaPXq1X+5XMOGDXMfOfnfnwsvvDC3zS+//KKLLrpIu+yyi8qWLas99thDo0ePztPPmDFj1LlzZ1WsWFFZWVlatWpVvrZj1apVuvDCC1W7dm2VKVNGe+yxh1555ZV89QUUBvvuu6/Gjh2roUOH6oMPPtCmTZtsuwoVKuROZv7Qu3dvbdmyRf/9739zY2+++aa6du2qSpUqqXjx4ipZsqSuu+46LV++XMuWLcvXOv7+++8aNmyYmjdvrlKlSqlEiRIqVaqU5s+fry+//DJffW6rZ8+eeSYaX3/9tb766iv16dMndx3++DniiCO0dOlSzZ07N19jffzxx0E/Rx11VFB/cXdx/uruDgCgaOMOzV/o3LmzTj/99Mi3hkuWLNGSJUt02223qXnz5vruu+903nnnacmSJXrmmWdi+/v444/zPIM/a9YsHXrooTrhhBNyYwMGDNBbb72lcePGqWHDhpo8ebIuuOAC1alTJ/eb5HXr1umwww7TYYcdpsGDB+dr2zZu3KhDDz1UNWrU0DPPPKNddtlFixYtUoUKFfLVH1AYPPXUUxo6dKgeeOABXXvttdppp5107LHHasSIEapVq1Zuu5o1a0aW/ePf/7hT8NFHH6lbt27q3Lmz7r//fu2yyy4qVaqUnn/+ed10001av359vtbxsssu07///W9deeWV6tSpk6pUqaJixYrp7LPPznef26pdu3ae///xxx8lSQMHDtTAgQPtMj///HO+xmrTpk1Qu+LF//o7zWrVqknauv+3/XxWrFhh79wAAHYMTGjyoWXLlnr22Wdz/3/XXXfVTTfdpL59++r333/PfVxjW9WrV8/z/zfffLN23XVXderUKTf2/vvv67TTTlPnzp0lSeecc47uu+8+ffLJJ7kTmv79+0uS3n777dh1XLx4sS677DJNnjxZxYoV0wEHHKC77rorN4H3oYce0ooVKzRt2rTcb2obNGiQyG4ACp2dd95ZI0eO1MiRI/X9999r4sSJuuqqq7Rs2TK99tprue3++AP/f2VnZ0v68w/r8ePHq2TJknrppZdUpkyZ3HbJvpNl3LhxOvXUUzVs2LA88Z9//lmVK1dOqu8/bHs3Y+edd5YkDR48WMcdd5xdJr+5O6l65KxVq1aSpJkzZ6p58+a58d9//11fffWVTj755HytHwCkEo+cpQcTmhRZvXq1KlasGDuZ2dbGjRs1btw4XXbZZXn+uDjggAM0ceJEnXnmmapTp47efvttzZs3T3fddVfwuqxbt04HH3ywDjzwQP33v/9ViRIlNHToUB122GH64osvVKpUKU2cOFH777+/LrzwQr3wwguqXr26evfurSuvvPJvvykFioL69evroosu0htvvKH33nsvz7+tXbtWEydOzPPY2RNPPKFixYrl5rdkZWWpRIkSec6X9evX67HHHouMVbp06eC7K1lZWZFE+5dfflmLFy/WbrvtFrx9idh9993VpEkTff7555GJVLI+/vjjoHaNGjX6y39v3769ateurbFjx+rEE0/MjT/zzDP65ZdfYidiAICijwlNCixfvlz/+te/dO655wYv8/zzz2vVqlWRbyTvvvtu9evXT7vssotKlCihYsWK6YEHHtABBxwQ3Pf48eNzl/tjsvTwww+rcuXKevvtt9WtWzctWLBAb775pvr06aNXXnlF8+fP14UXXqjff/89tzoTUJSsXr1aBx98sHr37q1mzZqpQoUK+vjjj/Xaa69F/hiuVq2azj//fH3//fdq2rSpXnnlFd1///06//zzcwsCHHnkkbrjjjvUu3dvnXPOOVq+fLluu+02W/WrVatWGj9+vJ566ik1btxYZcqUyb3jsK0ePXpo7NixatasmVq3bq3p06fr1ltvzS2XXFDuu+8+HX744erevbtOP/101a1bVytWrNCXX36pGTNm6P/+7//y1W+7du1Ssn7FixfXiBEjdMopp+jcc8/VySefrPnz52vQoEE69NBDddhhh6VkHABA4cOE5n8MGzYsz7eT69ev1wcffKCLLrooN/bqq6/qwAMPzP3/NWvW6Mgjj1Tz5s11/fXXB4/14IMP6vDDD1edOnXyxO+++2598MEHmjhxoho0aKD//ve/uuCCC1S7dm117do1qO/p06fr66+/juTD/Pbbb/rmm28kba3IVKNGDY0ZM0bFixfX3nvvrSVLlujWW29lQoMiqUyZMmrfvr0ee+wxffvtt9q0aZPq16+vK6+8UoMGDcrTtlatWvr3v/+tgQMHaubMmapataquvvpq3XDDDbltDjnkED300EO65ZZbdNRRR6lu3brq16+fatSoobPOOitPfzfccIOWLl2qfv36ae3atWrQoEFsVa677rpLJUuW1PDhw/XLL79or7320nPPPad//vOfKd8n/+vggw/WRx99pJtuukn9+/fXypUrVa1aNTVv3ly9evUq0LFD9e3bV8WLF9fNN9+ssWPHqmrVqjr11FN10003pXvVAEASL9ZMl6yc/30D3A5uxYoVWrFiRe7/9+nTR//4xz/yfHtbt25dlS1bVtLWx1K6d++ucuXKRZ6j/yvfffedGjdurOeeey5Pydj169erUqVKmjBhgo488sjc+Nlnn60ffvghzzP+0tYcmoMPPlgrV67M82z9+eefrxkzZujxxx+PjF29enVVqlRJnTp1UsmSJfO8UPDVV1/VEUccoQ0bNqhUqVJB2wIUNZ07d9bPP//Me00AAMHWrFmjSpUqqbMy627B75Le1p+pEUVVJu3ztKtatWqeSjlly5ZVjRo17HPra9asUffu3VW6dGlNnDgxeDIjbX38q0aNGnkmLZK0adMmbdq0ScWK5Z1PFy9eXFu2bAnuf6+99tJTTz2lGjVqxB68HTt21BNPPKEtW7bkjjdv3jzVrl2byQwAAAAKjR3lTlRKrV27Vt26ddOvv/6qBx98UGvWrFF2drays7PzlGXu0qVLnreKS1sf9Xr44Yd12mmnRQoIVKxYUZ06ddIVV1yht99+WwsXLtTYsWP16KOP6thjj81tl52drc8++0xff/21pK1Vfz777LPcu0t9+vTRzjvvrKOPPlrvvPOOFi5cqKlTp+rSSy/VDz/8IGnrXZzly5fr0ksv1bx58/Tyyy9r2LBhed6JA6Dw+N93x7ifRL4UAQDkT/EM/NkRMKHJh+nTp+vDDz/UzJkztdtuu6l27dq5P4sWLcpt980330Te3fD666/r+++/15lnnmn7Hj9+vPbZZx/16dNHzZs3180336ybbrpJ5513Xm6be++9V23bts192/lBBx2ktm3bauLEiZKkcuXK6b///a/q16+v4447TnvssYfOPPNMrV+/PveOTb169TR58mR9/PHHat26tS655BJdeumluuqqq1K6r4DC5u233y50j5t9++23Klmy5F/+3HjjjeleTQAACgQ5NABQyG3cuFFffPHFX7apU6dOpAgJACA1/sih6aLMyuf4XdIbIocGAJDhSpUqlbLyyACA/CumzHrMa0d52JhHzgAAAAAUWtyh0dZE/SVLlqhChQq5L6IEAABA5sjJydHatWtVp06dSEVY7NiY0EhasmSJ6tWrl+7VAAAAwN9YtGiRdtlll3SvhsWLNdODCY2kChUqSNp6ghTlhCkAAIDCas2aNapXr17u323AH5jQSLmPmVWsWJEJDQAAQAYjPQDbYkIDAAAApECmvcySKmcAAAAAkOGY0AAAAAAotNL+yNnixYt15ZVX6tVXX9X69evVtGlTPfjgg9p7770jbc8991yNGTNGd955p/r3758b37BhgwYOHKgnn3xS69evV5cuXfSf//wnYytgAACAHdPmzZu1adOmdK9GRipZsqSKF8+kB7YSR5Wz9EjrhGblypXq2LGjDj74YL366quqUaOGvvnmG1WuXDnS9vnnn9eHH36oOnXqRP6tf//+evHFFzV+/HhVq1ZNl19+uXr06KHp06cX+hMDAAAUfjk5OcrOztaqVavSvSoZrXLlyqpVqxaJ/0hIWic0t9xyi+rVq6eHH344N9awYcNIu8WLF+uiiy7SpEmTdOSRR+b5t9WrV+vBBx/UY489pq5du0qSxo0bp3r16un1119X9+7dC3QbAAAA/s4fk5kaNWqoXLly/MG+jZycHK1bt07Lli2TJNWuXTvNa4TCJK0TmokTJ6p79+464YQTNHXqVNWtW1cXXHCB+vXrl9tmy5YtOuWUU3TFFVeoRYsWkT6mT5+uTZs2qVu3brmxOnXqqGXLlpo2bRoTGgAAkFabN2/OncxUq1Yt3auTscqWLStJWrZsmWrUqFEon7Khyll6pPXRugULFmj06NFq0qSJJk2apPPOO0+XXHKJHn300dw2t9xyi0qUKKFLLrnE9pGdna1SpUqpSpUqeeI1a9ZUdna2XWbDhg1as2ZNnh8AAICC8EfOTLly5dK8Jpnvj31EnhESkdY7NFu2bFG7du00bNgwSVLbtm01e/ZsjR49WqeeeqqmT5+uu+66SzNmzEj41mxOTk7sMsOHD9cNN9yQ9PoDAACE4jGzv8c+Qn6k9Q5N7dq11bx58zyxPfbYQ99//70k6Z133tGyZctUv359lShRQiVKlNB3332nyy+/PDfXplatWtq4caNWrlyZp59ly5apZs2adtzBgwdr9erVuT+LFi1K/cYBAABgh1I8A392BGmd0HTs2FFz587NE5s3b54aNGggSTrllFP0xRdf6LPPPsv9qVOnjq644gpNmjRJkrT33nurZMmSmjJlSm4fS5cu1axZs9ShQwc7bunSpVWxYsU8PwAAAAAKn7ROaAYMGKAPPvhAw4YN09dff60nnnhCY8aM0YUXXihJqlatmlq2bJnnp2TJkqpVq5Z23313SVKlSpV01lln6fLLL9cbb7yhTz/9VH379lWrVq1yq54BAAAgcaeffrqysrKUlZWlEiVKqH79+jr//PMjT8ZMmzZNRxxxhKpUqaIyZcqoVatWuv3227V58+Y87bKysvT8889vxy3AjiCtE5p99tlHEyZM0JNPPqmWLVvqX//6l0aOHKk+ffok1M+dd96pY445Rr169VLHjh1Vrlw5vfjii4WyOgYAAEAmOeyww7R06VJ9++23euCBB/Tiiy/qggsuyP33CRMmqFOnTtpll1301ltv6auvvtKll16qm266SSeddJJycnLSuPbbV7EM/NkRpLUogCT16NFDPXr0CG7/7bffRmJlypTRqFGjNGrUqBSuGQAAQOr1m9hPs36aldZ1aFm9pe7veX9Q29KlS6tWrVqSpF122UUnnniixo4dK0n69ddf1a9fP/Xs2VNjxozJXebss89WzZo11bNnTz399NM68cQTU74NwB/SPqEBAADYkcz6aZY++OGDdK9GvixYsECvvfaaSpYsKUmaPHmyli9froEDB0baHnXUUWratKmefPJJJjQoUExoAAAAEOull17STjvtpM2bN+u3336TJN1xxx2SthZzkrZWqXWaNWuW22ZHUEyZVVls8983KRKY0AAAACDWwQcfrNGjR2vdunV64IEHNG/ePF188cV52sTlyfzVewGBVNlRcoUAAACQD+XLl9duu+2m1q1b6+6779aGDRtyX1DetGlTSdKXX35pl/3qq6/UpEmT7bau2DFxhwYAAGA7alm9ZbpXIal1uP7663X44Yfr/PPPV7du3VS1alXdfvvtkff/TZw4UfPnz9e//vWvZFe30Mi0l1lm0roUJCY0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ldq3b6/bb79dxxxzjEaPHp3vfjNsMwEAAAAURTNmzNCBBx4oSXrmmWdUs2ZNfffdd3r00Ud1991357tfJjQAAAAACty6detUocLWN3JNnjxZxx13nIoVK6b99ttP333n3pwXhgkNAAAAkArprmiW4VXOdtttNz3//PNatGiRJk2apG7dukmSli1bpooVK+a7X4oCFHW1JJ2WNzTtimgzlwAt+bfMu1mwSzYNTRqO487BVSb2lVvYvZ55dxOr0csPftTUaOy6HyOhdv2jzZ4z3bltcUnIca43se53RmMup99sibSLH+cYE+tkYiP84ttF6HG1MevNSKzUo75taxNzb3RPJAF7W3G/U0IT80Ml8lZ1N45LPHeJzS6Z3CWyu6RqSXrx/mhseb9orKNZ1iXcu2Ilq2LGdgnlbnm3L92vW7dsXEEBd2lyXOK4G8etT9znfbKJDcypGw1+YAqBmEz41gdFY27fStLEwFhowrw7FxO5prrE/tDEfHfeuM9G8seq6zOZIgVAYXLdddepd+/eGjBggLp06aL9999f0ta7NW3bts13v0xoAAAAABS4448/XgcccICWLl2a+w4aSerSpYuOPfbYfPfLhAYAAABIhWLKuMe8Mk2tWrVUq1atPLFkXqopMaEBAAAAsJ18/PHH+r//+z99//332rgx7wO6zz3nHtz/exQFAAAAAFDgxo8fr44dO2rOnDmaMGGCNm3apDlz5ujNN99UpUouOzMMExoAAAAgFdL9Es0Mf7HmsGHDdOedd+qll15SqVKldNddd+nLL79Ur169VL9+/Xz3yyNnRd1CSRfmDbliXytiFndz5dUm5qobxVXaCeWq0Lj13NPEtMjElphYvaf94K6UjNnIn0yz0EdnE9k/rnpZjbkJdLCN2gm0/TD/wyTNXYddJSJXkayB6+/U8LFd1SL32brPsZ6JRWvkxXOVsNz5EPp7Kq6d2x5X0ayWiblTxFWZWhUz9lpT0cx9tqH7PLR6mOT3ZRMTc+eduya6SlbuchM3tuMqT7pl3WfjPkNJ6uGCT0UrmrU5Kdrss/ejsZ6mu09ixnbXSvc5uvPOnd/uWIs7zkOr77nij+73neOqA0pStom549zF3HEV97saKCy++eYbHXnkkZKk0qVL69dff1VWVpYGDBigQw45RDfccEO++s2weRsAAACAoqhq1apau3br1y51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komVNzEpPJHefY6h+yfZ5Pg6JuYKKTgbExhHC8Jim00BgETO79Drg2vnfq8Chd3gwYP1+eef6+2339Zhhx2WG+/atauuv/56XXWV+8Ph7zGhAQAAAFDgnn/+eT311FPab7/9lJX15+2j5s2b65tvvsl3v0xoAAAAgFSgytlf+umnn1SjRo1I/Ndff80zwUlUWnNohgwZoqysrDw/tWrVytPmyy+/VM+ePVWpUiVVqFBB++23X+7zdpK0YcMGXXzxxdp5551Vvnx59ezZUz/88MP23hQAAAAAf2GfffbRyy+/nPv/f0xi7r//fu2///757jftd2hatGih11//8yHV4sX/nEp+8803OuCAA3TWWWfphhtuUKVKlfTll1+qTJk/n/Dt37+/XnzxRY0fP17VqlXT5Zdfrh49emj69Ol5+gIAAACQPsOHD9dhhx2mOXPm6Pfff9ddd92l2bNn6/3339fUqTGJjwHSPqEpUaJE5K7MH6655hodccQRGjHizyzixo0b5/736tWr9eCDD+qxxx5T165dJUnjxo1TvXr19Prrr6t79+4Fu/KFQJ0saeA2Wbn3mSxQlyQr+TdL/2ZiwW8nbzExGjvAxCRpz2joCNPMJcW6qax7I/YzfmSdeJRZ+x7R2LemAEDoNPrwmPirJubeOl43tqJB/l1gYv8xibL2jdy9TKyVicVkqIcmyibzNUW5mLhLOnbjuFvacYnIIf3FCU0Gduet271tY5Y/08R6jDfBVdHQjaYwxCMx4zjJfI72yn5qNPTN7TEd7BUN7Wo+XFfQwF2Dbm1v+vvQD+2Kk1w01gTNRo46Mhrbd0Y0ttwPbcd210XHHZOuGELc+TDFVRr4dzTU+qyw9Qk97yTpWhOr3jIac39KmdorViLFEEKvI5ShLaR45Mz67LPP1KZNG3Xo0EHvvfeebrvtNu26666aPHmy9tprL73//vtq1cr90RAm7efL/PnzVadOHTVq1EgnnXSSFizY+tfTli1b9PLLL6tp06bq3r27atSoofbt2+v555/PXXb69OnatGmTunXrlhurU6eOWrZsqWnTpm3vTQEAAACwjb322kt77723Ro8erfr16+uRRx7RrFmzNGfOHI0bNy6pyYyU5glN+/bt9eijj2rSpEm6//77lZ2drQ4dOmj58uVatmyZfvnlF91888067LDDNHnyZB177LE67rjjcm9JZWdnq1SpUqpSpUqefmvWrKnsbHdvYasNGzZozZo1eX4AAAAApN57772nvfbaS1dddZVq166tU045RW+99VbK+k/rhObwww/XP/7xD7Vq1Updu3bNTRJ65JFHtGXL1hvcRx99tAYMGKA2bdroqquuUo8ePXTvvebFGP8jJyfnLyslDB8+XJUqVcr9qVfP3YgHAAAAEpDuF2m6nwyw//775968GD16tBYtWqSuXbtq11131U033ZR0Qa8M2cytypcvr1atWmn+/PnaeeedVaJECTVv3jxPmz322CO3ylmtWrW0ceNGrVy5Mk+bZcuWqWZN9/rIrQYPHqzVq1fn/ixaFPoUMQAAAID8KFu2rE477TS9/fbbmjdvnk4++WTdd999atSokY44wmUphkl7UYD/tWHDBn355Zc68MADVapUKe2zzz6aO3dunjbz5s1TgwYNJEl77723SpYsqSlTpqhXr60ZyUuXLtWsWbPyFBLYVunSpVW6tHvHdhG0337S/e/nCZ37WPTu1VsmoVaSbjIxk5dqc85c4nhFk0S/xcQk/xZ0l5gaOit3CeZvxrTt8lI09pmJhSaCLstxGfOunIGkXVdHQnVNYn4y+yIuofYFFzOnknsT+UVmE6vfbBom8DVKaC5jaEEBW8wggeXdfnPLhvYX1zaU69PlXs+KWd4+mPurid0ZDc00zRLZ7rh4SJ9TTGxXk0z+TVx1hazole2bp6+JxJqaY9peM8xDA9/EVGKwlzuXXV+rQTS253eRUEtTFCDmkmqP/wqB7UKP0+gabvWAqSZzdp1o7L9m2Y6BY7vrkuQL2VxsYm67XSER1y70eJb8tdv9LgktDgIUVrvuuquuuuoq1atXT1dffbUmTYr5uyhAWic0AwcO1FFHHaX69etr2bJlGjp0qNasWaPTTjtNknTFFVfoxBNP1EEHHaSDDz5Yr732ml588UW9/fbbkqRKlSrprLPO0uWXX65q1aqpatWqGjhwYO4jbAAAAMB2Q5WzIFOnTtVDDz2kZ599VsWLF1evXr101lmBZQ6NtE5ofvjhB5188sn6+eefVb16de2333764IMPcu/AHHvssbr33ns1fPhwXXLJJdp999317LPP6oADDsjt484771SJEiXUq1cvrV+/Xl26dNHYsWN5Bw0AAACQIRYtWqSxY8dq7NixWrhwoTp06KBR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dN17772aMGGC1qxZo7vuuksJCQm65ZZbInoO6kacouvyOs7tBtQLRmgAoAG59tprdfvtt2vEiBH605/+pGbNmukf//iH280CUAuFhYVhF+Wfeqxbt65Wx7j66qtVWlqqFStW6Ne//rWGDh2qPXv2hGx39OhRzZkzJ2h0RpKMMRo7dqxat26tZcuWac2aNcrPz9eQIUO0e/duST+M7CxZskTnnHNO4NG5c2dJ0tdffy1Jqq6uDnR6evbsqTvuuEO33367pk+fXqv3h4YtmrqQAIA68Mwzz6hbt2564403tG7dOjVr1sztJgGohYKCAg0bNuyM23To0KFWx0hKStKFF16oCy+8UL1791bHjh1VVFSkhx56KGi7N998U0eOHAkZLVm8eLHeffddVVRUBNZqTJs2TcXFxZo1a5YefPBBVVdX67rrrtOTTz4Zcvw2bdoE/tulS5eg53JycjRv3rxavT80bHRoAKCB2bx5s3bt2qXq6mpt3bpV3bt3d7tJAGohLS0t7PSvSDHG6NixYyHxoqIiXX/99UpPTw+KHzlyRJIUGxs8+Sc2NlbV1dWSpF69emnevHnq0KGD4uPtl6D9+vXTxo0bg2KbNm1S+/btf/Z7qV/RVlksmtoSOUw5A4AGpKqqSiNGjNDvfvc7Pf744xozZoy+/fZbt5sFoJ5s27ZNpaWl2rZtm06ePKnS0lKVlpbq0KFDgW06d+6st99+W5J0+PBhTZgwQatWrdLWrVv1ySef6LbbbtOOHTt00003Be37q6++0tKlS3XbbbeFHLdPnz5KSUnRqFGj9Omnn2rTpk26//779c0332jw4MGSpHHjxmn//v0aPny41qxZo82bN2vhwoUaPXq0Tp48KUn6y1/+olWrVmnSpEn66quvNGfOHL3yyisaN25cpE4ZGgA6NADQgDz88MPy+/164YUX9MADDygnJydkrjuAhuuRRx5Rz549NXHiRB06dEg9e/ZUz549g9bYbNy4UX6/X5IUFxen//73v/rtb3+rTp06aciQIdq7d6+WLVumrl27Bu37tdde07nnnmstMpKWlqYFCxbo0KFDGjBggC699FJ9/PHHmj9/fqBaWlZWlpYvX66TJ08qLy9P3bp109133y2fzxcY2bnsssv09ttva+7cuerWrZv+/ve/a+rUqRoxYkSkThkaAO5DAwANxIcffqhBgwZpyZIluuKKKyT98Nfa7t27a/LkyTW60R4AwLkf70OzSsnJ57jdnIDKykPy+Xo3+PvQNI6JdQDQCFx11VU6fvx4UKxdu3Y/68Z6AAB4BVPOAAAAAHgWIzQAAABAnaDKmRsYoQEAAADgWXRoAAAAAHhW4xiHAgAAACIuTtF1eR3ndgPqBSM0AAAAADyLDg0AAAAAz4qmMTEAAADAw+IUXdO8oqktkcMIDQAAAADPokMDAAAAwLOYcgYAAADUCW6s6QZGaAAAAAB4Fh0aAAAAAJ7VOMahAAAAgIhjypkbGKEBAAAA4Fl0aAAAAAB4VuMYhwIAAAAijilnbmCEBgAAAIBn0aEBAAAA4FmNYxwKAAAAiLg4RdfldZzbDagXjNAAAAAA8Cw6NAAAAAA8K5rGxAAAAAAPo8qZGxihAQAAAOBZdGgAAAAAeFbjGIcCAAAAIo4pZ25ghAYAAACAZ9GhAQAAAOBZjWMcCgAAAIg4ppy5gREaAAAAAJ5FhwYAAACAZzWOcSgAAAAg4phy5gZGaAAAAAB4VuPotgEAAAARVllZ6XYTgkRbeyKFDg0AAABQC02bNlVmZqays7PdbkqIzMxMNW3a1O1mRFSMMca43QgAAADAy77//ntVVVW53YwQTZs2VbNmzdxuRkTRoQEAAADgWRQFAAAAAOBZdGgAAAAAeBYdGgAAAACeRYcGAAAAgGfRoQEAAADgWXRoAAAAAHgWHRoAAAAAnvX/ASS//MeCxPawAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 1000x1000 with 2 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Define a padding value\n",
+    "padding = 0.1\n",
+    "\n",
+    "# Calculate the bounds of the roi with padding\n",
+    "x_min, y_min, x_max, y_max = roi.total_bounds\n",
+    "width = x_max - x_min\n",
+    "height = y_max - y_min\n",
+    "\n",
+    "# Plot the DataArray over the shapefilefig\n",
+    "fig, ax = plt.subplots(figsize=(10, 10))\n",
+    "raster.plot(\n",
+    "    ax=ax,\n",
+    "    cmap=\"hot_r\",\n",
+    "    cbar_kwargs={\n",
+    "        \"label\": \"Vertically Integrated % Mass Burnt\",\n",
+    "        \"orientation\": \"vertical\",\n",
+    "    },\n",
+    ")\n",
+    "roi.plot(ax=ax, facecolor=\"none\", edgecolor=\"green\", linewidth=4)\n",
+    "\n",
+    "# Set the new bounds with padding\n",
+    "ax.set_xlim(x_min - width * padding, x_max + width * padding)\n",
+    "ax.set_ylim(y_min - height * padding, y_max + height * padding)\n",
+    "\n",
+    "# Add the legend\n",
+    "legend_line = mlines.Line2D([], [], color=\"green\", linewidth=4, label=\"ROI\")\n",
+    "ax.legend(handles=[legend_line])\n",
+    "\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a9f6b3ceaa486040",
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2023-10-11T12:45:19.972760Z",
+     "start_time": "2023-10-11T12:45:19.968375Z"
+    },
+    "collapsed": false,
+    "jupyter": {
+     "outputs_hidden": false
+    }
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..ffc98de
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,32 @@
+# mkdocs.yml
+site_name: quicfire-tools Documentation
+
+theme:
+  name: "material"
+
+nav:
+  - Home: index.md
+  # - Explanation: explanation.md
+  # - Tutorials: tutorials.md
+  # - How-To Guides: how-to-guides.md
+  - Reference: reference.md
+
+repo_url: https://github.com/silvxlabs/quicfire-tools
+repo_name: quicfire-tools
+
+
+plugins:
+  - search
+  - mkdocstrings:
+      handlers:
+        python:
+          options:
+            docstring_style: numpy
+            docstring_section_style: table
+            ignore_init_summary: true
+            show_root_heading: true
+            show_source: false
+            members_order: source
+            annotations_path: brief
+            separate_signature: true
+            show_signature_annotations: true
diff --git a/quicfire_tools/__init__.py b/quicfire_tools/__init__.py
index 4f58b46..2fd3afd 100644
--- a/quicfire_tools/__init__.py
+++ b/quicfire_tools/__init__.py
@@ -1,9 +1,4 @@
 from quicfire_tools.inputs import SimulationInputs
-from quicfire_tools.outputs import SimulationOutputs, OutputFile
-from quicfire_tools.parameters import SimulationParameters
+from quicfire_tools.outputs import SimulationOutputs
 
-
-__all__ = ['SimulationInputs',
-           'SimulationParameters',
-           'SimulationOutputs',
-           'OutputFile']
+__all__ = ["SimulationInputs", "SimulationOutputs"]
diff --git a/quicfire_tools/examples.py b/quicfire_tools/examples.py
new file mode 100644
index 0000000..c81a05e
--- /dev/null
+++ b/quicfire_tools/examples.py
@@ -0,0 +1,43 @@
+from quicfire_tools.inputs import SimulationInputs, QUIC_fire
+from quicfire_tools.ignitions import RectangleIgnition
+
+
+def create_line_fire() -> SimulationInputs:
+    # Set up the basic simulation inputs
+    sim_inputs = SimulationInputs.setup_simple_simulation(
+        nx=200,
+        ny=200,
+        simulation_time=600,
+        wind_speed=1.7,
+        wind_direction=90,
+    )
+
+    # Make modifications to the QUIC_Fire input file
+    quic_fire: QUIC_fire = sim_inputs.get_input("QUIC_fire")
+    quic_fire.random_seed = 222
+    quic_fire.time_now = 1653321600
+    quic_fire.sim_time = 300
+    quic_fire.out_time_fire = 50
+    quic_fire.out_time_wind = 50
+    quic_fire.out_time_emis_rad = 50
+    quic_fire.out_time_wind_avg = 50
+    quic_fire.nz = 1
+    quic_fire.dz = 1.0
+    quic_fire.fuel_flag = 1
+    quic_fire.fuel_density = 0.7
+    quic_fire.fuel_moisture = 0.05
+    quic_fire.fuel_height = 1.0
+    line_ignition = RectangleIgnition(
+        x_min=150,
+        y_min=100,
+        x_length=100,
+        y_length=100,
+    )
+    quic_fire.ignition_type = line_ignition
+    quic_fire.ignitions_per_cell = 100
+
+    # Write the input file deck to a directory
+    sim_inputs.write_inputs("tmp")
+
+
+line_fire_simulation = create_line_fire()
diff --git a/quicfire_tools/ignitions.py b/quicfire_tools/ignitions.py
new file mode 100644
index 0000000..5f214de
--- /dev/null
+++ b/quicfire_tools/ignitions.py
@@ -0,0 +1,171 @@
+"""
+QUIC-Fire Tools Ignitions Module
+"""
+from __future__ import annotations
+
+# Core Imports
+from enum import Enum
+
+# External Imports
+from pydantic import BaseModel, SerializeAsAny
+
+
+class IgnitionSources(int, Enum):
+    rectangle = 1
+    square_ring = 2
+    circular_ring = 3
+    ignite_dat_file = 6
+
+
+class IgnitionType(BaseModel):
+    """
+    Test docs
+    """
+
+    ignition_flag: SerializeAsAny[IgnitionSources]
+
+    def __str__(self):
+        return (
+            f"{self.ignition_flag.value}\t! 1 = rectangle, "
+            f"2 = square ring, 3 = circular ring, "
+            f"4 = file (QF_Ignitions.inp), "
+            f"5 = time-dependent ignitions (QF_IgnitionPattern.inp), "
+            f"6 = ignite.dat (firetech)"
+        )
+
+
+class RectangleIgnition(IgnitionType):
+    """
+    Represents a rectangle ignition source in QUIC-Fire.
+
+    Parameters
+    ----------
+    x_min : float
+        South-west corner in the x-direction [m]
+    y_min : float
+        South-west corner in the y-direction [m]
+    x_length : float
+        Length in the x-direction [m]
+    y_length : float
+        Length in the y-direction [m]
+    """
+
+    ignition_flag: SerializeAsAny[IgnitionSources] = IgnitionSources(1)
+    x_min: int
+    y_min: int
+    x_length: int
+    y_length: int
+
+    def __str__(self):
+        flag_line = super().__str__()
+        locations = (
+            f"\n{self.x_min}\t! South-west corner in the x-direction\n"
+            f"{self.y_min}\t! South-west corner in the y-direction\n"
+            f"{self.x_length}\t! Length in the x-direction\n"
+            f"{self.y_length}\t! Length in the y-direction"
+        )
+        return flag_line + locations
+
+
+class SquareRingIgnition(IgnitionType):
+    """
+    Represents a square ring ignition source in QUIC-Fire.
+
+    Parameters
+    ----------
+    x_min : float
+        South-west corner in the x-direction [m]
+    y_min : float
+        South-west corner in the y-direction [m]
+    x_length : float
+        Length in the x-direction [m]
+    y_length : float
+        Length in the y-direction [m]
+    x_width : float
+        Width in the x-direction [m]
+    y_width : float
+        Width in the y-direction [m]
+    """
+
+    ignition_flag: SerializeAsAny[IgnitionSources] = IgnitionSources(2)
+    x_min: int
+    y_min: int
+    x_length: int
+    y_length: int
+    x_width: int
+    y_width: int
+
+    def __str__(self):
+        flag_line = super().__str__()
+        locations = (
+            f"\n{self.x_min}\t! South-west corner in the x-direction\n"
+            f"{self.y_min}\t! South-west corner in the y-direction\n"
+            f"{self.x_length}\t! Length in the x-direction\n"
+            f"{self.y_length}\t! Length in the y-direction\n"
+            f"{self.x_width}\t! Width in the x-direction\n"
+            f"{self.y_width}\t! Width in the y-direction"
+        )
+        return flag_line + locations
+
+
+class CircularRingIgnition(IgnitionType):
+    """
+    Represents a circular ring ignition source in QUIC-Fire.
+
+    Parameters
+    ----------
+    x_min : float
+        South-west corner in the x-direction [m]
+    y_min : float
+        South-west corner in the y-direction [m]
+    x_length : float
+        Length in the x-direction [m]
+    y_length : float
+        Length in the y-direction [m]
+    ring_width : float
+        Width of the ring [m]
+    """
+
+    ignition_flag: SerializeAsAny[IgnitionSources] = IgnitionSources(3)
+    x_min: int
+    y_min: int
+    x_length: int
+    y_length: int
+    ring_width: int
+
+    def __str__(self):
+        flag_line = super().__str__()
+        locations = (
+            f"\n{self.x_min}\t! South-west corner in the x-direction\n"
+            f"{self.y_min}\t! South-west corner in the y-direction\n"
+            f"{self.x_length}\t! Length in the x-direction\n"
+            f"{self.y_length}\t! Length in the y-direction\n"
+            f"{self.ring_width}\t! Width of the ring"
+        )
+        return flag_line + locations
+
+
+def default_line_ignition(nx, ny, wind_direction):
+    width = 10
+    if 45 <= wind_direction < 135:
+        x_min = (0.9 * (nx * 2)) - width
+        y_min = 0.1 * (ny * 2)
+        x_length = width
+        y_length = 0.8 * (nx * 2)
+    elif 135 <= wind_direction < 225:
+        x_min = 0.1 * (nx * 2)
+        y_min = 0.1 * (ny * 2)
+        x_length = 0.8 * (nx * 2)
+        y_length = width
+    elif 225 <= wind_direction < 315:
+        x_min = 0.1 * (nx * 2)
+        y_min = 0.1 * (ny * 2)
+        x_length = width
+        y_length = 0.8 * (nx * 2)
+    else:
+        x_min = 0.1 * (ny * 2)
+        y_min = (0.9 * (nx * 2)) - width
+        x_length = 0.8 * (nx * 2)
+        y_length = width
+
+    return x_min, y_min, x_length, y_length
diff --git a/quicfire_tools/input-templates/v5.1.1/QFire_Advanced_User_Inputs.inp b/quicfire_tools/input-templates/v5.1.1/QFire_Advanced_User_Inputs.inp
deleted file mode 100644
index 9485541..0000000
--- a/quicfire_tools/input-templates/v5.1.1/QFire_Advanced_User_Inputs.inp
+++ /dev/null
@@ -1,14 +0,0 @@
-0.05			! N/A, fraction of the cells on fire that will launch a firebrand
-40.			! N/A, scaling factor of the radius represented by the firebrands launched
-1				! s, time step for the firebrands trajectory calculation
-10				! s, how often to launch firebrands
-500			! N/A, number of firebrands distributed over the landing area
-20.			! N/A, FB_FRACTION_LAUNCHED_to_RT_ratio
-50.			! N/A, min_b_value_coef
-0.75			! N/A, fb_frac_of_max_size
-180			! s, germination_delay
-5.				! N/A, fraction of the cell on fire (to scale w)
-50				! N/A, minimum number of ignitions via firebrands at a point
-100			! N/A, maximum number of ignitions via firebrands at a point
-0.523598		! rad, min_theta_value (pi/6)
-0.03        ! m, fb thickness
\ No newline at end of file
diff --git a/quicfire_tools/input-templates/v5.1.1/Runtime_Advanced_User_Inputs.inp b/quicfire_tools/input-templates/v5.1.1/Runtime_Advanced_User_Inputs.inp
deleted file mode 100644
index be86501..0000000
--- a/quicfire_tools/input-templates/v5.1.1/Runtime_Advanced_User_Inputs.inp
+++ /dev/null
@@ -1,1 +0,0 @@
-$num_cpus  ! max number of cpu
\ No newline at end of file
diff --git a/quicfire_tools/input-templates/v5.1.1/sensor1.inp b/quicfire_tools/input-templates/v5.1.1/sensor1.inp
deleted file mode 100644
index 3713549..0000000
--- a/quicfire_tools/input-templates/v5.1.1/sensor1.inp
+++ /dev/null
@@ -1,12 +0,0 @@
-sensor1 !Site Name 
-0 !Upper level flag (1 = use this profile for upper level winds)
-50 !Upper level height (meters)
-1 !Site Coordinate Flag (1=QUIC, 2=UTM, 3=Lat/Lon)
-1 !X coordinate (meters)
-1 !Y coordinate (meters)
-$timenow !Begining of time step in Unix Epoch time (integer seconds since 1970/1/1 00:00:00)
-1 !site boundary layer flag (1 = log, 2 = exp, 3 = urban canopy, 4 = discrete data points)
-0.1 !site zo
-0. ! 1/L (default = 0)
-!Height (m),Speed	(m/s), Direction (deg relative to true N)
-2 $wind_speed $wind_direction
diff --git a/quicfire_tools/input-templates/v5.2.3/QFire_Bldg_Advanced_User_Inputs.inp b/quicfire_tools/input-templates/v5.2.3/QFire_Bldg_Advanced_User_Inputs.inp
deleted file mode 100755
index 6f44eeb..0000000
--- a/quicfire_tools/input-templates/v5.2.3/QFire_Bldg_Advanced_User_Inputs.inp
+++ /dev/null
@@ -1,8 +0,0 @@
-1			! N/A, flag to convert QUIC-URB buildings to fuel (0 = no, 1 = yes)
-0.5		! kg/m3, thin fuel density within buildings (if no fuel is specified)
-2.			! N/A, attenuation coefficient within buildings
-0.1	   ! m, surface roughness within buildings
-1			! N/A, flag to convert fuel to canopy for winds (0 = no, 1 = yes)
-1			! N/A, update canopy winds when fuel is consumed (0 = no, 1 = yes)
-1			! N/A, attenuation coefficient within fuel for the Cionco profile (default = 1)
-0.1	   ! m, surface roughness within fuel (default = 0.1 m)
diff --git a/quicfire_tools/input-templates/v5.2.3/QFire_Plume_Advanced_User_Inputs.inp b/quicfire_tools/input-templates/v5.2.3/QFire_Plume_Advanced_User_Inputs.inp
deleted file mode 100755
index a1d2b25..0000000
--- a/quicfire_tools/input-templates/v5.2.3/QFire_Plume_Advanced_User_Inputs.inp
+++ /dev/null
@@ -1,16 +0,0 @@
-150000				! N/A, max number of plume at each time step
-0.1				! m/s, minimum vertical velocity of a plume. If wc is below minimum, the plume is eliminated (default 0.1 m/s)
-100				! m/s, maximum vertical velocity of a plume (default 100 m/s)
-0.1				! N/A, minimum speed ratio (plume vertical velocity/wind speed). If below, the plume is eliminated (default 0.1)
-0.					! 1/s2, brunt vaisala frequency squared
-1					! N/A creeping flag: 0 = off, 1 = on
-0					! Flag time step (0 = constant, 1 = adaptive)
-1              ! s, flag = 0: plumes time step plume, flag = 1: minimum plumes time step
-1              ! sor option (0 = reset lambda at each call, 1 = keep)
-10             ! alpha 2 - plume centerline
-2              ! alpha 2 - plume edges
-30.            ! deg, max angle between plumes to merging
-0.7            ! N/A, fraction of overlap of plumes for merging 
-1              ! N/A, which wplume-to-grid scheme: 0 = new, 1 = old
-10             ! N/A, number of points per edge for new scheme (only new scheme)
-1              ! N/A, w computation: 1 = max(w), 0 = sum(w^3)
diff --git a/quicfire_tools/input-templates/v5.2.3/QUIC_fire.inp b/quicfire_tools/input-templates/v5.2.3/QUIC_fire.inp
deleted file mode 100644
index 07bfe9a..0000000
--- a/quicfire_tools/input-templates/v5.2.3/QUIC_fire.inp
+++ /dev/null
@@ -1,43 +0,0 @@
-1					! Fire flag: 1 = run fire; 0 = no fire
--1				    ! Random number generator: -1: use time and date, any other integer > 0 is used as the seed
-! FIRE TIMES
-$timenow		    ! When the fire is ignited in Unix Epoch time (integer seconds since 1970/1/1 00:00:00). Must be greater or equal to the time of the first wind
-$sim_time			! Total simulation time for the fire [s]
-1					! time step for the fire simulation [s]
-1					! Number of fire time steps done before updating the quic wind field (integer, >= 1)
-$output_time		! After how many fire time steps to print out fire-related files (excluding emissions and radiation)
-$output_time		! After how many quic updates to print out wind-related files
-$output_time		! After how many fire time steps to average emissions and radiation
-$output_time		! After how many quic updates to print out averaged wind-related files
-! FIRE GRID
-$nz					! Number of vertical layers of fire grid cells (integer)
-0					! Vertical stretching flag: 0 = uniform dz, 1 = custom
-$dz                 ! m, dz
-! FILE PATH
-""
-1                   ! Fuel types are in separate files
-2                   ! File is stream (1) or headers (2)
-! FUEL
-$fuel_flag		    ! fuel density flag: 1 = uniform; 2 = provided thru QF_FuelDensity.inp, 3 = Firetech files for quic grid, 4 = Firetech files for different grid (need interpolation)    $fuel_density
-$fuel_flag		    ! fuel moisture flag: 1 = uniform; 2 = provided thru QF_FuelMoisture.inp, 3 = Firetech files for quic grid, 4 = Firetech files for different grid (need interpolation)  $fuel_moisture $fuel_height_flag
-! IGNITION LOCATIONS
-$ignition_flag      ! 1 = rectangle, 2 = square ring, 3 = circular ring, 4 = file (QF_Ignitions.inp), 5 = time-dependent ignitions (QF_IgnitionPattern.inp), 6 = ignite.dat (firetech)      $ignition_locations
-2                   ! number of ignitions
-! FIREBRANDS
-0				    ! 0 = off, 1 = on
-! OUTPUT FILES (formats depend on the grid type flag)
-1					! Output gridded energy-to-atmosphere (3D fire grid + extra layers)
-0					! Output compressed array reaction rate (fire grid)
-1					! Output compressed array fuel density (fire grid)
-1					! Output gridded wind (u,v,w,sigma) (3D fire grid)
-1					! Output gridded QU winds with fire effects, instantaneous (QUIC-URB grid)
-0					! Output gridded QU winds with fire effects, averaged (QUIC-URB grid)
-0					! Output plume trajectories (ONLY FOR DEBUG)
-1					! Output compressed array fuel moisture (fire grid)
-1					! Output vertically-integrated % mass burnt (fire grid)
-0					! Output trajectories firebrands
-0					! Output compressed array emissions (fire grid)
-0					! Output gridded thermal radiation (fire grid)
-0                   ! Output surface fire intensity at every fire time step
-! AUTOKILL
-$auto_kill          ! Kill if the fire is out and there are no more ignitions or firebrands (0 = no, 1 = yes)
\ No newline at end of file
diff --git a/quicfire_tools/input-templates/v5.2.3/QU_TopoInputs.inp b/quicfire_tools/input-templates/v5.2.3/QU_TopoInputs.inp
deleted file mode 100644
index 87c1cfc..0000000
--- a/quicfire_tools/input-templates/v5.2.3/QU_TopoInputs.inp
+++ /dev/null
@@ -1,11 +0,0 @@
-Specify file name for custom topo (full path)
-"topo.dat"
-$topo_flag     ! N/A, topo flag: 0 = flat, 1 = Gaussian hill, 2 = hill pass, 3 = slope mesa, 4 = canyon, 5 = custom, 6 = half circle, 7 = sinusoid, 8 = cos hill, 9 = QP_elevation.inp, 10 = terrainOutput.txt (ARA), 11 = terrain.dat (firetec)
-1     ! N/A, smoothing method (0 = none (default for idealized terrain), 1 = blur, 2 = David's)
-200     ! N/A, number of smoothing passes
-200   ! N/A, number of initial SOR iterations (only if fire is run)
-1     ! N/A, sor cycles
-0.7   ! N/A, sor relaxation parameter (default for flat is 1.78, ignored if there is no terrain)
-0     ! N/A, add slope flow correction (0 = no, 1 = yes)
-Command to run slope flow code (system specific)
-""
diff --git a/quicfire_tools/input-templates/v5.2.3/QU_buildings.inp b/quicfire_tools/input-templates/v5.2.3/QU_buildings.inp
deleted file mode 100755
index 6dd3867..0000000
--- a/quicfire_tools/input-templates/v5.2.3/QU_buildings.inp
+++ /dev/null
@@ -1,4 +0,0 @@
-!QUIC 6.26
-0.1			!Wall roughness length (m)
-0			!Number of Buildings
-0			!Number of Polygon Building Nodes
diff --git a/quicfire_tools/input-templates/v5.2.3/QU_simparams.inp b/quicfire_tools/input-templates/v5.2.3/QU_simparams.inp
deleted file mode 100755
index 400ed26..0000000
--- a/quicfire_tools/input-templates/v5.2.3/QU_simparams.inp
+++ /dev/null
@@ -1,67 +0,0 @@
-!QUIC 6.26
-$nx !nx - Domain Length(X) Grid Cells
-$ny !ny - Domain Width(Y) Grid Cells
-32 ! NZ - domain height(Z) grid cells
-$dx ! DX [m]
-$dy ! DY [m]
-3 !Vertical stretching flag (0 = uniform, 1 = custom, 2 = parabolic Z, 3 = parabolic DZ, 4 = exponential)
-1.000000 ! Surface DZ [m]
-5 ! Number of uniform surface cells
-! DZ array [m]
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.078399
-1.313596
-1.705591
-2.254385
-2.959976
-3.822366
-4.841553
-6.017539
-7.350323
-8.839905
-10.486285
-12.289463
-14.249439
-16.366213
-18.639786
-21.070156
-23.657325
-26.401292
-29.302056
-32.354352
-35.354352
-38.354352
-41.354352
-44.354352
-47.354352
-50.354352
-53.354352
-1 ! Number of time increments
-0 ! UTC conversion [hours]
-! Begining of time step in Unix epoch time [integer seconds since 1970/1/1 00:00:00]
-$timenow
-2 ! Rooftop flag (0 = none, 1 = log profile, 2 = vortex)
-3 ! Upwind cavity flag (0 = none, 1 = Rockle, 2 = MVP, 3 = HMVP)
-4 ! Street canyon flag (0 = none, 1 = Roeckle, 2 = CPB, 3 = exp. param. PKK, 4 = Roeckle w/ Fackrel)
-1 ! Street intersection flag (0 = off, 1 = on)
-4 ! Wake flag (0 = none, 1 = Rockle, 2 = modified Rockle, 3 = area scaled)
-1 ! Sidewall flag (0 = off, 1 = on)
-1 ! Individual tree wake flag
-2 ! Canopy flag (0 = off, 1 = Cionco w/o wakes, 2 = Cionco w/ wakes)
-1 ! Season flag (1 = Summer, 2 = Winter, 3 = Transition)
-10 ! Maximum number of iterations
-3 ! Residual reduction (Orders of Magnitude)
-0 ! Use diffusion algorithm (0 = off, 1 = on)
-20 ! Number of diffusion iterations
-0 ! Domain rotation relative to true north [degrees] (cw = +)
-0.0 ! UTMX of domain origin [m]
-0.0 ! UTMY of domain origin [m]
-1 ! UTM zone
-17 ! UTM zone leter (1 = A, 2 = B, etc.)
-0 ! QUIC-CFD Flag
-0 ! Explosive building damage flag (1 = on)
-0 ! Building Array Flag (1 = on)
diff --git a/quicfire_tools/input-templates/v5.2.3/Runtime_Advanced_User_Inputs.inp b/quicfire_tools/input-templates/v5.2.3/Runtime_Advanced_User_Inputs.inp
deleted file mode 100755
index 58f4b83..0000000
--- a/quicfire_tools/input-templates/v5.2.3/Runtime_Advanced_User_Inputs.inp
+++ /dev/null
@@ -1,2 +0,0 @@
-$num_cpus  ! max number of cpu threads used
-0  ! Use Adaptive Computation Window (0=Disabled 1=Enabled)
diff --git a/quicfire_tools/input-templates/v5.2.3/gridlist b/quicfire_tools/input-templates/v5.2.3/gridlist
deleted file mode 100644
index 4facaff..0000000
--- a/quicfire_tools/input-templates/v5.2.3/gridlist
+++ /dev/null
@@ -1,8 +0,0 @@
-n=$nx
-m=$ny 
-l=$nz
-aa1=$dz
-nv=8
-dx=$dx
-dy=$dy
-dz=$dz
diff --git a/quicfire_tools/input-templates/v5.2.3/sensor1.inp b/quicfire_tools/input-templates/v5.2.3/sensor1.inp
deleted file mode 100644
index 3713549..0000000
--- a/quicfire_tools/input-templates/v5.2.3/sensor1.inp
+++ /dev/null
@@ -1,12 +0,0 @@
-sensor1 !Site Name 
-0 !Upper level flag (1 = use this profile for upper level winds)
-50 !Upper level height (meters)
-1 !Site Coordinate Flag (1=QUIC, 2=UTM, 3=Lat/Lon)
-1 !X coordinate (meters)
-1 !Y coordinate (meters)
-$timenow !Begining of time step in Unix Epoch time (integer seconds since 1970/1/1 00:00:00)
-1 !site boundary layer flag (1 = log, 2 = exp, 3 = urban canopy, 4 = discrete data points)
-0.1 !site zo
-0. ! 1/L (default = 0)
-!Height (m),Speed	(m/s), Direction (deg relative to true N)
-2 $wind_speed $wind_direction
diff --git a/quicfire_tools/inputs.py b/quicfire_tools/inputs.py
index 057a0ab..0f7aaab 100644
--- a/quicfire_tools/inputs.py
+++ b/quicfire_tools/inputs.py
@@ -3,234 +3,2179 @@
 """
 from __future__ import annotations
 
+
 # Core Imports
+import json
 import time
+import importlib.resources
 from pathlib import Path
 from string import Template
+from typing import Literal
+
+# External Imports
+import numpy as np
+from pydantic import (
+    BaseModel,
+    Field,
+    NonNegativeFloat,
+    NonNegativeInt,
+    PositiveFloat,
+    PositiveInt,
+    computed_field,
+    field_validator,
+    SerializeAsAny,
+)
+
+# Internal imports
+from quicfire_tools.ignitions import (
+    IgnitionSources,
+    CircularRingIgnition,
+    IgnitionType,
+    RectangleIgnition,
+    SquareRingIgnition,
+    default_line_ignition,
+)
+from quicfire_tools.topography import (
+    TopoSources,
+    CanyonTopo,
+    CosHillTopo,
+    GaussianHillTopo,
+    HalfCircleTopo,
+    HillPassTopo,
+    SinusoidTopo,
+    SlopeMesaTopo,
+    TopoType,
+)
+from quicfire_tools.utils import compute_parabolic_stretched_grid
 
-# Internal Imports
-from quicfire_tools.parameters import SimulationParameters
+
+DOCS_PATH = (
+    importlib.resources.files("quicfire_tools")
+    .joinpath("inputs")
+    .joinpath("documentation")
+)
+TEMPLATES_PATH = (
+    importlib.resources.files("quicfire_tools").joinpath("inputs").joinpath("templates")
+)
 
 
 class SimulationInputs:
     """
-    Input Module
+    Class representing a QUIC-Fire input file deck.
+
+    This is the fundamental class in the quicfire_tools.inputs module. It is
+    used to create, modify, and write QUIC-Fire input file decks. It is also
+    used to read in existing QUIC-Fire input file decks.
     """
 
-    def __init__(self, directory: Path | str):
-        if isinstance(directory, str):
-            path = Path(directory)
-            directory = path.resolve()
+    _required_inputs: list[str] = ["QUIC_fire", "QU_simparams", "gridlist"]
+
+    def __init__(self, input_files: list[InputFile]):
+        # Validate that all required input files are present
+        input_file_names = [input_file.name for input_file in input_files]
+        for required_input in self._required_inputs:
+            if required_input not in input_file_names:
+                raise ValueError(f"Missing required input file: {required_input}")
+
+        # Initialize a dictionary of input files
+        self._inputs = {i.name: i for i in input_files}
+
+    def list_inputs(self) -> list[str]:
+        """
+        List all input files by name in the SimulationInputs object.
 
-        directory.mkdir(parents=True, exist_ok=True)
-        self.directory = directory
+        Returns
+        -------
+        list[str]
+            List of input file names.
+        """
+        return list(self._inputs.keys())
 
-    def setup_input_files(self, params):
+    def get_input(self, input_name: str) -> InputFile:
         """
-        Populates input file templates with user defined parameters
+        Retrieve an input file object by name from the SimulationInputs object.
 
         Parameters
         ----------
-        params: SimulationParameters
-            Dictionary of user defined parameters.
+        input_name: str
+            Name of the input file to retrieve.
 
         Returns
         -------
-        None:
-            Sets up simulation files in the simulation directory.
+        InputFile
+            Input file object.
+        """
+        return self._inputs[input_name]
 
+    def write_inputs(self, directory: str | Path, version: str = "latest") -> None:
         """
-        # Convert params to dict
-        params = params.to_dict()
+        Write all input files in the SimulationInputs object to a specified
+        directory.
 
-        # Get current unix time
-        params["timenow"] = int(time.time())
+        This method is the core method of the SimulationInputs class. It
+        is the principle way to translate a SimulationInputs object into a
+        QUIC-Fire input file deck.
 
-        # Write fuels data
-        (params["fuel_density"], params["fuel_moisture"],
-         params["fuel_height_flag"]) = self._write_fuel(params)
+        Parameters
+        ----------
+        directory: str | Path
+            Directory to write the input files to.
+        version: str
+            Version of the input files to write. Default is "latest".
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
 
-        # Write ignition data
-        params["ignition_locations"] = self._write_ignition_locations(params)
+        if not directory.exists():
+            raise NotADirectoryError(f"{directory} does not exist")
 
-        # Write input template files
-        try:
-            version = params["version"]
-        except KeyError:
-            version = "latest"
-        template_files_path = Path(
-            __file__).parent / "input-templates" / version
-        template_files_list = template_files_path.glob("*")
-        for fname in template_files_list:
-            self._fill_form_with_dict(fname, params)
+        # Skip writing gridlist and rasterorigin if fuel_flag == 1
+        skip_inputs = []
+        quic_fire: QUIC_fire = self.get_input("QUIC_fire")
+        if quic_fire.fuel_flag == 1:
+            skip_inputs.extend(["gridlist", "rasterorigin"])
 
-    @staticmethod
-    def _write_fuel(params: dict) -> tuple[str, str, str]:
+        # Write each input file to the output directory
+        for input_name in self.list_inputs():
+            if input_name in skip_inputs:
+                continue
+            input_file = self.get_input(input_name)
+            input_file.to_file(directory, version=version)
+
+        # Copy QU_landuse from the template directory to the output directory
+        template_file_path = TEMPLATES_PATH / version / "QU_landuse.inp"
+        output_file_path = directory / "QU_landuse.inp"
+        with open(template_file_path, "rb") as ftemp:
+            with open(output_file_path, "wb") as fout:
+                fout.write(ftemp.read())
+
+    @classmethod
+    def setup_simulation(
+        cls,
+        nx: int,
+        ny: int,
+        fire_nz: int,
+        simulation_time: int,
+        wind_speed: float,
+        wind_direction: float,
+        fuel_flag: int,
+        ignition_type: IgnitionType,
+        topo_type: TopoType,
+        fuel_density: float = None,
+        fuel_moisture: float = None,
+        fuel_height: float = None,
+        quic_nz: int = 22,
+        quic_height: float = 300,
+        dx: float = 2,
+        dy: float = 2,
+        fire_dz: float = 1,
+        output_time: int = 30,
+    ):
         """
-        Writes fuel data to the QUIC_fire.inp input file. This function
+        Creates a SimulationInputs object to build a QUIC-Fire input file deck
+        and run a simulation.
 
         Parameters
         ----------
-        params: dict
-            Dictionary of user defined parameters.
+        nx: int
+            Number of cells in the x-direction [-]
+        ny: int
+            Number of cells in the y-direction [-]
+        fire_nz: int
+            Number of cells in the z-direction for the fire grid [-]
+        simulation_time: int
+            Number of seconds to run the simulation for [s]
+        wind_speed: float
+            Wind speed [m/s]
+        wind_direction: float
+            Wind direction [deg]. 0 deg is north, 90 deg is east, etc. Must
+            be in range [0, 360).
+        ignition_type: IgnitionType
+            Ignition type specified as an IgnitionsType class from ignitions.py
+            1 = rectangle
+            2 = square ring
+            3 = circular ring
+            6 = ignite.dat (Firetec file)
+        topo_type : TopoType
+            Topography type specified as a TopoType class from topography.py
+            0 = no terrain file provided, QUIC-Fire is run with flat terrain
+            1 = Gaussian hill
+            2 = hill pass
+            3 = slope mesa
+            4 = canyon
+            5 = custom
+            6 = half circle
+            7 = sinusoid
+            8 = cos hill
+            9 = terrain is provided via QP_elevation.bin (see Section 2.7)
+            10 = terrain is provided via terrainOutput.txt
+            11 = terrain.dat (firetec)
+        fuel_flag: int
+            Flag defning fuel input source [-]
+        quic_nz: int
+            Number of cells in the z-direction for the QUIC grid [-]
+        quic_height: float
+            Height of the QUIC grid [m]. Determines the cell size in the z-direction
+            for the QUIC grid. Must be 3 * the height of maximum elevation and tallest fuels.
+            See utils.calculate_quic_height
+        dx: float
+            Cell size in the x-direction [m]
+        dy: float
+            Cell size in the y-direction [m]
+        fire_dz: float
+            Cell size in the z-direction for the fire grid [m]
+        output_time: int
+            Number of seconds between output files [s]
+        fuel_density: float
+            Fuel density for uniform fuels [kg/m**3]
+        fuel_moisture: float
+            Fuel moisture for uniform fuels [-]
+        fuel_height: float
+            Surface fuel height for uniform fuels [m]
 
         Returns
         -------
-        None:
-            Writes fuel data to the fuel_data.inp file.
+        SimulationInputs
+            Class containing the inputs to build a QUIC-Fire
+            input file deck and run a simulation.
+        """
+        return cls(
+            cls.initialize_inputs(
+                nx,
+                ny,
+                fire_nz,
+                quic_nz,
+                quic_height,
+                dx,
+                dy,
+                fire_dz,
+                wind_speed,
+                wind_direction,
+                simulation_time,
+                output_time,
+                ignition_type,
+                topo_type,
+                fuel_flag,
+                fuel_density,
+                fuel_moisture,
+                fuel_height,
+            )
+        )
 
+    @classmethod
+    def setup_simple_simulation(
+        cls,
+        nx: int,
+        ny: int,
+        simulation_time: int,
+        wind_speed: float,
+        wind_direction: float,
+        fire_nz: int = 1,
+        quic_nz: int = 22,
+        quic_height: float = 300,
+        dx: float = 2,
+        dy: float = 2,
+        fire_dz: float = 1,
+        output_time: int = 30,
+        topo_flag: int = 0,
+        fuel_flag: int = 1,
+        fuel_density: float = 0.6,
+        fuel_moisture: float = 0.5,
+        fuel_height: float = 1,
+    ):
         """
-        # Get data from params
-        fuel_flag = params["fuel_flag"]
+        Creates a SimulationInputs object with default inputs to
+        build a QUIC-Fire input file deck and run a simulation
+        with flat terrain and uniform fuels and a line ignition.
 
-        # Uniform fuel properties
-        if fuel_flag == 1:
-            fuel_density = "\n" + str(params["fuel_density"])
-            fuel_moisture = "\n" + str(params["fuel_moisture"])
-            fuel_height = (f"\n{fuel_flag}    ! fuel height flag: 1 = uniform; "
-                           f"2 = provided thru QF_FuelMoisture.inp, 3 = Firetech"
-                           f" files for quic grid, 4 = Firetech files for "
-                           f"different grid (need interpolation)"
-                           f"\n{str(params['fuel_height'])}")
-
-        # Custom fuel .dat files (fuel flags 3 or 4)
-        else:
-            fuel_density, fuel_moisture, fuel_height = "", "", ""
+        Parameters
+        ----------
+        nx: int
+            Number of cells in the x-direction [-]
+        ny: int
+            Number of cells in the y-direction [-]
+        simulation_time: int
+            Number of seconds to run the simulation for [s]
+        wind_speed: float
+            Wind speed [m/s]
+        wind_direction: float
+            Wind direction [deg]. 0 deg is north, 90 deg is east, etc. Must
+            be in range [0, 360).
+        fire_nz: int
+            Number of cells in the z-direction for the fire grid [-]
+        quic_nz: int
+            Number of cells in the z-direction for the QUIC grid [-]
+        quic_height: float
+            Height of the QUIC grid [m]. Determines the cell size in the z-direction
+            for the QUIC grid. Must be 3 * the height of maximum elevation and tallest fuels.
+            See utils.calculate_quic_height
+        dx: float
+            Cell size in the x-direction [m]
+        dy: float
+            Cell size in the y-direction [m]
+        fire_dz: float
+            Cell size in the z-direction for the fire grid [m]
+        output_time: int
+            Number of seconds between output files [s]
+        ignition_flag: int
+            Flag defining ignition type [-]. See ignitions.IgnitionSources
+        topo_flag: int
+            Flag defining the topography type [-]. See topography.TopoSources
+        fuel_flag: int
+            Flag defning fuel input source [-]
+        fuel_density: float
+            Fuel density for uniform fuels [kg/m**3]
+        fuel_moisture: float
+            Fuel moisture for uniform fuels [-]
+        fuel_height: float
+            Surface fuel height for uniform fuels [m]
 
-        return fuel_density, fuel_moisture, fuel_height
+        Returns
+        -------
+        SimulationInputs
+            Class containing the default inputs to build a QUIC-Fire
+            input file deck and run a simulation on flat terrain with
+            uniform fuels and a line ignition.
+        """
+        x_min_ig, y_min_ig, x_length_ig, y_length_ig = default_line_ignition(
+            nx, ny, wind_direction
+        )
+        ignition_type = RectangleIgnition(
+            x_min=x_min_ig,
+            y_min=y_min_ig,
+            x_length=x_length_ig,
+            y_length=y_length_ig,
+        )
+
+        topo_type = TopoType(topo_flag=TopoSources(topo_flag))
 
-    def _write_ignition_locations(self, params: dict) -> str:
+        return cls(
+            cls.initialize_inputs(
+                nx,
+                ny,
+                fire_nz,
+                quic_nz,
+                quic_height,
+                dx,
+                dy,
+                fire_dz,
+                wind_speed,
+                wind_direction,
+                simulation_time,
+                output_time,
+                ignition_type,
+                topo_type,
+                fuel_flag,
+                fuel_density,
+                fuel_moisture,
+                fuel_height,
+            )
+        )
+
+    @classmethod
+    def setup_custom_simulation(
+        cls,
+        nx: int,
+        ny: int,
+        fire_nz: int,
+        simulation_time: int,
+        wind_speed: float,
+        wind_direction: float,
+        quic_nz: int = 22,
+        quic_height: float = 300,
+        dx: float = 2,
+        dy: float = 2,
+        fire_dz: float = 1,
+        output_time: int = 30,
+        ignition_flag: int = 6,
+        topo_flag: int = 5,
+        fuel_flag: int = 4,
+        fuel_density: float = None,
+        fuel_moisture: float = None,
+        fuel_height: float = None,
+    ):
         """
-        Writes ignition locations file to simulation directory if ignition flag
-        is 6. Otherwise, it writes the ignition locations to the QUIC_fire.inp
-        input file.
+        Creates a SimulationInputs object with default inputs to
+        build a QUIC-Fire input file deck and run a simulation on a
+        domain with custom fuels, topography, and ignitions.
 
         Parameters
         ----------
-        params: dict
-            Dictionary of user defined parameters.
+        nx: int
+            Number of cells in the x-direction [-]
+        ny: int
+            Number of cells in the y-direction [-]
+        fire_nz: int
+            Number of cells in the z-direction for the fire grid [-]
+        simulation_time: int
+            Number of seconds to run the simulation for [s]
+        wind_speed: float
+            Wind speed [m/s]
+        wind_direction: float
+            Wind direction [deg]. 0 deg is north, 90 deg is east, etc. Must
+            be in range [0, 360).
+        quic_nz: int
+            Number of cells in the z-direction for the QUIC grid [-]
+        quic_height: float
+            Height of the QUIC grid [m]. Determines the cell size in the z-direction
+            for the QUIC grid. Must be 3 * the height of maximum elevation and tallest fuels.
+            See utils.calculate_quic_height
+        dx: float
+            Cell size in the x-direction [m]
+        dy: float
+            Cell size in the y-direction [m]
+        fire_dz: float
+            Cell size in the z-direction for the fire grid [m]
+        output_time: int
+            Number of seconds between output files [s]
+        fuel_flag: int
+            Flag defning fuel input source [-]
+        fuel_density: float
+            Fuel density for uniform fuels [kg/m**3]
+        fuel_moisture: float
+            Fuel moisture for uniform fuels [-]
+        fuel_height: float
+            Surface fuel height for uniform fuels [m]
 
         Returns
         -------
-        ignition_locations: str
-            Data string to write to the QUIC_fire.inp input file.
-
+        SimulationInputs
+            Class containing the default inputs to build a QUIC-Fire
+            input file deck and run a simulation on a domain with custom
+            fuels, topography, and ignitions.
         """
-        if params["ignition_flag"] == 6 or params["ignition_flag"] == 7:
-            return ""
+        ignition_type = IgnitionType(ignition_flag=IgnitionSources(ignition_flag))
+        topo_type = TopoType(topo_flag=TopoSources(topo_flag))
 
-        else:  # Ignition flag 1
-            return self._write_line_fire_ignition(params)
+        return cls(
+            cls.initialize_inputs(
+                nx,
+                ny,
+                fire_nz,
+                quic_nz,
+                quic_height,
+                dx,
+                dy,
+                fire_dz,
+                wind_speed,
+                wind_direction,
+                simulation_time,
+                output_time,
+                ignition_type,
+                topo_type,
+                fuel_flag,
+                fuel_density,
+                fuel_moisture,
+                fuel_height,
+            )
+        )
 
-    @staticmethod
-    def _write_line_fire_ignition(params: dict) -> str:
-        """
-        Writes line fire ignition locations to the QUIC_fire.inp input file.
+    def initialize_inputs(
+        nx: int,
+        ny: int,
+        fire_nz: int,
+        quic_nz: int,
+        quic_height: float,
+        dx: float,
+        dy: float,
+        fire_dz: float,
+        wind_speed: float,
+        wind_direction: float,
+        simulation_time: int,
+        output_time: int,
+        ignition_type: IgnitionType,
+        topo_type: TopoType,
+        fuel_flag: int,
+        fuel_density: float,
+        fuel_moisture: float,
+        fuel_height: float,
+    ):
+        # Initialize default input files
+        raster_origin = RasterOrigin()
+        qu_bldgs = QU_Buildings()
+        qu_fileoptions = QU_Fileoptions()
+        qfire_adv_user_input = QFire_Advanced_User_Inputs()
+        qfire_bldg_inputs = QFire_Bldg_Advanced_User_Inputs()
+        qfire_plume_inputs = QFire_Plume_Advanced_User_Inputs()
+        runtime_inputs = RuntimeAdvancedUserInputs()
+        qu_movingcoords = QU_movingcoords()
+        qp_buildout = QP_buildout()
+        qu_metparams = QU_metparams()
+
+        # Initialize input files with required parameters
+        start_time = int(time.time())
+        quic_fire = QUIC_fire(
+            nz=fire_nz,
+            time_now=start_time,
+            sim_time=simulation_time,
+            ignition_type=ignition_type,
+            fuel_flag=fuel_flag,
+            fuel_density=fuel_density,
+            fuel_moisture=fuel_moisture,
+            fuel_height=fuel_height,
+            out_time_fire=output_time,
+            out_time_wind=output_time,
+            out_time_emis_rad=output_time,
+            out_time_wind_avg=output_time,
+        )
+        gridlist = Gridlist(n=nx, m=ny, l=fire_nz, dx=dx, dy=dy, dz=fire_dz, aa1=1.0)
+        wind_sensor = Sensor1(
+            time_now=start_time, wind_speed=wind_speed, wind_direction=wind_direction
+        )
+        qu_topo = QU_TopoInputs(topo_type=topo_type)
+        qu_simparams = QU_Simparams(
+            nx=nx,
+            ny=ny,
+            nz=quic_nz,
+            dx=dx,
+            dy=dy,
+            quic_domain_height=quic_height,
+        )
+
+        input_files = [
+            raster_origin,
+            qu_bldgs,
+            qu_fileoptions,
+            qfire_adv_user_input,
+            qfire_bldg_inputs,
+            qfire_plume_inputs,
+            qu_topo,
+            runtime_inputs,
+            qu_movingcoords,
+            qp_buildout,
+            qu_metparams,
+            qu_simparams,
+            quic_fire,
+            gridlist,
+            wind_sensor,
+        ]
+
+        return input_files
 
-        Line fire ignition takes the following parameters:
-        fire_source_x0: south-west corner in the x-direction
-        fire_source_y0: south-west corner in the y-direction
-        fire_source_xlen: length in the x-direction
-        fire_source_ylen: length in the y-direction
-        num_ignition_cells: number of ignition cells constant at 100
+    @classmethod
+    def from_directory(cls, directory: str | Path) -> SimulationInputs:
+        """
+        Initializes a SimulationInputs object from a directory containing a
+        QUIC-Fire input file deck.
 
         Parameters
         ----------
-        params: dict
-            Dictionary of user defined parameters.
+        directory: str | Path
+            Directory containing a QUIC-Fire input file deck.
 
         Returns
         -------
-        ignition_locations: str
-            Data string to write to the QUIC_fire.inp input file.
-        """
-        # Get data from params
-        wind_direction = params["wind_direction"]
-        nx, ny = params["nx"], params["ny"]
-        dx, dy = params["dx"], params["dy"]
-
-        # Hold number ignitions constant at 100 per documentation
-        # num_ignition_cells = 100
-
-        # Compute cardinal direction from wind direction
-        dirs = ["N", "E", "S", "W"]
-        ix = round(wind_direction / (360. / len(dirs)))
-        cardinal_direction = dirs[ix % len(dirs)]
-
-        # Ignition strip on top border
-        if cardinal_direction == "N":
-            fire_source_x0 = int(0.1 * nx * dx)
-            fire_source_y0 = int(0.9 * ny * dy) - 1
-            fire_source_xlen = int(0.8 * nx * dx)
-            fire_source_ylen = 1
-
-        # Ignition strip on left border
-        elif cardinal_direction == "W":
-            fire_source_x0 = int(0.1 * nx * dx) - 1
-            fire_source_y0 = int(0.1 * ny * dy)
-            fire_source_xlen = 1
-            fire_source_ylen = int(0.8 * ny * dy)
-
-        # Ignition strip on bottom border
-        elif cardinal_direction == "S":
-            fire_source_x0 = int(0.1 * nx * dx)
-            fire_source_y0 = int(0.1 * ny * dy) - 1
-            fire_source_xlen = int(0.8 * nx * dx)
-            fire_source_ylen = 1
-
-        # Ignition strip on right border
-        else:
-            fire_source_x0 = int(0.9 * nx * dx) - 1
-            fire_source_y0 = int(0.1 * ny * dy)
-            fire_source_xlen = 1
-            fire_source_ylen = int(0.8 * ny * dy)
+        SimulationInputs
+            Class containing the input files in the QUIC-Fire input file deck.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+        input_files = []
+        for input_file_name in cls._required_inputs:
+            input_obj = globals()[input_file_name]
+            input_file = input_obj.from_file(directory)
+            input_files.append(input_file)
+        return cls(input_files)
+
+
+class InputFile(BaseModel, validate_assignment=True):
+    """
+    Base class representing an input file.
+
+    This base class provides a common interface for all input files in order to
+    accomplish two main goals:
+    1) Return documentation for each parameter in the input file.
+    2) Provide a method to write the input file to a specified directory.
+    """
 
-        ignition_list = ["", fire_source_x0, fire_source_y0, fire_source_xlen,
-                         fire_source_ylen]
-        return "\n".join((str(x) for x in ignition_list))
+    name: str
+    _extension: str
+    _param_info: dict = None
 
-    def _fill_form_with_dict(self, template_file_path: Path, params: dict):
+    @property
+    def _filename(self):
+        return f"{self.name}{self._extension}"
+
+    @property
+    def param_info(self):
+        """
+        Return a dictionary of parameter information for the input file.
         """
-        Fills a form with a dictionary of values.
+        if self._param_info is None:  # open the file if it hasn't been read in
+            with open(DOCS_PATH / f"{self._filename}.json", "r") as f:
+                self._param_info = json.load(f)
+        return self._param_info
 
-        Parameters
-        ----------
-        template_file_path: Path
-            Path to the template file
-        params: dict
-            Dictionary of user defined parameters.
+    def list_parameters(self):
+        """List all parameters in the input file."""
+        return list(self.param_info.keys())
+
+    def get_documentation(self, parameter: str = None):
+        """
+        Retrieve documentation for a parameter. If no parameter is specified,
+        return documentation for all parameters.
+        """
+        if parameter:
+            return self.param_info.get(parameter, {})
+        else:
+            return self.param_info
+
+    def print_documentation(self, parameter: str = None):
+        """
+        Print documentation for a parameter. If no parameter is specified,
+        print documentation for all parameters.
+        """
+        if parameter:
+            info = self.get_documentation(parameter)
+        else:
+            info = self.get_documentation()
+        for key, value in info.items():
+            key = key.replace("_", " ").capitalize()
+            print(f"- {key}: {value}")
+
+    def to_dict(self):
+        """
+        Convert the object to a dictionary, excluding attributes that start
+        with an underscore.
 
         Returns
         -------
-        None:
-            Writes parameter data to the template file
+        dict
+            Dictionary representation of the object.
         """
-        output_file_path = self.directory / template_file_path.name
+        return self.model_dump(
+            exclude={"name", "_extension", "_filename", "param_info"}
+        )
+
+    def to_file(self, directory: Path, version: str = "latest"):
+        """
+        Write the input file to a specified directory.
+
+        Attributes
+        ----------
+        directory : Path
+            Directory to write the input file to.
+        version : str
+            Version of the input file to write. Default is "latest".
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+
+        template_file_path = TEMPLATES_PATH / version / f"{self._filename}"
         with open(template_file_path, "r") as ftemp:
-            with open(output_file_path, "w") as fout:
-                src = Template(ftemp.read())
-                result = src.substitute(params)
-                fout.write(result)
-
-
-if __name__ == '__main__':
-    test_params = SimulationParameters(
-        nx=100,
-        ny=100,
-        nz=1,
-        dx=1.,
-        dy=1.,
-        dz=1.,
-        wind_speed=4.,
-        wind_direction=270,
-        sim_time=60,
-        auto_kill=1,
-        num_cpus=1,
-        fuel_flag=3,
-        ignition_flag=1,
-        output_time=10,
-        topo_flag=0,
+            src = Template(ftemp.read())
+
+        result = src.substitute(self.to_dict())
+
+        output_file_path = directory / self._filename
+        with open(output_file_path, "w") as fout:
+            fout.write(result)
+
+    @classmethod
+    def from_dict(cls, data: dict):
+        return cls(**data)
+
+
+class Gridlist(InputFile):
+    """
+    Class representing the gridlist.txt file. This file contains the grid
+    information for the QUIC-Fire simulation when canopies are present.
+
+    Attributes
+    ----------
+    n : int
+        Number of cells in the x-direction [-]
+    m : int
+        Number of cells in the y-direction [-]
+    l : int
+        Number of cells in the z-direction [-]
+    dx : float
+        Cell size in the x-direction [m]
+    dy : float
+        Cell size in the y-direction [m]
+    dz : float
+        Cell size in the z-direction [m]
+    aa1 : float
+        Stretching factor for the vertical grid spacing [-]
+    """
+
+    name: str = Field("gridlist", frozen=True)
+    _extension: str = ""
+    n: PositiveInt
+    m: PositiveInt
+    l: PositiveInt
+    dx: PositiveFloat
+    dy: PositiveFloat
+    dz: PositiveFloat
+    aa1: PositiveFloat
+
+
+class RasterOrigin(InputFile):
+    """
+    Class representing the rasterorigin.txt file. This file contains the
+    coordinates of the south-west corner of the domain in UTM coordinates.
+
+    Attributes
+    ----------
+    utm_x : float
+        UTM-x coordinates of the south-west corner of domain [m]
+    utm_y : float
+        UTM-y coordinates of the south-west corner of domain [m]
+    """
+
+    name: str = Field("rasterorigin", frozen=True)
+    _extension: str = ".txt"
+    utm_x: NonNegativeFloat = 0.0
+    utm_y: NonNegativeFloat = 0.0
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        """
+        Initializes a RasterOrigin object from a directory containing a
+        rasterorigin.txt file.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "rasterorigin.txt", "r") as f:
+            lines = f.readlines()
+        return cls(utm_x=float(lines[0].split()[0]), utm_y=float(lines[1].split()[0]))
+
+
+class QU_Buildings(InputFile):
+    """
+    Class representing the QU_buildings.inp file. This file contains the
+    building-related data for the QUIC-Fire simulation. This class is not
+    currently used in QUIC-Fire.
+
+    Attributes
+    ----------
+    wall_roughness_length : float
+        Wall roughness length [m]. Must be greater than 0. Default is 0.1.
+    number_of_buildings : int
+        Number of buildings [-]. Default is 0. Not currently used in QUIC-Fire.
+    number_of_polygon_nodes : int
+        Number of polygon building nodes [-]. Default is 0. Not currently used
+        in QUIC-Fire.
+    """
+
+    name: str = Field("QU_buildings", frozen=True)
+    _extension: str = ".inp"
+    wall_roughness_length: PositiveFloat = 0.1
+    number_of_buildings: NonNegativeInt = 0
+    number_of_polygon_nodes: NonNegativeInt = 0
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        """
+        Initializes a QU_Buildings object from a directory containing a
+        QU_buildings.inp file.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "QU_buildings.inp", "r") as f:
+            lines = f.readlines()
+        return cls(
+            wall_roughness_length=float(lines[1].split()[0]),
+            number_of_buildings=int(lines[2].split()[0]),
+            number_of_polygon_nodes=int(lines[3].split()[0]),
+        )
+
+
+class QU_Fileoptions(InputFile):
+    """
+    Class representing the QU_fileoptions.inp file. This file contains
+    file output-related options for the QUIC-Fire simulation.
+
+    Attributes
+    ----------
+    output_data_file_format_flag : int
+        Output data file format flag. Values accepted are [1, 2, 3].
+        Recommended value 2. 1 - binary, 2 - ASCII, 3 - both.
+    non_mass_conserved_initial_field_flag : int
+        Flag to write out non-mass conserved initial field file uofield.dat.
+        Values accepted are [0, 1]. Recommended value 0. 0 - off, 1 - on.
+    initial_sensor_velocity_field_flag : int
+        Flag to write out the file uosensorfield.dat. Values accepted are
+        [0, 1]. Recommended value 0. 0 - off, 1 - on.
+    qu_staggered_velocity_file_flag : int
+        Flag to write out the file QU_staggered_velocity.bin. Values accepted
+        are [0, 1]. Recommended value 0. 0 - off, 1 - on.
+    generate_wind_startup_files_flag : int
+        Generate wind startup files for ensemble simulations. Values accepted
+        are [0, 1]. Recommended value 0. 0 - off, 1 - on.
+    """
+
+    name: str = Field("QU_fileoptions", frozen=True)
+    _extension: str = ".inp"
+    output_data_file_format_flag: Literal[1, 2, 3] = 2
+    non_mass_conserved_initial_field_flag: Literal[0, 1] = 0
+    initial_sensor_velocity_field_flag: Literal[0, 1] = 0
+    qu_staggered_velocity_file_flag: Literal[0, 1] = 0
+    generate_wind_startup_files_flag: Literal[0, 1] = 0
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        """
+        Initializes a QU_Fileoptions object from a directory containing a
+        QU_fileoptions.inp file.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "QU_fileoptions.inp", "r") as f:
+            lines = f.readlines()
+        return cls(
+            output_data_file_format_flag=int(lines[1].split()[0]),
+            non_mass_conserved_initial_field_flag=int(lines[2].split()[0]),
+            initial_sensor_velocity_field_flag=int(lines[3].split()[0]),
+            qu_staggered_velocity_file_flag=int(lines[4].split()[0]),
+            generate_wind_startup_files_flag=int(lines[5].split()[0]),
+        )
+
+
+class QU_Simparams(InputFile):
+    """
+    Class representing the QU_simparams.inp file. This file contains the
+    simulation parameters for the QUIC-Fire simulation.
+
+    nx : int
+        Number of cells in the x-direction [-]. Recommended value: > 100
+    ny : int
+        Number of cells in the y-direction [-]. Recommended value: > 100
+    nz : int
+        Number of cells in the z-direction [-].
+    dx : float
+        Cell size in the x-direction [m]. Recommended value: 2 m
+    dy : float
+        Cell size in the y-direction [m]. Recommended value: 2 m
+    quic_domain_height : float
+        QUIC domain height [m]. Recommended value: 300 m
+    surface_vertical_cell_size : float
+        Surface vertical cell size [m].
+    number_surface_cells : int
+        Number of uniform surface cells [-].
+    stretch_grid_flag : int
+        Vertical grid stretching flag, values accepted [0, 1, 3]. Default is 3.
+        0 - uniform, 1 - custom, 3 - parabolic. If stretch_grid_flag is 0 or 3
+        dz_array is computed from nz, surface_vertical_cell_size, and
+        number_surface_cells. If stretch_grid_flag is 1, custom_dz_array must
+        be provided.
+    custom_dz_array : list[float]
+        Vertical grid spacing array [m]. Must be provided if stretch_grid_flag
+        is 1. If stretch_grid_flag is 0 or 3, dz_array is computed from nz,
+        surface_vertical_cell_size, and number_surface_cells.
+    utc_offset : int
+        Hours difference from UTC (aka UTM) [h]
+    wind_times : list[int]
+        List of times at which the winds are available in Unix Epoch time
+        (integer seconds since 1970/1/1 00:00:00). These are UTC times.
+        Defaults to [int(time.time())] if not provided.
+    sor_iter_max : int
+        Maximum number of iterations of the SOR wind solver. Recommended value:
+        10. Default is 10.
+    sor_residual_reduction : int
+        Residual reduction to assess convergence of the SOR solver (orders of
+        magnitude). Recommended value: 3. Default is 3.
+    use_diffusion_flag : int
+        Use diffusion algorithm: 0 = off, 1 = on. Recommended value: 0.
+        Default is 0.
+    number_diffusion_iterations : int
+        Number of diffusion iterations. Recommended value: 10. Default is 10.
+    domain_rotation : float
+        Domain rotation relative to true north (clockwise is positive)
+        [degrees]. Recommended value: 0 deg. Default is 0.
+    utm_x : float
+        UTM-x coordinates of the south-west corner of domain [m]. Default is 0.
+    utm_y : float
+        UTM-y coordinates of the south-west corner of domain [m]. Default is 0.
+    utm_zone_number : int
+        UTM zone number [-]. Default is 1.
+    utm_zone_letter : int
+        UTM zone letter (A=1, B=2, ...) [-]. Default is 1.
+    quic_cfd_flag : int
+        QUIC-CFD flag: 0 = off, 1 = on. Recommended value: 0. Default is 0.
+    explosive_bldg_flag : int
+        Explosive building damage flag: 0 = off, 1 = on. Recommended value: 0.
+        Default is 0.
+    bldg_array_flag : int
+        Building array flag. 0 = off, 1 = on. Recommended value: 0. Default is
+        0.
+    """
+
+    name: str = Field("QU_simparams", frozen=True)
+    _extension: str = ".inp"
+    nx: PositiveInt
+    ny: PositiveInt
+    nz: PositiveInt
+    dx: PositiveFloat
+    dy: PositiveFloat
+    quic_domain_height: PositiveFloat
+    surface_vertical_cell_size: PositiveFloat = 1.0
+    number_surface_cells: PositiveInt = 5
+    stretch_grid_flag: Literal[0, 1, 3] = 3
+    custom_dz_array: list[PositiveFloat] = []
+    utc_offset: int = 0
+    wind_times: list[int] = [int(time.time())]
+    sor_iter_max: PositiveInt = 10
+    sor_residual_reduction: PositiveInt = 3
+    use_diffusion_flag: Literal[0, 1] = 0
+    number_diffusion_iterations: PositiveInt = 10
+    domain_rotation: float = 0.0
+    utm_x: float = 0.0
+    utm_y: float = 0.0
+    utm_zone_number: PositiveInt = 1
+    utm_zone_letter: PositiveInt = 1
+    quic_cfd_flag: Literal[0, 1] = 0
+    explosive_bldg_flag: Literal[0, 1] = 0
+    bldg_array_flag: Literal[0, 1] = 0
+    _from_file: bool = False
+    _from_file_dz_array: list[PositiveFloat] = []
+
+    @computed_field
+    @property
+    def _dz_array(self) -> list[float]:
+        if self._from_file:
+            return self._from_file_dz_array
+        elif self.stretch_grid_flag == 0:
+            return [self.surface_vertical_cell_size] * self.nz
+        elif self.stretch_grid_flag == 1:
+            return self.custom_dz_array
+        elif self.stretch_grid_flag == 3:
+            return compute_parabolic_stretched_grid(
+                self.surface_vertical_cell_size,
+                self.number_surface_cells,
+                self.nz,
+                self.quic_domain_height,
+            ).tolist()
+
+    @computed_field
+    @property
+    def _vertical_grid_lines(self) -> str:
+        """
+        Parses the vertical grid stretching flag and dz_array to generate the
+        vertical grid as a string for the QU_simparams.inp file.
+
+        Also modifies dz_array if stretch_grid_flag is not 1.
+        """
+        stretch_grid_func_map = {
+            0: self._stretch_grid_flag_0,
+            1: self._stretch_grid_flag_1,
+            3: self._stretch_grid_flag_3,
+        }
+        return stretch_grid_func_map[self.stretch_grid_flag]()
+
+    @computed_field
+    @property
+    def _wind_time_lines(self) -> str:
+        return self._generate_wind_time_lines()
+
+    def _stretch_grid_flag_0(self):
+        """
+        Generates a uniform vertical grid as a string for the QU_simparams.inp
+        file. Adds the uniform grid to dz_array.
+        """
+        # Create the lines for the uniform grid
+        surface_dz_line = (
+            f"{float(self.surface_vertical_cell_size)}\t" f"! Surface DZ [m]"
+        )
+        number_surface_cells_line = (
+            f"{self.number_surface_cells}\t" f"! Number of uniform surface cells"
+        )
+
+        return f"{surface_dz_line}\n{number_surface_cells_line}"
+
+    def _stretch_grid_flag_1(self):
+        """
+        Generates a custom vertical grid as a string for the QU_simparams.inp
+        file.
+        """
+        # Verify that dz_array is not empty
+        if not self._dz_array:
+            raise ValueError(
+                "dz_array must not be empty if stretch_grid_flag "
+                "is 1. Please provide a custom_dz_array with nz "
+                "elements or use a different stretch_grid_flag."
+            )
+
+        # Verify that nz is equal to the length of dz_array
+        if self.nz != len(self._dz_array):
+            raise ValueError(
+                f"nz must be equal to the length of dz_array. "
+                f"{self.nz} != {len(self._dz_array)}"
+            )
+
+        # Verify that the first number_surface_cells_line elements of dz_array
+        # are equal to the surface_vertical_cell_size
+        for dz in self._dz_array[: self.number_surface_cells]:
+            if dz != self.surface_vertical_cell_size:
+                raise ValueError(
+                    "The first number_surface_cells_line "
+                    "elements of dz_array must be equal to "
+                    "surface_vertical_cell_size"
+                )
+
+        # Write surface vertical cell size line
+        surface_dz_line = (
+            f"{float(self.surface_vertical_cell_size)}\t! " f"Surface DZ [m]"
+        )
+
+        # Write header line
+        header_line = "! DZ array [m]"
+
+        # Write dz_array lines
+        dz_array_lines_list = []
+        for dz in self._dz_array:
+            dz_array_lines_list.append(f"{float(dz)}")
+        dz_array_lines = "\n".join(dz_array_lines_list)
+
+        return f"{surface_dz_line}\n{header_line}\n{dz_array_lines}"
+
+    def _stretch_grid_flag_3(self):
+        """
+        Generates a vertical grid for stretch_grid_flag 3 as a string for the
+        QU_simparams.inp file. Stretch grid flag 3 is a stretching with
+        parabolic vertical cell size. Adds the parabolic grid to dz_array.
+        """
+        # Write surface vertical cell size line
+        surface_dz_line = (
+            f"{float(self.surface_vertical_cell_size)}\t! " f"Surface DZ [m]"
+        )
+
+        # Write number of surface cells line
+        number_surface_cells_line = (
+            f"{self.number_surface_cells}\t! " f"Number of uniform surface cells"
+        )
+
+        # Write header line
+        header_line = "! DZ array [m]"
+
+        # Write dz_array lines
+        dz_lines = "\n".join([f"{float(dz)}" for dz in self._dz_array])
+
+        return (
+            f"{surface_dz_line}\n{number_surface_cells_line}\n{header_line}"
+            f"\n{dz_lines}"
+        )
+
+    def _generate_wind_time_lines(self):
+        """
+        Parses the utc_offset and wind_step_times to generate the wind times
+        as a string for the QU_simparams.inp file.
+        """
+        # Verify that wind_step_times is not empty
+        if not self.wind_times:
+            raise ValueError(
+                "wind_step_times must not be empty. Please "
+                "provide a wind_step_times with num_wind_steps "
+                "elements or use a different num_wind_steps."
+            )
+
+        # Write number of time increments line
+        number_time_increments_line = (
+            f"{len(self.wind_times)}\t" f"! Number of time increments"
+        )
+
+        # Write utc_offset line
+        utc_offset_line = f"{self.utc_offset}\t! UTC offset [hours]"
+
+        # Write header line
+        header_line = "! Wind step times [s]"
+
+        # Write wind_step_times lines
+        wind_step_times_lines_list = []
+        for wind_time in self.wind_times:
+            wind_step_times_lines_list.append(f"{wind_time}")
+        wind_step_times_lines = "\n".join(wind_step_times_lines_list)
+
+        return "\n".join(
+            [
+                number_time_increments_line,
+                utc_offset_line,
+                header_line,
+                wind_step_times_lines,
+            ]
+        )
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        """
+        Initializes a QU_Simparams object from a directory containing a
+        QU_simparams.inp file.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+
+        with open(directory / "QU_simparams.inp", "r") as f:
+            lines = f.readlines()
+
+        # Read QU grid parameters
+        nx = int(lines[1].strip().split("!")[0])
+        ny = int(lines[2].strip().split("!")[0])
+        nz = int(lines[3].strip().split("!")[0])
+        dx = float(lines[4].strip().split("!")[0])
+        dy = float(lines[5].strip().split("!")[0])
+
+        # Read stretch grid flag
+        stretch_grid_flag = int(lines[6].strip().split("!")[0])
+
+        # Read vertical grid lines as function of stretch grid flag
+        _from_file_dz_array = []
+        custom_dz_array = []
+        if stretch_grid_flag == 0:
+            surface_vertical_cell_size = float(lines[7].strip().split("!")[0])
+            number_surface_cells = int(lines[8].strip().split("!")[0])
+            current_line = 9
+        elif stretch_grid_flag == 1:
+            surface_vertical_cell_size = float(lines[7].strip().split("!")[0])
+            number_surface_cells = 5
+            for i in range(9, 9 + nz):
+                custom_dz_array.append(float(lines[i].strip().split("!")[0]))
+            current_line = 9 + nz
+        elif stretch_grid_flag == 3:
+            surface_vertical_cell_size = float(lines[7].strip().split("!")[0])
+            number_surface_cells = int(lines[8].strip().split("!")[0])
+            _ = lines[9].strip().split("!")[0]
+            for i in range(10, 10 + nz):
+                _from_file_dz_array.append(float(lines[i].strip().split("!")[0]))
+            current_line = 10 + nz
+        else:
+            raise ValueError("stretch_grid_flag must be 0, 1, or 3.")
+
+        # Read QU wind parameters
+        number_wind_steps = int(lines[current_line].strip().split("!")[0])
+        utc_offset = int(lines[current_line + 1].strip().split("!")[0])
+        _ = lines[current_line + 2].strip().split("!")[0]
+        wind_times = []
+        for i in range(current_line + 3, current_line + 3 + number_wind_steps):
+            wind_times.append(int(lines[i].strip()))
+        current_line = current_line + 3 + number_wind_steps
+
+        # Skip not used parameters
+        current_line += 9
+
+        # Read remaining QU parameters
+        sor_iter_max = int(lines[current_line].strip().split("!")[0])
+        sor_residual_reduction = int(lines[current_line + 1].strip().split("!")[0])
+        use_diffusion_flag = int(lines[current_line + 2].strip().split("!")[0])
+        number_diffusion_iterations = int(lines[current_line + 3].strip().split("!")[0])
+        domain_rotation = float(lines[current_line + 4].strip().split("!")[0])
+        utm_x = float(lines[current_line + 5].strip().split("!")[0])
+        utm_y = float(lines[current_line + 6].strip().split("!")[0])
+        utm_zone_number = int(lines[current_line + 7].strip().split("!")[0])
+        utm_zone_letter = int(lines[current_line + 8].strip().split("!")[0])
+        quic_cfd_flag = int(lines[current_line + 9].strip().split("!")[0])
+        explosive_bldg_flag = int(lines[current_line + 10].strip().split("!")[0])
+        bldg_array_flag = int(lines[current_line + 11].strip().split("!")[0])
+
+        return cls(
+            nx=nx,
+            ny=ny,
+            nz=nz,
+            dx=dx,
+            dy=dy,
+            surface_vertical_cell_size=surface_vertical_cell_size,
+            number_surface_cells=number_surface_cells,
+            stretch_grid_flag=stretch_grid_flag,
+            custom_dz_array=custom_dz_array,
+            utc_offset=utc_offset,
+            wind_times=wind_times,
+            sor_iter_max=sor_iter_max,
+            sor_residual_reduction=sor_residual_reduction,
+            use_diffusion_flag=use_diffusion_flag,
+            number_diffusion_iterations=number_diffusion_iterations,
+            domain_rotation=domain_rotation,
+            utm_x=utm_x,
+            utm_y=utm_y,
+            utm_zone_number=utm_zone_number,
+            utm_zone_letter=utm_zone_letter,
+            quic_cfd_flag=quic_cfd_flag,
+            explosive_bldg_flag=explosive_bldg_flag,
+            bldg_array_flag=bldg_array_flag,
+            _from_file=True,
+            _from_file_dz_array=_from_file_dz_array,
+        )
+
+
+class QFire_Advanced_User_Inputs(InputFile):
+    """
+    Class representing the QFire_Advanced_User_Inputs.inp input file. This file
+    contains advanced parameters related to firebrands.
+
+    Attributes
+    ----------
+    fraction_cells_launch_firebrands : PositiveFloat
+        Fraction of cells that could launch firebrand tracers from which
+        firebrand tracers will actually be launched [-]. Higher value = more
+        firebrand tracers. Recommended value: 0.05
+    firebrand_radius_scale_factor : PositiveFloat
+        Multiplicative factor used to relate the length scale of the mixing
+        (firebrand distribution entrainment length scale) to the initial size
+        of the distribution [-]. Higher value = higher growth rate or RT
+        (firebrand distribution) with flight time. Recommended value: 40
+    firebrand_trajectory_time_step : PositiveInt
+        Time step used to determine the firebrand tracer trajectory [s].
+        Higher value = less accurate trajectory. Recommended value: 1 s
+    firebrand_launch_interval : PositiveInt
+        Time interval between launching of firebrand tracers [s]. Higher value =
+        less firebrand tracers launched. Recommended value: 10 s
+    firebrands_per_deposition : PositiveInt
+        Number of firebrand tracers that one firebrand tracer launched
+        represents [-]. Recommended value: 500
+    firebrand_area_ratio : PositiveFloat
+        Multiplicative factor used to relate the cell area and fraction of cells
+        from which tracers are launched to initial area represented by one
+        firebrand [-].
+    minimum_burn_rate_coefficient : PositiveFloat
+        Multiplicative factor relating the minimum mass-loss rate that a
+        firebrand tracer needs to have to justify continuing to track its
+        trajectory to the energy associated with a new ignition [-].
+    max_firebrand_thickness_fraction : PositiveFloat
+        Multiplicative factor relating the thickness of launched firebrand
+        tracer to maximum loftable firebrand thickness [-].
+    firebrand_germination_delay : PositiveInt
+        Time after a firebrand has landed at which a fire is started [s]
+    vertical_velocity_scale_factor : PositiveFloat
+        Maximum value of the multiplicative factor of the vertical velocity
+        experienced by a firebrand = 1/(fraction of the QUIC-URB on fire) [-]
+    minimum_firebrand_ignitions : PositiveInt
+        Minimum number of ignitions to be sampled in a position where a
+        firebrand lands [-]
+    maximum_firebrand_ignitions : PositiveInt
+        Maximum number of ignitions sampled at positions distributed within RT
+        around where a firebrand tracer lands [-]
+    minimum_landing_angle : PositiveFloat
+        Minimum value considered for the angle between the trajectory of the
+        firebrand when it hits the ground and horizontal [rad]
+    maximum_firebrand_thickness : PositiveFloat
+        Maximum firebrand's thickness [m]
+    """
+
+    name: str = Field("QFire_Advanced_User_Inputs", frozen=True)
+    _extension: str = ".inp"
+    fraction_cells_launch_firebrands: PositiveFloat = Field(0.05, ge=0, lt=1)
+    firebrand_radius_scale_factor: PositiveFloat = Field(40.0, ge=1)
+    firebrand_trajectory_time_step: PositiveInt = 1
+    firebrand_launch_interval: PositiveInt = 10
+    firebrands_per_deposition: PositiveInt = 500
+    firebrand_area_ratio: PositiveFloat = 20.0
+    minimum_burn_rate_coefficient: PositiveFloat = 50.0
+    max_firebrand_thickness_fraction: PositiveFloat = 0.75
+    firebrand_germination_delay: PositiveInt = 180
+    vertical_velocity_scale_factor: PositiveFloat = 5.0
+    minimum_firebrand_ignitions: PositiveInt = 50
+    maximum_firebrand_ignitions: PositiveInt = 100
+    minimum_landing_angle: PositiveFloat = Field(0.523598, ge=0, le=np.pi / 2)
+    maximum_firebrand_thickness: PositiveFloat = 0.03
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        """
+        Initializes a QFire_Advanced_User_Inputs object from a directory
+        containing a QFire_Advanced_User_Inputs.inp file.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "QFire_Advanced_User_Inputs.inp", "r") as f:
+            lines = f.readlines()
+        return cls(
+            fraction_cells_launch_firebrands=float(lines[0].split()[0]),
+            firebrand_radius_scale_factor=float(lines[1].split()[0]),
+            firebrand_trajectory_time_step=int(lines[2].split()[0]),
+            firebrand_launch_interval=int(lines[3].split()[0]),
+            firebrands_per_deposition=int(lines[4].split()[0]),
+            firebrand_area_ratio=float(lines[5].split()[0]),
+            minimum_burn_rate_coefficient=float(lines[6].split()[0]),
+            max_firebrand_thickness_fraction=float(lines[7].split()[0]),
+            firebrand_germination_delay=int(lines[8].split()[0]),
+            vertical_velocity_scale_factor=float(lines[9].split()[0]),
+            minimum_firebrand_ignitions=int(lines[10].split()[0]),
+            maximum_firebrand_ignitions=int(lines[11].split()[0]),
+            minimum_landing_angle=float(lines[12].split()[0]),
+            maximum_firebrand_thickness=float(lines[13].split()[0]),
+        )
+
+
+class QUIC_fire(InputFile):
+    """
+    Class representing the QUIC_fire.inp input file. This file
+    contains the parameters relating to the fire simulation and
+    outputs.
+
+    Parameters
+    ----------
+    fire_flag : Literal[0, 1]
+        Fire flag, 1 = run fire; 0 = no fire
+    random_seed : int
+        Random number generator, -1: use time and date, any other integer > 0
+    time_now : PositiveInt
+        When the fire is ignited in Unix Epoch time (integer seconds since
+        1970/1/1 00:00:00). Must be greater or equal to the time of the first
+        wind
+    sim_time : PositiveInt
+        Total simulation time for the fire [s]
+    fire_time_step : PositiveInt
+        Time step for the fire simulation [s]
+    quic_time_step : PositiveInt
+        Number of fire time steps done before updating the quic wind field
+        (integer, >= 1)
+    out_time_fire : PositiveInt
+        After how many fire time steps to print out fire-related files (excluding emissions and radiation)
+    out_time_wind : PositiveInt
+        After how many quic updates to print out wind-related files
+    out_time_emis_rad : PositiveInt
+        After how many fire time steps to average emissions and radiation
+    out_time_wind_avg : PositiveInt
+        After how many quic updates to print out averaged wind-related files
+    nz : PositiveInt
+        Number of fire grid cells in the z-direction.
+    stretch_grid_flag : Literal[0, 1]
+        Vertical stretching flag: 0 = uniform dz, 1 = custom
+    dz : PositiveInt
+        Cell size in the z-direction [m] of the fire grid. Recommended value: 1m
+    dz_array : List[PositiveFloat]
+        Custom dz, one dz per line must be specified, from the ground to the
+        top of the domain
+    fuel_flag : Literal[1, 2, 3, 4]
+        Flag for fuel inputs:
+            - density
+            - moisture
+            - height
+        1 = uniform; 2 = provided thru QF_FuelDensity.inp, 3 = Firetech files
+        for quic grid, 4 = Firetech files for different grid
+        (need interpolation)
+    fuel_density : PositiveFloat
+        Fuel density (kg/m3)
+    fuel_moisture : PositiveFloat
+        Fuel moisture = mass of water/mass of dry fuel
+    fuel_height : PositiveFloat
+        Fuel height of surface layer (m)
+    ignition_type: IgnitionType
+        Ignition type specified as an IgnitionsType class from ignitions.py
+        1 = rectangle
+        2 = square ring
+        3 = circular ring
+        6 = ignite.dat (Firetec file)
+    ignitions_per_cell : PositiveInt
+        Number of ignition per cell of the fire model. Recommended max value
+        of 100
+    firebrand_flag : Literal[0, 1]
+        Firebrand flag, 0 = off; 1 = on. Recommended value = 0; firebrands
+        are untested for small scale problems
+    auto_kill : Literal[0, 1]
+        Kill if the fire is out and there are no more ignitions or firebrands
+        (0 = no, 1 = yes)
+    eng_to_atm_out : Literal[0, 1]
+        Output flag [0, 1]: gridded energy-to-atmosphere
+        (3D fire grid + extra layers)
+    react_rate_out : Literal[0, 1]
+        Output flag [0, 1]: compressed array reaction rate (fire grid)
+    fuel_dens_out : Literal[0, 1]
+        Output flag [0, 1]: compressed array fuel density (fire grid)
+    qf_wind_out : Literal[0, 1]
+        Output flag [0, 1]: gridded wind (u,v,w,sigma) (3D fire grid)
+    qu_wind_inst_out : Literal[0, 1]
+        Output flag [0, 1]: gridded QU winds with fire effects, instantaneous
+        (QUIC-URB grid)
+    qu_wind_avg_out : Literal[0, 1]
+        Output flag [0, 1]: gridded QU winds with fire effects, averaged
+        (QUIC-URB grid)
+    fuel_moist_out : Literal[0, 1]
+        Output flag [0, 1]: compressed array fuel moisture (fire grid)
+    mass_burnt_out : Literal[0, 1]
+        Output flag [0, 1]: vertically-integrated % mass burnt (fire grid)
+    firebrand_out : Literal[0, 1]
+        Output flag [0, 1]: firebrand trajectories. Must be 0 when firebrand
+        flag is 0
+    emissions_out : Literal[0, 1, 2, 3, 4, 5]
+        Output flag [0, 5]: compressed array emissions (fire grid):
+            0 = do not output any emission related variables
+            1 = output emissions files and simulate CO in QUIC-SMOKE
+            2 = output emissions files and simulate PM2.5 in QUIC- SMOKE
+            3 = output emissions files and simulate both CO and PM2.5 in
+                QUIC-SMOKE
+            4 = output emissions files but use library approach in QUIC-SMOKE
+            5 = output emissions files and simulate both water in QUIC-SMOKE
+    radiation_out : Literal[0, 1]
+        Output flag [0, 1]: gridded thermal radiation (fire grid)
+    intensity_out : Literal[0, 1]
+        Output flag [0, 1]: surface fire intensity at every fire time step
+    """
+
+    name: str = "QUIC_fire"
+    _extension: str = ".inp"
+    fire_flag: Literal[0, 1] = 1
+    random_seed: int = Field(ge=-1, default=-1)
+    time_now: PositiveInt
+    sim_time: PositiveInt
+    fire_time_step: PositiveInt = 1
+    quic_time_step: PositiveInt = 1
+    out_time_fire: PositiveInt = 30
+    out_time_wind: PositiveInt = 30
+    out_time_emis_rad: PositiveInt = 30
+    out_time_wind_avg: PositiveInt = 30
+    nz: PositiveInt
+    stretch_grid_flag: Literal[0, 1] = 0
+    dz: PositiveInt = 1
+    dz_array: list[PositiveFloat] = []
+    fuel_flag: Literal[1, 2, 3, 4] = 4
+    fuel_density: PositiveFloat | None = None
+    fuel_moisture: PositiveFloat | None = None
+    fuel_height: PositiveFloat | None = None
+    ignition_type: SerializeAsAny[IgnitionType] = IgnitionType(
+        ignition_flag=IgnitionSources(6)
     )
+    ignitions_per_cell: PositiveInt = 2
+    firebrand_flag: Literal[0, 1] = 0
+    auto_kill: Literal[0, 1] = 1
+    eng_to_atm_out: Literal[0, 1] = 0
+    react_rate_out: Literal[0, 1] = 0
+    fuel_dens_out: Literal[0, 1] = 1
+    qf_wind_out: Literal[0, 1] = 1
+    qu_wind_inst_out: Literal[0, 1] = 0
+    qu_wind_avg_out: Literal[0, 1] = 0
+    fuel_moist_out: Literal[0, 1] = 0
+    mass_burnt_out: Literal[0, 1] = 0
+    firebrand_out: Literal[0, 1] = 0
+    emissions_out: Literal[0, 1, 2, 3, 4, 5] = 0
+    radiation_out: Literal[0, 1] = 0
+    intensity_out: Literal[0, 1] = 0
+
+    @field_validator("random_seed")
+    @classmethod
+    def validate_random_seed(cls, v: int) -> int:
+        if v == 0:
+            raise ValueError("QUIC_fire.inp: random_seed must be not be 0")
+        return v
+
+    @computed_field
+    @property
+    def _stretch_grid_input(self) -> str:
+        """
+        Writes a custom stretch grid to QUIC_fire.inp, if provided.
+        """
+        if self.stretch_grid_flag == 1:
+            # Verify that dz_array is not empty
+            if not self.dz_array:
+                raise ValueError(
+                    "dz_array must not be empty if stretch_grid_flag "
+                    "is 1. Please provide a dz_array with nz elements"
+                    " or use a different stretch_grid_flag."
+                )
+
+            # Verify that nz is equal to the length of dz_array
+            if self.nz != len(self.dz_array):
+                raise ValueError(
+                    f"nz must be equal to the length of dz_array. "
+                    f"{self.nz} != {len(self.dz_array)}"
+                )
+
+            # Write dz_array lines
+            dz_array_lines_list = []
+            for dz in self.dz_array:
+                dz_array_lines_list.append(f"{float(dz)}")
+            dz_array_lines = "\n".join(dz_array_lines_list)
+
+            return f"{dz_array_lines}\n"
+        else:
+            return str(self.dz)
+
+    @computed_field
+    @property
+    def _ignition_lines(self) -> str:
+        return str(self.ignition_type)
+
+    @computed_field
+    @property
+    def _fuel_lines(self) -> str:
+        flag_line = (
+            " 1 = uniform; "
+            "2 = provided thru QF_FuelMoisture.inp, 3 = Firetech"
+            " files for quic grid, 4 = Firetech files for "
+            "different grid (need interpolation)"
+        )
+        fuel_density_flag_line = f"{self.fuel_flag}\t! fuel density flag:" + flag_line
+        fuel_moist_flag_line = f"\n{self.fuel_flag}\t! fuel moisture flag:" + flag_line
+        fuel_height_flag_line = f"\n{self.fuel_flag}\t! fuel height flag:" + flag_line
+        if self.fuel_flag == 1:
+            try:
+                assert self.fuel_density is not None
+                assert self.fuel_moisture is not None
+                assert self.fuel_height is not None
+            except AssertionError:
+                raise ValueError(
+                    "fuel_params: FuelInputs class must have values for fuel_density, fuel_moisture, and fuel_height"
+                )
+            fuel_dens_line = f"\n{self.fuel_density}"
+            fuel_moist_line = f"\n{self.fuel_moisture}"
+            fuel_height_line = f"\n{self.fuel_height}"
+            return (
+                fuel_density_flag_line
+                + fuel_dens_line
+                + fuel_moist_flag_line
+                + fuel_moist_line
+                + fuel_height_flag_line
+                + fuel_height_line
+            )
+        return fuel_density_flag_line + fuel_moist_flag_line
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        """
+        Initializes a QUIC_fire object from a directory containing a
+        QUIC_Fire.inp file.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+
+        with open(directory / "QUIC_fire.inp", "r") as f:
+            lines = f.readlines()
+
+        # Read fire flag and random seed
+        fire_flag = int(lines[0].strip().split("!")[0])
+        random_seed = int(lines[1].strip().split("!")[0])
+
+        # Read fire times
+        time_now = int(lines[3].strip().split("!")[0])
+        sim_time = int(lines[4].strip().split("!")[0])
+        fire_time_step = int(lines[5].strip().split("!")[0])
+        quic_time_step = int(lines[6].strip().split("!")[0])
+        out_time_fire = int(lines[7].strip().split("!")[0])
+        out_time_wind = int(lines[8].strip().split("!")[0])
+        out_time_emis_rad = int(lines[9].strip().split("!")[0])
+        out_time_wind_avg = int(lines[10].strip().split("!")[0])
+
+        # Read fire grid parameters
+        nz = int(lines[12].strip().split("!")[0])
+        stretch_grid_flag = int(lines[13].strip().split("!")[0])
+        dz_array = []
+        if stretch_grid_flag == 0:
+            dz = int(lines[14].strip().split("!")[0])
+            current_line = 15
+        else:
+            for i in range(14, 14 + len(dz_array)):
+                try:
+                    float(lines[i].strip())
+                except ValueError:
+                    print(
+                        "QUIC_fire.inp: dz input value is not a float. Does the number of dz inputs match nz?"
+                    )
+                dz_array.append(float(lines[i].strip()))
+            current_line = 15 + len(dz_array)
+
+        current_line += 4  # skip unused lines
+
+        # Read fuel inputs
+        # current_line = ! FUEL
+        current_line += 1  # header
+        fuel_flag = int(lines[current_line].strip().split("!")[0])
+        if fuel_flag == 1:
+            fuel_density = float(lines[current_line + 1].strip())
+            moisture_flag = int(lines[current_line + 2].strip().split("!")[0])
+            fuel_moisture = float(lines[current_line + 3].strip())
+            height_flag = int(lines[current_line + 4].strip().split("!")[0])
+            fuel_height = float(lines[current_line + 5].strip())
+            if moisture_flag != fuel_flag or height_flag != fuel_flag:
+                raise ValueError(
+                    "QUIC_fire.inp: Fuel moisture and fue height flags must match fuel density flag"
+                )
+            current_line += 6
+        else:
+            fuel_density = None
+            fuel_moisture = None
+            fuel_height = None
+            current_line += 2
+
+            # Read ignition inputs
+        # current_line = ! IGNITION LOCATIONS
+        current_line += 1  # header
+        ignition_flag = int(lines[current_line].strip().split("!")[0])
+        add_lines = {1: 4, 2: 6, 3: 5, 4: 0, 5: 0, 6: 0, 7: 0}
+        add = add_lines.get(ignition_flag)
+        ignition_params = []
+        current_line += 1
+        for i in range(current_line, current_line + add):
+            ignition_params.append(int(lines[i].strip().split("!")[0]))
+        if ignition_flag == 1:
+            x_min, y_min, x_length, y_length = ignition_params
+            ignition_type = RectangleIgnition(
+                x_min=x_min, y_min=y_min, x_length=x_length, y_length=y_length
+            )
+        elif ignition_flag == 2:
+            x_min, y_min, x_length, y_length, x_width, y_width = ignition_params
+            ignition_type = SquareRingIgnition(
+                x_min=x_min,
+                y_min=y_min,
+                x_length=x_length,
+                y_length=y_length,
+                x_width=x_width,
+                y_width=y_width,
+            )
+        elif ignition_flag == 3:
+            x_min, y_min, x_length, y_length, ring_width = ignition_params
+            ignition_type = CircularRingIgnition(
+                x_min=x_min,
+                y_min=y_min,
+                x_length=x_length,
+                y_length=y_length,
+                ring_width=ring_width,
+            )
+        elif ignition_flag == 6:
+            ignition_type = IgnitionType(ignition_flag=6)
+        current_line += add
+        ignitions_per_cell = int(lines[current_line].strip().split("!")[0])
+        current_line += 1
+
+        # Read firebrands
+        # current_line = ! FIREBRANDS
+        current_line += 1  # header
+        firebrand_flag = int(lines[current_line].strip().split("!")[0])
+        current_line += 1
+
+        # Read output flags
+        # current_line = !OUTPUT_FILES
+        eng_to_atm_out = int(lines[current_line + 1].strip().split("!")[0])
+        react_rate_out = int(lines[current_line + 2].strip().split("!")[0])
+        fuel_dens_out = int(lines[current_line + 3].strip().split("!")[0])
+        qf_wind_out = int(lines[current_line + 4].strip().split("!")[0])
+        qu_wind_inst_out = int(lines[current_line + 5].strip().split("!")[0])
+        qu_wind_avg_out = int(lines[current_line + 6].strip().split("!")[0])
+        # ! Output plume trajectories
+        fuel_moist_out = int(lines[current_line + 8].strip().split("!")[0])
+        mass_burnt_out = int(lines[current_line + 9].strip().split("!")[0])
+        firebrand_out = int(lines[current_line + 10].strip().split("!")[0])
+        emissions_out = int(lines[current_line + 11].strip().split("!")[0])
+        radiation_out = int(lines[current_line + 12].strip().split("!")[0])
+        intensity_out = int(lines[current_line + 13].strip().split("!")[0])
+        # ! AUTOKILL
+        auto_kill = int(lines[current_line + 15].strip().split("!")[0])
+
+        return cls(
+            fire_flag=fire_flag,
+            random_seed=random_seed,
+            time_now=time_now,
+            sim_time=sim_time,
+            fire_time_step=fire_time_step,
+            quic_time_step=quic_time_step,
+            out_time_fire=out_time_fire,
+            out_time_wind=out_time_wind,
+            out_time_emis_rad=out_time_emis_rad,
+            out_time_wind_avg=out_time_wind_avg,
+            nz=nz,
+            stretch_grid_flag=stretch_grid_flag,
+            dz=dz,
+            dz_array=dz_array,
+            fuel_flag=fuel_flag,
+            fuel_density=fuel_density,
+            fuel_moisture=fuel_moisture,
+            fuel_height=fuel_height,
+            ignition_type=ignition_type,
+            ignitions_per_cell=ignitions_per_cell,
+            firebrand_flag=firebrand_flag,
+            eng_to_atm_out=eng_to_atm_out,
+            react_rate_out=react_rate_out,
+            fuel_dens_out=fuel_dens_out,
+            qf_wind_out=qf_wind_out,
+            qu_wind_inst_out=qu_wind_inst_out,
+            qu_wind_avg_out=qu_wind_avg_out,
+            fuel_moist_out=fuel_moist_out,
+            mass_burnt_out=mass_burnt_out,
+            firebrand_out=firebrand_out,
+            emissions_out=emissions_out,
+            radiation_out=radiation_out,
+            intensity_out=intensity_out,
+            auto_kill=auto_kill,
+        )
+
+
+class QFire_Bldg_Advanced_User_Inputs(InputFile):
+    """
+    Class representing the QFire_Bldg_Advanced_User_Inputs.inp input file. This
+    file contains advanced parameters related to buildings and fuel.
+
+    Attributes
+    ----------
+    convert_buildings_to_fuel_flag : int
+        Flag to convert QUIC-URB buildings to fuel. 0 = do not convert,
+        1 = convert. Recommended value: 0.
+    building_fuel_density : PositiveFloat
+        Thin fuel density within buildings if no fuel is specified and buildings
+        are converted to fuel. Higher value = more fuel. Recommended value: 0.5.
+        Units: [kg/m^3]
+    building_attenuation_coefficient : PositiveFloat
+        Attenuation coefficient within buildings if buildings are converted to
+        fuel. Higher value = more drag. Recommended value: 2.
+    building_surface_roughness : PositiveFloat
+        Surface roughness within buildings if buildings are converted to fuel.
+        Higher value = lower wind speed. Recommended value: 0.01 m. Units: [m]
+    convert_fuel_to_canopy_flag : int
+        Flag to convert fuel to canopy for winds. 0 = do not convert,
+        1 = convert. Recommended value: 1.
+    update_canopy_winds_flag : int
+        Flag to update canopy winds when fuel is consumed. 0 = do not update,
+        1 = update. Recommended value: 1.
+    fuel_attenuation_coefficient : PositiveFloat
+        Attenuation coefficient within fuel for the wind profile. Higher
+        value = more drag. Recommended value: 1.
+    fuel_surface_roughness : PositiveFloat
+        Surface roughness within fuel. Higher value = lower wind speed.
+        Recommended value: 0.1 m. Units: [m]
+    """
+
+    name: str = Field("QFire_Bldg_Advanced_User_Inputs", frozen=True)
+    _extension: str = ".inp"
+    convert_buildings_to_fuel_flag: Literal[0, 1] = 0
+    building_fuel_density: PositiveFloat = Field(0.5, ge=0)
+    building_attenuation_coefficient: PositiveFloat = Field(2.0, ge=0)
+    building_surface_roughness: PositiveFloat = Field(0.01, ge=0)
+    convert_fuel_to_canopy_flag: Literal[0, 1] = 1
+    update_canopy_winds_flag: Literal[0, 1] = 1
+    fuel_attenuation_coefficient: PositiveFloat = Field(1.0, ge=0)
+    fuel_surface_roughness: PositiveFloat = Field(0.1, ge=0)
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        """
+        Initializes a QFire_Bldg_Advanced_User_Inputs object from a directory
+        containing a QFire_Bldg_Advanced_User_Inputs.inp file.
+        """
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "QFire_Bldg_Advanced_User_Inputs.inp", "r") as f:
+            lines = f.readlines()
+        return cls(
+            convert_buildings_to_fuel_flag=int(lines[0].split()[0]),
+            building_fuel_density=float(lines[1].split()[0]),
+            building_attenuation_coefficient=float(lines[2].split()[0]),
+            building_surface_roughness=float(lines[3].split()[0]),
+            convert_fuel_to_canopy_flag=int(lines[4].split()[0]),
+            update_canopy_winds_flag=int(lines[5].split()[0]),
+            fuel_attenuation_coefficient=float(lines[6].split()[0]),
+            fuel_surface_roughness=float(lines[7].split()[0]),
+        )
 
-    sim_test = SimulationInputs("../tests/tmp/test-simulation/")
-    sim_test.setup_input_files(test_params)
+
+class QFire_Plume_Advanced_User_Inputs(InputFile):
+    """
+    Class representing the QFire_Plume_Advanced_User_Inputs.inp input file.
+    This file contains advanced parameters related to modeling buoyant plumes.
+
+    Attributes
+    ----------
+    max_plumes_per_timestep : PositiveInt
+        Maximum number of plumes allowed at each time step. Higher values slow
+        down the simulation. Default value: 150,000. Recommended range:
+        50,000 - 500,000.
+    min_plume_updraft_velocity : PositiveFloat
+        Minimum plume updraft velocity [m/s]. If plume velocity drops below this
+        value, the plume is removed. Higher values reduce number of plumes.
+        Default value: 0.1 m/s.
+    max_plume_updraft_velocity : PositiveFloat
+        Maximum allowed plume updraft velocity [m/s]. Default value: 100 m/s.
+    min_velocity_ratio : PositiveFloat
+        Minimum ratio between plume updraft velocity and wind speed. If ratio
+        drops below this value, plume is removed. Higher values reduce plumes.
+        Default value: 0.1.
+    brunt_vaisala_freq_squared : NonNegativeFloat
+        Inverse of the Brunt-Vaisala frequency squared [1/s^2], a measure of
+        atmospheric stability. Default value: 0 1/s^2.
+    creeping_flag : Literal[0, 1]
+        Flag to enable (1) or disable (0) fire spread by creeping.
+        Default value: 1.
+    adaptive_timestep_flag : Literal[0, 1]
+        Enable (1) or disable (0) adaptive time stepping. Adaptive time stepping
+        improves accuracy but increases simulation time. Default value: 0.
+    plume_timestep : PositiveFloat
+        Time step [s] used to compute buoyant plume trajectories. Higher values
+        reduce accuracy. Default value: 1s.
+    sor_option_flag : Literal[0, 1]
+        SOR solver option. 0 = standard SOR, 1 = memory SOR. Default value: 1.
+    sor_alpha_plume_center : PositiveFloat
+        SOR alpha value at plume centerline. Higher values reduce influence of
+        plumes on winds. Default value: 10.
+    sor_alpha_plume_edge : PositiveFloat
+        SOR alpha value at plume edge. Higher values reduce influence of plumes
+        on winds. Default value: 1.
+        max_plume_merging_angle : PositiveFloat
+        Maximum angle [degrees] between plumes to determine merging eligibility.
+        Higher values increase plume merging. Default value: 30 degrees.
+    max_plume_overlap_fraction : PositiveFloat
+        Maximum fraction of smaller plume trajectory overlapped by larger plume
+        to be considered for merging. Higher values increase merging.
+    plume_to_grid_updrafts_flag : Literal[0, 1]
+        Method to map plume updrafts to grid. 0 = new method, 1 = old method.
+        New method improves accuracy. Default value: 1. New method takes longer,
+        but is needed if smoke is simulated afterwards.
+    max_points_along_plume_edge : PositiveInt
+        Maximum points to sample along grid cell edge for new plume-to-grid
+        method. Default value: 10.
+    plume_to_grid_intersection_flag : Literal[0, 1]
+        Scheme to sum plume-to-grid updrafts when multiple plumes intersect a
+        grid cell. 0 = cube method, 1 = max value method. Default value: 1.
+    """
+
+    name: str = Field("QFire_Plume_Advanced_User_Inputs", frozen=True)
+    _extension: str = ".inp"
+    max_plumes_per_timestep: PositiveInt = Field(150000, gt=0)
+    min_plume_updraft_velocity: PositiveFloat = Field(0.1, gt=0)
+    max_plume_updraft_velocity: PositiveFloat = Field(100.0, gt=0)
+    min_velocity_ratio: PositiveFloat = Field(0.1, gt=0)
+    brunt_vaisala_freq_squared: NonNegativeFloat = Field(0.0, ge=0)
+    creeping_flag: Literal[0, 1] = 1
+    adaptive_timestep_flag: Literal[0, 1] = 0
+    plume_timestep: PositiveFloat = Field(1.0, gt=0)
+    sor_option_flag: Literal[0, 1] = 1
+    sor_alpha_plume_center: PositiveFloat = Field(10.0, gt=0)
+    sor_alpha_plume_edge: PositiveFloat = Field(1.0, gt=0)
+    max_plume_merging_angle: PositiveFloat = Field(30.0, gt=0, le=180)
+    max_plume_overlap_fraction: PositiveFloat = Field(0.7, gt=0, le=1)
+    plume_to_grid_updrafts_flag: Literal[0, 1] = 1
+    max_points_along_plume_edge: PositiveInt = Field(10, ge=1, le=100)
+    plume_to_grid_intersection_flag: Literal[0, 1] = 1
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        if isinstance(directory, str):
+            directory = Path(directory)
+
+        with open(directory / "QFire_Plume_Advanced_User_Inputs.inp", "r") as f:
+            lines = f.readlines()
+
+        return cls(
+            max_plumes_per_timestep=int(lines[0].split()[0]),
+            min_plume_updraft_velocity=float(lines[1].split()[0]),
+            max_plume_updraft_velocity=float(lines[2].split()[0]),
+            min_velocity_ratio=float(lines[3].split()[0]),
+            brunt_vaisala_freq_squared=float(lines[4].split()[0]),
+            creeping_flag=int(lines[5].split()[0]),
+            adaptive_timestep_flag=int(lines[6].split()[0]),
+            plume_timestep=float(lines[7].split()[0]),
+            sor_option_flag=int(lines[8].split()[0]),
+            sor_alpha_plume_center=float(lines[9].split()[0]),
+            sor_alpha_plume_edge=float(lines[10].split()[0]),
+            max_plume_merging_angle=float(lines[11].split()[0]),
+            max_plume_overlap_fraction=float(lines[12].split()[0]),
+            plume_to_grid_updrafts_flag=int(lines[13].split()[0]),
+            max_points_along_plume_edge=int(lines[14].split()[0]),
+            plume_to_grid_intersection_flag=int(lines[15].split()[0]),
+        )
+
+
+class QU_TopoInputs(InputFile):
+    """
+    Class representing the QU_TopoInputs.inp input file. This file
+    contains advanced inputs pertaining to topography.
+
+    filename : str
+        Path to the custom topo file (only used with option 5). Cannot be .bin. Use .dat or .inp
+    topo_type : TopoType
+        Topography type specified as a TopoType class from topography.py
+        0 = no terrain file provided, QUIC-Fire is run with flat terrain
+        1 = Gaussian hill
+        2 = hill pass
+        3 = slope mesa
+        4 = canyon
+        5 = custom
+        6 = half circle
+        7 = sinusoid
+        8 = cos hill
+        9 = terrain is provided via QP_elevation.bin (see Section 2.7)
+        10 = terrain is provided via terrainOutput.txt
+        11 = terrain.dat (firetec)
+    smoothing_method : int
+        0 = none (default for idealized topo)
+        1 = Blur
+        2 = David Robinson’s method based on second derivative
+    smoothing_passes : int
+        Number of smoothing passes. Real terrain MUST be smoothed
+    sor_iterations : int
+        Number of SOR iteration to define background winds before starting the fire
+    sor_cycles : int
+        Number of times the SOR solver initial fields is reset to define
+        background winds before starting the fire
+    sor_relax : float
+        SOR overrelaxation coefficient. Only used if there is topo.
+    """
+
+    name: str = "QU_TopoInputs"
+    _extension: str = ".inp"
+    filename: str = "topo.dat"
+    topo_type: SerializeAsAny[TopoType] = TopoType(topo_flag=TopoSources(0))
+    smoothing_method: Literal[0, 1, 2] = 2
+    smoothing_passes: PositiveInt = Field(le=500, default=500)
+    sor_iterations: PositiveInt = Field(le=500, default=200)
+    sor_cycles: Literal[0, 1, 2, 3, 4] = 4
+    sor_relax: PositiveFloat = Field(le=2, default=0.9)
+
+    @computed_field
+    @property
+    def _topo_lines(self) -> str:
+        return str(self.topo_type)
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "QU_TopoInputs.inp", "r") as f:
+            lines = f.readlines()
+
+        # Line 0 is Header
+        filename = str(lines[1].strip())
+        # Get topo lines
+        topo_flag = int(lines[2].strip().split("!")[0])
+        add_dict = {
+            0: 0,
+            1: 4,
+            2: 2,
+            3: 3,
+            4: 5,
+            5: 0,
+            6: 3,
+            7: 2,
+            8: 2,
+            9: 0,
+            10: 0,
+            11: 0,
+        }
+        add = add_dict.get(topo_flag)
+        topo_params = []
+        for i in range(3, 3 + add):
+            topo_params.append(float(lines[i].strip().split("!")[0]))
+        if topo_flag == 1:
+            x_hilltop, y_hilltop, elevation_max, elevation_std = topo_params
+            topo_type = GaussianHillTopo(
+                x_hilltop=int(x_hilltop),
+                y_hilltop=int(y_hilltop),
+                elevation_max=int(elevation_max),
+                elevation_std=elevation_std,
+            )
+        elif topo_flag == 2:
+            max_height, location_param = topo_params
+            topo_type = HillPassTopo(
+                max_height=int(max_height), location_param=location_param
+            )
+        elif topo_flag == 3:
+            slope_axis, slope_value, flat_fraction = topo_params
+            topo_type = SlopeMesaTopo(
+                slope_axis=int(slope_axis),
+                slope_value=slope_value,
+                flat_fraction=flat_fraction,
+            )
+        elif topo_flag == 4:
+            x_start, y_center, slope_value, canyon_std, vertical_offset = topo_params
+            topo_type = CanyonTopo(
+                x_start=int(x_start),
+                y_center=int(y_center),
+                sloe_value=slope_value,
+                canyon_std=canyon_std,
+                vertical_offset=vertical_offset,
+            )
+        elif topo_flag == 6:
+            x_location, y_location, radius = topo_params
+            topo_type = HalfCircleTopo(
+                x_location=int(x_location), y_location=int(y_location), radius=radius
+            )
+        elif topo_flag == 7:
+            period, amplitude = topo_params
+            topo_type = SinusoidTopo(period=period, amplitude=amplitude)
+        elif topo_flag == 8:
+            aspect, height = topo_params
+            topo_type = CosHillTopo(aspect=aspect, height=height)
+        else:
+            topo_type = TopoType(topo_flag=topo_flag)
+        current_line = 3 + add
+        # Smoothing and SOR
+        smoothing_method = int(lines[current_line].strip().split("!")[0])
+        smoothing_passes = int(lines[current_line + 1].strip().split("!")[0])
+        sor_iterations = int(lines[current_line + 2].strip().split("!")[0])
+        sor_cycles = int(lines[current_line + 3].strip().split("!")[0])
+        sor_relax = float(lines[current_line + 4].strip().split("!")[0])
+
+        return cls(
+            filename=filename,
+            topo_type=topo_type,
+            smoothing_method=smoothing_method,
+            smoothing_passes=smoothing_passes,
+            sor_iterations=sor_iterations,
+            sor_cycles=sor_cycles,
+            sor_relax=sor_relax,
+        )
+
+
+class RuntimeAdvancedUserInputs(InputFile):
+    """
+    Class representing the Runtime_Advanced_User_Inputs.inp input file.
+    This file contains advanced parameters related to computer memory usage.
+
+    Attributes
+    ----------
+    num_cpus : PositiveInt
+        Maximum number of CPU to use. Do not exceed 8. Use 1 for ensemble
+        simulations.
+    use_acw : Literal[0,1]
+        Use Adaptive Computation Window (0=Disabled 1=Enabled)
+    """
+
+    name: str = "Runtime_Advanced_User_Inputs"
+    _extension: str = ".inp"
+    num_cpus: PositiveInt = Field(le=8, default=8)
+    use_acw: Literal[0, 1] = 0
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "Runtime_Advanced_User_Inputs.inp", "r") as f:
+            lines = f.readlines()
+
+        return cls(
+            num_cpus=int(lines[0].strip().split("!")[0]),
+            use_acw=int(lines[1].strip().split("!")[0]),
+        )
+
+
+class QU_movingcoords(InputFile):
+    """
+    Class representing the QU_movingcoords.inp input file.
+    This is a QUIC legacy file that is not modified for QUIC-Fire use.
+    """
+
+    name: str = "QU_movingcoords"
+    _extension: str = ".inp"
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        if isinstance(directory, str):
+            directory = Path(directory)
+
+        with open(directory / "QU_movingcoords.inp", "r") as f:
+            lines = f.readlines()
+
+        if int(lines[1].strip().split("!")[0]) == 1:
+            print(
+                "WARNING: QU_movingcoords.inp: Moving coordinates flag == 1 not supported."
+            )
+
+        return cls()
+
+
+class QP_buildout(InputFile):
+    """
+    Class representing the QU_buildout.inp input file.
+    This is a QUIC legacy file that is not modified for QUIC-Fire use.
+    """
+
+    name: str = "QP_buildout"
+    _extension: str = ".inp"
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        if isinstance(directory, str):
+            directory = Path(directory)
+
+        with open(directory / "QP_buildout.inp", "r") as f:
+            lines = f.readlines()
+
+        if int(lines[0].strip().split("!")[0]) == 1:
+            print("WARNING: QP_buildout.inp: number of buildings will be set to 0.")
+        if int(lines[1].strip().split("!")[0]) == 1:
+            print(
+                "WARNING: QP_buildout.inp: number of vegetative canopies will be set to 0."
+            )
+
+        return cls()
+
+
+class QU_metparams(InputFile):
+    """
+    Class representing the QU_metparams.inp input file.
+    This file contains information about wind profiles
+
+    Attributes
+    ----------
+    num_sensors : int
+        Number of measuring sites. Multiple wind profiles are not yet supported.
+    sensor_name : str
+        Name of the wind profile. This will correspond to the filename of the wind profile, e.g. sensor1.inp
+    """
+
+    name: str = "QU_metparams"
+    _extension: str = ".inp"
+    num_sensors: PositiveInt = 1
+    sensor_name: str = "sensor1"
+
+    @computed_field
+    @property
+    def _sensor_lines(self) -> str:
+        return (
+            f"{self.sensor_name} !Site Name\n" f"!File name\n" f"{self.sensor_name}.inp"
+        )
+
+    @classmethod
+    def from_file(cls, directory):
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "QU_metparams.inp", "r") as f:
+            lines = f.readlines()
+        return cls(
+            num_sensors=int(lines[2].strip().split()[0]),
+            sensor_name=str(lines[4].strip().split()[0].strip()),
+        )
+
+
+class Sensor1(InputFile):
+    """
+    Class representing the sensor1.inp input file.
+    This file contains information on winds, and serves as the
+    primary source for wind speed(s) and direction(s)
+
+    Attributes
+    ----------
+    time_now : PositiveInt
+        Begining of time step in Unix Epoch time (integer seconds since
+        1970/1/1 00:00:00). Must match time at beginning of fire
+        (QU_Simparams.inp and QUIC_fire.inp)
+    sensor_height : PositiveFloat
+        Wind measurement height (m). Default is 6.1m (20ft)
+    wind_speed : PositiveFloat
+        Wind speed (m/s)
+    wind_direction : NonNegativeInt < 360
+        Wind direction (degrees). Use 0° for North
+    """
+
+    name: str = "sensor1"
+    _extension: str = ".inp"
+    time_now: PositiveInt
+    sensor_height: PositiveFloat = 6.1  # 20ft
+    wind_speed: PositiveFloat
+    wind_direction: NonNegativeInt = Field(lt=360)
+
+    @computed_field
+    @property
+    def _wind_lines(self) -> str:
+        """
+        This is meant to support wind shifts in the future.
+        This computed field could be altered to reproduce the lines below
+        for a series of times, speeds, and directions.
+        """
+        return (
+            f"{self.time_now} !Begining of time step in Unix Epoch time"
+            f"(integer seconds since 1970/1/1 00:00:00)\n"
+            f"1 !site boundary layer flag (1 = log, 2 = exp, 3 = urban "
+            f"canopy, 4 = discrete data points)\n"
+            f"0.1 !site zo\n"
+            f"0. ! 1/L (default = 0)\n"
+            f"!Height (m),Speed	(m/s), Direction (deg relative to true N)\n"
+            f"{self.sensor_height} {self.wind_speed} {self.wind_direction}"
+        )
+
+    @classmethod
+    def from_file(cls, directory: str | Path):
+        if isinstance(directory, str):
+            directory = Path(directory)
+        with open(directory / "sensor1.inp", "r") as f:
+            lines = f.readlines()
+        return cls(
+            time_now=int(lines[6].strip().split("!")[0]),
+            sensor_height=float(lines[11].split(" ")[0]),
+            wind_speed=float(lines[11].split(" ")[1]),
+            wind_direction=int(lines[11].split(" ")[2]),
+        )
diff --git a/quicfire_tools/inputs/documentation/IgnitionType.json b/quicfire_tools/inputs/documentation/IgnitionType.json
new file mode 100644
index 0000000..6d29398
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/IgnitionType.json
@@ -0,0 +1,113 @@
+{
+    "rectangle_ignition": {
+        "x_min": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "Any",
+            "description": "South-west corner in the x-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_min": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "Any",
+            "description": "South-west corner in the y-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "x_length": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Length in the x-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_length": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Length in the y-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        }
+    },
+    "square_ring_ignition": {
+        "x_min": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "Any",
+            "description": "South-west corner in the x-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_min": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "Any",
+            "description": "South-west corner in the y-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "x_length": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Length in the x-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_length": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Length in the y-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "x_width": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Width of the ring in the x-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_width": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Width of the ring in the y-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        }
+    },
+    "cicular_ring_ignition": {
+        "x_min": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "Any",
+            "description": "South-west corner in the x-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_min": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "Any",
+            "description": "South-west corner in the y-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "x_length": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Length in the x-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_length": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Length in the y-direction",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "ring_width": {
+            "values_accepted": "> 0",
+            "tested_values_range": "Any",
+            "description": "Width of the ring",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        }
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/QFire_Advanced_User_Inputs.inp.json b/quicfire_tools/inputs/documentation/QFire_Advanced_User_Inputs.inp.json
new file mode 100644
index 0000000..63c5b11
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QFire_Advanced_User_Inputs.inp.json
@@ -0,0 +1,114 @@
+{
+  "fraction_cells_launch_firebrands": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "(0, 1]",
+    "tested_values_range": "0.05-0.9",
+    "description": "Fraction of cells that could launch firebrand tracers from which firebrand tracers will actually be launched. Higher value = more firebrand tracers. Recommended value: 0.05",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "firebrand_radius_scale_factor": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "> 1",
+    "tested_values_range": "40-80",
+    "description": "Multiplicative factor used to relate the length scale of the mixing (firebrand distribution entrainment length scale) to the initial size of the distribution. Higher value = higher growth rate or RT (firebrand distribution) with flight time. Recommended value: 40",
+    "units": "[-]",
+    "can_be_modified": "N"
+  },
+  "firebrand_trajectory_time_step": {
+    "data_type": "PositiveInt",
+    "values_accepted": "\u2265 1",
+    "tested_values_range": "1",
+    "description": "Time step used to determine the firebrand tracer trajectory. Higher value = less accurate trajectory. Recommended value: 1 s",
+    "units": "[s]",
+    "can_be_modified": "Y"
+  },
+  "firebrand_launch_interval": {
+    "data_type": "PositiveInt",
+    "values_accepted": "> 0",
+    "tested_values_range": "10-20",
+    "description": "Time interval between launching of firebrand tracers. Higher value = less firebrand tracers launched. Recommended value: 10 s",
+    "units": "[s]",
+    "can_be_modified": "Y"
+  },
+  "firebrands_per_deposition": {
+    "data_type": "PositiveInt",
+    "values_accepted": "> 0",
+    "tested_values_range": "500",
+    "description": "Number of firebrand tracers that one firebrand tracer launched represents. Recommended value: 500",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "firebrand_area_ratio": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "> 0",
+    "tested_values_range": "20.",
+    "description": "Multiplicative factor used to relate the cell area and fraction of cells from which tracers are launched to initial area represented by one firebrand.",
+    "units": "[-]",
+    "can_be_modified": "N"
+  },
+  "minimum_burn_rate_coefficient": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "> 0",
+    "tested_values_range": "50.",
+    "description": "Multiplicative factor relating the minimum mass-loss rate that a firebrand tracer needs to have to justify continuing to track its trajectory to the energy associated with a new ignition",
+    "units": "[-]",
+    "can_be_modified": "N"
+  },
+  "max_firebrand_thickness_fraction": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.75",
+    "description": "Multiplicative factor relating the thickness of launched firebrand tracer to maximum loftable firebrand thickness",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "firebrand_germination_delay": {
+    "data_type": "PositiveInt",
+    "values_accepted": "> 0",
+    "tested_values_range": "180",
+    "description": "Time after a firebrand has landed at which a fire is started",
+    "units": "[s]",
+    "can_be_modified": "Y"
+  },
+  "vertical_velocity_scale_factor": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "> 1",
+    "tested_values_range": "5-10",
+    "description": "Maximum value of the multiplicative factor of the vertical velocity experienced by a firebrand = 1/(fraction of the QUIC-URB on fire)",
+    "units": "[-]",
+    "can_be_modified": "N"
+  },
+  "minimum_firebrand_ignitions": {
+    "data_type": "PositiveInt",
+    "values_accepted": "> 0",
+    "tested_values_range": "50-100",
+    "description": "Minimum number of ignitions to be sampled in a position where a firebrand lands",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "maximum_firebrand_ignitions": {
+    "data_type": "PositiveInt",
+    "values_accepted": "> 0",
+    "tested_values_range": "100-500",
+    "description": "Maximum number of ignitions sampled at positions distributed within RT around where a firebrand tracer lands",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "minimum_landing_angle": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "[0, PI/2]",
+    "tested_values_range": "PI/3-PI/6",
+    "description": "Minimum value considered for the angle between the trajectory of the firebrand when it hits the ground and horizontal",
+    "units": "[rad]",
+    "can_be_modified": "N"
+  },
+  "maximum_firebrand_thickness": {
+    "data_type": "PositiveFloat",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.03-0.05",
+    "description": "Maximum firebrand's thickness",
+    "units": "[m]",
+    "can_be_modified": "Y"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/QFire_Bldg_Advanced_User_Inputs.inp.json b/quicfire_tools/inputs/documentation/QFire_Bldg_Advanced_User_Inputs.inp.json
new file mode 100644
index 0000000..d34fe4a
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QFire_Bldg_Advanced_User_Inputs.inp.json
@@ -0,0 +1,74 @@
+{
+  "convert_buildings_to_fuel_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Flag to convert QUIC-URB buildings to fuel. 0 = do not convert, 1 = convert.",
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "0"
+  },
+  "building_fuel_density": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.5",
+    "description": "Thin fuel density within buildings if no fuel is specified and buildings are converted to fuel. Higher value = more fuel.",
+    "units": "[kg/m^3]",
+    "can_be_modified": "N",
+    "recommended_value": "0.5"
+  },
+  "building_attenuation_coefficient": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "1-2",
+    "description": "Attenuation coefficient within buildings if buildings are converted to fuel. Higher value = more drag.",
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "2"
+  },
+  "building_surface_roughness": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.01-0.1",
+    "description": "Surface roughness within buildings if buildings are converted to fuel. Higher value = lower wind speed.",
+    "units": "[m]",
+    "can_be_modified": "N",
+    "recommended_value": "0.01 m"
+  },
+  "convert_fuel_to_canopy_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Flag to convert fuel to canopy for winds. 0 = do not convert, 1 = convert.",
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "1"
+  },
+  "update_canopy_winds_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Flag to update canopy winds when fuel is consumed. 0 = do not update, 1 = update.",
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "1"
+  },
+  "fuel_attenuation_coefficient": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "1-2",
+    "description": "Attenuation coefficient within fuel for the Cionco wind profile. Higher value = more drag.",
+    "units": "[-]",
+    "can_be_modified": "Y",
+    "recommended_value": "1"
+  },
+  "fuel_surface_roughness": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.01-0.1",
+    "description": "Surface roughness within fuel. Higher value = lower wind speed.",
+    "units": "[m]",
+    "can_be_modified": "N",
+    "recommended_value": "0.1 m"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/QFire_Plume_Advanced_User_Inputs.inp.json b/quicfire_tools/inputs/documentation/QFire_Plume_Advanced_User_Inputs.inp.json
new file mode 100644
index 0000000..abc1b39
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QFire_Plume_Advanced_User_Inputs.inp.json
@@ -0,0 +1,132 @@
+{
+  "max_plumes_per_timestep": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "[50k, 500k]",
+    "description": "Maximum number of plumes at each time step. Higher value = slower simulation.",
+    "units": "[-]",
+    "can_be_modified": "Y",
+    "recommended_value": "150,000"
+  },
+  "min_plume_updraft_velocity": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.1-0.5",
+    "description": "Minimum plume updraft velocity. If a plume updraft is below this value, the plume is removed from the simulation. Higher value = less plumes, faster simulation.",
+    "units": "[m/s]",
+    "can_be_modified": "Y",
+    "recommended_value": "0.1 m/s"
+  },
+  "max_plume_updraft_velocity": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "200",
+    "description": "Maximum updraft velocity. Recommended value: 100 m/s.",
+    "units": "[m/s]",
+    "can_be_modified": "Y"
+  },
+  "min_velocity_ratio": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.05-0.1",
+    "description": "Minimum ratio between the plume updraft velocity and the wind speed. If below, the plume is removed from the simulation, unless its updraft is 0.5 m/s or higher. Higher value = less plumes, faster simulation. Recommended value: 0.1.",
+    "units": "[-]",
+    "can_be_modified": "N"
+  },
+  "brunt_vaisala_freq_squared": {
+    "data_type": "REAL",
+    "values_accepted": ">= 0",
+    "tested_values_range": "0",
+    "description": "Inverse of the Brunt-Vaisala frequency squared (measure of atmospheric stability). Recommended value: 0 1/s2.",
+    "units": "[1/s2]",
+    "can_be_modified": "Y"
+  },
+  "creeping_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Flag: 0 = do not spread fire by creeping, 1 = spread fire by creeping. Recommended value: 1.",
+    "units": "[-]",
+    "can_be_modified": "N"
+  },
+  "adaptive_timestep_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Time step flag: 0 = constant time step, 1 = adaptive time step. Adaptive time step = more accurate plume trajectory, longer simulation time. Recommended value: 0.",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "plume_timestep": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "1-10",
+    "description": "Time step used to compute the buoyant plume trajectory. Higher value = less accurate plume trajectory. Recommended value: 1 s.",
+    "units": "[s]",
+    "can_be_modified": "Y"
+  },
+  "sor_option_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "SOR solver option: 0 = standard SOR, 1 = memory SOR. Recommended value: 1.",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "sor_alpha_plume_center": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "1-10",
+    "description": "SOR alpha! value (plume centerline). Higher value = w-component in the cells affected by the plumes is modified less by the SOR solver. Recommended value: 10.",
+    "units": "[-]",
+    "can_be_modified": "N"
+  },
+  "sor_alpha_plume_edge": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "1-10",
+    "description": "SOR alpha! value (plume periphery). Higher value = w-component in the cells affected by the plumes is modified less by the SOR solver. Recommended value: 1.",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "max_plume_merging_angle": {
+    "data_type": "REAL",
+    "values_accepted": "(0, 180]",
+    "tested_values_range": "30-60",
+    "description": "Maximum angle between plumes to determine if they can be merged. Higher value = more plumes merged. Recommended value: 30 deg.",
+    "units": "[deg]",
+    "can_be_modified": "N"
+  },
+  "max_plume_overlap_fraction": {
+    "data_type": "REAL",
+    "values_accepted": "(0, 1]",
+    "tested_values_range": "0.7-1",
+    "description": "Maximum fraction of a plume P trajectory length used to determine if a plume Q overlaps enough to be merged. Higher value = more plumes merged. Recommended value: 0.7.",
+    "units": "[deg]",
+    "can_be_modified": "N"
+  },
+  "plume_to_grid_updrafts_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Method to compute the plume-to-grid updrafts. 0 = new method, needed if smoke is simulated afterwards. Takes longer. 1 = old method. Recommended value: 1.",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "max_points_along_plume_edge": {
+    "data_type": "INT",
+    "values_accepted": "[1, 100]",
+    "tested_values_range": "[2-10]",
+    "description": "How many points to sample along the QU cells edges for the new method (line above). Recommended value: 10.",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "plume_to_grid_intersection_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Scheme to compute the plume-to-grid updrafts when more than one plume intersects with a QU cell. 0 = use the cube method. 1 = use the max value. Recommended value: 1.",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/QP_buildout.inp.json b/quicfire_tools/inputs/documentation/QP_buildout.inp.json
new file mode 100644
index 0000000..97908d8
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QP_buildout.inp.json
@@ -0,0 +1,12 @@
+{
+    "num_buildings":{
+        "values_accepted": "0",
+        "description": "total number of buildings",
+        "can_be_modified": "N"
+    },
+    "num_canopies": {
+        "values_accepted": "0",
+        "description": "total number of vegitative canopies",
+        "can_be_modified": "N"
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/QUIC_fire.inp.json b/quicfire_tools/inputs/documentation/QUIC_fire.inp.json
new file mode 100644
index 0000000..16d23eb
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QUIC_fire.inp.json
@@ -0,0 +1,277 @@
+{
+    "fire_flag": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "0 = only QUIC-URB simulation, no other input required",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "random_seed": {
+        "values_accepted": "[-1 +Inf)",
+        "tested_values_range": "Any",
+        "description": "accepted: -1 = use time and date to define the random number seed, >0 = use specified value to initialize random number generator",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "Any integer > 0"
+    },
+    "time_now": {
+        "values_accepted": ">= 0",
+        "tested_values_range": "Any",
+        "description": "When the fire is ignited in Unix Epoch time, i.e., integer seconds since 1/1/1970 00:00:00 (fire must start at or after the first wind, see QU_simparams.inp)",
+        "units": "[s]",
+        "can_be_modified": "N"
+    },
+    "sim_time": {
+        "values_accepted": "> 0",
+        "tested_values_range": "(0 10800]",
+        "description": "Total simulation time for the fire model. Higher value = longer simulation",
+        "units": "[s]",
+        "can_be_modified": "Y"
+    },
+    "fire_time_step": {
+        "values_accepted": "> 0",
+        "tested_values_range": "1-10",
+        "description": "Time step for the simulation for the fire model. Higher value = less accurate simulation",
+        "units": "[s]",
+        "can_be_modified": "N",
+        "recommended_value": "1 s"
+    },
+    "quic_time_step": {
+        "values_accepted": ">= 1",
+        "tested_values_range": "1-5",
+        "description": "Number of fire time steps done before updating the wind field. Higher value = less accurate simulation (less coupling between winds and fire)",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "1 to 5"
+    },
+    "out_time_fire": {
+        "values_accepted": ">= 1 or -1",
+        "tested_values_range": "1-100 and -1",
+        "description": "Number of updates of the fire before printing the output files for the fire model (all but emissions and thermal radiation). Higher value = less output. Use -1 to provide custom times in file QFire_ListOutputTimes.inp",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "4 or higher."
+    },
+    "out_time_wind": {
+        "values_accepted": ">= 1 or -1",
+        "tested_values_range": "1-100 and -1",
+        "description": "Number of updates of the wind field before printing the output files for the instantaneous QUIC-URB winds. Higher value = less output. Recommended value 2 or higher. Use -1 to provide custom times in file QFire_ListOutputTimes.inp",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "2 or higher."
+    },
+    "out_time_emis_rad": {
+        "values_accepted": ">= 1 or -1",
+        "tested_values_range": "1-100 and -1",
+        "description": "Number of updates of the fire before printing the output files for the emissions and thermal radiation. Higher value = less output. Use -1 to provide custom times in file QFire_ListOutputTimes.inp",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "out_time_wind_avg": {
+        "values_accepted": ">= 1 or -1",
+        "tested_values_range": "1-100 and -1",
+        "description": "Number of updates of the wind field before printing the output files for the average QUIC- URB winds (needed for smoke calculations). Higher value = less output. Use -1 to provide custom times in file QFire_ListOutputTimes.inp",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "nz": {
+        "values_accepted": ">= 1",
+        "tested_values_range": "1-100",
+        "description": "Number of cells in the vertical direction for the fire model. See below how to determine the number of cells.",
+        "units": "[-]",
+        "can_be_modified": "N"
+    },
+    "stretch_grid_flag": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0",
+        "description": "Vertical spacing model: 0 = constant dz, only one value must follow",
+        "units": "[-]",
+        "can_be_modified": "N",
+        "recommended_value": "0"
+    },
+    "dz_array": {
+        "values_accepted": "> 0",
+        "tested_values_range": "1-10",
+        "description": "Fire model cell size in the vertical direction. If stretchflag == 0: defaults to 1 m. If stretchflag == 1: list of values. Number of values must equal number of cells in the vertical direction. Higher value = less accurate fire and fuel description",
+        "units": "[m]",
+        "can_be_modified": "Y",
+        "recommended_value": "1 m"
+    },
+    "file_path": {
+        "values_accepted": "-",
+        "tested_values_range": "Any",
+        "description": "Files it refers to: treesrhof.dat; treesmoist.dat; treesfueldepth.dat; ignite.dat; rasterorigin.txt; gridlist. Empty quotes '': Firetec files are in the same folders of all other inputs. Path within quotes, with folder separator at the end: Firetec files are in teh specified folder",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "fuel_file_type": {
+        "values_accepted": "[1-2]",
+        "tested_values_range": "1-2",
+        "description": "Format of the trees* files: 1 = all fuel types are in one file; 2 = files are broken down by fuel type and named with '_#' to reduce peak RAM use",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "fuel_file_format": {
+        "values_accepted": "[1-2]",
+        "tested_values_range": "1-2",
+        "description": "Format of the trees* files: 1 = binary files have stream format (ARA format); 2 = binary files have Fortran headers",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "1"
+    },
+    "fuel_flag": {
+        "values_accepted": "[1-4]",
+        "tested_values_range": "1-4",
+        "description": "Flag for fuel density, moisture, and height: 1 = density/moisture/height is uniform over the domain and provided with the next line input; 2 = density/moisture/height is provided through QF_FuelDensity.inp/QF_FuelMoisture.inp/QF_FuelHeight.inp; 3 = density/moisture/height is provided through Firetec file (treesrhof.dat/treesmoist.dat/treesdepth.dat) matching QUIC-Fire grid; 4 = density/moisture/height is provided through Firetec files for an arbitrary grid. The files gridlist and rasterorigin.txt must also be provided",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "fuel_density": {
+        "values_accepted": "> 0",
+        "tested_values_range": "0.2-3",
+        "description": "Fuel density",
+        "units": "[kg/m**3]",
+        "can_be_modified": "Y"
+    },
+    "fuel_moisture": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0-1",
+        "description": "Fuel moisture = mass of water/mass of dry fuel",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "fuel_height": {
+        "values_accepted": "> 0",
+        "tested_values_range": "0.7-3.0",
+        "description": "Fuel height",
+        "units": "[m]",
+        "can_be_modified": "Y"
+    },
+    "ignition_flag": {
+        "values_accepted": "[1 6]",
+        "tested_values_range": "1-6",
+        "description": "Ignition source shape flag: 1 = rectangle; 2 = square ring; 3 = circular ring; 4 = initial ignition locations provided through file QF_Ignitions.inp; 5 = time- and space-dependent ignition locations provided through file QF_IgnitionPattern.inp; 6 = ignite.dat (Firetec file); (NOTE: Flag of 7 seems to work better for ignite.dat - NJT)",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "6 (NJT recommendation: 7)"
+    },
+    "ignitions_per_cell": {
+        "values_accepted": "> 0",
+        "tested_values_range": "10-10000",
+        "description": "Number of ignition per cell of the fire model",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "100 (seems to have no effect). (CHANGED RECOMMENDATION PER QF MEETINGS: 2)"
+    },
+    "firebrand_flag": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag: 0 = firrebrands are off; 1 = firebrands are on",
+        "units": "[-]",
+        "can_be_modified": "N",
+        "recommended_value": "0 (firebrands are untested for small scale problems)"
+    },
+    "eng_to_atm_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the gridded energy-to-atmoshpere. File name: fire-energy_to_atmos-XXXXX.bin",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "react_rate_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the gridded reaction rate. File name: fire-reaction_rate-XXXXX.bin",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "fuel_dens_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the gridded fuel density. File name: fuels-dens-XXXXX.bin. NOTE: if 'emissions_out' is set to 4, this flag is set to 1 independently from the user choice",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "qf_wind_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the gridded wind components (u,v,w) for the fire grid. File names: winduXXXXX.bin = x-component; windvXXXXX.bin = y-component; windwXXXXX.bin = z-component",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "qu_wind_inst_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the gridded wind components (u,v,w) for the QUIC-URB grid. File names: qf_winduXXXXX.bin = x-component; qf_windvXXXXX.bin = y-component; qu_windwXXXXX.bin = z-component; qu_wplumeXXXXX.bin = w field from buoyant plumes, before mass consistency",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "qu_wind_avg_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the gridded average wind components (u,v,w) for the QUIC-URB grid. File names: qf_windu_aveXXXXX.bin = x-component; qu_windv_aveXXXXX.bin = y-component; qu_windw_aveXXXXX.bin = z-component. Set to 1 only if QUIC-Smoke is run for PM2.5 and CO plume transport and dispersion simulations",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "0"
+    },
+    "plume_traj_out": {
+        "values_accepted": "[0 2]",
+        "tested_values_range": "0, 2",
+        "description": "Flag to output the plume trajectories: 0 = do not output; 1 = use csv format; 2 = use binary format. File names: plume_trajectory.bin or csv; plume_mergetrajectory.bin or csv",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "0 (Files will be huge, used for debugging only)"
+    },
+    "fuel_moist_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the fuel moisture. File name: fuels-moist-XXXXX.bin",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "mass_burnt_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the vertically-integrated % mass burnt. File name: mburnt_integ-XXXXX.bin",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "firebrand_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the firebrands trajectories. File name: firebrabrands_traj.bin",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "0"
+    },
+    "emissions_out": {
+        "values_accepted": "[0 4]",
+        "tested_values_range": "[0 4]",
+        "description": "Flag for emissions: 0 = do not output any emission related variables; 1 = output emissions fiiles and simulate CO in QUIC-SMOKE; 2 = output emissions files and simulate PM2.5 in QUIC-SMOKE; 3 = output emissions files and simulate both CO and PM2.5 in QUIC-SMOKE; 4 = output emissions files but use library approach in QUIC-SMOKE; 5 = output emissions files and simulate both water in QUIC-SMOKE. File names: pm_emissions-XXXXX.bin; emissions_distribution-XXXXX.bin; co_emissions-XXXXX.bin; water_emissions-XXXXX.bin. Note; to run smoke transport and dispersion, the 'QU_winds_avg_out' must be set to 1 too",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "radiation_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) the thermal radiation. File names: thermalradiation-XXXXX.bin; thermaldose-XXXXX.bin",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "0"
+    },
+    "intensity_out": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to output (1) or not (0) surface fire intensity at every fire time step",
+        "units": "[-]",
+        "can_be_modified": "Y",
+        "recommended_value": "0"
+    },
+    "auto_kill": {
+        "values_accepted": "[0 1]",
+        "tested_values_range": "0, 1",
+        "description": "Flag to kill (1) or not (0) the simulation oif the fire goes out and there are no more ignitions or firebrands or plumes. The fuel and winds will be dumped at this last time step",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/QU_Simparams.inp.json b/quicfire_tools/inputs/documentation/QU_Simparams.inp.json
new file mode 100644
index 0000000..72f0ed0
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QU_Simparams.inp.json
@@ -0,0 +1,175 @@
+{
+  "nx": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "100-2000",
+    "description": "Number of cells in the x-direction",
+    "units": "[-]",
+    "recommended_value": "> 100"
+  },
+  "ny": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "100-2000",
+    "description": "Number of cells in the y-direction",
+    "units": "[-]",
+    "recommended_value": "> 100"
+  },
+  "nz": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "10-100",
+    "description": "Number of cells in the z-direction",
+    "units": "[-]"
+  },
+  "dx": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.5-250",
+    "description": "Cell size in the x-direction",
+    "units": "[m]",
+    "recommended_value": "2 m"
+  },
+  "dy": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.5-250",
+    "description": "Cell size in the y-direction",
+    "units": "[m]",
+    "recommended_value": "2 m"
+  },
+  "stretch_grid_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1, 2, 3, 4]",
+    "tested_values_range": "[0, 1, 3]",
+    "description": "Vertical grid stretching flag",
+    "units": "[-]",
+    "recommended_value": "3"
+  },
+  "surface_vertical_cell_size": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.5-5",
+    "description": "Surface vertical cell size",
+    "units": "[m]"
+  },
+  "number_surface_cells": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "1-5",
+    "description": "Number of cells with uniform cell size at the surface",
+    "units": "[-]"
+  },
+  "dz_array": {
+    "data_type": "REAL",
+    "values_accepted": "> 0",
+    "tested_values_range": "0.5-200",
+    "description": "Values of the vertical cell sizes",
+    "units": "[m]"
+  },
+  "utc_offset": {
+    "data_type": "INT",
+    "values_accepted": "[-12, +12]",
+    "tested_values_range": "-12 - +12",
+    "description": "Hours difference from UTM",
+    "units": "[h]"
+  },
+  "wind_times": {
+    "data_type": "INT",
+    "values_accepted": "0 - Inf",
+    "tested_values_range": "0 - Inf",
+    "description": "List of times at which the winds are available in Unix Epoch time",
+    "units": "[s]"
+  },
+  "sor_iter_max": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "[1, 500]",
+    "description": "Maximum number of iterations of the SOR wind solver",
+    "units": "[-]",
+    "recommended_value": "10"
+  },
+  "sor_residual_reduction": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "[1, 5]",
+    "description": "Residual reduction to assess convergence of the SOR solver",
+    "units": "[-]",
+    "recommended_value": "3"
+  },
+  "use_diffusion_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Use diffusion algorithm",
+    "units": "[-]",
+    "recommended_value": "0"
+  },
+  "number_diffusion_iterations": {
+    "data_type": "INT",
+    "values_accepted": "> 0",
+    "tested_values_range": "[0, 50]",
+    "description": "Number of diffusion iterations",
+    "units": "[-]"
+  },
+  "domain_rotation": {
+    "data_type": "REAL",
+    "values_accepted": "[-90, +90]",
+    "tested_values_range": "[-90, +90]",
+    "description": "Domain rotation relative to true north",
+    "units": "[degrees]",
+    "recommended_value": "0 deg"
+  },
+  "utm_x": {
+    "data_type": "REAL",
+    "values_accepted": "Can go across UTM zones",
+    "tested_values_range": "",
+    "description": "UTM-x coordinates of the south-west corner of domain",
+    "units": "[m]"
+  },
+  "utm_y": {
+    "data_type": "REAL",
+    "values_accepted": "Can go across UTM zones",
+    "tested_values_range": "",
+    "description": "UTM-y coordinates of the south-west corner of domain",
+    "units": "[m]"
+  },
+  "utm_zone_number": {
+    "data_type": "INT",
+    "values_accepted": "[1, 60]",
+    "tested_values_range": "[1, 60]",
+    "description": "UTM zone number",
+    "units": "[-]"
+  },
+  "utm_zone_letter": {
+    "data_type": "INT",
+    "values_accepted": "[1, 26]",
+    "tested_values_range": "[1, 26]",
+    "description": "UTM zone letter (A=1, B=2,..)",
+    "units": "[-]"
+  },
+  "quic_cfd_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "QUIC-CFD flag",
+    "units": "[-]",
+    "recommended_value": "0"
+  },
+  "explosive_bldg_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Explosive building damage flag",
+    "units": "[-]",
+    "recommended_value": "0"
+  },
+  "bldg_array_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0, 1]",
+    "tested_values_range": "[0, 1]",
+    "description": "Building array flag",
+    "units": "[-]",
+    "recommended_value": "0"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/QU_TopoInputs.inp.json b/quicfire_tools/inputs/documentation/QU_TopoInputs.inp.json
new file mode 100644
index 0000000..30ab09a
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QU_TopoInputs.inp.json
@@ -0,0 +1,55 @@
+{
+    "filename": {
+        "values_accepted": "Any",
+        "tested_values_range": "Any",
+        "description": "Path to the custom topo file (only used with option 5). Cannot be .bin. Use .dat or .inp",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "topo_flag": {
+        "values_accepted": "[0 2]",
+        "tested_values_range": "[0 2]",
+        "description": "Topo flag: 0 = no terrain file provided, QUIC-Fire is run with flat terrain, 1 = Gaussian hill, 2 = hill pass, 3 = slope mesa, 4 = canyon, 5 = custom, 6 = half circle, 7 = sinusoid, 8 = cos hill, 9 = terrain is provided via QP_elevation.bin (see Section 2.7), 10 = terrain is provided via terrainOutput.txt, 11 = terrain.dat (firetec)",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "smoothing_method": {
+        "values_accepted": "[0 2]",
+        "tested_values_range": "[0 2]",
+        "description": "Smoothing method: 0 = none (default for idealized topo), 1 = Blur, 2 = David’s method based on second derivative",
+        "units": "[-]",
+        "recommended_value": "2 for real topo",
+        "can_be_modified": "Y"
+    },
+    "smoothing_passes": {
+        "values_accepted": "[0 500]",
+        "tested_values_range": "[0 200]",
+        "description": "Number of smoothing passes. Real terrain MUST be smoothed.",
+        "units": "[-]",
+        "recommended_value": "200 for real topo"
+    },
+    "sor_iterations": {
+        "values_accepted": "[0 500]",
+        "tested_values_range": "[0 500]",
+        "description": "Number of SOR iteration to define background winds before starting the fire",
+        "units": "[-]",
+        "recommended_value": "500 for real topo",
+        "can_be_modified": "Y"
+    },
+    "sor_cycles": {
+        "values_accepted": "[0 10]",
+        "tested_values_range": "[0 4]",
+        "description": "Number of times the SOR solver initial fields is reset to define background winds before starting the fire",
+        "units": "[-]",
+        "recommended_value": "4 for real topo",
+        "can_be_modified": "Y"
+    },
+    "sor_relax": {
+        "values_accepted": "[0 2]",
+        "tested_values_range": "[0.9 1.8]",
+        "description": "SOR overrelaxation coefficient. Only used if there is topo.",
+        "units": "[-]",
+        "recommended_value": "0.9-1.3 for real topo",
+        "can_be_modified": "Y"
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/QU_buildings.inp.json b/quicfire_tools/inputs/documentation/QU_buildings.inp.json
new file mode 100644
index 0000000..13e959b
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QU_buildings.inp.json
@@ -0,0 +1,25 @@
+{
+  "wall_roughness_length": {
+        "values_accepted": "> 0",
+        "tested_values_range": "> 0",
+        "description": "Wall roughness length",
+        "units": "[m]",
+        "can_be_modified": "N"
+    },
+    "number_of_buildings": {
+        "values_accepted": "> 0",
+        "tested_values_range": "[1, 30000]",
+        "description": "Number of buildings",
+        "units": "[-]",
+        "can_be_modified": "N",
+        "recommended_value": "0 (building algorithms are not part of QUIC-Fire)"
+    },
+    "number_of_polygon_nodes": {
+        "values_accepted": "> 0",
+        "tested_values_range": "[1, 500]",
+        "description": "Number of polygon building nodes",
+        "units": "[-]",
+        "can_be_modified": "N",
+        "recommended_value": "0"
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/QU_fileoptions.inp.json b/quicfire_tools/inputs/documentation/QU_fileoptions.inp.json
new file mode 100644
index 0000000..18961d9
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QU_fileoptions.inp.json
@@ -0,0 +1,51 @@
+{
+  "output_data_file_format_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0 3]",
+    "tested_values_range": "[0 3]",
+    "description": "Output data file format flag: 1 = ascii, 2 = binary, 3 = both",
+    "values": {
+      "1": "ascii",
+      "2": "binary",
+      "3": "both"
+    },
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "2"
+  },
+  "non_mass_conserved_initial_field_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0 1]",
+    "tested_values_range": "[0 1]",
+    "description": "Flag to write out non-mass conserved initial field (uofield.dat): 0 = do not write, 1 = write",
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "0"
+  },
+  "initial_sensor_velocity_field_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0 1]",
+    "tested_values_range": "[0 1]",
+    "description": "Flag to write out the file uosensorfield.dat, the initial sensor velocity field: 0 = do not write, 1 = write",
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "0"
+  },
+  "qu_staggered_velocity_file_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0 1]",
+    "tested_values_range": "[0 1]",
+    "description": "Flag to write out the file QU_staggered_velocity.bin used by QUIC-Pressure: 0 = do not write, 1 = write",
+    "units": "[-]",
+    "can_be_modified": "N",
+    "recommended_value": "0"
+  },
+  "generate_wind_startup_files_flag": {
+    "data_type": "INT",
+    "values_accepted": "[0 1]",
+    "tested_values_range": "[0 1]",
+    "description": "Generate wind startup files for ensemble simulations: 0 = do not write, 1 = write",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/QU_metparams.inp.json b/quicfire_tools/inputs/documentation/QU_metparams.inp.json
new file mode 100644
index 0000000..33280a5
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QU_metparams.inp.json
@@ -0,0 +1,16 @@
+{
+    "num_sensors": {
+        "values_accepted": "1",
+        "tested_values_range": "[1 Inf)",
+        "description": "Number of measuring sites",
+        "units": "[-]",
+        "can_be_modified": "N"
+    },
+    "sensor_name": {
+        "values_acepted": "sensor1",
+        "tested_values_range": "N/A",
+        "description": "Name of the wind profile",
+        "units": "[-]",
+        "can_be_modified": "N"
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/QU_movingcoords.inp.json b/quicfire_tools/inputs/documentation/QU_movingcoords.inp.json
new file mode 100644
index 0000000..432be37
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/QU_movingcoords.inp.json
@@ -0,0 +1,7 @@
+{
+    "moving_coordinates_flag": {
+        "values_accepted": "0",
+        "description": "Moving coordinates flag (0=no, 1=yes)",
+        "can_be_modified": "N"
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/Runtime_Advanced_User_Inputs.inp.json b/quicfire_tools/inputs/documentation/Runtime_Advanced_User_Inputs.inp.json
new file mode 100644
index 0000000..5459233
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/Runtime_Advanced_User_Inputs.inp.json
@@ -0,0 +1,17 @@
+{
+  "num_cpus":{
+    "data_type": "PositiveInt",
+    "values_accepted": ">0",
+    "tested_values_range": "[1, 8]",
+    "description": "Maximum number of CPU to use. Do not exceed 8. Use 1 for ensemble simulations.",
+    "units": "[-]",
+    "can_be_modified": "Y"
+  },
+  "use_acw":{
+    "data_type": "Literal[0, 1]",
+    "values_accepted": "0,1",
+    "tested_values_range": "[0,1]",
+    "description": "Use Adaptive Computation Window (0=Disabled 1=Enabled)",
+    "can_be_modified": "Y"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/TopoType.json b/quicfire_tools/inputs/documentation/TopoType.json
new file mode 100644
index 0000000..cdf912f
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/TopoType.json
@@ -0,0 +1,163 @@
+{
+    "gaussian_hill_topo": {
+        "x_hilltop": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "[0 Lx]",
+            "description": "Gaussian hill top location x-dir",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_hilltop": {
+            "values_accepted": "[0 Ly]",
+            "tested_values_range": "[0 Ly]",
+            "description": "Gaussian hill top location y-dir",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "elevation_max" : {
+            "values_accepted": "[0 Lz/3]",
+            "tested_values_range": "[0 Lz/3]",
+            "description": "Gaussian hill max elevation",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "elevation_std": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Gaussian hill standard deviation",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        }
+    },
+    "hill_pass_topo": {
+        "max_height": {
+            "values_accepted": "[0 Lz/3]",
+            "tested_values_range": "[0 Lz/3]",
+            "description": "Hill pass maximum height",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "location_param": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Hill pass location parameter",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        }
+    },
+    "slope_mesa_topo": {
+        "slope_axis": {
+            "values_accepted": "[0 1]",
+            "tested_values_range": "[0 1]",
+            "description": "Slope axis: 0=X, 1=Y",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "slope_value": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Slope in dh/dx or dh/dy",
+            "units": "[-]",
+            "can_be_modified": "Y"
+        },
+        "flat_fraction": {
+            "values_accepted": "[0 1]",
+            "tested_values_range": "[0 1]",
+            "description": "Fraction of domain that is flat",
+            "units": "[-]",
+            "can_be_modified": "Y"
+        }
+    },
+    "canyon_topo": {
+        "x_start": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "[0 Lx]",
+            "description": "Canyon location in x-dir",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_center": {
+            "values_accepted": "[0 Ly]",
+            "tested_values_range": "[0 Ly]",
+            "description": "Canyon location in x-dir",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "slope_value": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Slope in dh/dx or dh/dy",
+            "units": "[-]",
+            "can_be_modified": "Y"
+        },
+        "canyon_std": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Canyon function standard deviation",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "vertical_offset": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Canyon vertical offset",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        }
+    },
+    "half_circle_topo": {
+        "x_location": {
+            "values_accepted": "[0 Lx]",
+            "tested_values_range": "[0 Lx]",
+            "description": "Half circle x-location",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "y_location": {
+            "values_accepted": "[0 Ly]",
+            "tested_values_range": "[0 Ly]",
+            "description": "Half circle y-location",
+            "units": "[m]",
+            "can_be_modified": "Y"
+        },
+        "radius": {
+            "values_accepted": ">0",
+            "tested_values_range": "(0 Lx/2)",
+            "description": "Half circle radius",
+            "units": "[-]",
+            "can_be_modified": "Y"
+        }
+    },
+    "sinusoid_topo": {
+        "period": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Sinusoid period",
+            "units": "[-]",
+            "can_be_modified": "Y"
+        },
+        "amplitude": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Sinusoid amplitude",
+            "units": "[-]",
+            "can_be_modified": "Y"
+        }
+    },
+    "cos_hill_topo": {
+        "aspect": {
+            "values_accepted": "> 0",
+            "tested_values_range": "> 0",
+            "description": "Hill aspect",
+            "units": "[-] (likely degree)",
+            "can_be_modified": "Y"
+        },
+        "height": {
+            "values_accepted": "[0 Lz/3]",
+            "tested_values_range": "[0 Lz/3]",
+            "description": "Hill height",
+            "units": "[-] (likely m)",
+            "can_be_modified": "Y"
+        }
+    }
+}
diff --git a/quicfire_tools/inputs/documentation/gridlist.json b/quicfire_tools/inputs/documentation/gridlist.json
new file mode 100644
index 0000000..68a9c78
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/gridlist.json
@@ -0,0 +1,46 @@
+{
+  "n": {
+      "values_accepted": "> 0",
+      "tested_values_range": "> 0",
+      "description": "Number of cells in the x-direction",
+      "units": "[-]"
+  },
+  "m": {
+      "values_accepted": "> 0",
+      "tested_values_range": "> 0",
+      "description": "Number of cells in the y-direction",
+      "units": "[-]"
+  },
+  "l": {
+      "values_accepted": "> 0",
+      "tested_values_range": "> 0",
+      "description": "Number of cells in the z-direction",
+      "units": "[-]"
+  },
+  "dx": {
+      "values_accepted": "> 0",
+      "tested_values_range": "> 0",
+      "recommended_value": "2m",
+      "description": "Cell size in the x-direction",
+      "units": "[m]"
+  },
+  "dy": {
+      "values_accepted": "> 0",
+      "tested_values_range": "> 0",
+      "recommended_value": "2m",
+      "description": "Cell size in the y-direction",
+      "units": "[m]"
+  },
+  "dz": {
+      "values_accepted": "> 0",
+      "tested_values_range": "> 0",
+      "description": "Number that multiplied by the number of cells  in the z-direction would provide the height of the domain",
+      "units": "[m]"
+  },
+  "aa1": {
+      "values_accepted": "> 0",
+      "tested_values_range": "> 0",
+      "description": "Stretching factor for the vertical grid spacing",
+      "units": "[-]"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/rasterorigin.txt.json b/quicfire_tools/inputs/documentation/rasterorigin.txt.json
new file mode 100644
index 0000000..6e441d3
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/rasterorigin.txt.json
@@ -0,0 +1,17 @@
+{
+  "utm_x": {
+    "values_accepted": "> 0",
+    "tested_values_range": "> 0",
+    "description": "South-west corner of the Firetec domain, UTM-x",
+    "units": "[m]",
+    "variable_name_fortran": "ft%utmx"
+  },
+
+  "utm_y": {
+    "values_accepted": "> 0",
+    "tested_values_range": "> 0",
+    "description": "South-west corner of the Firetec domain, UTM-y",
+    "units": "[m]",
+    "variable_name_fortran": "ft%utmy"
+  }
+}
diff --git a/quicfire_tools/inputs/documentation/sensor1.inp.json b/quicfire_tools/inputs/documentation/sensor1.inp.json
new file mode 100644
index 0000000..e07423a
--- /dev/null
+++ b/quicfire_tools/inputs/documentation/sensor1.inp.json
@@ -0,0 +1,34 @@
+{
+    "time_now":{
+        "data_type": "NonNegativeInt",
+        "values_accepted": "[0 Inf)",
+        "tested_values": "[0 Inf)",
+        "description": "Beginning of time step in Unix Epoch time (integer seconds since 1970/1/1 00:00:00)",
+        "units": "[-]",
+        "can_be_modified": "Y"
+    },
+    "sensor_height": {
+        "data_type": "PositiveFloat",
+        "values_accepted": ">0",
+        "tested_values": "N/A",
+        "description": "Wind measurement height",
+        "units": "[m]",
+        "can_be_modified": "Y"
+    },
+    "wind_speed": {
+        "data_type": "PositiveFloat",
+        "values_accepted": ">0",
+        "tested_values": "N/A",
+        "description": "Wind speed",
+        "units": "[m/s]",
+        "can_be_modified": "Y"
+    },
+    "wind_direction": {
+        "data_type": "PositiveInt",
+        "values_accepted": "[0 359]",
+        "tested_values": "[0 359]",
+        "description": "Wind direction",
+        "units": "[degree]",
+        "can_be_modified": "Y"
+    }
+}
diff --git a/quicfire_tools/input-templates/latest/QFire_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.1.1/QFire_Advanced_User_Inputs.inp
old mode 100755
new mode 100644
similarity index 98%
rename from quicfire_tools/input-templates/latest/QFire_Advanced_User_Inputs.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QFire_Advanced_User_Inputs.inp
index 5ff63c7..6c70b36
--- a/quicfire_tools/input-templates/latest/QFire_Advanced_User_Inputs.inp
+++ b/quicfire_tools/inputs/templates/v5.1.1/QFire_Advanced_User_Inputs.inp
@@ -1,14 +1,14 @@
-0.05			! N/A, fraction of the cells on fire that will launch a firebrand
-40.			! N/A, scaling factor of the radius represented by the firebrands launched
-1				! s, time step for the firebrands trajectory calculation
-10				! s, how often to launch firebrands
-500			! N/A, number of firebrands distributed over the landing area
-20.			! N/A, FB_FRACTION_LAUNCHED_to_RT_ratio
-50.			! N/A, min_b_value_coef
-0.75			! N/A, fb_frac_of_max_size
-180			! s, germination_delay
-5.				! N/A, fraction of the cell on fire (to scale w)
-50				! N/A, minimum number of ignitions via firebrands at a point
-100			! N/A, maximum number of ignitions via firebrands at a point
-0.523598		! rad, min_theta_value (pi/6)
-0.03        ! m, fb thickness
+0.05			! N/A, fraction of the cells on fire that will launch a firebrand
+40.			! N/A, scaling factor of the radius represented by the firebrands launched
+1				! s, time step for the firebrands trajectory calculation
+10				! s, how often to launch firebrands
+500			! N/A, number of firebrands distributed over the landing area
+20.			! N/A, FB_FRACTION_LAUNCHED_to_RT_ratio
+50.			! N/A, min_b_value_coef
+0.75			! N/A, fb_frac_of_max_size
+180			! s, germination_delay
+5.				! N/A, fraction of the cell on fire (to scale w)
+50				! N/A, minimum number of ignitions via firebrands at a point
+100			! N/A, maximum number of ignitions via firebrands at a point
+0.523598		! rad, min_theta_value (pi/6)
+0.03        ! m, fb thickness
diff --git a/quicfire_tools/input-templates/v5.1.1/QFire_Bldg_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.1.1/QFire_Bldg_Advanced_User_Inputs.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.1.1/QFire_Bldg_Advanced_User_Inputs.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QFire_Bldg_Advanced_User_Inputs.inp
diff --git a/quicfire_tools/input-templates/v5.1.1/QFire_Plume_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.1.1/QFire_Plume_Advanced_User_Inputs.inp
similarity index 93%
rename from quicfire_tools/input-templates/v5.1.1/QFire_Plume_Advanced_User_Inputs.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QFire_Plume_Advanced_User_Inputs.inp
index 67b317e..b0b462e 100644
--- a/quicfire_tools/input-templates/v5.1.1/QFire_Plume_Advanced_User_Inputs.inp
+++ b/quicfire_tools/inputs/templates/v5.1.1/QFire_Plume_Advanced_User_Inputs.inp
@@ -10,7 +10,7 @@
 10             ! alpha 2 - plume centerline
 2              ! alpha 2 - plume edges
 30.            ! deg, max angle between plumes to merging
-0.7            ! N/A, fraction of overlap of plumes for merging 
+0.7            ! N/A, fraction of overlap of plumes for merging
 1              ! N/A, which wplume-to-grid scheme: 0 = new, 1 = old
 10             ! N/A, number of points per edge for new scheme (only new scheme)
 1              ! N/A, w computation: 1 = max(w), 0 = sum(w^3)
diff --git a/quicfire_tools/input-templates/v5.1.1/QP_buildout.inp b/quicfire_tools/inputs/templates/v5.1.1/QP_buildout.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.1.1/QP_buildout.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QP_buildout.inp
diff --git a/quicfire_tools/input-templates/v5.1.1/QUIC_fire.inp b/quicfire_tools/inputs/templates/v5.1.1/QUIC_fire.inp
similarity index 98%
rename from quicfire_tools/input-templates/v5.1.1/QUIC_fire.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QUIC_fire.inp
index 397a7a5..c8d6e63 100644
--- a/quicfire_tools/input-templates/v5.1.1/QUIC_fire.inp
+++ b/quicfire_tools/inputs/templates/v5.1.1/QUIC_fire.inp
@@ -40,4 +40,4 @@ $ignition_flag      ! 1 = rectangle, 2 = square ring, 3 = circular ring, 4 = fil
 0					! Output gridded thermal radiation (fire grid)
 0                   ! Output surface fire intensity at every fire time step
 ! AUTOKILL
-$auto_kill          ! Kill if the fire is out and there are no more ignitions or firebrands (0 = no, 1 = yes)
\ No newline at end of file
+$auto_kill          ! Kill if the fire is out and there are no more ignitions or firebrands (0 = no, 1 = yes)
diff --git a/quicfire_tools/input-templates/v5.1.1/QU_TopoInputs.inp b/quicfire_tools/inputs/templates/v5.1.1/QU_TopoInputs.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.1.1/QU_TopoInputs.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QU_TopoInputs.inp
diff --git a/quicfire_tools/input-templates/v5.1.1/QU_buildings.inp b/quicfire_tools/inputs/templates/v5.1.1/QU_buildings.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.1.1/QU_buildings.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QU_buildings.inp
diff --git a/quicfire_tools/input-templates/latest/QU_fileoptions.inp b/quicfire_tools/inputs/templates/v5.1.1/QU_fileoptions.inp
old mode 100755
new mode 100644
similarity index 86%
rename from quicfire_tools/input-templates/latest/QU_fileoptions.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QU_fileoptions.inp
index cd9678d..605458f
--- a/quicfire_tools/input-templates/latest/QU_fileoptions.inp
+++ b/quicfire_tools/inputs/templates/v5.1.1/QU_fileoptions.inp
@@ -1,6 +1,6 @@
-! QUIC 6.26 File Header
-2   !output data file format flag (1=ascii, 2=binary, 3=both)
-0   !flag to write out non-mass conserved initial field (uofield.dat) (1=write,0=no write)
-0   !flag to write out the file uosensorfield.dat, the initial sensor velocity field (1=write,0=no write)
-0   !flag to write out the file QU_staggered_velocity.bin used by QUIC-Pressure(1=write,0=no write)
-0   !flag to generate startup files (0 = no, 1 = yes)
\ No newline at end of file
+! QUIC 6.26 File Header
+2   !output data file format flag (1=ascii, 2=binary, 3=both)
+0   !flag to write out non-mass conserved initial field (uofield.dat) (1=write,0=no write)
+0   !flag to write out the file uosensorfield.dat, the initial sensor velocity field (1=write,0=no write)
+0   !flag to write out the file QU_staggered_velocity.bin used by QUIC-Pressure(1=write,0=no write)
+0   !flag to generate startup files (0 = no, 1 = yes)
diff --git a/quicfire_tools/input-templates/v5.1.1/QU_landuse.inp b/quicfire_tools/inputs/templates/v5.1.1/QU_landuse.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.1.1/QU_landuse.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QU_landuse.inp
diff --git a/quicfire_tools/input-templates/v5.2.3/QU_metparams.inp b/quicfire_tools/inputs/templates/v5.1.1/QU_metparams.inp
similarity index 88%
rename from quicfire_tools/input-templates/v5.2.3/QU_metparams.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QU_metparams.inp
index a41fb25..988c4ef 100644
--- a/quicfire_tools/input-templates/v5.2.3/QU_metparams.inp
+++ b/quicfire_tools/inputs/templates/v5.1.1/QU_metparams.inp
@@ -2,6 +2,6 @@
 0 !Met input flag (0=QUIC,1=WRF,2=ITT MM5,3=HOTMAC)
 1 !Number of measuring sites
 1 !Maximum size of data points profiles
-sensor1 !Site Name 
+sensor1 !Site Name
 !File name
 sensor1.inp
diff --git a/quicfire_tools/input-templates/v5.1.1/QU_movingcoords.inp b/quicfire_tools/inputs/templates/v5.1.1/QU_movingcoords.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.1.1/QU_movingcoords.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QU_movingcoords.inp
diff --git a/quicfire_tools/input-templates/v5.1.1/QU_simparams.inp b/quicfire_tools/inputs/templates/v5.1.1/QU_simparams.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.1.1/QU_simparams.inp
rename to quicfire_tools/inputs/templates/v5.1.1/QU_simparams.inp
diff --git a/quicfire_tools/inputs/templates/v5.1.1/Runtime_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.1.1/Runtime_Advanced_User_Inputs.inp
new file mode 100644
index 0000000..980f37f
--- /dev/null
+++ b/quicfire_tools/inputs/templates/v5.1.1/Runtime_Advanced_User_Inputs.inp
@@ -0,0 +1,1 @@
+$num_cpus  ! max number of cpu
diff --git a/quicfire_tools/input-templates/v5.1.1/gridlist b/quicfire_tools/inputs/templates/v5.1.1/gridlist
similarity index 99%
rename from quicfire_tools/input-templates/v5.1.1/gridlist
rename to quicfire_tools/inputs/templates/v5.1.1/gridlist
index dfa168f..a55adba 100644
--- a/quicfire_tools/input-templates/v5.1.1/gridlist
+++ b/quicfire_tools/inputs/templates/v5.1.1/gridlist
@@ -92,4 +92,4 @@
        nonos=1 nfct=1 nonosold=1
        inonlocal=0 isubgridgas=0
        !st=1.0e-05
-/
\ No newline at end of file
+/
diff --git a/quicfire_tools/input-templates/latest/rasterorigin.txt b/quicfire_tools/inputs/templates/v5.1.1/rasterorigin.txt
similarity index 92%
rename from quicfire_tools/input-templates/latest/rasterorigin.txt
rename to quicfire_tools/inputs/templates/v5.1.1/rasterorigin.txt
index b0916ba..3549dca 100644
--- a/quicfire_tools/input-templates/latest/rasterorigin.txt
+++ b/quicfire_tools/inputs/templates/v5.1.1/rasterorigin.txt
@@ -4,4 +4,4 @@
 3752846.04249607
 742265.868913356
 3742846.04249607
-10000
\ No newline at end of file
+10000
diff --git a/quicfire_tools/input-templates/latest/sensor1.inp b/quicfire_tools/inputs/templates/v5.1.1/sensor1.inp
similarity index 96%
rename from quicfire_tools/input-templates/latest/sensor1.inp
rename to quicfire_tools/inputs/templates/v5.1.1/sensor1.inp
index 3713549..7d72798 100644
--- a/quicfire_tools/input-templates/latest/sensor1.inp
+++ b/quicfire_tools/inputs/templates/v5.1.1/sensor1.inp
@@ -1,4 +1,4 @@
-sensor1 !Site Name 
+sensor1 !Site Name
 0 !Upper level flag (1 = use this profile for upper level winds)
 50 !Upper level height (meters)
 1 !Site Coordinate Flag (1=QUIC, 2=UTM, 3=Lat/Lon)
diff --git a/quicfire_tools/input-templates/v5.2.3/QFire_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.2.3/QFire_Advanced_User_Inputs.inp
similarity index 98%
rename from quicfire_tools/input-templates/v5.2.3/QFire_Advanced_User_Inputs.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QFire_Advanced_User_Inputs.inp
index 5ff63c7..6c70b36 100755
--- a/quicfire_tools/input-templates/v5.2.3/QFire_Advanced_User_Inputs.inp
+++ b/quicfire_tools/inputs/templates/v5.2.3/QFire_Advanced_User_Inputs.inp
@@ -1,14 +1,14 @@
-0.05			! N/A, fraction of the cells on fire that will launch a firebrand
-40.			! N/A, scaling factor of the radius represented by the firebrands launched
-1				! s, time step for the firebrands trajectory calculation
-10				! s, how often to launch firebrands
-500			! N/A, number of firebrands distributed over the landing area
-20.			! N/A, FB_FRACTION_LAUNCHED_to_RT_ratio
-50.			! N/A, min_b_value_coef
-0.75			! N/A, fb_frac_of_max_size
-180			! s, germination_delay
-5.				! N/A, fraction of the cell on fire (to scale w)
-50				! N/A, minimum number of ignitions via firebrands at a point
-100			! N/A, maximum number of ignitions via firebrands at a point
-0.523598		! rad, min_theta_value (pi/6)
-0.03        ! m, fb thickness
+0.05			! N/A, fraction of the cells on fire that will launch a firebrand
+40.			! N/A, scaling factor of the radius represented by the firebrands launched
+1				! s, time step for the firebrands trajectory calculation
+10				! s, how often to launch firebrands
+500			! N/A, number of firebrands distributed over the landing area
+20.			! N/A, FB_FRACTION_LAUNCHED_to_RT_ratio
+50.			! N/A, min_b_value_coef
+0.75			! N/A, fb_frac_of_max_size
+180			! s, germination_delay
+5.				! N/A, fraction of the cell on fire (to scale w)
+50				! N/A, minimum number of ignitions via firebrands at a point
+100			! N/A, maximum number of ignitions via firebrands at a point
+0.523598		! rad, min_theta_value (pi/6)
+0.03        ! m, fb thickness
diff --git a/quicfire_tools/input-templates/latest/QFire_Bldg_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.2.3/QFire_Bldg_Advanced_User_Inputs.inp
similarity index 100%
rename from quicfire_tools/input-templates/latest/QFire_Bldg_Advanced_User_Inputs.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QFire_Bldg_Advanced_User_Inputs.inp
diff --git a/quicfire_tools/input-templates/latest/QFire_Plume_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.2.3/QFire_Plume_Advanced_User_Inputs.inp
similarity index 92%
rename from quicfire_tools/input-templates/latest/QFire_Plume_Advanced_User_Inputs.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QFire_Plume_Advanced_User_Inputs.inp
index a1d2b25..b0b462e 100755
--- a/quicfire_tools/input-templates/latest/QFire_Plume_Advanced_User_Inputs.inp
+++ b/quicfire_tools/inputs/templates/v5.2.3/QFire_Plume_Advanced_User_Inputs.inp
@@ -1,16 +1,16 @@
-150000				! N/A, max number of plume at each time step
-0.1				! m/s, minimum vertical velocity of a plume. If wc is below minimum, the plume is eliminated (default 0.1 m/s)
-100				! m/s, maximum vertical velocity of a plume (default 100 m/s)
-0.1				! N/A, minimum speed ratio (plume vertical velocity/wind speed). If below, the plume is eliminated (default 0.1)
-0.					! 1/s2, brunt vaisala frequency squared
-1					! N/A creeping flag: 0 = off, 1 = on
-0					! Flag time step (0 = constant, 1 = adaptive)
-1              ! s, flag = 0: plumes time step plume, flag = 1: minimum plumes time step
-1              ! sor option (0 = reset lambda at each call, 1 = keep)
-10             ! alpha 2 - plume centerline
-2              ! alpha 2 - plume edges
-30.            ! deg, max angle between plumes to merging
-0.7            ! N/A, fraction of overlap of plumes for merging 
-1              ! N/A, which wplume-to-grid scheme: 0 = new, 1 = old
-10             ! N/A, number of points per edge for new scheme (only new scheme)
-1              ! N/A, w computation: 1 = max(w), 0 = sum(w^3)
+150000				! N/A, max number of plume at each time step
+0.1				! m/s, minimum vertical velocity of a plume. If wc is below minimum, the plume is eliminated (default 0.1 m/s)
+100				! m/s, maximum vertical velocity of a plume (default 100 m/s)
+0.1				! N/A, minimum speed ratio (plume vertical velocity/wind speed). If below, the plume is eliminated (default 0.1)
+0.					! 1/s2, brunt vaisala frequency squared
+1					! N/A creeping flag: 0 = off, 1 = on
+0					! Flag time step (0 = constant, 1 = adaptive)
+1              ! s, flag = 0: plumes time step plume, flag = 1: minimum plumes time step
+1              ! sor option (0 = reset lambda at each call, 1 = keep)
+10             ! alpha 2 - plume centerline
+2              ! alpha 2 - plume edges
+30.            ! deg, max angle between plumes to merging
+0.7            ! N/A, fraction of overlap of plumes for merging
+1              ! N/A, which wplume-to-grid scheme: 0 = new, 1 = old
+10             ! N/A, number of points per edge for new scheme (only new scheme)
+1              ! N/A, w computation: 1 = max(w), 0 = sum(w^3)
diff --git a/quicfire_tools/input-templates/latest/QFire_Pyvista.inp b/quicfire_tools/inputs/templates/v5.2.3/QFire_Pyvista.inp
similarity index 99%
rename from quicfire_tools/input-templates/latest/QFire_Pyvista.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QFire_Pyvista.inp
index d2a32d6..af7515e 100644
--- a/quicfire_tools/input-templates/latest/QFire_Pyvista.inp
+++ b/quicfire_tools/inputs/templates/v5.2.3/QFire_Pyvista.inp
@@ -25,4 +25,3 @@ camOrbit=0
 windBarNormalized=none
 windBarBounds=[-10.0,10.0]
 compile=0 run=1 compiler='gfortran' compiler_mode='release' testcase='LineFire' ./adv_compile_and_run.sh
-
diff --git a/quicfire_tools/input-templates/v5.2.3/QP_buildout.inp b/quicfire_tools/inputs/templates/v5.2.3/QP_buildout.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.2.3/QP_buildout.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QP_buildout.inp
diff --git a/quicfire_tools/inputs/templates/v5.2.3/QUIC_fire.inp b/quicfire_tools/inputs/templates/v5.2.3/QUIC_fire.inp
new file mode 100644
index 0000000..958623b
--- /dev/null
+++ b/quicfire_tools/inputs/templates/v5.2.3/QUIC_fire.inp
@@ -0,0 +1,42 @@
+$fire_flag         ! Fire flag: 1 = run fire; 0 = no fire
+$random_seed               ! Random number generator: -1: use time and date, any other integer > 0 is used as the seed
+! FIRE TIMES
+$time_now		    ! When the fire is ignited in Unix Epoch time (integer seconds since 1970/1/1 00:00:00). Must be greater or equal to the time of the first wind
+$sim_time			! Total simulation time for the fire [s]
+$fire_time_step		! time step for the fire simulation [s]
+$quic_time_step		! Number of fire time steps done before updating the quic wind field (integer, >= 1)
+$out_time_fire      ! After how many fire time steps to print out fire-related files (excluding emissions and radiation)
+$out_time_wind      ! After how many quic updates to print out wind-related files
+$out_time_emis_rad  ! After how many fire time steps to average emissions and radiation
+$out_time_wind_avg  ! After how many quic updates to print out averaged wind-related files
+! FIRE GRID
+$nz					! Number of vertical layers of fire grid cells (integer)
+$stretch_grid_flag  ! Vertical stretching flag: 0 = uniform dz, 1 = custom
+$_stretch_grid_input ! m, dz
+! FILE PATH
+""
+1                   ! Fuel types are in separate files
+2                   ! File is stream (1) or headers (2)
+! FUEL
+$_fuel_lines
+! IGNITION LOCATIONS
+$_ignition_lines
+$ignitions_per_cell ! number of ignitions
+! FIREBRANDS
+$firebrand_flag		! 0 = off, 1 = on
+! OUTPUT FILES (formats depend on the grid type flag)
+$eng_to_atm_out		! Output gridded energy-to-atmosphere (3D fire grid + extra layers)
+$react_rate_out		! Output compressed array reaction rate (fire grid)
+$fuel_dens_out		! Output compressed array fuel density (fire grid)
+$QF_wind_out	    ! Output gridded wind (u,v,w,sigma) (3D fire grid)
+$QU_wind_inst_out	! Output gridded QU winds with fire effects, instantaneous (QUIC-URB grid)
+$QU_wind_avg_out		! Output gridded QU winds with fire effects, averaged (QUIC-URB grid)
+0					! Output plume trajectories (ONLY FOR DEBUG)
+$fuel_moist_out		! Output compressed array fuel moisture (fire grid)
+$mass_burnt_out		! Output vertically-integrated % mass burnt (fire grid)
+$firebrand_out		! Output trajectories firebrands
+$emissions_out		! Output compressed array emissions (fire grid)
+$radiation_out		! Output gridded thermal radiation (fire grid)
+$intensity_out      ! Output surface fire intensity at every fire time step
+! AUTOKILL
+$auto_kill          ! Kill if the fire is out and there are no more ignitions or firebrands (0 = no, 1 = yes)
diff --git a/quicfire_tools/inputs/templates/v5.2.3/QU_TopoInputs.inp b/quicfire_tools/inputs/templates/v5.2.3/QU_TopoInputs.inp
new file mode 100644
index 0000000..c8d5663
--- /dev/null
+++ b/quicfire_tools/inputs/templates/v5.2.3/QU_TopoInputs.inp
@@ -0,0 +1,11 @@
+Specify file name for custom topo (full path)
+$filename
+$_topo_lines
+$smoothing_method   ! N/A, smoothing method (0 = none (default for idealized terrain), 1 = blur, 2 = David's)
+$smoothing_passes   ! N/A, number of smoothing passes
+$sor_iterations     ! N/A, number of initial SOR iterations (only if fire is run)
+$sor_cycles         ! N/A, sor cycles
+$sor_relax          ! N/A, sor relaxation parameter (default for flat is 1.78, ignored if there is no terrain)
+0                   ! N/A, add slope flow correction (0 = no, 1 = yes)
+Command to run slope flow code (system specific)
+""
diff --git a/quicfire_tools/input-templates/latest/QU_buildings.inp b/quicfire_tools/inputs/templates/v5.2.3/QU_buildings.inp
similarity index 96%
rename from quicfire_tools/input-templates/latest/QU_buildings.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QU_buildings.inp
index 6dd3867..db22cec 100755
--- a/quicfire_tools/input-templates/latest/QU_buildings.inp
+++ b/quicfire_tools/inputs/templates/v5.2.3/QU_buildings.inp
@@ -1,4 +1,4 @@
-!QUIC 6.26
-0.1			!Wall roughness length (m)
-0			!Number of Buildings
-0			!Number of Polygon Building Nodes
+!QUIC 6.26
+0.1			!Wall roughness length (m)
+0			!Number of Buildings
+0			!Number of Polygon Building Nodes
diff --git a/quicfire_tools/input-templates/v5.2.3/QU_fileoptions.inp b/quicfire_tools/inputs/templates/v5.2.3/QU_fileoptions.inp
similarity index 86%
rename from quicfire_tools/input-templates/v5.2.3/QU_fileoptions.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QU_fileoptions.inp
index cd9678d..605458f 100755
--- a/quicfire_tools/input-templates/v5.2.3/QU_fileoptions.inp
+++ b/quicfire_tools/inputs/templates/v5.2.3/QU_fileoptions.inp
@@ -1,6 +1,6 @@
-! QUIC 6.26 File Header
-2   !output data file format flag (1=ascii, 2=binary, 3=both)
-0   !flag to write out non-mass conserved initial field (uofield.dat) (1=write,0=no write)
-0   !flag to write out the file uosensorfield.dat, the initial sensor velocity field (1=write,0=no write)
-0   !flag to write out the file QU_staggered_velocity.bin used by QUIC-Pressure(1=write,0=no write)
-0   !flag to generate startup files (0 = no, 1 = yes)
\ No newline at end of file
+! QUIC 6.26 File Header
+2   !output data file format flag (1=ascii, 2=binary, 3=both)
+0   !flag to write out non-mass conserved initial field (uofield.dat) (1=write,0=no write)
+0   !flag to write out the file uosensorfield.dat, the initial sensor velocity field (1=write,0=no write)
+0   !flag to write out the file QU_staggered_velocity.bin used by QUIC-Pressure(1=write,0=no write)
+0   !flag to generate startup files (0 = no, 1 = yes)
diff --git a/quicfire_tools/input-templates/v5.2.3/QU_landuse.inp b/quicfire_tools/inputs/templates/v5.2.3/QU_landuse.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.2.3/QU_landuse.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QU_landuse.inp
diff --git a/quicfire_tools/input-templates/v5.1.1/QU_metparams.inp b/quicfire_tools/inputs/templates/v5.2.3/QU_metparams.inp
similarity index 58%
rename from quicfire_tools/input-templates/v5.1.1/QU_metparams.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QU_metparams.inp
index a41fb25..5e21336 100644
--- a/quicfire_tools/input-templates/v5.1.1/QU_metparams.inp
+++ b/quicfire_tools/inputs/templates/v5.2.3/QU_metparams.inp
@@ -1,7 +1,5 @@
 !QUIC 6.26
 0 !Met input flag (0=QUIC,1=WRF,2=ITT MM5,3=HOTMAC)
-1 !Number of measuring sites
+$num_sensors    !Number of measuring sites
 1 !Maximum size of data points profiles
-sensor1 !Site Name 
-!File name
-sensor1.inp
+$_sensor_lines
diff --git a/quicfire_tools/input-templates/v5.2.3/QU_movingcoords.inp b/quicfire_tools/inputs/templates/v5.2.3/QU_movingcoords.inp
similarity index 100%
rename from quicfire_tools/input-templates/v5.2.3/QU_movingcoords.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QU_movingcoords.inp
diff --git a/quicfire_tools/input-templates/latest/QU_simparams.inp b/quicfire_tools/inputs/templates/v5.2.3/QU_simparams.inp
similarity index 96%
rename from quicfire_tools/input-templates/latest/QU_simparams.inp
rename to quicfire_tools/inputs/templates/v5.2.3/QU_simparams.inp
index 400ed26..ae1ee5e 100755
--- a/quicfire_tools/input-templates/latest/QU_simparams.inp
+++ b/quicfire_tools/inputs/templates/v5.2.3/QU_simparams.inp
@@ -1,67 +1,67 @@
-!QUIC 6.26
-$nx !nx - Domain Length(X) Grid Cells
-$ny !ny - Domain Width(Y) Grid Cells
-32 ! NZ - domain height(Z) grid cells
-$dx ! DX [m]
-$dy ! DY [m]
-3 !Vertical stretching flag (0 = uniform, 1 = custom, 2 = parabolic Z, 3 = parabolic DZ, 4 = exponential)
-1.000000 ! Surface DZ [m]
-5 ! Number of uniform surface cells
-! DZ array [m]
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.078399
-1.313596
-1.705591
-2.254385
-2.959976
-3.822366
-4.841553
-6.017539
-7.350323
-8.839905
-10.486285
-12.289463
-14.249439
-16.366213
-18.639786
-21.070156
-23.657325
-26.401292
-29.302056
-32.354352
-35.354352
-38.354352
-41.354352
-44.354352
-47.354352
-50.354352
-53.354352
-1 ! Number of time increments
-0 ! UTC conversion [hours]
-! Begining of time step in Unix epoch time [integer seconds since 1970/1/1 00:00:00]
-$timenow
-2 ! Rooftop flag (0 = none, 1 = log profile, 2 = vortex)
-3 ! Upwind cavity flag (0 = none, 1 = Rockle, 2 = MVP, 3 = HMVP)
-4 ! Street canyon flag (0 = none, 1 = Roeckle, 2 = CPB, 3 = exp. param. PKK, 4 = Roeckle w/ Fackrel)
-1 ! Street intersection flag (0 = off, 1 = on)
-4 ! Wake flag (0 = none, 1 = Rockle, 2 = modified Rockle, 3 = area scaled)
-1 ! Sidewall flag (0 = off, 1 = on)
-1 ! Individual tree wake flag
-2 ! Canopy flag (0 = off, 1 = Cionco w/o wakes, 2 = Cionco w/ wakes)
-1 ! Season flag (1 = Summer, 2 = Winter, 3 = Transition)
-10 ! Maximum number of iterations
-3 ! Residual reduction (Orders of Magnitude)
-0 ! Use diffusion algorithm (0 = off, 1 = on)
-20 ! Number of diffusion iterations
-0 ! Domain rotation relative to true north [degrees] (cw = +)
-0.0 ! UTMX of domain origin [m]
-0.0 ! UTMY of domain origin [m]
-1 ! UTM zone
-17 ! UTM zone leter (1 = A, 2 = B, etc.)
-0 ! QUIC-CFD Flag
-0 ! Explosive building damage flag (1 = on)
-0 ! Building Array Flag (1 = on)
+!QUIC 6.26
+$nx !nx - Domain Length(X) Grid Cells
+$ny !ny - Domain Width(Y) Grid Cells
+32 ! NZ - domain height(Z) grid cells
+$dx ! DX [m]
+$dy ! DY [m]
+3 !Vertical stretching flag (0 = uniform, 1 = custom, 2 = parabolic Z, 3 = parabolic DZ, 4 = exponential)
+1.000000 ! Surface DZ [m]
+5 ! Number of uniform surface cells
+! DZ array [m]
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.078399
+1.313596
+1.705591
+2.254385
+2.959976
+3.822366
+4.841553
+6.017539
+7.350323
+8.839905
+10.486285
+12.289463
+14.249439
+16.366213
+18.639786
+21.070156
+23.657325
+26.401292
+29.302056
+32.354352
+35.354352
+38.354352
+41.354352
+44.354352
+47.354352
+50.354352
+53.354352
+1 ! Number of time increments
+0 ! UTC conversion [hours]
+! Begining of time step in Unix epoch time [integer seconds since 1970/1/1 00:00:00]
+$timenow
+2 ! Rooftop flag (0 = none, 1 = log profile, 2 = vortex)
+3 ! Upwind cavity flag (0 = none, 1 = Rockle, 2 = MVP, 3 = HMVP)
+4 ! Street canyon flag (0 = none, 1 = Roeckle, 2 = CPB, 3 = exp. param. PKK, 4 = Roeckle w/ Fackrel)
+1 ! Street intersection flag (0 = off, 1 = on)
+4 ! Wake flag (0 = none, 1 = Rockle, 2 = modified Rockle, 3 = area scaled)
+1 ! Sidewall flag (0 = off, 1 = on)
+1 ! Individual tree wake flag
+2 ! Canopy flag (0 = off, 1 = Cionco w/o wakes, 2 = Cionco w/ wakes)
+1 ! Season flag (1 = Summer, 2 = Winter, 3 = Transition)
+10 ! Maximum number of iterations
+3 ! Residual reduction (Orders of Magnitude)
+0 ! Use diffusion algorithm (0 = off, 1 = on)
+20 ! Number of diffusion iterations
+0 ! Domain rotation relative to true north [degrees] (cw = +)
+0.0 ! UTMX of domain origin [m]
+0.0 ! UTMY of domain origin [m]
+1 ! UTM zone
+17 ! UTM zone leter (1 = A, 2 = B, etc.)
+0 ! QUIC-CFD Flag
+0 ! Explosive building damage flag (1 = on)
+0 ! Building Array Flag (1 = on)
diff --git a/quicfire_tools/inputs/templates/v5.2.3/Runtime_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/v5.2.3/Runtime_Advanced_User_Inputs.inp
new file mode 100755
index 0000000..1083241
--- /dev/null
+++ b/quicfire_tools/inputs/templates/v5.2.3/Runtime_Advanced_User_Inputs.inp
@@ -0,0 +1,2 @@
+$num_cpus  ! max number of cpu threads used
+$use_acw  ! Use Adaptive Computation Window (0=Disabled 1=Enabled)
diff --git a/quicfire_tools/input-templates/latest/gridlist b/quicfire_tools/inputs/templates/v5.2.3/gridlist
similarity index 86%
rename from quicfire_tools/input-templates/latest/gridlist
rename to quicfire_tools/inputs/templates/v5.2.3/gridlist
index 4facaff..4c76e52 100644
--- a/quicfire_tools/input-templates/latest/gridlist
+++ b/quicfire_tools/inputs/templates/v5.2.3/gridlist
@@ -1,5 +1,5 @@
 n=$nx
-m=$ny 
+m=$ny
 l=$nz
 aa1=$dz
 nv=8
diff --git a/quicfire_tools/input-templates/v5.1.1/rasterorigin.txt b/quicfire_tools/inputs/templates/v5.2.3/rasterorigin.txt
similarity index 92%
rename from quicfire_tools/input-templates/v5.1.1/rasterorigin.txt
rename to quicfire_tools/inputs/templates/v5.2.3/rasterorigin.txt
index b0916ba..3549dca 100644
--- a/quicfire_tools/input-templates/v5.1.1/rasterorigin.txt
+++ b/quicfire_tools/inputs/templates/v5.2.3/rasterorigin.txt
@@ -4,4 +4,4 @@
 3752846.04249607
 742265.868913356
 3742846.04249607
-10000
\ No newline at end of file
+10000
diff --git a/quicfire_tools/inputs/templates/v5.2.3/sensor1.inp b/quicfire_tools/inputs/templates/v5.2.3/sensor1.inp
new file mode 100644
index 0000000..f944d5c
--- /dev/null
+++ b/quicfire_tools/inputs/templates/v5.2.3/sensor1.inp
@@ -0,0 +1,7 @@
+sensor1 !Site Name
+0 !Upper level flag (1 = use this profile for upper level winds)
+50 !Upper level height (meters)
+1 !Site Coordinate Flag (1=QUIC, 2=UTM, 3=Lat/Lon)
+1 !X coordinate (meters)
+1 !Y coordinate (meters)
+$_wind_lines
diff --git a/quicfire_tools/outputs.py b/quicfire_tools/outputs.py
index ac31c53..fa799e3 100644
--- a/quicfire_tools/outputs.py
+++ b/quicfire_tools/outputs.py
@@ -7,9 +7,6 @@
 import re
 from pathlib import Path
 
-# Internal imports
-from quicfire_tools.parameters import SimulationParameters
-
 # External imports
 import zarr
 import numpy as np
@@ -19,17 +16,17 @@
 FUELS_OUTPUTS = {
     "fire-energy_to_atmos": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
         "description": "Energy released to the atmosphere that generates "
-                       "buoyant plumes",
+        "buoyant plumes",
         "units": "kW",
     },
     "fire-reaction_rate": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
@@ -38,7 +35,7 @@
     },
     "fuels-dens": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
@@ -47,7 +44,7 @@
     },
     "fuels-moist": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
@@ -56,7 +53,7 @@
     },
     "groundfuelheight": {
         "file_format": "gridded",
-        "number_dimensions": 2,
+        "dimensions": ["y", "x"],
         "grid": "fire",
         "delimiter": None,
         "extension": ".bin",
@@ -65,41 +62,41 @@
     },
     "mburnt_integ": {
         "file_format": "gridded",
-        "number_dimensions": 2,
+        "dimensions": ["y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
         "description": "2D file containing the percentage of mass burnt for each (i,j) "
-                       "location on the fire grid (vertically integrated)",
+        "location on the fire grid (vertically integrated)",
         "units": "%",
     },
 }
 THERMAL_RADIATION_OUTPUTS = {
     "thermaldose": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
         "description": "The output shows the thermal flux to skin of a person "
-                       "collocated with fuel (for health effects).",
+        "collocated with fuel (for health effects).",
         "units": "(kW/m^2)^(4/3)s",
     },
     "thermalradiation": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
         "description": "The output shows the thermal flux to skin of a person "
-                       "collocated with fuel (for health effects).",
+        "collocated with fuel (for health effects).",
         "units": "kW/m^2",
     },
 }
 WIND_OUTPUTS = {
     "windu": {
         "file_format": "gridded",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "",
         "extension": ".bin",
@@ -108,7 +105,7 @@
     },
     "windv": {
         "file_format": "gridded",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "",
         "extension": ".bin",
@@ -117,7 +114,7 @@
     },
     "windw": {
         "file_format": "gridded",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "",
         "extension": ".bin",
@@ -128,22 +125,22 @@
 EMISSIONS_OUTPUTS = {
     "co-emissions": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
         "description": "Mass of CO emitted between two emission file output"
-                       "times in grams",
+        "times in grams",
         "units": "g",
     },
     "pm-emissions": {
         "file_format": "compressed",
-        "number_dimensions": 3,
+        "dimensions": ["z", "y", "x"],
         "grid": "fire",
         "delimiter": "-",
         "extension": ".bin",
         "description": "Mass of PM2.5 emitted between two emission file output"
-                       "times in grams",
+        "times in grams",
         "units": "g",
     },
 }
@@ -156,11 +153,22 @@
 
 
 class OutputFile:
-    def __init__(self, name: str, file_format: str, shape: tuple,
-                 grid: str, delimiter: str, extension: str,
-                 description: str, units: str, index_map=None):
+    def __init__(
+        self,
+        name: str,
+        file_format: str,
+        dimensions: list[str],
+        shape: tuple,
+        grid: str,
+        delimiter: str,
+        extension: str,
+        description: str,
+        units: str,
+        index_map=None,
+    ):
         self.name = name
         self.file_format = file_format
+        self.dimensions = dimensions
         self.shape = shape
         self.grid = grid
         self.delimiter = delimiter
@@ -170,21 +178,43 @@ def __init__(self, name: str, file_format: str, shape: tuple,
         self.times = []  # List of times corresponding to the timesteps
         self.filepaths = []  # List of file paths for each timestep
         function_mappings = {
-            'gridded': _process_gridded_bin,
-            'compressed': _process_compressed_bin
+            "gridded": _process_gridded_bin,
+            "compressed": _process_compressed_bin,
         }
         self._output_function = function_mappings.get(self.file_format)
         if self._output_function is None:
             raise ValueError(f"Unknown output format: {self.file_format}")
-        self._compressed_index_map = index_map if (self.file_format ==
-                                                   'compressed') else None
-
-    def add_timestep(self, time: float, filepath: str) -> None:
-        """Add a new timestep to the OutputFile."""
-        self.times.append(time)
-        self.filepaths.append(filepath)
+        self._compressed_index_map = (
+            index_map if (self.file_format == "compressed") else None
+        )
 
-    def to_numpy(self, timestep: int | list[int] | None = None) -> np.ndarray:
+    def to_numpy(self, timestep: int | list[int] = None) -> np.ndarray:
+        """
+        Return a numpy array for the given output and timestep(s) with shape
+        (time, nz, ny, nx). If timestep is None, then all timesteps are
+        returned.
+
+        Parameters
+        ----------
+        timestep: int | list[int]
+            The timestep(s) to return. If None, then all timesteps are returned.
+
+        Returns
+        -------
+        np.ndarray
+            A 4D numpy array with shape (time, nz, ny, nx) containing the
+            output data.
+
+        Examples
+        --------
+        >>> import quicfire_tools as qft
+        >>> outputs = qft.SimulationOutputs("path/to/outputs", 50, 100, 100)
+        >>> fire_energy = outputs.get_output("fire-energy_to_atmos")
+        >>> # Get all timesteps for the fire-energy_to_atmos output
+        >>> fire_energy_all = fire_energy.to_numpy()
+        >>> # Get the first timestep for the fire-energy_to_atmos output
+        >>> fire_energy_slice = fire_energy.to_numpy(timestep=0)
+        """
         self._validate_timestep(timestep)
         selected_files = self._select_files_based_on_timestep(timestep)
         return self._get_multiple_timesteps(selected_files)
@@ -202,7 +232,9 @@ def _validate_timestep(self, timestep: int | list[int] | None) -> None:
         else:
             raise TypeError(f"Invalid timestep type: {type(timestep)}")
 
-    def _select_files_based_on_timestep(self, timestep: int | list[int] | None) -> list[Path]:
+    def _select_files_based_on_timestep(
+        self, timestep: int | list[int] | None
+    ) -> list[Path]:
         """Return files selected based on timestep."""
         if timestep is None:
             return self.filepaths
@@ -212,14 +244,14 @@ def _select_files_based_on_timestep(self, timestep: int | list[int] | None) -> l
 
     def _get_single_timestep(self, output_file: Path) -> np.ndarray:
         """Return a numpy array for the given output file."""
-        return self._output_function(output_file,
-                                     self.shape,
-                                     self._compressed_index_map)
+        return self._output_function(
+            output_file, self.shape, self._compressed_index_map
+        )
 
     def _get_multiple_timesteps(self, output_files: list[Path]) -> np.ndarray:
         """Return a numpy array for the given output files."""
         arrays = [self._get_single_timestep(of) for of in output_files]
-        return arrays[0] if len(arrays) == 1 else np.stack(arrays)
+        return arrays[0] if len(arrays) == 1 else np.concatenate(arrays, axis=0)
 
 
 class SimulationOutputs:
@@ -231,8 +263,7 @@ class SimulationOutputs:
     zarr file.
     """
 
-    def __init__(self, output_directory: Path | str,
-                 params: SimulationParameters) -> None:
+    def __init__(self, output_directory: Path | str, nz: int, ny: int, nx: int):
         # Convert to Path and resolve
         output_directory = Path(output_directory).resolve()
 
@@ -241,7 +272,9 @@ def __init__(self, output_directory: Path | str,
 
         # Assign attributes
         self.output_directory = output_directory
-        self.params = params
+        self.nz = nz
+        self.ny = ny
+        self.nx = nx
 
         # Get indexing information from the fire grid
         self._fire_indexes = self._process_fire_indexes()
@@ -288,19 +321,21 @@ def _build_output_files_map(self):
                 self.outputs[key] = OutputFile(
                     name=key,
                     file_format=attributes["file_format"],
+                    dimensions=attributes["dimensions"],
                     shape=shape,
                     grid=attributes["grid"],
                     delimiter=attributes["delimiter"],
                     extension=attributes["extension"],
                     description=attributes["description"],
                     units=attributes["units"],
-                    index_map=self._fire_indexes
+                    index_map=self._fire_indexes,
                 )
 
                 # Populate the output file with timesteps and filepaths
                 for filepath in output_files_list:
                     time = self._get_output_file_time(key, filepath)
-                    self.outputs[key].add_timestep(time, filepath)
+                    self.outputs[key].times.append(time)
+                    self.outputs[key].filepaths.append(filepath)
 
     def _get_list_output_paths(self, name) -> list[Path]:
         """
@@ -312,25 +347,24 @@ def _get_list_output_paths(self, name) -> list[Path]:
         return paths
 
     def _get_output_shape(self, name, attrs) -> tuple:
-        if attrs["number_dimensions"] == 2:
-            return self.params.ny, self.params.nx
-        # elif attrs["number_dimensions"] == 3 and name == "fire-energy_to_atmos":
-        #     _process_vertical_grid(self.output_directory / "grid.bin", self.params.nx, self.params.ny)
-        elif attrs["number_dimensions"] == 3 and attrs["grid"] == "fire":
-            return self.params.ny, self.params.nx, self.params.nz + 1
+        number_dimensions = len(attrs["dimensions"])
+        if number_dimensions == 2:
+            return 1, self.ny, self.nx
+        elif number_dimensions == 3 and attrs["grid"] == "fire":
+            return self.nz + 1, self.ny, self.nx
         else:
-            return self.params.ny, self.params.nx, self.params.nz
+            return self.nz, self.ny, self.nx
 
     @staticmethod
     def _get_output_file_time(output, fpath) -> int:
         """Get the time of the output file."""
-        delimiter = OUTPUTS_MAP[output]['delimiter']
-        extension = OUTPUTS_MAP[output]['extension']
+        delimiter = OUTPUTS_MAP[output]["delimiter"]
+        extension = OUTPUTS_MAP[output]["extension"]
 
         try:
-            if delimiter == '':
+            if delimiter == "":
                 # Split on first numeric component
-                name_parts = re.split(r'(\d+)', fpath.name)
+                name_parts = re.split(r"(\d+)", fpath.name)
                 file_time = name_parts[1]
             else:
                 file_time = fpath.name.split(delimiter)[-1].split(extension)[0]
@@ -375,40 +409,120 @@ def _process_fire_indexes(self) -> ndarray:
 
             return ijk
 
-    def list_available_outputs(self):
-        """Return a list of keys representing available outputs."""
+    def _validate_output(self, output: str) -> OutputFile:
+        """Validate output."""
+        try:
+            output = self.outputs[output]
+        except KeyError:
+            raise ValueError(
+                f"{output} is not a valid output. Valid "
+                f"outputs are: {self.list_available_outputs()}"
+            )
+        return output
+
+    def list_available_outputs(self) -> list[str]:
+        """
+        Return a list of available output names.
+
+        Returns
+        -------
+        list[str]
+            A list of available output names.
+
+        Examples
+        --------
+        >>> import quicfire_tools as qft
+        >>> outputs = qft.SimulationOutputs("path/to/outputs")
+        >>> outputs.list_available_outputs()
+        ['fire-energy_to_atmos', 'fuels-dens', 'groundfuelheight', 'mburnt_integ']
+        """
         return list(self.outputs.keys())
 
-    def get_output(self, key):
-        """Return a list of times for a given output key."""
-        return self.outputs[key]
+    def get_output(self, key) -> OutputFile:
+        """
+        Return the OutputFile object for the given output name.
+
+        Parameters
+        ----------
+        key: str
+            The name of the output to return.
+
+        Returns
+        -------
+        OutputFile
+            The OutputFile object for the given output name.
+
+        Raises
+        ------
+        ValueError
+            If the output name is not valid.
+
+        Examples
+        --------
+        >>> import quicfire_tools as qft
+        >>> outputs = qft.SimulationOutputs("path/to/outputs")
+        >>> fire_energy = outputs.get_output("fire-energy_to_atmos")
+        >>> fire_energy
+        <quicfire_tools.outputs.OutputFile object at 0x7f8b1c2b6d90>
+        """
+        return self._validate_output(key)
 
-    def to_numpy(self, key: str | OutputFile,
-                 timestep: None | int | list[int] = None) -> np.ndarray:
-        """Return a numpy array for the given output and timestep(s)."""
+    def to_numpy(self, key: str, timestep: None | int | list[int] = None) -> np.ndarray:
+        """
+        Returns a 4D numpy array for the given output and timestep(s) with shape
+        (time, nz, ny, nx). If timestep is None, then all timesteps are
+        returned.
+
+        Parameters
+        ----------
+        key: str
+            The name of the output to return.
+        timestep: int | list[int] | None
+            The timestep(s) to return. If None, then all timesteps are returned.
+
+        Returns
+        -------
+        np.ndarray
+            A 4D numpy array with shape (time, nz, ny, nx) containing the
+            output data.
+
+        Examples
+        --------
+        >>> import quicfire_tools as qft
+        >>> outputs = qft.SimulationOutputs("path/to/outputs", 50, 100, 100)
+        >>> output_name = "fire-energy_to_atmos"
+        >>> # Get all timesteps for the fire-energy_to_atmos output
+        >>> fire_energy_all = outputs.to_numpy(output_name)
+        >>> # Get the first timestep for the fire-energy_to_atmos output
+        >>> fire_energy_slice = outputs.to_numpy(output_name, timestep=0)
+        """
         output = self._validate_output(key)
         return output.to_numpy(timestep)
 
-    def _validate_output(self, output: str | OutputFile) -> OutputFile:
-        """Validate output."""
-        if isinstance(output, str):
-            try:
-                output = self.outputs[output]
-            except KeyError:
-                raise ValueError(f"{output} is not a valid output. Valid "
-                                 f"outputs are: {self.list_available_outputs()}")
-        elif isinstance(output, OutputFile):
-            if output not in self.outputs.values():
-                raise ValueError(f"{output} is not a valid output. Valid "
-                                 f"outputs are: {self.list_available_outputs()}")
-        else:
-            raise TypeError(f"output must be a string or OutputFile object. "
-                            f"Got {type(output)}")
-        return output
-
-    def to_dask(self, key: str | OutputFile,
-                timestep: None | int | list[int] = None) -> np.ndarray:
-        """Return a dask array for the given output and timestep(s)."""
+    def to_dask(self, key: str) -> da.Array:
+        """
+        Returns a dask array for the given output with shape (time, nz, ny, nx).
+
+        Parameters
+        ----------
+        key: str
+            The name of the output to return.
+
+        Returns
+        -------
+        da.Array
+            A dask array with shape (time, nz, ny, nx) containing the output
+            data with chunks of size (1, nz, ny, nx). The dask array is
+            lazily evaluated, so users must call `.compute()` to retrieve the
+            data.
+
+        Examples
+        --------
+        >>> import quicfire_tools as qft
+        >>> outputs = qft.SimulationOutputs("path/to/outputs", 50, 100, 100)
+        >>> fire_energy = outputs.to_dask("fire-energy_to_atmos")
+        >>> fire_energy.compute()
+        """
         output = self._validate_output(key)
 
         # Create a dask array for the output file
@@ -423,46 +537,73 @@ def to_dask(self, key: str | OutputFile,
 
         return dask_array
 
-    def to_zarr(self, fpath: Path):
-        """Write the data to a zarr file."""
+    def to_zarr(
+        self, fpath: str | Path, outputs: str | list[str] = None
+    ) -> zarr.hierarchy.Group:
+        """
+        Write the outputs to a zarr file.
+
+        Parameters
+        ----------
+        fpath: str | Path
+            The path to the zarr file to be written.
+        outputs: str | list[str]
+            The name of the output(s) to write to the zarr file. If None, then
+            all outputs are written to the zarr file.
+
+        Returns
+        -------
+        zarr.hierarchy.Group
+            The zarr file object.
+        """
+        if isinstance(fpath, str):
+            fpath = Path(fpath)
+
         # Create the zarr file
         zarr_file = zarr.open(str(fpath), mode="w")
 
+        # Get a list of outputs to write to the zarr file
+        if outputs is None:
+            outputs = self.list_available_outputs()
+        elif isinstance(outputs, str):
+            outputs = [outputs]
+
         # Write each output to the zarr file
-        for output_name, output in self.outputs.items():
+        for output_name in outputs:
+            # Get the output object and verify it exists
+            output = self.get_output(output_name)
+
             # Create a zarr dataset for the output
             shape = (len(output.times), *output.shape)
             chunks = [1 if i == 0 else shape[i] for i in range(len(shape))]
-            zarr_file.create_dataset(
-                output_name,
-                shape=shape,
-                chunks=chunks,
-                dtype=float)
+            zarr_dataset = zarr_file.create_dataset(
+                output_name, shape=shape, chunks=chunks, dtype=float
+            )
+            zarr_dataset.attrs["_ARRAY_DIMENSIONS"] = ["time", "z", "y", "x"]
 
             # Write each timestep to the output's zarr dataset
             for time_step in range(len(output.times)):
                 data = self.to_numpy(output_name, time_step)
-                zarr_file[output_name][time_step, ...] = data
+                zarr_dataset[time_step, ...] = data[0, ...]
 
         return zarr_file
 
 
-def _process_compressed_bin(filename, dim_yxz, *args) -> ndarray:
+def _process_compressed_bin(filename, dim_zyx, *args) -> ndarray:
     """
-    Converts the contents of a sparse .bin file to a dense NumPy array.
+    Converts the contents of a sparse .bin file to a dense array with shape
+    (1, nz, ny, nx).
 
-    This function reads a .bin file containing sparse data and converts it to
-    a dense 3D NumPy array. The mapping from sparse to dense is guided by an
-    index map provided as an argument. The index map must match the sparse data
-    in the .bin file, defining the locations of nonzero values within the dense
-    array.
+    The mapping from sparse to dense is guided by an index map provided as an
+    argument. The index map must match the sparse data in the .bin file,
+    defining the locations of nonzero values within the dense array.
 
     Parameters
     ----------
     filename : str | Path
         The name or path of the sparse .bin file to be processed.
-    dim_yxz : tuple of int
-        The number of y, x, z cells to store in the 3D array, given as a tuple
+    dim_zyx : tuple of int
+        The number of z, y, x cells to store in the 3D array, given as a tuple
         of three integers.
     *args : tuple
         Additional arguments, specifically expecting the index map for mapping
@@ -472,9 +613,7 @@ def _process_compressed_bin(filename, dim_yxz, *args) -> ndarray:
     Returns
     -------
     ndarray
-        A dense 3D NumPy array with shape defined by `dim_yxz`, and data type
-        np.float32. The array represents the dense form of the sparse data
-        from the .bin file.
+        A dense 4D array of shape (1, nz, ny, nx) containing the sparse data.
 
     Raises
     ------
@@ -482,55 +621,56 @@ def _process_compressed_bin(filename, dim_yxz, *args) -> ndarray:
         If the index map (fire_indexes) is not provided in the arguments.
     ValueError
         If the index map (fire_indexes) is None.
-   """
-    # TODO: Rename fire_indexes to something more generic
+    """
     try:
         fire_indexes = args[0]
     except IndexError:
-        raise ValueError("fire_indexes must be provided when processing "
-                         "compressed .bin files.")
+        raise ValueError(
+            "fire_indexes must be provided when processing " "compressed .bin files."
+        )
     if fire_indexes is None:
-        raise ValueError("fire_indexes must be provided when processing "
-                         "compressed .bin files.")
+        raise ValueError(
+            "fire_indexes must be provided when processing " "compressed .bin files."
+        )
 
     # Initialize the 3D array
-    full_3d_array = np.zeros(dim_yxz, dtype=np.float32)
+    full_array = np.zeros([1, *dim_zyx], dtype=np.float32)
+    array_3d = full_array[0, :, :, :]
 
     with open(filename, "rb") as fid:
         # Read header
         np.fromfile(fid, dtype=np.int32, count=1)
 
         # Read in the sparse values
-        sparse_values = np.fromfile(
-            fid, dtype=np.float32, count=fire_indexes.shape[0]
-        )
+        sparse_values = np.fromfile(fid, dtype=np.float32, count=fire_indexes.shape[0])
 
         # Map indices of the sparse data to the indices of the dense array
         indices = (
-            fire_indexes[:, 1],
-            fire_indexes[:, 0],
-            fire_indexes[:, 2],
+            fire_indexes[:, 2],  # k indices (z)
+            fire_indexes[:, 1],  # j indices (y)
+            fire_indexes[:, 0],  # i indices (x)
         )
 
         # Update the full array with the sparse indices
-        full_3d_array[indices] = sparse_values
+        array_3d[indices] = sparse_values
 
-    return full_3d_array
+    full_array[0, ...] = array_3d
+    return full_array.astype(float)
 
 
-def _process_gridded_bin(filename, dims, *args) -> ndarray:
+def _process_gridded_bin(filename, dims_zyx, *args) -> ndarray:
     """
     Converts the data stored in a gridded .bin file to an np array. The
-    function handles both 2D and 3D data based on the dimensions provided.
+    function takes in a 3D array of dimensions (nz, ny, nx) and returns an
+    array of shape (1, nz, ny, nx).
 
     Parameters
     ----------
     filename : str | Path
         File path to the .bin file that contains the gridded data.
-    dims : tuple
-        Dimensions of the data. If a 2-element tuple (ny, nx) is provided,
-        the function processes 2D data. If a 3-element tuple (ny, nx, nz)
-        is provided, the function processes 3D data.
+    dims_zyx : tuple
+        A tuple of length 3 containing the number of z, y, and x cells in the
+        3D array.
     *args : list
         Additional arguments that might be passed to the underlying slice
         processing function (_process_gridded_bin_slice).
@@ -538,24 +678,20 @@ def _process_gridded_bin(filename, dims, *args) -> ndarray:
     Returns
     -------
     ndarray
-        A NumPy array containing the data extracted from the .bin file. The
-        array's shape corresponds to the provided dimensions, and its data type
-        is np.float32.
+        A 4D array of shape (1, nz, ny, nx) containing the gridded data.
     """
     # Initialize the array
-    array = np.zeros(dims, dtype=np.float32)
+    array = np.zeros([1, *dims_zyx], dtype=np.float32)
 
+    nz, ny, nx = dims_zyx
     with open(filename, "rb") as f:
         # Read header
         _ = np.fromfile(f, dtype=np.float32, count=1)
 
         # Read in gridded data
-        if len(dims) == 2:  # 2D data
-            array[:, :] = _process_gridded_bin_slice(f, *dims)
-        else:  # 3D data
-            for k in range(dims[2]):
-                array[:, :, k] = _process_gridded_bin_slice(f, *dims[:2])
-    return array
+        for k in range(nz):
+            array[0, k, :, :] = _process_gridded_bin_slice(f, ny, nx)
+    return array.astype(float)
 
 
 def _process_gridded_bin_slice(fid, ny, nx) -> ndarray:
diff --git a/quicfire_tools/parameters.py b/quicfire_tools/parameters.py
index 0db9797..261960d 100644
--- a/quicfire_tools/parameters.py
+++ b/quicfire_tools/parameters.py
@@ -1,5 +1,5 @@
 # External Imports
-from pydantic import BaseModel, Field, field_validator
+from pydantic import BaseModel, Field
 
 
 class SimulationParameters(BaseModel):
@@ -64,22 +64,39 @@ def to_dict(self):
         return self.model_dump()
 
     @classmethod
-    def from_fastfuels(cls, zarray, wind_speed, wind_direction, sim_time, auto_kill, num_cpus, fuel_flag, ignition_flag, output_time, topo_flag, fuel_density, fuel_moisture, fuel_height):
-        return cls(nx=zarray.attrs["dx"],
-                   ny=zarray.attrs["dy"],
-                   nz=zarray.attrs["dz"],
-                   dx=zarray.attrs["dx"],
-                   dy=zarray.attrs["dy"],
-                   dz=zarray.attrs["dz"],
-                   wind_speed=wind_speed,
-                   wind_direction=wind_direction,
-                   sim_time=sim_time,
-                   auto_kill=auto_kill,
-                   num_cpus=num_cpus,
-                   fuel_flag=fuel_flag,
-                   ignition_flag=ignition_flag,
-                   output_time=output_time,
-                   topo_flag=topo_flag,
-                   fuel_density=fuel_density,
-                   fuel_moisture=fuel_moisture,
-                   fuel_height=fuel_height)
+    def from_fastfuels(
+        cls,
+        zarray,
+        wind_speed,
+        wind_direction,
+        sim_time,
+        auto_kill,
+        num_cpus,
+        fuel_flag,
+        ignition_flag,
+        output_time,
+        topo_flag,
+        fuel_density,
+        fuel_moisture,
+        fuel_height,
+    ):
+        return cls(
+            nx=zarray.attrs["dx"],
+            ny=zarray.attrs["dy"],
+            nz=zarray.attrs["dz"],
+            dx=zarray.attrs["dx"],
+            dy=zarray.attrs["dy"],
+            dz=zarray.attrs["dz"],
+            wind_speed=wind_speed,
+            wind_direction=wind_direction,
+            sim_time=sim_time,
+            auto_kill=auto_kill,
+            num_cpus=num_cpus,
+            fuel_flag=fuel_flag,
+            ignition_flag=ignition_flag,
+            output_time=output_time,
+            topo_flag=topo_flag,
+            fuel_density=fuel_density,
+            fuel_moisture=fuel_moisture,
+            fuel_height=fuel_height,
+        )
diff --git a/quicfire_tools/topography.py b/quicfire_tools/topography.py
new file mode 100644
index 0000000..5e9a05b
--- /dev/null
+++ b/quicfire_tools/topography.py
@@ -0,0 +1,148 @@
+"""
+QUIC-Fire Tools Topography Model
+"""
+from __future__ import annotations
+
+# Core Imports
+from enum import Enum
+
+# External Imports
+from typing import Literal
+
+from pydantic import BaseModel, Field, PositiveFloat, PositiveInt, SerializeAsAny
+
+
+class TopoSources(int, Enum):
+    flat = 0
+    gaussian_hill = 1
+    hill_pass = 2
+    slope_mesa = 3
+    canyon = 4
+    custom = 5
+    half_circle = 6
+    sinusoid = 7
+    cos_hill = 8
+    QP_elevation_bin = 9
+    terrainOutput_txt = 10
+    terrain_dat = 11
+
+
+class TopoType(BaseModel):
+    topo_flag: SerializeAsAny[TopoSources]
+
+    def __str__(self):
+        return (
+            f"{self.topo_flag.value}\t\t! N/A, "
+            f"topo flag: 0 = flat, 1 = Gaussian hill, "
+            f"2 = hill pass, 3 = slope mesa, 4 = canyon, "
+            f"5 = custom, 6 = half circle, 7 = sinusoid, "
+            f"8 = cos hill, 9 = QP_elevation.inp, "
+            f"10 = terrainOutput.txt (ARA), "
+            f"11 = terrain.dat (firetec)"
+        )
+
+
+class GaussianHillTopo(TopoType):
+    topo_flag: SerializeAsAny[TopoSources] = TopoSources(1)
+    x_hilltop: PositiveInt
+    y_hilltop: PositiveInt
+    elevation_max: PositiveInt
+    elevation_std: PositiveFloat
+
+    def __str__(self):
+        flag_line = super().__str__()
+        params = (
+            f"\n{self.x_hilltop}\t! m, x-center\n"
+            f"{self.y_hilltop}\t! m, y-center\n"
+            f"{self.elevation_max}\t! m, max height\n"
+            f"{self.elevation_std}\t! m, std"
+        )
+        return flag_line + params
+
+
+class HillPassTopo(TopoType):
+    topo_flag: SerializeAsAny[TopoSources] = TopoSources(2)
+    max_height: PositiveInt
+    location_param: PositiveFloat
+
+    def __str__(self):
+        flag_line = super().__str__()
+        params = (
+            f"\n{self.max_height}\t! m, max height\n"
+            f"{self.location_param}\t! m, location parameter"
+        )
+        return flag_line + params
+
+
+class SlopeMesaTopo(TopoType):
+    topo_flag: SerializeAsAny[TopoSources] = TopoSources(3)
+    slope_axis: Literal[0, 1]
+    slope_value: PositiveFloat
+    flat_fraction: float = Field(ge=0, le=1)
+
+    def __str__(self):
+        flag_line = super().__str__()
+        params = (
+            f"\n{self.slope_axis}\t! N/A, slope axis (0 = x, 1 = y)\n"
+            f"{self.slope_value}\t! N/A, slope val (dh/dx)\n"
+            f"{self.flat_fraction}\t! N/A, fraction of domain that is flat"
+        )
+        return flag_line + params
+
+
+class CanyonTopo(TopoType):
+    topo_flag: SerializeAsAny[TopoSources] = TopoSources(4)
+    x_start: PositiveInt
+    y_center: PositiveInt
+    slope_value: PositiveFloat
+    canyon_std: PositiveFloat
+    vertical_offset: PositiveFloat
+
+    def __str__(self):
+        flag_line = super().__str__()
+        params = (
+            f"\n{self.x_start}\t! m, x-start of canyon on slope\n"
+            f"{self.y_center}\t! m, y-center of canyon"
+            f"{self.slope_value}\t! N/A, slope\n"
+            f"{self.canyon_std}\t! m, std\n"
+            f"{self.vertical_offset}\t! m, height offset of the bottom of the canyon"
+        )
+        return flag_line + params
+
+
+class HalfCircleTopo(TopoType):
+    topo_flag: SerializeAsAny[TopoSources] = TopoSources(6)
+    x_location: PositiveInt
+    y_location: PositiveInt
+    radius: PositiveFloat
+
+    def __str__(self):
+        flag_line = super().__str__()
+        params = (
+            f"\n{self.x_location}\t! m, x-location\n"
+            f"{self.y_location}\t! m, y-location\n"
+            f"{self.radius}\t! m, radius of half circle"
+        )
+        return flag_line + params
+
+
+class SinusoidTopo(TopoType):
+    topo_flag: SerializeAsAny[TopoSources] = TopoSources(7)
+    period: PositiveFloat
+    amplitude: PositiveFloat
+
+    def __str__(self):
+        flag_line = super().__str__()
+        params = f"\n{self.period}\t! m, mean\n" f"{self.amplitude}\t! m, amplitude"
+        return flag_line + params
+
+
+class CosHillTopo(TopoType):
+    topo_flag: SerializeAsAny[TopoSources] = TopoSources(8)
+    aspect: PositiveFloat
+    height: PositiveInt
+
+    def __str__(self):
+        flag_line = super().__str__()
+        params = f"\n{self.aspect}\t! m, mean\n" f"{self.height}\t! m, height"
+        return flag_line + params
diff --git a/quicfire_tools/utils.py b/quicfire_tools/utils.py
new file mode 100644
index 0000000..1d24b11
--- /dev/null
+++ b/quicfire_tools/utils.py
@@ -0,0 +1,154 @@
+"""
+Utility functions for quicfire-tools.
+"""
+
+from pathlib import Path
+import numpy as np
+from scipy.io import FortranFile
+
+from quicfire_tools.topography import TopoType
+
+
+def compute_parabolic_stretched_grid(
+    dz_surf: float, n_surf_cell: int, n_tot_cells: int, domain_height: float
+) -> np.ndarray:
+    """
+    Generate a vertical grid spacing array with parabolic stretching.
+
+    Parameters
+    ----------
+    dz_surf : float
+        Vertical cell spacing at the surface, typically about 1 m.
+    n_surf_cell : int
+        Number of cells with constant vertical cell spacing (dz_surf) at the
+        surface.
+    n_tot_cells : int
+        Total number of vertical cells in the grid. Typically ranges between
+        20 and 30.
+    domain_height : float
+        Total height of the grid. For flat terrain without smoke transport
+        concerns, it is usually around 100 m. For terrain with features, it
+        should be approximately 3 times the height of the tallest feature.
+
+    Returns
+    -------
+    np.ndarray
+        Array representing the vertical grid spacing (dz) values for the
+        simulation.
+
+    Notes
+    -----
+    The function computes a parabolic stretching of the vertical grid spacings.
+    The grid consists of a specified number of cells with uniform spacing at
+    the surface, followed by cells with spacings determined by a parabolic
+    formula until the total domain height is achieved.
+    """
+    dzmax_high = domain_height - dz_surf * n_surf_cell
+    dzmax_low = 0
+
+    dz = np.ones(n_tot_cells) * dz_surf
+
+    while True:
+        dzmax = 0.5 * (dzmax_low + dzmax_high)
+
+        c1 = (dzmax - dz_surf) / ((n_tot_cells - n_surf_cell) ** 2)
+        c2 = -2.0 * c1 * n_surf_cell
+        c3 = dz_surf + c1 * n_surf_cell**2
+
+        # Apply parabolic formula for cells beyond the surface cells
+        kreal = np.arange(n_surf_cell, n_tot_cells, dtype=float)
+        dz[n_surf_cell:] = (c1 * kreal**2) + (c2 * kreal) + c3
+
+        zmax_temp = np.sum(dz)
+
+        if abs(domain_height - zmax_temp) < 0.001:
+            break
+        elif zmax_temp > domain_height:
+            dzmax_high = dzmax
+        else:
+            dzmax_low = dzmax
+
+    dz[-1] += domain_height - np.sum(dz)
+
+    return dz
+
+
+def read_topo_dat(
+    topo_path: Path | str, filename: str, x_dim: int, y_dim: int, order: str = "C"
+):
+    """
+    Read in a topo.dat file as a numpy array.
+    """
+    if isinstance(topo_path, str):
+        topo_path = Path(topo_path)
+
+    full_path = topo_path / filename
+
+    with open(full_path, "rb") as fin:
+        arr = (
+            FortranFile(fin)
+            .read_reals(dtype="float32")
+            .reshape((y_dim, x_dim), order=order)
+        )
+
+    return arr
+
+
+def calculate_quic_height(
+    topo_type: TopoType,
+    fire_nz: int,
+    fire_dz: int,
+    nx: int,
+    ny: int,
+    topo_path: Path | str = None,
+    topo_name: str = "topo.dat",
+) -> int:
+    """
+    Calculate the QUIC domain height from the fire grid height and the maximum elevation.
+
+    Parameters
+    ----------
+    topo_height : TopoType
+        Instance of TopoType class defining topography parameters for chosen method.
+    fire_nz : int
+        Number of cells in vertical dimension of fire grid
+    fire_dz : int
+        Cell size of fire grid in vertical direction (m)
+    nx : int
+        Number of cells in x-direction of domain
+    ny : int
+        Number of cells in y-direction of domain
+    topo_path : Path | str
+        Path to directory where topo.dat file is saved.
+    topo_name : str
+        Name of Fortran .dat file definiing topography. Defaults to "topo.dat"
+    """
+    fire_height = fire_nz * fire_dz
+    if topo_type.topo_flag.value == 0:
+        topo_height = 0
+    elif topo_type.topo_flag.value == 1:
+        topo_height = topo_type.elevation_max
+    elif topo_type.topo_flag.value == 2:
+        topo_height = topo_type.max_height
+    elif topo_type.topo_flag.value == 3:
+        # something with slope_value and flat_fraction
+        pass
+    elif topo_type.topo_flag.value == 4:
+        # don't know how to do this one either
+        pass
+    elif topo_type.topo_flag.value == 6:
+        # maybe something with radius?
+        pass
+    elif topo_type.topo_flag.value == 7:
+        topo_height = 2 * topo_type.amplitude  # probably?
+    elif topo_type.topo_flag.value == 8:
+        topo_height = topo_type.height
+    elif topo_type.topo_flag.value == 5:
+        if topo_path is None:
+            raise ValueError(
+                "Must supply path to directory containing topography .dat file"
+            )
+        topo_dat = read_topo_dat(topo_path, topo_name, nx, ny)
+        topo_height = np.max(topo_dat) - np.min(topo_dat)
+
+    return int((topo_height + fire_height) * 3)
diff --git a/requirements/docs.txt b/requirements/docs.txt
index d27ee82..4a30805 100644
--- a/requirements/docs.txt
+++ b/requirements/docs.txt
@@ -1,2 +1,2 @@
 mkdocstrings
-mkdocstrings-python
\ No newline at end of file
+mkdocstrings-python
diff --git a/requirements/readme.md b/requirements/readme.md
index a6b833a..c08b860 100644
--- a/requirements/readme.md
+++ b/requirements/readme.md
@@ -16,4 +16,3 @@ Requirements for building documentation.
 
 Requirements for testing with different Python versions. Uses conda environment
 yaml files.
-
diff --git a/requirements/requirements.yml b/requirements/requirements.yml
index 9400144..7a182ec 100644
--- a/requirements/requirements.yml
+++ b/requirements/requirements.yml
@@ -11,4 +11,4 @@ dependencies:
   - pandas
   - ca-certificates
   - openssl
-  - dask
\ No newline at end of file
+  - dask
diff --git a/setup.py b/setup.py
index 62c04e8..11313ba 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,3 @@
-import os
 import requests
 from setuptools import find_packages, setup
 
@@ -23,9 +22,7 @@ def get_version():
 VERSION = get_version()
 LICENSE = "MIT"
 URL = "https://github.com/silvxlabs/quicfire-tools"
-PROJECT_URLS = {
-    "Bug Tracker": f"{URL}/issues"
-}
+PROJECT_URLS = {"Bug Tracker": f"{URL}/issues"}
 
 setup(
     name=NAME,
@@ -36,20 +33,22 @@ def get_version():
     license=LICENSE,
     url=URL,
     project_urls=PROJECT_URLS,
-    classifiers=["Intended Audience :: Developers",
-                 "Intended Audience :: Science/Research",
-                 "License :: OSI Approved :: MIT License",
-                 "Operating System :: OS Independent",
-                 "Programming Language :: Python :: 3",
-                 "Programming Language :: Python :: 3.8",
-                 "Programming Language :: Python :: 3.9",
-                 "Programming Language :: Python :: 3.10",
-                 "Programming Language :: Python :: 3.11",
-                 "Topic :: Scientific/Engineering", ],
+    classifiers=[
+        "Intended Audience :: Developers",
+        "Intended Audience :: Science/Research",
+        "License :: OSI Approved :: MIT License",
+        "Operating System :: OS Independent",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
+        "Topic :: Scientific/Engineering",
+    ],
     package_dir={"": "."},
     packages=find_packages(exclude=["docs", "tests"]),
     package_data={
-        'quicfire_tools': ['input-templates/*/*'],
+        "quicfire_tools": ["templates/*/*"],
     },
     include_package_data=True,
     install_requires=[


Test patch:
diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 0000000..c0511c0
--- /dev/null
+++ b/pytest.ini
@@ -0,0 +1,2 @@
+[pytest]
+log_cli = true
diff --git a/quicfire_tools/input-templates/latest/QUIC_fire.inp b/quicfire_tools/input-templates/latest/QUIC_fire.inp
deleted file mode 100644
index 07bfe9a..0000000
--- a/quicfire_tools/input-templates/latest/QUIC_fire.inp
+++ /dev/null
@@ -1,43 +0,0 @@
-1					! Fire flag: 1 = run fire; 0 = no fire
--1				    ! Random number generator: -1: use time and date, any other integer > 0 is used as the seed
-! FIRE TIMES
-$timenow		    ! When the fire is ignited in Unix Epoch time (integer seconds since 1970/1/1 00:00:00). Must be greater or equal to the time of the first wind
-$sim_time			! Total simulation time for the fire [s]
-1					! time step for the fire simulation [s]
-1					! Number of fire time steps done before updating the quic wind field (integer, >= 1)
-$output_time		! After how many fire time steps to print out fire-related files (excluding emissions and radiation)
-$output_time		! After how many quic updates to print out wind-related files
-$output_time		! After how many fire time steps to average emissions and radiation
-$output_time		! After how many quic updates to print out averaged wind-related files
-! FIRE GRID
-$nz					! Number of vertical layers of fire grid cells (integer)
-0					! Vertical stretching flag: 0 = uniform dz, 1 = custom
-$dz                 ! m, dz
-! FILE PATH
-""
-1                   ! Fuel types are in separate files
-2                   ! File is stream (1) or headers (2)
-! FUEL
-$fuel_flag		    ! fuel density flag: 1 = uniform; 2 = provided thru QF_FuelDensity.inp, 3 = Firetech files for quic grid, 4 = Firetech files for different grid (need interpolation)    $fuel_density
-$fuel_flag		    ! fuel moisture flag: 1 = uniform; 2 = provided thru QF_FuelMoisture.inp, 3 = Firetech files for quic grid, 4 = Firetech files for different grid (need interpolation)  $fuel_moisture $fuel_height_flag
-! IGNITION LOCATIONS
-$ignition_flag      ! 1 = rectangle, 2 = square ring, 3 = circular ring, 4 = file (QF_Ignitions.inp), 5 = time-dependent ignitions (QF_IgnitionPattern.inp), 6 = ignite.dat (firetech)      $ignition_locations
-2                   ! number of ignitions
-! FIREBRANDS
-0				    ! 0 = off, 1 = on
-! OUTPUT FILES (formats depend on the grid type flag)
-1					! Output gridded energy-to-atmosphere (3D fire grid + extra layers)
-0					! Output compressed array reaction rate (fire grid)
-1					! Output compressed array fuel density (fire grid)
-1					! Output gridded wind (u,v,w,sigma) (3D fire grid)
-1					! Output gridded QU winds with fire effects, instantaneous (QUIC-URB grid)
-0					! Output gridded QU winds with fire effects, averaged (QUIC-URB grid)
-0					! Output plume trajectories (ONLY FOR DEBUG)
-1					! Output compressed array fuel moisture (fire grid)
-1					! Output vertically-integrated % mass burnt (fire grid)
-0					! Output trajectories firebrands
-0					! Output compressed array emissions (fire grid)
-0					! Output gridded thermal radiation (fire grid)
-0                   ! Output surface fire intensity at every fire time step
-! AUTOKILL
-$auto_kill          ! Kill if the fire is out and there are no more ignitions or firebrands (0 = no, 1 = yes)
\ No newline at end of file
diff --git a/quicfire_tools/input-templates/latest/QU_TopoInputs.inp b/quicfire_tools/input-templates/latest/QU_TopoInputs.inp
deleted file mode 100644
index 87c1cfc..0000000
--- a/quicfire_tools/input-templates/latest/QU_TopoInputs.inp
+++ /dev/null
@@ -1,11 +0,0 @@
-Specify file name for custom topo (full path)
-"topo.dat"
-$topo_flag     ! N/A, topo flag: 0 = flat, 1 = Gaussian hill, 2 = hill pass, 3 = slope mesa, 4 = canyon, 5 = custom, 6 = half circle, 7 = sinusoid, 8 = cos hill, 9 = QP_elevation.inp, 10 = terrainOutput.txt (ARA), 11 = terrain.dat (firetec)
-1     ! N/A, smoothing method (0 = none (default for idealized terrain), 1 = blur, 2 = David's)
-200     ! N/A, number of smoothing passes
-200   ! N/A, number of initial SOR iterations (only if fire is run)
-1     ! N/A, sor cycles
-0.7   ! N/A, sor relaxation parameter (default for flat is 1.78, ignored if there is no terrain)
-0     ! N/A, add slope flow correction (0 = no, 1 = yes)
-Command to run slope flow code (system specific)
-""
diff --git a/quicfire_tools/inputs/templates/latest/QFire_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/latest/QFire_Advanced_User_Inputs.inp
new file mode 100755
index 0000000..a9c7cb9
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/QFire_Advanced_User_Inputs.inp
@@ -0,0 +1,14 @@
+$fraction_cells_launch_firebrands       ! N/A, fraction of the cells on fire that will launch a firebrand
+$firebrand_radius_scale_factor          ! N/A, scaling factor of the radius represented by the firebrands launched
+$firebrand_trajectory_time_step         ! s, time step for the firebrands trajectory calculation
+$firebrand_launch_interval              ! s, how often to launch firebrands
+$firebrands_per_deposition              ! N/A, number of firebrands distributed over the landing area
+$firebrand_area_ratio                   ! N/A, FB_FRACTION_LAUNCHED_to_RT_ratio
+$minimum_burn_rate_coefficient          ! N/A, min_b_value_coef
+$max_firebrand_thickness_fraction       ! N/A, fb_frac_of_max_size
+$firebrand_germination_delay            ! s, germination_delay
+$vertical_velocity_scale_factor         ! N/A, fraction of the cell on fire (to scale w)
+$minimum_firebrand_ignitions            ! N/A, minimum number of ignitions via firebrands at a point
+$maximum_firebrand_ignitions            ! N/A, maximum number of ignitions via firebrands at a point
+$minimum_landing_angle                  ! rad, min_theta_value (pi/6)
+$maximum_firebrand_thickness            ! m, fb thickness
diff --git a/quicfire_tools/inputs/templates/latest/QFire_Bldg_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/latest/QFire_Bldg_Advanced_User_Inputs.inp
new file mode 100755
index 0000000..b2725a5
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/QFire_Bldg_Advanced_User_Inputs.inp
@@ -0,0 +1,8 @@
+$convert_buildings_to_fuel_flag         ! N/A, flag to convert QUIC-URB buildings to fuel (0 = no, 1 = yes)
+$building_fuel_density                  ! kg/m3, thin fuel density within buildings (if no fuel is specified)
+$building_attenuation_coefficient       ! N/A, attenuation coefficient within buildings
+$building_surface_roughness             ! m, surface roughness within buildings
+$convert_fuel_to_canopy_flag            ! N/A, flag to convert fuel to canopy for winds (0 = no, 1 = yes)
+$update_canopy_winds_flag               ! N/A, update canopy winds when fuel is consumed (0 = no, 1 = yes)
+$fuel_attenuation_coefficient           ! N/A, attenuation coefficient within fuel for the Cionco profile (default = 1)
+$fuel_surface_roughness                 ! m, surface roughness within fuel (default = 0.1 m)
diff --git a/quicfire_tools/inputs/templates/latest/QFire_Plume_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/latest/QFire_Plume_Advanced_User_Inputs.inp
new file mode 100755
index 0000000..e9b36cf
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/QFire_Plume_Advanced_User_Inputs.inp
@@ -0,0 +1,16 @@
+$max_plumes_per_timestep                ! N/A, max number of plume at each time step
+$min_plume_updraft_velocity				! m/s, minimum vertical velocity of a plume. If wc is below minimum, the plume is eliminated (default 0.1 m/s)
+$max_plume_updraft_velocity				! m/s, maximum vertical velocity of a plume (default 100 m/s)
+$min_velocity_ratio				        ! N/A, minimum speed ratio (plume vertical velocity/wind speed). If below, the plume is eliminated (default 0.1)
+$brunt_vaisala_freq_squared				! 1/s2, brunt vaisala frequency squared
+$creeping_flag					        ! N/A creeping flag: 0 = off, 1 = on
+$adaptive_timestep_flag					! Flag time step (0 = constant, 1 = adaptive)
+$plume_timestep                         ! s, time step used to compute the buoyant plume trajectory
+$sor_option_flag                        ! sor option (0 = reset lambda at each call, 1 = keep)
+$sor_alpha_plume_center                 ! alpha 2 - plume centerline
+$sor_alpha_plume_edge                   ! alpha 2 - plume edges
+$max_plume_merging_angle                ! deg, max angle between plumes to merging
+$max_plume_overlap_fraction             ! N/A, fraction of overlap of plumes for merging
+$plume_to_grid_updrafts_flag            ! N/A, which wplume-to-grid scheme: 0 = new, 1 = old
+$max_points_along_plume_edge            ! N/A, number of points per edge for new scheme (only new scheme)
+$plume_to_grid_intersection_flag        ! N/A, w computation: 1 = max(w), 0 = sum(w^3)
diff --git a/quicfire_tools/input-templates/v5.2.3/QFire_Pyvista.inp b/quicfire_tools/inputs/templates/latest/QFire_Pyvista.inp
similarity index 99%
rename from quicfire_tools/input-templates/v5.2.3/QFire_Pyvista.inp
rename to quicfire_tools/inputs/templates/latest/QFire_Pyvista.inp
index d2a32d6..af7515e 100644
--- a/quicfire_tools/input-templates/v5.2.3/QFire_Pyvista.inp
+++ b/quicfire_tools/inputs/templates/latest/QFire_Pyvista.inp
@@ -25,4 +25,3 @@ camOrbit=0
 windBarNormalized=none
 windBarBounds=[-10.0,10.0]
 compile=0 run=1 compiler='gfortran' compiler_mode='release' testcase='LineFire' ./adv_compile_and_run.sh
-
diff --git a/quicfire_tools/input-templates/latest/QP_buildout.inp b/quicfire_tools/inputs/templates/latest/QP_buildout.inp
similarity index 100%
rename from quicfire_tools/input-templates/latest/QP_buildout.inp
rename to quicfire_tools/inputs/templates/latest/QP_buildout.inp
diff --git a/quicfire_tools/inputs/templates/latest/QUIC_fire.inp b/quicfire_tools/inputs/templates/latest/QUIC_fire.inp
new file mode 100644
index 0000000..914e11c
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/QUIC_fire.inp
@@ -0,0 +1,42 @@
+$fire_flag         ! Fire flag: 1 = run fire; 0 = no fire
+$random_seed               ! Random number generator: -1: use time and date, any other integer > 0 is used as the seed
+! FIRE TIMES
+$time_now		    ! When the fire is ignited in Unix Epoch time (integer seconds since 1970/1/1 00:00:00). Must be greater or equal to the time of the first wind
+$sim_time			! Total simulation time for the fire [s]
+$fire_time_step		! time step for the fire simulation [s]
+$quic_time_step		! Number of fire time steps done before updating the quic wind field (integer, >= 1)
+$out_time_fire      ! After how many fire time steps to print out fire-related files (excluding emissions and radiation)
+$out_time_wind      ! After how many quic updates to print out wind-related files
+$out_time_emis_rad  ! After how many fire time steps to average emissions and radiation
+$out_time_wind_avg  ! After how many quic updates to print out averaged wind-related files
+! FIRE GRID
+$nz					! Number of vertical layers of fire grid cells (integer)
+$stretch_grid_flag  ! Vertical stretching flag: 0 = uniform dz, 1 = custom
+$_stretch_grid_input ! m, dz
+! FILE PATH
+""
+1                   ! Fuel types are in separate files
+2                   ! File is stream (1) or headers (2)
+! FUEL
+$_fuel_lines
+! IGNITION LOCATIONS
+$_ignition_lines
+$ignitions_per_cell ! number of ignitions
+! FIREBRANDS
+$firebrand_flag		! 0 = off, 1 = on
+! OUTPUT FILES (formats depend on the grid type flag)
+$eng_to_atm_out		! Output gridded energy-to-atmosphere (3D fire grid + extra layers)
+$react_rate_out		! Output compressed array reaction rate (fire grid)
+$fuel_dens_out		! Output compressed array fuel density (fire grid)
+$qf_wind_out	    ! Output gridded wind (u,v,w,sigma) (3D fire grid)
+$qu_wind_inst_out	! Output gridded QU winds with fire effects, instantaneous (QUIC-URB grid)
+$qu_wind_avg_out		! Output gridded QU winds with fire effects, averaged (QUIC-URB grid)
+0					! Output plume trajectories (ONLY FOR DEBUG)
+$fuel_moist_out		! Output compressed array fuel moisture (fire grid)
+$mass_burnt_out		! Output vertically-integrated % mass burnt (fire grid)
+$firebrand_out		! Output trajectories firebrands
+$emissions_out		! Output compressed array emissions (fire grid)
+$radiation_out		! Output gridded thermal radiation (fire grid)
+$intensity_out      ! Output surface fire intensity at every fire time step
+! AUTOKILL
+$auto_kill          ! Kill if the fire is out and there are no more ignitions or firebrands (0 = no, 1 = yes)
diff --git a/quicfire_tools/inputs/templates/latest/QU_TopoInputs.inp b/quicfire_tools/inputs/templates/latest/QU_TopoInputs.inp
new file mode 100644
index 0000000..c8d5663
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/QU_TopoInputs.inp
@@ -0,0 +1,11 @@
+Specify file name for custom topo (full path)
+$filename
+$_topo_lines
+$smoothing_method   ! N/A, smoothing method (0 = none (default for idealized terrain), 1 = blur, 2 = David's)
+$smoothing_passes   ! N/A, number of smoothing passes
+$sor_iterations     ! N/A, number of initial SOR iterations (only if fire is run)
+$sor_cycles         ! N/A, sor cycles
+$sor_relax          ! N/A, sor relaxation parameter (default for flat is 1.78, ignored if there is no terrain)
+0                   ! N/A, add slope flow correction (0 = no, 1 = yes)
+Command to run slope flow code (system specific)
+""
diff --git a/quicfire_tools/inputs/templates/latest/QU_buildings.inp b/quicfire_tools/inputs/templates/latest/QU_buildings.inp
new file mode 100755
index 0000000..dfc62c4
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/QU_buildings.inp
@@ -0,0 +1,4 @@
+!QUIC 6.26
+$wall_roughness_length			!Wall roughness length (m)
+$number_of_buildings			!Number of Buildings
+$number_of_polygon_nodes			!Number of Polygon Building Nodes
diff --git a/quicfire_tools/input-templates/v5.1.1/QU_fileoptions.inp b/quicfire_tools/inputs/templates/latest/QU_fileoptions.inp
old mode 100644
new mode 100755
similarity index 87%
rename from quicfire_tools/input-templates/v5.1.1/QU_fileoptions.inp
rename to quicfire_tools/inputs/templates/latest/QU_fileoptions.inp
index 9eeefa0..605458f
--- a/quicfire_tools/input-templates/v5.1.1/QU_fileoptions.inp
+++ b/quicfire_tools/inputs/templates/latest/QU_fileoptions.inp
@@ -3,4 +3,4 @@
 0   !flag to write out non-mass conserved initial field (uofield.dat) (1=write,0=no write)
 0   !flag to write out the file uosensorfield.dat, the initial sensor velocity field (1=write,0=no write)
 0   !flag to write out the file QU_staggered_velocity.bin used by QUIC-Pressure(1=write,0=no write)
-0   !flag to generate startup files (0 = no, 1 = yes)
\ No newline at end of file
+0   !flag to generate startup files (0 = no, 1 = yes)
diff --git a/quicfire_tools/input-templates/latest/QU_landuse.inp b/quicfire_tools/inputs/templates/latest/QU_landuse.inp
similarity index 100%
rename from quicfire_tools/input-templates/latest/QU_landuse.inp
rename to quicfire_tools/inputs/templates/latest/QU_landuse.inp
diff --git a/quicfire_tools/input-templates/latest/QU_metparams.inp b/quicfire_tools/inputs/templates/latest/QU_metparams.inp
similarity index 58%
rename from quicfire_tools/input-templates/latest/QU_metparams.inp
rename to quicfire_tools/inputs/templates/latest/QU_metparams.inp
index a41fb25..5e21336 100644
--- a/quicfire_tools/input-templates/latest/QU_metparams.inp
+++ b/quicfire_tools/inputs/templates/latest/QU_metparams.inp
@@ -1,7 +1,5 @@
 !QUIC 6.26
 0 !Met input flag (0=QUIC,1=WRF,2=ITT MM5,3=HOTMAC)
-1 !Number of measuring sites
+$num_sensors    !Number of measuring sites
 1 !Maximum size of data points profiles
-sensor1 !Site Name 
-!File name
-sensor1.inp
+$_sensor_lines
diff --git a/quicfire_tools/input-templates/latest/QU_movingcoords.inp b/quicfire_tools/inputs/templates/latest/QU_movingcoords.inp
similarity index 100%
rename from quicfire_tools/input-templates/latest/QU_movingcoords.inp
rename to quicfire_tools/inputs/templates/latest/QU_movingcoords.inp
diff --git a/quicfire_tools/inputs/templates/latest/QU_simparams.inp b/quicfire_tools/inputs/templates/latest/QU_simparams.inp
new file mode 100755
index 0000000..3fb3d20
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/QU_simparams.inp
@@ -0,0 +1,30 @@
+!QUIC 6.26
+$nx ! nx - Domain Length (X) Grid Cells
+$ny ! ny - Domain Width (Y) Grid Cells
+$nz ! nz - domain height (Z) grid cells
+$dx ! DX [m]
+$dy ! DY [m]
+$stretch_grid_flag ! Vertical stretching flag (0 = uniform, 1 = custom, 2 = parabolic Z, 3 = parabolic DZ, 4 = exponential)
+$_vertical_grid_lines
+$_wind_time_lines
+2 ! (NOT USED) Rooftop flag (0 = none, 1 = log profile, 2 = vortex)
+3 ! (NOT USED) Upwind cavity flag (0 = none, 1 = Rockle, 2 = MVP, 3 = HMVP)
+4 ! (NOT USED) Street canyon flag (0 = none, 1 = Roeckle, 2 = CPB, 3 = exp. param. PKK, 4 = Roeckle w/ Fackrel)
+1 ! (NOT USED) Street intersection flag (0 = off, 1 = on)
+4 ! (NOT USED) Wake flag (0 = none, 1 = Rockle, 2 = modified Rockle, 3 = area scaled)
+1 ! (NOT USED) Sidewall flag (0 = off, 1 = on)
+1 ! (NOT USED) Individual tree wake flag
+2 ! (NOT USED) Canopy flag (0 = off, 1 = Cionco w/o wakes, 2 = Cionco w/ wakes)
+1 ! (NOT USED) Season flag (1 = Summer, 2 = Winter, 3 = Transition)
+$sor_iter_max ! Maximum number of iterations
+$sor_residual_reduction ! Residual reduction (Orders of Magnitude)
+$use_diffusion_flag ! Use diffusion algorithm (0 = off, 1 = on)
+$number_diffusion_iterations ! Number of diffusion iterations
+$domain_rotation ! Domain rotation relative to true north [degrees] (cw = +)
+$utm_x ! UTMX of domain origin [m]
+$utm_y ! UTMY of domain origin [m]
+$utm_zone_number ! UTM zone
+$utm_zone_letter ! UTM zone leter (1 = A, 2 = B, etc.)
+$quic_cfd_flag ! QUIC-CFD Flag
+$explosive_bldg_flag ! Explosive building damage flag (1 = on)
+$bldg_array_flag ! Building Array Flag (1 = on)
diff --git a/quicfire_tools/input-templates/latest/Runtime_Advanced_User_Inputs.inp b/quicfire_tools/inputs/templates/latest/Runtime_Advanced_User_Inputs.inp
similarity index 100%
rename from quicfire_tools/input-templates/latest/Runtime_Advanced_User_Inputs.inp
rename to quicfire_tools/inputs/templates/latest/Runtime_Advanced_User_Inputs.inp
diff --git a/quicfire_tools/inputs/templates/latest/gridlist b/quicfire_tools/inputs/templates/latest/gridlist
new file mode 100644
index 0000000..34df7c1
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/gridlist
@@ -0,0 +1,7 @@
+n=$n
+m=$m
+l=$l
+aa1=$aa1
+dx=$dx
+dy=$dy
+dz=$dz
diff --git a/quicfire_tools/input-templates/v5.2.3/rasterorigin.txt b/quicfire_tools/inputs/templates/latest/rasterorigin.txt
similarity index 77%
rename from quicfire_tools/input-templates/v5.2.3/rasterorigin.txt
rename to quicfire_tools/inputs/templates/latest/rasterorigin.txt
index b0916ba..0cd1bf6 100644
--- a/quicfire_tools/input-templates/v5.2.3/rasterorigin.txt
+++ b/quicfire_tools/inputs/templates/latest/rasterorigin.txt
@@ -1,7 +1,7 @@
-0.
-0.
+$utm_x
+$utm_y
 752265.868913356
 3752846.04249607
 742265.868913356
 3742846.04249607
-10000
\ No newline at end of file
+10000
diff --git a/quicfire_tools/inputs/templates/latest/sensor1.inp b/quicfire_tools/inputs/templates/latest/sensor1.inp
new file mode 100644
index 0000000..f944d5c
--- /dev/null
+++ b/quicfire_tools/inputs/templates/latest/sensor1.inp
@@ -0,0 +1,7 @@
+sensor1 !Site Name
+0 !Upper level flag (1 = use this profile for upper level winds)
+50 !Upper level height (meters)
+1 !Site Coordinate Flag (1=QUIC, 2=UTM, 3=Lat/Lon)
+1 !X coordinate (meters)
+1 !Y coordinate (meters)
+$_wind_lines
diff --git a/requirements/tests-310.yml b/requirements/tests-310.yml
index fdbebf1..462413e 100644
--- a/requirements/tests-310.yml
+++ b/requirements/tests-310.yml
@@ -13,4 +13,5 @@ dependencies:
   - zarr
   - numpy
   - scipy
-  - dask
\ No newline at end of file
+  - dask
+  - xarray
diff --git a/requirements/tests-311.yml b/requirements/tests-311.yml
index c126e27..9740021 100644
--- a/requirements/tests-311.yml
+++ b/requirements/tests-311.yml
@@ -13,4 +13,5 @@ dependencies:
   - zarr
   - numpy
   - scipy
-  - dask
\ No newline at end of file
+  - dask
+  - xarray
diff --git a/requirements/tests-38.yml b/requirements/tests-38.yml
index a45ee9f..6c289d1 100644
--- a/requirements/tests-38.yml
+++ b/requirements/tests-38.yml
@@ -13,4 +13,5 @@ dependencies:
   - zarr
   - numpy
   - scipy
-  - dask
\ No newline at end of file
+  - dask
+  - xarray
diff --git a/requirements/tests-39.yml b/requirements/tests-39.yml
index dd3c67d..32fd0d3 100644
--- a/requirements/tests-39.yml
+++ b/requirements/tests-39.yml
@@ -13,4 +13,5 @@ dependencies:
   - zarr
   - numpy
   - scipy
-  - dask
\ No newline at end of file
+  - dask
+  - xarray
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..7dcdbfc
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,8 @@
+import os
+
+TEST_ENV = os.environ.get("TEST_ENV", "local")
+
+if TEST_ENV == "local":
+    import sys
+
+    sys.path.append("../quicfire_tools")
diff --git a/tests/data/test-input/crazy_canyon_100m.zip b/tests/data/test-input/crazy_canyon_100m.zip
deleted file mode 100644
index 56a8f71..0000000
Binary files a/tests/data/test-input/crazy_canyon_100m.zip and /dev/null differ
diff --git a/tests/data/test-input/topo.dat b/tests/data/test-input/topo.dat
deleted file mode 100644
index 1b7953d..0000000
Binary files a/tests/data/test-input/topo.dat and /dev/null differ
diff --git a/tests/data/test-input/treesfueldepth.dat b/tests/data/test-input/treesfueldepth.dat
deleted file mode 100644
index 6e3b567..0000000
Binary files a/tests/data/test-input/treesfueldepth.dat and /dev/null differ
diff --git a/tests/data/test-input/treesmoist.dat b/tests/data/test-input/treesmoist.dat
deleted file mode 100644
index 2c2b02b..0000000
Binary files a/tests/data/test-input/treesmoist.dat and /dev/null differ
diff --git a/tests/data/test-input/treesrhof.dat b/tests/data/test-input/treesrhof.dat
deleted file mode 100644
index 65dae72..0000000
Binary files a/tests/data/test-input/treesrhof.dat and /dev/null differ
diff --git a/tests/data/test-inputs/stretchgrid_0.txt b/tests/data/test-inputs/stretchgrid_0.txt
new file mode 100644
index 0000000..e7aeccc
--- /dev/null
+++ b/tests/data/test-inputs/stretchgrid_0.txt
@@ -0,0 +1,2 @@
+1.0	! Surface DZ [m]
+5	! Number of uniform surface cells
\ No newline at end of file
diff --git a/tests/data/test-inputs/stretchgrid_1.txt b/tests/data/test-inputs/stretchgrid_1.txt
new file mode 100644
index 0000000..fb1760e
--- /dev/null
+++ b/tests/data/test-inputs/stretchgrid_1.txt
@@ -0,0 +1,28 @@
+1.0	! Surface DZ [m]
+! DZ array [m]
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
\ No newline at end of file
diff --git a/tests/data/test-inputs/stretchgrid_3.txt b/tests/data/test-inputs/stretchgrid_3.txt
new file mode 100644
index 0000000..b3f8e15
--- /dev/null
+++ b/tests/data/test-inputs/stretchgrid_3.txt
@@ -0,0 +1,29 @@
+1.0	! Surface DZ [m]
+5	! Number of uniform surface cells
+! DZ array [m]
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0
+1.0954701278755725
+1.38188051150229
+1.8592311508801522
+2.5275220460091594
+3.3867531968893108
+4.436924603520609
+5.678036265903049
+7.110088184036636
+8.733080357921368
+10.547012787557245
+12.551885472944265
+14.74769841408243
+17.134451610971745
+19.712145063612198
+22.480778772003795
+25.440352736146544
+28.590866956040436
+31.932321431685473
+35.46471616308165
+39.18878414733607
\ No newline at end of file
diff --git a/tests/data/test-inputs/wind_times.txt b/tests/data/test-inputs/wind_times.txt
new file mode 100644
index 0000000..4e23d79
--- /dev/null
+++ b/tests/data/test-inputs/wind_times.txt
@@ -0,0 +1,4 @@
+1	! Number of time increments
+0	! UTC offset [hours]
+! Wind step times [s]
+0
\ No newline at end of file
diff --git a/tests/test_input_module.py b/tests/test_input_module.py
index e0446f3..c4f70c6 100644
--- a/tests/test_input_module.py
+++ b/tests/test_input_module.py
@@ -1,340 +1,1900 @@
-# Core Imports
-import sys
+"""
+Test module for the inputs module of the quicfire_tools package.
+"""
+import pytest
+from pydantic import ValidationError
+from pathlib import Path
 
-# Internal Imports
-sys.path.append("../quicfire_tools")
-from quicfire_tools.inputs import SimulationInputs
+from quicfire_tools.inputs import (
+    Gridlist,
+    RasterOrigin,
+    QU_Buildings,
+    QU_Fileoptions,
+    QU_Simparams,
+    QFire_Advanced_User_Inputs,
+    QUIC_fire,
+    QFire_Bldg_Advanced_User_Inputs,
+    QFire_Plume_Advanced_User_Inputs,
+    QU_TopoInputs,
+    RuntimeAdvancedUserInputs,
+    QU_movingcoords,
+    QP_buildout,
+    QU_metparams,
+    Sensor1,
+    SimulationInputs,
+)
+from quicfire_tools.ignitions import RectangleIgnition
+from quicfire_tools.topography import TopoType, GaussianHillTopo
 
-# External Imports
-import pytest
+# Create a tmp/ directory to store the temporary test files
+Path("tmp/").mkdir(exist_ok=True)
+
+
+class TestGridList:
+    def test_init(self):
+        """Test the initialization of a Gridlist object."""
+        # Test the default initialization
+        gridlist = Gridlist(n=10, m=10, l=10, dx=1, dy=1, dz=1, aa1=1)
+        assert isinstance(gridlist, Gridlist)
+        assert gridlist.n == 10
+        for i in ["n", "m", "l", "dx", "dy", "dz", "aa1"]:
+            assert i in gridlist.list_parameters()
+
+        # Test data type casting
+        gridlist = Gridlist(n="10", m=10, l=10, dx=1, dy=1, dz=1, aa1=1)
+        assert isinstance(gridlist.n, int)
+        assert gridlist.n == 10
+
+        # Pass bad parameters: non-real numbers
+        with pytest.raises(ValidationError):
+            Gridlist(n=2.5, m=10, l=10, dx="", dy=1, dz=1, aa1=1)
+        with pytest.raises(ValidationError):
+            Gridlist(n="a", m=10, l=10, dx=1, dy=1, dz=1, aa1=1)
+
+        # Pass bad parameters: zero or negative values
+        with pytest.raises(ValidationError):
+            Gridlist(n=-10, m=10, l=10, dx=0, dy=1, dz=1, aa1=1)
+        with pytest.raises(ValidationError):
+            Gridlist(n=10, m=10, l=10, dx=1, dy=0, dz=1, aa1=1)
+
+    def test_to_dict(self):
+        gridlist = Gridlist(n=10, m=10, l=10, dx=1, dy=1, dz=1, aa1=1)
+        result_dict = gridlist.to_dict()
+        assert result_dict["n"] == 10
+        assert result_dict["m"] == 10
+        assert result_dict["l"] == 10
+        assert result_dict["dx"] == 1
+        assert result_dict["dy"] == 1
+        assert result_dict["dz"] == 1
+        assert "_validate_inputs" not in result_dict
+
+    def test_to_docs(self):
+        gridlist = Gridlist(n=10, m=10, l=10, dx=1, dy=1, dz=1, aa1=1)
+        result_dict = gridlist.to_dict()
+        result_docs = gridlist.get_documentation()
+        for key in result_dict:
+            assert key in result_docs
+        for key in result_docs:
+            assert key in result_dict
+
+    def test_to_file(self):
+        """Test the write_file method of a Gridlist object."""
+        gridlist = Gridlist(n=10, m=10, l=10, dx=1.0, dy=1.0, dz=1.0, aa1=1.0)
+        gridlist.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/gridlist", "r") as file:
+            lines = file.readlines()
+            assert lines[0].split("=")[1].strip() == "10"
+            assert lines[1].split("=")[1].strip() == "10"
+            assert lines[2].split("=")[1].strip() == "10"
+            assert lines[3].split("=")[1].strip() == "1.0"
+            assert lines[4].split("=")[1].strip() == "1.0"
+            assert lines[5].split("=")[1].strip() == "1.0"
+            assert lines[6].split("=")[1].strip() == "1.0"
+
+        # Test writing to a non-existent directory
+        with pytest.raises(FileNotFoundError):
+            gridlist.to_file("/non_existent_path/gridlist.txt")
+
+
+class TestRasterOrigin:
+    def test_init(self):
+        """Test the initialization of a RasterOrigin object."""
+        # Test the default initialization
+        raster_origin = RasterOrigin()
+        assert isinstance(raster_origin, RasterOrigin)
+        assert raster_origin.utm_x == 0.0
+        assert raster_origin.utm_y == 0.0
+
+        # Test the default initialization
+        raster_origin = RasterOrigin(utm_x=500.0, utm_y=1000.0)
+        assert isinstance(raster_origin, RasterOrigin)
+        assert raster_origin.utm_x == 500.0
+        assert raster_origin.utm_y == 1000.0
+
+        # Test data type casting
+        raster_origin = RasterOrigin(utm_x="500", utm_y=1000.0)
+        assert isinstance(raster_origin.utm_x, float)
+        assert raster_origin.utm_x == 500.0
+
+        # Pass bad parameters: non-real numbers
+        with pytest.raises(ValidationError):
+            RasterOrigin(utm_x="x", utm_y=1000.0)
+
+        # Pass bad parameters: zero or negative values
+        with pytest.raises(ValidationError):
+            RasterOrigin(utm_x=-1, utm_y=1000.0)
+        with pytest.raises(ValidationError):
+            RasterOrigin(utm_x=500.0, utm_y=-1000.0)
+
+    def test_to_dict(self):
+        """Test the to_dict method of a RasterOrigin object."""
+        raster_origin = RasterOrigin(utm_x=500.0, utm_y=1000.0)
+        result_dict = raster_origin.to_dict()
+        assert result_dict["utm_x"] == raster_origin.utm_x
+        assert result_dict["utm_y"] == raster_origin.utm_y
+
+    def test_from_dict(self):
+        """Test the from_dict method of a RasterOrigin object."""
+        raster_origin = RasterOrigin(utm_x=500.0, utm_y=1000.0)
+        result_dict = raster_origin.to_dict()
+        test_object = RasterOrigin.from_dict(result_dict)
+        assert isinstance(test_object, RasterOrigin)
+        assert raster_origin == test_object
+
+    def test_to_docs(self):
+        raster_origin = RasterOrigin(utm_x=500.0, utm_y=1000.0)
+        result_dict = raster_origin.to_dict()
+        result_docs = raster_origin.get_documentation()
+        for key in result_dict:
+            assert key in result_docs
+        for key in result_docs:
+            assert key in result_dict
+
+    def test_to_file(self):
+        """Test the to_file method of a RasterOrigin object."""
+        raster_origin = RasterOrigin(utm_x=500.0, utm_y=1000.0)
+        raster_origin.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/rasterorigin.txt", "r") as file:
+            lines = file.readlines()
+            assert float(lines[0].strip()) == raster_origin.utm_x
+            assert float(lines[1].strip()) == raster_origin.utm_y
+
+        # Test writing to a non-existent directory
+        with pytest.raises(FileNotFoundError):
+            raster_origin.to_file("/non_existent_path/rasterorigin.txt")
+
+    def test_from_file(self):
+        """Test initializing a class from a rasterorigin.txt file."""
+        raster_origin = RasterOrigin()
+        raster_origin.to_file("tmp/")
+        test_object = RasterOrigin.from_file("tmp/")
+        assert isinstance(test_object, RasterOrigin)
+        assert raster_origin == test_object
+
+
+class TestQU_Buildings:
+    def test_init(self):
+        """Test the initialization of a QU_Buildings object."""
+        # Test the default initialization
+        qu_buildings = QU_Buildings()
+        assert qu_buildings.wall_roughness_length == 0.1
+        assert qu_buildings.number_of_buildings == 0
+        assert qu_buildings.number_of_polygon_nodes == 0
+
+        # Test custom initialization
+        qu_buildings = QU_Buildings(
+            wall_roughness_length=1.0, number_of_buildings=0, number_of_polygon_nodes=0
+        )
+        assert qu_buildings.wall_roughness_length == 1.0
+        assert qu_buildings.number_of_buildings == 0
+        assert qu_buildings.number_of_polygon_nodes == 0
+
+        # Test data type casting
+        qu_buildings = QU_Buildings(
+            wall_roughness_length="1.0", number_of_buildings=1.0
+        )
+        assert isinstance(qu_buildings.wall_roughness_length, float)
+        assert qu_buildings.wall_roughness_length == 1.0
+        assert isinstance(qu_buildings.number_of_buildings, int)
+        assert qu_buildings.number_of_buildings == 1
+
+        # Pass bad parameters
+        with pytest.raises(ValidationError):
+            QU_Buildings(
+                wall_roughness_length=-1,
+                number_of_buildings=0,
+                number_of_polygon_nodes=0,
+            )
+        with pytest.raises(ValidationError):
+            QU_Buildings(
+                wall_roughness_length=1,
+                number_of_buildings=-1,
+                number_of_polygon_nodes=0,
+            )
+        with pytest.raises(ValidationError):
+            QU_Buildings(wall_roughness_length=0)
+
+    def test_to_dict(self):
+        """Test the to_dict method of a QU_Buildings object."""
+        qu_buildings = QU_Buildings()
+        result_dict = qu_buildings.to_dict()
+        assert (
+            result_dict["wall_roughness_length"] == qu_buildings.wall_roughness_length
+        )
+        assert result_dict["number_of_buildings"] == qu_buildings.number_of_buildings
+        assert (
+            result_dict["number_of_polygon_nodes"]
+            == qu_buildings.number_of_polygon_nodes
+        )
+
+    def test_from_dict(self):
+        """Test the from_dict method of a QU_Buildings object."""
+        qu_buildings = QU_Buildings()
+        result_dict = qu_buildings.to_dict()
+        test_object = QU_Buildings.from_dict(result_dict)
+        assert isinstance(test_object, QU_Buildings)
+        assert qu_buildings == test_object
+
+    def test_to_docs(self):
+        qu_buildings = QU_Buildings()
+        result_dict = qu_buildings.to_dict()
+        result_docs = qu_buildings.get_documentation()
+        for key in result_dict:
+            assert key in result_docs
+        for key in result_docs:
+            assert key in result_dict
+
+    def test_to_file(self):
+        """Test the to_file method of a QU_Buildings object."""
+        qu_buildings = QU_Buildings()
+        qu_buildings.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/QU_buildings.inp", "r") as file:
+            lines = file.readlines()
+            assert (
+                float(lines[1].strip().split("\t")[0])
+                == qu_buildings.wall_roughness_length
+            )
+            assert (
+                int(lines[2].strip().split("\t")[0]) == qu_buildings.number_of_buildings
+            )
+            assert (
+                int(lines[3].strip().split("\t")[0])
+                == qu_buildings.number_of_polygon_nodes
+            )
+
+        # Test writing to a non-existent directory
+        with pytest.raises(FileNotFoundError):
+            qu_buildings.to_file("/non_existent_path/QU_buildings.inp")
+
+    def test_from_file(self):
+        """Test initializing a class from a QU_buildings.inp file."""
+        qu_buildings = QU_Buildings()
+        qu_buildings.to_file("tmp/")
+        test_object = QU_Buildings.from_file("tmp/")
+        assert isinstance(test_object, QU_Buildings)
+        assert qu_buildings == test_object
+
+
+class TestQU_Fileoptions:
+    def test_init(self):
+        # Test default initialization
+        qu_fileoptions = QU_Fileoptions()
+        assert qu_fileoptions.output_data_file_format_flag == 2
+        assert qu_fileoptions.non_mass_conserved_initial_field_flag == 0
+        assert qu_fileoptions.initial_sensor_velocity_field_flag == 0
+        assert qu_fileoptions.qu_staggered_velocity_file_flag == 0
+        assert qu_fileoptions.generate_wind_startup_files_flag == 0
+
+        # Test custom initialization #1
+        qu_fileoptions = QU_Fileoptions(output_data_file_format_flag=1)
+        assert qu_fileoptions.output_data_file_format_flag == 1
+
+        # Test custom initialization #2
+        qu_fileoptions = QU_Fileoptions(non_mass_conserved_initial_field_flag=1)
+        assert qu_fileoptions.non_mass_conserved_initial_field_flag == 1
+
+        # Test custom initialization #3
+        qu_fileoptions = QU_Fileoptions(generate_wind_startup_files_flag=1)
+        assert qu_fileoptions.generate_wind_startup_files_flag == 1
+
+        # Test invalid output_data_file_format_flag flags
+        for invalid_flag in [-1, 0, 5, "1", 1.0, 1.5]:
+            with pytest.raises(ValidationError):
+                QU_Fileoptions(output_data_file_format_flag=invalid_flag)
+
+        # Test invalid non_mass_conserved_initial_field_flag flag
+        for invalid_flag in [-1, 0.0, "1", 2]:
+            with pytest.raises(ValidationError):
+                QU_Fileoptions(non_mass_conserved_initial_field_flag=invalid_flag)
+
+    def test_to_dict(self):
+        """Test the to_dict method of a QU_Buildings object."""
+        qu_fileoptions = QU_Fileoptions()
+        result_dict = qu_fileoptions.to_dict()
+        assert (
+            result_dict["output_data_file_format_flag"]
+            == qu_fileoptions.output_data_file_format_flag
+        )
+        assert (
+            result_dict["non_mass_conserved_initial_field_flag"]
+            == qu_fileoptions.non_mass_conserved_initial_field_flag
+        )
+        assert (
+            result_dict["initial_sensor_velocity_field_flag"]
+            == qu_fileoptions.initial_sensor_velocity_field_flag
+        )
+        assert (
+            result_dict["qu_staggered_velocity_file_flag"]
+            == qu_fileoptions.qu_staggered_velocity_file_flag
+        )
+        assert (
+            result_dict["generate_wind_startup_files_flag"]
+            == qu_fileoptions.generate_wind_startup_files_flag
+        )
+
+    def test_from_dict(self):
+        """Test the from_dict method of a QU_Buildings object."""
+        qu_fileoptions = QU_Fileoptions()
+        result_dict = qu_fileoptions.to_dict()
+        test_object = QU_Fileoptions.from_dict(result_dict)
+        assert isinstance(test_object, QU_Fileoptions)
+        assert qu_fileoptions == test_object
+
+    def test_to_docs(self):
+        qu_fileoptions = QU_Fileoptions()
+        result_dict = qu_fileoptions.to_dict()
+        result_docs = qu_fileoptions.get_documentation()
+        for key in result_dict:
+            assert key in result_docs
+
+    def test_to_file(self):
+        """Test the to_file method of a QU_Buildings object."""
+        qu_fileoptions = QU_Fileoptions()
+        qu_fileoptions.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/QU_fileoptions.inp", "r") as file:
+            lines = file.readlines()
+            assert int(lines[1].strip().split("!")[0]) == 2
+            assert int(lines[2].strip().split("!")[0]) == 0
+            assert int(lines[3].strip().split("!")[0]) == 0
+            assert int(lines[4].strip().split("!")[0]) == 0
+            assert int(lines[5].strip().split("!")[0]) == 0
+
+        # Test writing to a non-existent directory
+        with pytest.raises(FileNotFoundError):
+            qu_fileoptions.to_file("/non_existent_path/QU_buildings.inp")
+
+    def test_from_file(self):
+        """Test initializing a class from a QU_fileoptions.inp file."""
+        qu_fileoptions = QU_Fileoptions()
+        qu_fileoptions.to_file("tmp/")
+        test_object = QU_Fileoptions.from_file("tmp/")
+        assert isinstance(test_object, QU_Fileoptions)
+        assert qu_fileoptions == test_object
+
+
+class TestQU_Simparams:
+    @staticmethod
+    def get_test_object():
+        return QU_Simparams(nx=100, ny=100, nz=26, dx=2.0, dy=2, quic_domain_height=250)
+
+    def test_init(self):
+        # Test default initialization
+        qu_simparams = self.get_test_object()
+        assert qu_simparams.nx == 100
+        assert qu_simparams.ny == 100
+        assert qu_simparams.nz == 26
+        assert qu_simparams.dx == 2
+        assert qu_simparams.dy == 2
+        assert qu_simparams.surface_vertical_cell_size == 1
+        assert qu_simparams.number_surface_cells == 5
+        assert qu_simparams.stretch_grid_flag == 3
+        assert len(qu_simparams._dz_array) == 26
+        assert len(qu_simparams._vertical_grid_lines.split("\n")) == 29
+
+        # Test changing the default values
+        qu_simparams.nx = 150
+        assert qu_simparams.nx == 150
+
+        # Test property setters
+        qu_simparams.nz = 30
+        assert qu_simparams.nz == 30
+        assert len(qu_simparams._dz_array) == 30
+        assert len(qu_simparams._vertical_grid_lines.split("\n")) == 33
+
+        # Test data type casting
+        qu_simparams = QU_Simparams(
+            nx="100", ny=100, nz=26, dx=2, dy=2, quic_domain_height=5
+        )
+        assert isinstance(qu_simparams.nx, int)
+        assert qu_simparams.nx == 100
+
+        # Test with custom _dz_array
+        # TODO: Come back to this tests
+        # qu_simparams = QU_Simparams(nx=100, ny=100, nz=26, dx=2, dy=2,
+        #                             custom_dz_array=[1] * 26,
+        #                             quic_domain_height=250)
+        # assert qu_simparams._dz_array == [
+        #     qu_simparams.surface_vertical_cell_size] * 26
+
+        # Test invalid stretch_grid_flags
+        for invalid_flag in [-1, 4, "1", 1.0, 1.5, 2]:
+            with pytest.raises(ValidationError):
+                QU_Simparams(stretch_grid_flag=invalid_flag)
+
+    def test_dz_array(self):
+        # Test with stretch_grid_flag = 0
+        qu_simparams = self.get_test_object()
+        qu_simparams.stretch_grid_flag = 0
+        assert (
+            qu_simparams._dz_array
+            == [qu_simparams.surface_vertical_cell_size] * qu_simparams.nz
+        )
+
+        # Test with stretch_grid_flag = 1
+        qu_simparams = self.get_test_object()
+        qu_simparams.stretch_grid_flag = 1
+        qu_simparams.custom_dz_array = [0.5] * qu_simparams.nz
+        assert qu_simparams._dz_array == [0.5] * qu_simparams.nz
+
+        # Test with stretch_grid_flag = 3
+        qu_simparams = self.get_test_object()
+        assert len(qu_simparams._dz_array) == qu_simparams.nz
+
+    def test_stretch_grid_flag_0(self):
+        qu_simparams = self.get_test_object()
+        qu_simparams.stretch_grid_flag = 0
+        vertical_grid_lines = qu_simparams._stretch_grid_flag_0()
+        with open("data/test-inputs/stretchgrid_0.txt") as f:
+            expected_lines = f.readlines()
+        assert vertical_grid_lines == "".join(expected_lines)
+
+    def test_stretch_grid_flag_1(self):
+        qu_simparams = self.get_test_object()
+        qu_simparams.stretch_grid_flag = 1
+
+        # Test with no _dz_array input
+        with pytest.raises(ValueError):
+            qu_simparams._stretch_grid_flag_1()
+
+        # Test with 19 custom_dz_array inputs
+        qu_simparams.custom_dz_array = [1] * (qu_simparams.nz - 1)
+        with pytest.raises(ValueError):
+            qu_simparams._stretch_grid_flag_1()
+
+        # Test with dz inputs that don't match the surface values
+        qu_simparams.custom_dz_array = [1] * qu_simparams.nz
+        qu_simparams.custom_dz_array[0] = 2
+        with pytest.raises(ValueError):
+            qu_simparams._stretch_grid_flag_1()
+
+        # Test valid case
+        qu_simparams.custom_dz_array = [1] * qu_simparams.nz
+        vertical_grid_lines = qu_simparams._stretch_grid_flag_1()
+        with open("data/test-inputs/stretchgrid_1.txt") as f:
+            expected_lines = f.readlines()
+        assert vertical_grid_lines == "".join(expected_lines)
+
+    def test_stretch_grid_flag_3(self):
+        qu_simparams = self.get_test_object()
+        vertical_grid_lines = qu_simparams._stretch_grid_flag_3()
+        with open("data/test-inputs/stretchgrid_3.txt") as f:
+            expected_lines = f.readlines()
+        assert vertical_grid_lines == "".join(expected_lines)
+
+    def test_generate_vertical_grid(self):
+        qu_simparams = self.get_test_object()
+
+        # Test stretch_grid_flag = 0
+        qu_simparams.stretch_grid_flag = 0
+        with open("data/test-inputs/stretchgrid_0.txt") as f:
+            expected_lines = f.readlines()
+        assert qu_simparams._vertical_grid_lines == "".join(expected_lines)
+
+        # Test stretch_grid_flag = 1
+        qu_simparams.stretch_grid_flag = 1
+        qu_simparams.custom_dz_array = [1] * qu_simparams.nz
+        with open("data/test-inputs/stretchgrid_1.txt") as f:
+            expected_lines = f.readlines()
+        assert qu_simparams._vertical_grid_lines == "".join(expected_lines)
+
+        # Test stretch_grid_flag = 3
+        qu_simparams.stretch_grid_flag = 3
+        with open("data/test-inputs/stretchgrid_3.txt") as f:
+            expected_lines = f.readlines()
+        assert qu_simparams._vertical_grid_lines == "".join(expected_lines)
+
+    def test_generate_wind_times(self):
+        # Test valid wind_step_times
+        qu_simparams = self.get_test_object()
+        qu_simparams.wind_times = [0]
+        wind_times_lines = qu_simparams._generate_wind_time_lines()
+        with open("data/test-inputs/wind_times.txt") as f:
+            expected_lines = f.readlines()
+        assert wind_times_lines == "".join(expected_lines)
+
+        # Test invalid wind_step_times
+        qu_simparams.wind_times = []
+        with pytest.raises(ValueError):
+            qu_simparams._generate_wind_time_lines()
+
+    def test_to_dict(self):
+        """
+        Test the to_dict method of a QU_Simparams object.
+        """
+        qu_simparams = self.get_test_object()
+        result_dict = qu_simparams.to_dict()
+
+        # Test the passed parameters
+        assert result_dict["nx"] == qu_simparams.nx
+        assert result_dict["ny"] == qu_simparams.ny
+        assert result_dict["nz"] == qu_simparams.nz
+        assert result_dict["dx"] == qu_simparams.dx
+        assert result_dict["dy"] == qu_simparams.dy
+        assert (
+            result_dict["surface_vertical_cell_size"]
+            == qu_simparams.surface_vertical_cell_size
+        )
+        assert result_dict["number_surface_cells"] == qu_simparams.number_surface_cells
+
+        # Test the default parameters
+        assert (
+            result_dict["surface_vertical_cell_size"]
+            == qu_simparams.surface_vertical_cell_size
+        )
+        assert result_dict["number_surface_cells"] == qu_simparams.number_surface_cells
+        assert result_dict["stretch_grid_flag"] == qu_simparams.stretch_grid_flag
+        assert result_dict["_dz_array"] == qu_simparams._dz_array
+        assert result_dict["utc_offset"] == qu_simparams.utc_offset
+        assert result_dict["wind_times"] == qu_simparams.wind_times
+        assert result_dict["sor_iter_max"] == qu_simparams.sor_iter_max
+        assert (
+            result_dict["sor_residual_reduction"] == qu_simparams.sor_residual_reduction
+        )
+        assert result_dict["use_diffusion_flag"] == qu_simparams.use_diffusion_flag
+        assert (
+            result_dict["number_diffusion_iterations"]
+            == qu_simparams.number_diffusion_iterations
+        )
+        assert result_dict["domain_rotation"] == qu_simparams.domain_rotation
+        assert result_dict["utm_x"] == qu_simparams.utm_x
+        assert result_dict["utm_y"] == qu_simparams.utm_y
+        assert result_dict["utm_zone_number"] == qu_simparams.utm_zone_number
+        assert result_dict["utm_zone_letter"] == qu_simparams.utm_zone_letter
+        assert result_dict["quic_cfd_flag"] == qu_simparams.quic_cfd_flag
+        assert result_dict["explosive_bldg_flag"] == qu_simparams.explosive_bldg_flag
+        assert result_dict["bldg_array_flag"] == qu_simparams.bldg_array_flag
+
+    def test_from_dict(self):
+        """
+        Test the from_dict method of a QU_Simparams object.
+        """
+        qu_simparams = self.get_test_object()
+        result_dict = qu_simparams.to_dict()
+        test_object = QU_Simparams.from_dict(result_dict)
+        assert isinstance(test_object, QU_Simparams)
+        assert qu_simparams == test_object
+
+    def test_to_docs(self):
+        qu_simparams = self.get_test_object()
+        result_dict = qu_simparams.to_dict()
+        result_docs = qu_simparams.get_documentation()
+        for key in result_dict:
+            if key in ["_vertical_grid_lines", "_wind_time_lines", "custom_dz_array"]:
+                continue
+            assert key in result_docs
+        for key in result_docs:
+            assert key in result_dict
+
+    def test_to_file(self):
+        """
+        Test the to_file method of a QU_Simparams object.
+        """
+        qu_simparams = self.get_test_object()
+        qu_simparams.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/QU_simparams.inp", "r") as file:
+            lines = file.readlines()
+
+        # Check nx, ny, nz, dx, dy
+        assert int(lines[1].strip().split("!")[0]) == qu_simparams.nx
+        assert int(lines[2].strip().split("!")[0]) == qu_simparams.ny
+        assert int(lines[3].strip().split("!")[0]) == qu_simparams.nz
+        assert float(lines[4].strip().split("!")[0]) == qu_simparams.dx
+        assert float(lines[5].strip().split("!")[0]) == qu_simparams.dy
+
+        # Check stretch_grid_flag, surface_vertical_cell_size,
+        # number_surface_cells
+        assert int(lines[6].strip().split("!")[0]) == qu_simparams.stretch_grid_flag
+        assert (
+            float(lines[7].strip().split("!")[0])
+            == qu_simparams.surface_vertical_cell_size
+        )
+        assert int(lines[8].strip().split("!")[0]) == qu_simparams.number_surface_cells
+
+        # Check _dz_array
+        assert lines[9] == "! DZ array [m]\n"
+        for i in range(qu_simparams.nz):
+            index = i + 10
+            dz = qu_simparams._dz_array[i]
+            assert float(lines[index].strip()) == dz
+
+        # Update lines index
+        i_current = 10 + qu_simparams.nz
+
+        # Check number of time increments, utc_offset
+        assert int(lines[i_current].strip().split("!")[0]) == len(
+            qu_simparams.wind_times
+        )
+        assert (
+            int(lines[i_current + 1].strip().split("!")[0]) == qu_simparams.utc_offset
+        )
+
+        # Check wind_step_times
+        assert lines[i_current + 2] == "! Wind step times [s]\n"
+        for i in range(len(qu_simparams.wind_times)):
+            index = i_current + 3 + i
+            wind_time = qu_simparams.wind_times[i]
+            assert int(lines[index].strip()) == wind_time
+
+        # Update lines index
+        i_current = i_current + 3 + len(qu_simparams.wind_times)
+        i_current += 9  # Skip not used lines
+
+        # Check sor_iter_max, sor_residual_reduction
+        assert int(lines[i_current].strip().split("!")[0]) == qu_simparams.sor_iter_max
+        assert (
+            int(lines[i_current + 1].strip().split("!")[0])
+            == qu_simparams.sor_residual_reduction
+        )
+
+        # Check use_diffusion_flag, number_diffusion_iterations, domain_rotation
+        # utm_x, utm_y, utm_zone_number, utm_zone_letter, quic_cfd_flag,
+        # explosive_bldg_flag, bldg_array_flag
+        assert (
+            int(lines[i_current + 2].strip().split("!")[0])
+            == qu_simparams.use_diffusion_flag
+        )
+        assert (
+            int(lines[i_current + 3].strip().split("!")[0])
+            == qu_simparams.number_diffusion_iterations
+        )
+        assert (
+            float(lines[i_current + 4].strip().split("!")[0])
+            == qu_simparams.domain_rotation
+        )
+        assert float(lines[i_current + 5].strip().split("!")[0]) == qu_simparams.utm_x
+        assert float(lines[i_current + 6].strip().split("!")[0]) == qu_simparams.utm_y
+        assert (
+            int(lines[i_current + 7].strip().split("!")[0])
+            == qu_simparams.utm_zone_number
+        )
+        assert (
+            int(lines[i_current + 8].strip().split("!")[0])
+            == qu_simparams.utm_zone_letter
+        )
+        assert (
+            int(lines[i_current + 9].strip().split("!")[0])
+            == qu_simparams.quic_cfd_flag
+        )
+        assert (
+            int(lines[i_current + 10].strip().split("!")[0])
+            == qu_simparams.explosive_bldg_flag
+        )
+        assert (
+            int(lines[i_current + 11].strip().split("!")[0])
+            == qu_simparams.bldg_array_flag
+        )
+
+    def test_from_file(self):
+        """
+        Test initializing a class from a QU_simparams.inp file.
+        """
+        # Test stretch grid flag = 3
+        qu_simparams = self.get_test_object()
+        qu_simparams.to_file("tmp/")
+        test_object = QU_Simparams.from_file("tmp/")
+        assert isinstance(test_object, QU_Simparams)
+        assert qu_simparams == test_object
+
+        # Test stretch grid flag = 0
+        qu_simparams = self.get_test_object()
+        qu_simparams.stretch_grid_flag = 0
+        qu_simparams.to_file("tmp/")
+        test_object = QU_Simparams.from_file("tmp/")
+        assert isinstance(test_object, QU_Simparams)
+        assert qu_simparams == test_object
+
+        # Test stretch grid flag = 1
+        qu_simparams = self.get_test_object()
+        qu_simparams.stretch_grid_flag = 1
+        qu_simparams.custom_dz_array = [1] * qu_simparams.nz
+        qu_simparams.to_file("tmp/")
+        test_object = QU_Simparams.from_file("tmp/")
+        assert isinstance(test_object, QU_Simparams)
+        assert qu_simparams == test_object
+
+
+class TestQFire_Advanced_User_Inputs:
+    def test_init(self):
+        """Test the initialization of a QFire_Advanced_User_Inputs object."""
+        # Test the default initialization
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs()
+        assert qfire_advanced_user_inputs.fraction_cells_launch_firebrands == 0.05
+
+        # Test custom initialization
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs(
+            fraction_cells_launch_firebrands=0.1
+        )
+        assert qfire_advanced_user_inputs.fraction_cells_launch_firebrands == 0.1
+
+        # Test data type casting
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs(
+            fraction_cells_launch_firebrands="0.1"
+        )
+        assert isinstance(
+            qfire_advanced_user_inputs.fraction_cells_launch_firebrands, float
+        )
+        assert qfire_advanced_user_inputs.fraction_cells_launch_firebrands == 0.1
+
+        # Pass bad parameters: negative numbers
+        with pytest.raises(ValidationError):
+            QFire_Advanced_User_Inputs(fraction_cells_launch_firebrands=-1)
+
+        # Pass bad parameters: not a fraction
+        with pytest.raises(ValidationError):
+            QFire_Advanced_User_Inputs(fraction_cells_launch_firebrands=2)
+
+        # Pass bad parameters: not a valid range for theta
+        with pytest.raises(ValidationError):
+            QFire_Advanced_User_Inputs(minimum_landing_angle=361)
+
+    def test_to_dict(self):
+        """Test the to_dict method of a QFire_Advanced_User_Inputs object."""
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs()
+        result_dict = qfire_advanced_user_inputs.to_dict()
+        assert (
+            result_dict["fraction_cells_launch_firebrands"]
+            == qfire_advanced_user_inputs.fraction_cells_launch_firebrands
+        )
+        assert (
+            result_dict["firebrand_radius_scale_factor"]
+            == qfire_advanced_user_inputs.firebrand_radius_scale_factor
+        )
+        assert (
+            result_dict["firebrand_trajectory_time_step"]
+            == qfire_advanced_user_inputs.firebrand_trajectory_time_step
+        )
+        assert (
+            result_dict["firebrand_launch_interval"]
+            == qfire_advanced_user_inputs.firebrand_launch_interval
+        )
+        assert (
+            result_dict["firebrands_per_deposition"]
+            == qfire_advanced_user_inputs.firebrands_per_deposition
+        )
+        assert (
+            result_dict["firebrand_area_ratio"]
+            == qfire_advanced_user_inputs.firebrand_area_ratio
+        )
+        assert (
+            result_dict["minimum_burn_rate_coefficient"]
+            == qfire_advanced_user_inputs.minimum_burn_rate_coefficient
+        )
+        assert (
+            result_dict["max_firebrand_thickness_fraction"]
+            == qfire_advanced_user_inputs.max_firebrand_thickness_fraction
+        )
+        assert (
+            result_dict["firebrand_germination_delay"]
+            == qfire_advanced_user_inputs.firebrand_germination_delay
+        )
+        assert (
+            result_dict["vertical_velocity_scale_factor"]
+            == qfire_advanced_user_inputs.vertical_velocity_scale_factor
+        )
+        assert (
+            result_dict["minimum_firebrand_ignitions"]
+            == qfire_advanced_user_inputs.minimum_firebrand_ignitions
+        )
+        assert (
+            result_dict["maximum_firebrand_ignitions"]
+            == qfire_advanced_user_inputs.maximum_firebrand_ignitions
+        )
+        assert (
+            result_dict["minimum_landing_angle"]
+            == qfire_advanced_user_inputs.minimum_landing_angle
+        )
+        assert (
+            result_dict["maximum_firebrand_thickness"]
+            == qfire_advanced_user_inputs.maximum_firebrand_thickness
+        )
+
+    def test_from_dict(self):
+        """Test class initialization from a dictionary object"""
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs()
+        result_dict = qfire_advanced_user_inputs.to_dict()
+        test_obj = QFire_Advanced_User_Inputs.from_dict(result_dict)
+        assert test_obj == qfire_advanced_user_inputs
+
+    def test_to_docs(self):
+        """Test the to_docs method of a QFire_Advanced_User_Inputs object."""
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs()
+        result_dict = qfire_advanced_user_inputs.to_dict()
+        result_docs = qfire_advanced_user_inputs.get_documentation()
+        for key in result_dict:
+            assert key in result_docs
+        for key in result_docs:
+            assert key in result_dict
+
+    def test_to_file(self):
+        """Test the to_file method of a QFire_Advanced_User_Inputs object."""
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs(
+            fraction_cells_launch_firebrands=0.1
+        )
+        qfire_advanced_user_inputs.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/QFIRE_advanced_user_inputs.inp", "r") as file:
+            lines = file.readlines()
+            assert (
+                float(lines[0].strip().split("!")[0])
+                == qfire_advanced_user_inputs.fraction_cells_launch_firebrands
+            )
+            assert (
+                float(lines[1].strip().split("!")[0])
+                == qfire_advanced_user_inputs.firebrand_radius_scale_factor
+            )
+            assert (
+                float(lines[2].strip().split("!")[0])
+                == qfire_advanced_user_inputs.firebrand_trajectory_time_step
+            )
+            assert (
+                float(lines[3].strip().split("!")[0])
+                == qfire_advanced_user_inputs.firebrand_launch_interval
+            )
+            assert (
+                float(lines[4].strip().split("!")[0])
+                == qfire_advanced_user_inputs.firebrands_per_deposition
+            )
+            assert (
+                float(lines[5].strip().split("!")[0])
+                == qfire_advanced_user_inputs.firebrand_area_ratio
+            )
+            assert (
+                float(lines[6].strip().split("!")[0])
+                == qfire_advanced_user_inputs.minimum_burn_rate_coefficient
+            )
+            assert (
+                float(lines[7].strip().split("!")[0])
+                == qfire_advanced_user_inputs.max_firebrand_thickness_fraction
+            )
+            assert (
+                float(lines[8].strip().split("!")[0])
+                == qfire_advanced_user_inputs.firebrand_germination_delay
+            )
+            assert (
+                float(lines[9].strip().split("!")[0])
+                == qfire_advanced_user_inputs.vertical_velocity_scale_factor
+            )
+            assert (
+                float(lines[10].strip().split("!")[0])
+                == qfire_advanced_user_inputs.minimum_firebrand_ignitions
+            )
+            assert (
+                float(lines[11].strip().split("!")[0])
+                == qfire_advanced_user_inputs.maximum_firebrand_ignitions
+            )
+            assert (
+                float(lines[12].strip().split("!")[0])
+                == qfire_advanced_user_inputs.minimum_landing_angle
+            )
+            assert (
+                float(lines[13].strip().split("!")[0])
+                == qfire_advanced_user_inputs.maximum_firebrand_thickness
+            )
+
+        # Test writing to a non-existent directory
+        with pytest.raises(FileNotFoundError):
+            qfire_advanced_user_inputs.to_file(
+                "/non_existent_path/QFIRE_advanced_user_inputs.inp"
+            )
+
+    def test_from_file(self):
+        """Test initializing a class from a QFIRE_advanced_user_inputs.inp
+        file."""
+        qfire_advanced_user_inputs = QFire_Advanced_User_Inputs()
+        qfire_advanced_user_inputs.to_file("tmp/")
+        test_object = QFire_Advanced_User_Inputs.from_file("tmp/")
+        assert isinstance(test_object, QFire_Advanced_User_Inputs)
+        assert qfire_advanced_user_inputs == test_object
+
+
+class TestQUIC_fire:
+    @staticmethod
+    def get_test_object():
+        return QUIC_fire(nz=26, sim_time=60, time_now=1695311421)
+
+    @staticmethod
+    def get_complex_test_object():
+        return QUIC_fire(
+            nz=5,
+            sim_time=60,
+            time_now=1695311421,
+            ignition_type=RectangleIgnition(
+                x_min=20, y_min=20, x_length=10, y_length=160
+            ),
+            stretch_grid_flag=1,
+            dz_array=[1, 2, 3, 4, 5],
+            fuel_flag=1,
+            fuel_density=0.5,
+            fuel_moisture=1,
+            fuel_height=0.75,
+        )
+
+    def test_init(self):
+        # Test default initialization
+        quic_fire = self.get_test_object()
+        assert quic_fire.nz == 26
+        assert quic_fire.sim_time == 60
+
+        # Test changing the default values
+        quic_fire.nz = 27
+        assert quic_fire.nz == 27
+
+        # Test data type casting
+        quic_fire = QUIC_fire(nz="26", sim_time=60, time_now=1695311421)
+        assert isinstance(quic_fire.nz, int)
+        assert quic_fire.nz == 26
+
+        # Test stretch grid input
+        assert quic_fire.stretch_grid_flag == 0
+        assert quic_fire._stretch_grid_input == "1"
+        assert quic_fire.dz == 1
+        quic_fire.nz = 5
+        quic_fire.dz_array = [1, 2, 3, 4, 5]
+        quic_fire.stretch_grid_flag = 1
+        assert quic_fire._stretch_grid_input == "1.0\n2.0\n3.0\n4.0\n5.0\n"
+
+        # Test invalid dz array
+        quic_fire = QUIC_fire(
+            nz=26,
+            sim_time=60,
+            time_now=1695311421,
+            stretch_grid_flag=1,
+            dz_array=[1, 2, 3, 4, 5],
+        )
+        with pytest.raises(ValueError):
+            assert quic_fire._stretch_grid_input == "1.0\n2.0\n3.0\n4.0\n5.0\n"
+
+        # Test invalid random_seed
+        quic_fire = self.get_test_object()
+        with pytest.raises(ValidationError):
+            quic_fire.random_seed = 0
+
+        # Test fuel inputs
+        quic_fire = QUIC_fire(nz=26, sim_time=60, time_now=1695311421)
+        assert quic_fire.fuel_density is None
+
+        # Change fuel flag
+        quic_fire.fuel_flag = 1
+
+        # Writing QUIC_fire to file at this point should throw an error because
+        # fuel_density, fuel_moisture, and fuel_height are not set
+        with pytest.raises(ValueError):
+            quic_fire.to_file("tmp/")
+
+        # Set fuel_density, fuel_moisture, and fuel_height
+        quic_fire.fuel_density = 0.5
+        quic_fire.fuel_moisture = 1
+        quic_fire.fuel_height = 0.75
+        assert quic_fire._fuel_lines == (
+            f"{quic_fire.fuel_flag}\t! fuel density flag: 1 = uniform; "
+            f"2 = provided thru QF_FuelMoisture.inp, 3 = Firetech"
+            f" files for quic grid, 4 = Firetech files for "
+            f"different grid (need interpolation)"
+            f"\n0.5"
+            f"\n{quic_fire.fuel_flag}\t! fuel moisture flag: 1 = uniform; "
+            f"2 = provided thru QF_FuelMoisture.inp, 3 = Firetech"
+            f" files for quic grid, 4 = Firetech files for "
+            f"different grid (need interpolation)"
+            f"\n1.0"
+            f"\n{quic_fire.fuel_flag}\t! fuel height flag: 1 = uniform; "
+            f"2 = provided thru QF_FuelMoisture.inp, 3 = Firetech"
+            f" files for quic grid, 4 = Firetech files for "
+            f"different grid (need interpolation)"
+            f"\n0.75"
+        )
+
+    def test_to_dict(self):
+        """Test the to_dict method of a QUIC_fire object."""
+        quic_fire = self.get_complex_test_object()
+        result_dict = quic_fire.to_dict()
+
+        assert result_dict["nz"] == quic_fire.nz
+        assert result_dict["time_now"] == quic_fire.time_now
+        assert result_dict["sim_time"] == quic_fire.sim_time
+        assert result_dict["fire_flag"] == quic_fire.fire_flag
+        assert result_dict["random_seed"] == quic_fire.random_seed
+        assert result_dict["fire_time_step"] == quic_fire.fire_time_step
+        assert result_dict["quic_time_step"] == quic_fire.quic_time_step
+        assert result_dict["out_time_fire"] == quic_fire.out_time_fire
+        assert result_dict["out_time_wind"] == quic_fire.out_time_wind
+        assert result_dict["out_time_emis_rad"] == quic_fire.out_time_emis_rad
+        assert result_dict["out_time_wind_avg"] == quic_fire.out_time_wind_avg
+        assert result_dict["stretch_grid_flag"] == quic_fire.stretch_grid_flag
+        assert result_dict["dz"] == quic_fire.dz
+        assert result_dict["_dz_array"] == quic_fire.dz_array
+        assert result_dict["fuel_flag"] == quic_fire.fuel_flag
+        assert result_dict["fuel_density"] == quic_fire.fuel_density
+        assert result_dict["fuel_moisture"] == quic_fire.fuel_moisture
+        assert result_dict["fuel_height"] == quic_fire.fuel_height
+        assert result_dict["_fuel_lines"] == quic_fire._fuel_lines
+        assert (
+            result_dict["ignition_type"]["ignition_flag"]
+            == quic_fire.ignition_type.ignition_flag
+        )
+        assert result_dict["ignition_type"]["x_min"] == quic_fire.ignition_type.x_min
+        assert result_dict["ignition_type"]["y_min"] == quic_fire.ignition_type.y_min
+        assert (
+            result_dict["ignition_type"]["x_length"] == quic_fire.ignition_type.x_length
+        )
+        assert (
+            result_dict["ignition_type"]["y_length"] == quic_fire.ignition_type.y_length
+        )
+        assert result_dict["ignitions_per_cell"] == quic_fire.ignitions_per_cell
+        assert result_dict["firebrand_flag"] == quic_fire.firebrand_flag
+        assert result_dict["auto_kill"] == quic_fire.auto_kill
+        assert result_dict["eng_to_atm_out"] == quic_fire.eng_to_atm_out
+        assert result_dict["react_rate_out"] == quic_fire.react_rate_out
+        assert result_dict["fuel_dens_out"] == quic_fire.fuel_dens_out
+        assert result_dict["qf_wind_out"] == quic_fire.qf_wind_out
+        assert result_dict["qu_wind_inst_out"] == quic_fire.qu_wind_inst_out
+        assert result_dict["qu_wind_avg_out"] == quic_fire.qu_wind_avg_out
+        assert result_dict["fuel_moist_out"] == quic_fire.fuel_moist_out
+        assert result_dict["mass_burnt_out"] == quic_fire.mass_burnt_out
+        assert result_dict["firebrand_out"] == quic_fire.firebrand_out
+        assert result_dict["emissions_out"] == quic_fire.emissions_out
+        assert result_dict["radiation_out"] == quic_fire.radiation_out
+        assert result_dict["intensity_out"] == quic_fire.intensity_out
+
+        # Computed fields
+        assert result_dict["_stretch_grid_input"] == quic_fire._stretch_grid_input
+        assert result_dict["_ignition_lines"] == quic_fire._ignition_lines
+        assert result_dict["_fuel_lines"] == quic_fire._fuel_lines
+
+    def test_from_dict(self):
+        quic_fire = self.get_test_object()
+        test_dict = quic_fire.to_dict()
+        test_object = QUIC_fire.from_dict(test_dict)
+        assert test_object == quic_fire
+
+        quic_fire = self.get_complex_test_object()
+        test_dict = quic_fire.to_dict()
+        test_object = QUIC_fire.from_dict(test_dict)
+        assert test_object == quic_fire
+
+    # TODO: Clarify to_docs test
+    # def test_to_docs(self):
+    #     quic_fire = self.get_test_object()
+    #     result_dict = quic_fire.to_dict()
+    #     result_docs = quic_fire.get_documentation()
+    #     for key in result_dict:
+    #         assert key in result_docs
+    #     for key in result_docs:
+    #         assert key in result_dict
+
+    #     quic_fire = self.get_complex_test_object()
+    #     result_dict = quic_fire.to_dict()
+    #     result_docs = quic_fire.get_documentation()
+    #     for key in result_dict:
+    #         assert key in result_docs
+    #     for key in result_docs:
+    #         assert key in result_dict
+
+    def test_to_file(self):
+        quic_fire = self.get_complex_test_object()
+        quic_fire.to_file("tmp/")
+        with open("tmp/QUIC_fire.inp", "r") as file:
+            lines = file.readlines()
+
+        assert quic_fire.fire_flag == int(lines[0].strip().split("!")[0])
+        assert quic_fire.random_seed == int(lines[1].strip().split("!")[0])
+        assert quic_fire.time_now == int(lines[3].strip().split("!")[0])
+        assert quic_fire.sim_time == int(lines[4].strip().split("!")[0])
+        assert quic_fire.fire_time_step == int(lines[5].strip().split("!")[0])
+        assert quic_fire.quic_time_step == int(lines[6].strip().split("!")[0])
+        assert quic_fire.out_time_fire == int(lines[7].strip().split("!")[0])
+        assert quic_fire.out_time_wind == int(lines[8].strip().split("!")[0])
+        assert quic_fire.out_time_emis_rad == int(lines[9].strip().split("!")[0])
+        assert quic_fire.out_time_wind_avg == int(lines[10].strip().split("!")[0])
+        assert quic_fire.nz == int(lines[12].strip().split("!")[0])
+        assert quic_fire.stretch_grid_flag == int(lines[13].strip().split("!")[0])
+        dz_array = []
+        for i in range(14, 14 + len(quic_fire.dz_array)):
+            dz_array.append(float(lines[i].strip()))
+        assert quic_fire.dz_array == dz_array
+        current_line = 15 + len(quic_fire.dz_array)
+        current_line += 4  # skip unused lines
+        current_line += 1  # header
+        assert quic_fire.fuel_flag == int(lines[current_line].strip().split("!")[0])
+        assert quic_fire.fuel_density == float(lines[current_line + 1].strip())
+        assert quic_fire.fuel_moisture == float(lines[current_line + 3].strip())
+        assert quic_fire.fuel_height == float(lines[current_line + 5].strip())
+        current_line += 6
+        current_line += 1  # header
+        ignition_flag = int(lines[current_line].strip().split("!")[0])
+        ignition_params = []
+        current_line += 1
+        for i in range(current_line, current_line + 4):
+            ignition_params.append(float(lines[i].strip().split("!")[0]))
+        x_min, y_min, x_length, y_length = ignition_params
+        assert quic_fire.ignition_type == RectangleIgnition(
+            ignition_flag=ignition_flag,
+            x_min=x_min,
+            y_min=y_min,
+            x_length=x_length,
+            y_length=y_length,
+        )
+        current_line += 4
+        assert quic_fire.ignitions_per_cell == int(
+            lines[current_line].strip().split("!")[0]
+        )
+        current_line += 1
+        current_line += 1  # header
+        assert quic_fire.firebrand_flag == int(
+            lines[current_line].strip().split("!")[0]
+        )
+        current_line += 1
+        assert quic_fire.eng_to_atm_out == int(
+            lines[current_line + 1].strip().split("!")[0]
+        )
+        assert quic_fire.react_rate_out == int(
+            lines[current_line + 2].strip().split("!")[0]
+        )
+        assert quic_fire.fuel_dens_out == int(
+            lines[current_line + 3].strip().split("!")[0]
+        )
+        assert quic_fire.qf_wind_out == int(
+            lines[current_line + 4].strip().split("!")[0]
+        )
+        assert quic_fire.qu_wind_inst_out == int(
+            lines[current_line + 5].strip().split("!")[0]
+        )
+        assert quic_fire.qu_wind_avg_out == int(
+            lines[current_line + 6].strip().split("!")[0]
+        )
+        assert quic_fire.fuel_moist_out == int(
+            lines[current_line + 8].strip().split("!")[0]
+        )
+        assert quic_fire.mass_burnt_out == int(
+            lines[current_line + 9].strip().split("!")[0]
+        )
+        assert quic_fire.firebrand_out == int(
+            lines[current_line + 10].strip().split("!")[0]
+        )
+        assert quic_fire.emissions_out == int(
+            lines[current_line + 11].strip().split("!")[0]
+        )
+        assert quic_fire.radiation_out == int(
+            lines[current_line + 12].strip().split("!")[0]
+        )
+        assert quic_fire.intensity_out == int(
+            lines[current_line + 13].strip().split("!")[0]
+        )
+        assert quic_fire.auto_kill == int(
+            lines[current_line + 15].strip().split("!")[0]
+        )
+
+    def test_from_file(self):
+        """Test initializing a class from a QUIC_fire.inp
+        file."""
+        quic_fire = self.get_test_object()
+        quic_fire.to_file("tmp/")
+        test_object = QUIC_fire.from_file("tmp/")
+        assert isinstance(test_object, QUIC_fire)
+        assert quic_fire == test_object
+
+
+class Test_QFire_Bldg_Advanced_User_Inputs:
+    def test_default_init(self):
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs()
+
+        assert bldg_inputs.convert_buildings_to_fuel_flag == 0
+        assert bldg_inputs.building_fuel_density == 0.5
+        assert bldg_inputs.building_attenuation_coefficient == 2.0
+        assert bldg_inputs.building_surface_roughness == 0.01
+        assert bldg_inputs.convert_fuel_to_canopy_flag == 1
+        assert bldg_inputs.update_canopy_winds_flag == 1
+        assert bldg_inputs.fuel_attenuation_coefficient == 1.0
+        assert bldg_inputs.fuel_surface_roughness == 0.1
+
+    def test_custom_init(self):
+        # Change a flag
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs(convert_buildings_to_fuel_flag=1)
+        assert bldg_inputs.convert_buildings_to_fuel_flag == 1
+
+        # Change a float
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs(building_fuel_density=0.6)
+        assert bldg_inputs.building_fuel_density == 0.6
+
+        # Test data type casting
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs(building_fuel_density="0.6")
+        assert isinstance(bldg_inputs.building_fuel_density, float)
+
+    def test_init_invalid_values(self):
+        # Test invalid convert_buildings_to_fuel_flag
+        for invalid_flag in [-1, 2, "1", 1.0, 1.5]:
+            with pytest.raises(ValidationError):
+                QFire_Bldg_Advanced_User_Inputs(
+                    convert_buildings_to_fuel_flag=invalid_flag
+                )
+
+        # Test invalid building_fuel_density
+        for invalid_density in [-1, ""]:
+            with pytest.raises(ValidationError):
+                QFire_Bldg_Advanced_User_Inputs(building_fuel_density=invalid_density)
+
+    def test_to_dict(self):
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs()
+        result_dict = bldg_inputs.to_dict()
+
+        assert (
+            result_dict["convert_buildings_to_fuel_flag"]
+            == bldg_inputs.convert_buildings_to_fuel_flag
+        )
+        assert result_dict["building_fuel_density"] == bldg_inputs.building_fuel_density
+        assert (
+            result_dict["building_attenuation_coefficient"]
+            == bldg_inputs.building_attenuation_coefficient
+        )
+        assert (
+            result_dict["building_surface_roughness"]
+            == bldg_inputs.building_surface_roughness
+        )
+        assert (
+            result_dict["convert_fuel_to_canopy_flag"]
+            == bldg_inputs.convert_fuel_to_canopy_flag
+        )
+        assert (
+            result_dict["update_canopy_winds_flag"]
+            == bldg_inputs.update_canopy_winds_flag
+        )
+        assert (
+            result_dict["fuel_attenuation_coefficient"]
+            == bldg_inputs.fuel_attenuation_coefficient
+        )
+        assert (
+            result_dict["fuel_surface_roughness"] == bldg_inputs.fuel_surface_roughness
+        )
+
+    def test_from_dict(self):
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs()
+        result_dict = bldg_inputs.to_dict()
+        test_obj = QFire_Bldg_Advanced_User_Inputs.from_dict(result_dict)
+        assert test_obj == bldg_inputs
+
+    def test_to_docs(self):
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs()
+        result_dict = bldg_inputs.to_dict()
+        result_docs = bldg_inputs.get_documentation()
+        for key in result_dict:
+            assert key in result_docs
+        for key in result_docs:
+            assert key in result_dict
+
+    def test_to_file(self):
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs()
+        bldg_inputs.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/QFIRE_bldg_advanced_user_inputs.inp", "r") as file:
+            lines = file.readlines()
+        assert (
+            int(lines[0].strip().split("!")[0])
+            == bldg_inputs.convert_buildings_to_fuel_flag
+        )
+        assert (
+            float(lines[1].strip().split("!")[0]) == bldg_inputs.building_fuel_density
+        )
+        assert (
+            float(lines[2].strip().split("!")[0])
+            == bldg_inputs.building_attenuation_coefficient
+        )
+        assert (
+            float(lines[3].strip().split("!")[0])
+            == bldg_inputs.building_surface_roughness
+        )
+        assert (
+            int(lines[4].strip().split("!")[0])
+            == bldg_inputs.convert_fuel_to_canopy_flag
+        )
+        assert (
+            int(lines[5].strip().split("!")[0]) == bldg_inputs.update_canopy_winds_flag
+        )
+        assert (
+            float(lines[6].strip().split("!")[0])
+            == bldg_inputs.fuel_attenuation_coefficient
+        )
+        assert (
+            float(lines[7].strip().split("!")[0]) == bldg_inputs.fuel_surface_roughness
+        )
+
+        # Test writing to a non-existent directory
+        with pytest.raises(FileNotFoundError):
+            bldg_inputs.to_file(
+                "/non_existent_path/QFIRE_bldg_advanced_user_inputs.inp"
+            )
+
+    def test_from_file(self):
+        bldg_inputs = QFire_Bldg_Advanced_User_Inputs()
+        bldg_inputs.to_file("tmp/")
+        test_object = QFire_Bldg_Advanced_User_Inputs.from_file("tmp/")
+        assert isinstance(test_object, QFire_Bldg_Advanced_User_Inputs)
+        assert bldg_inputs == test_object
+
+
+class Test_QFire_Plume_Advanced_User_Inputs:
+    def test_default_init(self):
+        plume_inputs = QFire_Plume_Advanced_User_Inputs()
+
+        assert plume_inputs.max_plumes_per_timestep == 150000
+        assert plume_inputs.min_plume_updraft_velocity == 0.1
+        assert plume_inputs.max_plume_updraft_velocity == 100.0
+        assert plume_inputs.min_velocity_ratio == 0.1
+        assert plume_inputs.brunt_vaisala_freq_squared == 0.0
+        assert plume_inputs.creeping_flag == 1
+        assert plume_inputs.adaptive_timestep_flag == 0
+        assert plume_inputs.plume_timestep == 1.0
+        assert plume_inputs.sor_option_flag == 1
+        assert plume_inputs.sor_alpha_plume_center == 10.0
+        assert plume_inputs.sor_alpha_plume_edge == 1.0
+        assert plume_inputs.max_plume_merging_angle == 30.0
+        assert plume_inputs.max_plume_overlap_fraction == 0.7
+        assert plume_inputs.plume_to_grid_updrafts_flag == 1
+        assert plume_inputs.max_points_along_plume_edge == 10
+        assert plume_inputs.plume_to_grid_intersection_flag == 1
+
+    def test_custom_init(self):
+        plume_inputs = QFire_Plume_Advanced_User_Inputs(
+            max_plumes_per_timestep=100000,
+            min_plume_updraft_velocity=0.2,
+            creeping_flag=0,
+            max_plume_updraft_velocity="100.",
+        )
+        assert plume_inputs.max_plumes_per_timestep == 100000
+        assert plume_inputs.min_plume_updraft_velocity == 0.2
+        assert plume_inputs.creeping_flag == 0
+        assert plume_inputs.max_plume_updraft_velocity == 100.0
+
+    def test_invalid_values(self):
+        # Invalid max_plumes_per_timestep (Positive integer)
+        for value in [-1, 0, 1.5, "a"]:
+            with pytest.raises(ValidationError):
+                QFire_Plume_Advanced_User_Inputs(max_plumes_per_timestep=value)
+
+        # Invalid min_plume_updraft_velocity (Positive float)
+        for value in [-1, 0, "a"]:
+            with pytest.raises(ValidationError):
+                QFire_Plume_Advanced_User_Inputs(min_plume_updraft_velocity=value)
+
+        # Invalid brunt_vaisala_freq_squared (Non-negative float)
+        for value in [-1, "a"]:
+            with pytest.raises(ValidationError):
+                QFire_Plume_Advanced_User_Inputs(brunt_vaisala_freq_squared=value)
+
+        # Invalid creeping_flag (Literal 0 or 1)
+        for value in [-1, 2, 1.5, "a", "0"]:
+            with pytest.raises(ValidationError):
+                QFire_Plume_Advanced_User_Inputs(creeping_flag=value)
+
+    def test_to_dict(self):
+        plume_inputs = QFire_Plume_Advanced_User_Inputs()
+        result_dict = plume_inputs.to_dict()
+
+        assert (
+            result_dict["max_plumes_per_timestep"]
+            == plume_inputs.max_plumes_per_timestep
+        )
+        assert (
+            result_dict["min_plume_updraft_velocity"]
+            == plume_inputs.min_plume_updraft_velocity
+        )
+        assert (
+            result_dict["max_plume_updraft_velocity"]
+            == plume_inputs.max_plume_updraft_velocity
+        )
+        assert result_dict["min_velocity_ratio"] == plume_inputs.min_velocity_ratio
+        assert (
+            result_dict["brunt_vaisala_freq_squared"]
+            == plume_inputs.brunt_vaisala_freq_squared
+        )
+        assert result_dict["creeping_flag"] == plume_inputs.creeping_flag
+        assert (
+            result_dict["adaptive_timestep_flag"] == plume_inputs.adaptive_timestep_flag
+        )
+        assert result_dict["plume_timestep"] == plume_inputs.plume_timestep
+        assert result_dict["sor_option_flag"] == plume_inputs.sor_option_flag
+        assert (
+            result_dict["sor_alpha_plume_center"] == plume_inputs.sor_alpha_plume_center
+        )
+        assert result_dict["sor_alpha_plume_edge"] == plume_inputs.sor_alpha_plume_edge
+        assert (
+            result_dict["max_plume_merging_angle"]
+            == plume_inputs.max_plume_merging_angle
+        )
+        assert (
+            result_dict["max_plume_overlap_fraction"]
+            == plume_inputs.max_plume_overlap_fraction
+        )
+        assert (
+            result_dict["plume_to_grid_updrafts_flag"]
+            == plume_inputs.plume_to_grid_updrafts_flag
+        )
+        assert (
+            result_dict["max_points_along_plume_edge"]
+            == plume_inputs.max_points_along_plume_edge
+        )
+        assert (
+            result_dict["plume_to_grid_intersection_flag"]
+            == plume_inputs.plume_to_grid_intersection_flag
+        )
+
+    def test_from_dict(self):
+        plume_inputs = QFire_Plume_Advanced_User_Inputs()
+        result_dict = plume_inputs.to_dict()
+        test_obj = QFire_Plume_Advanced_User_Inputs.from_dict(result_dict)
+        assert test_obj == plume_inputs
+
+    def test_to_docs(self):
+        plume_inputs = QFire_Plume_Advanced_User_Inputs()
+        result_dict = plume_inputs.to_dict()
+        result_docs = plume_inputs.get_documentation()
+        for key in result_dict:
+            assert key in result_docs
+        for key in result_docs:
+            assert key in result_dict
+
+    def test_to_file(self):
+        plume_inputs = QFire_Plume_Advanced_User_Inputs()
+        plume_inputs.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/QFIRE_plume_advanced_user_inputs.inp", "r") as file:
+            lines = file.readlines()
+        assert (
+            int(lines[0].strip().split("!")[0]) == plume_inputs.max_plumes_per_timestep
+        )
+        assert (
+            float(lines[1].strip().split("!")[0])
+            == plume_inputs.min_plume_updraft_velocity
+        )
+        assert (
+            float(lines[2].strip().split("!")[0])
+            == plume_inputs.max_plume_updraft_velocity
+        )
+        assert float(lines[3].strip().split("!")[0]) == plume_inputs.min_velocity_ratio
+        assert (
+            float(lines[4].strip().split("!")[0])
+            == plume_inputs.brunt_vaisala_freq_squared
+        )
+        assert int(lines[5].strip().split("!")[0]) == plume_inputs.creeping_flag
+        assert (
+            int(lines[6].strip().split("!")[0]) == plume_inputs.adaptive_timestep_flag
+        )
+        assert float(lines[7].strip().split("!")[0]) == plume_inputs.plume_timestep
+        assert int(lines[8].strip().split("!")[0]) == plume_inputs.sor_option_flag
+        assert (
+            float(lines[9].strip().split("!")[0]) == plume_inputs.sor_alpha_plume_center
+        )
+        assert (
+            float(lines[10].strip().split("!")[0]) == plume_inputs.sor_alpha_plume_edge
+        )
+        assert (
+            float(lines[11].strip().split("!")[0])
+            == plume_inputs.max_plume_merging_angle
+        )
+        assert (
+            float(lines[12].strip().split("!")[0])
+            == plume_inputs.max_plume_overlap_fraction
+        )
+        assert (
+            int(lines[13].strip().split("!")[0])
+            == plume_inputs.plume_to_grid_updrafts_flag
+        )
+        assert (
+            int(lines[14].strip().split("!")[0])
+            == plume_inputs.max_points_along_plume_edge
+        )
+        assert (
+            int(lines[15].strip().split("!")[0])
+            == plume_inputs.plume_to_grid_intersection_flag
+        )
+
+    def test_from_file(self):
+        plume_inputs = QFire_Plume_Advanced_User_Inputs()
+        plume_inputs.to_file("tmp/")
+        test_object = QFire_Plume_Advanced_User_Inputs.from_file("tmp/")
+        assert isinstance(test_object, QFire_Plume_Advanced_User_Inputs)
+        assert plume_inputs == test_object
+
+
+class TestQUTopoInputs:
+    def get_default_test_object(self):
+        return QU_TopoInputs(topo_type=TopoType(topo_flag=0))
+
+    def get_complex_test_object(self):
+        return QU_TopoInputs(
+            topo_type=GaussianHillTopo(
+                x_hilltop=100, y_hilltop=150, elevation_max=500, elevation_std=20
+            ),
+            smoothing_method=1,
+            sor_relax=1.78,
+        )
+
+    def test_default_inputs(self):
+        topoinputs = self.get_default_test_object()
+        assert topoinputs.filename == "topo.dat"
+        assert isinstance(topoinputs.topo_type, TopoType)
+        assert topoinputs.smoothing_passes == 500
+
+    def test_complex_inputs(self):
+        topoinputs = self.get_complex_test_object()
+        assert topoinputs.topo_type.topo_flag.value == 1
+        assert topoinputs._topo_lines == (
+            "1\t\t! N/A, "
+            "topo flag: 0 = flat, 1 = Gaussian hill, "
+            "2 = hill pass, 3 = slope mesa, 4 = canyon, "
+            "5 = custom, 6 = half circle, 7 = sinusoid, "
+            "8 = cos hill, 9 = QP_elevation.inp, "
+            "10 = terrainOutput.txt (ARA), "
+            "11 = terrain.dat (firetec)\n"
+            "100\t! m, x-center\n"
+            "150\t! m, y-center\n"
+            "500\t! m, max height\n"
+            "20.0\t! m, std"
+        )
+        assert topoinputs.smoothing_method == 1
+        assert topoinputs.sor_relax == 1.78
+
+    def test_to_dict(self):
+        topoinputs = self.get_default_test_object()
+        test_dict = topoinputs.to_dict()
+        assert test_dict["smoothing_method"] == topoinputs.smoothing_method
+        assert test_dict["smoothing_passes"] == topoinputs.smoothing_passes
+        assert test_dict["sor_iterations"] == topoinputs.sor_iterations
+        assert test_dict["sor_cycles"] == topoinputs.sor_cycles
+        assert test_dict["sor_relax"] == topoinputs.sor_relax
+
+        topoinputs = self.get_complex_test_object()
+        test_dict = topoinputs.to_dict()
+        assert test_dict["topo_type"]["x_hilltop"] == topoinputs.topo_type.x_hilltop
+        assert test_dict["topo_type"]["y_hilltop"] == topoinputs.topo_type.y_hilltop
+        assert (
+            test_dict["topo_type"]["elevation_max"]
+            == topoinputs.topo_type.elevation_max
+        )
+        assert (
+            test_dict["topo_type"]["elevation_std"]
+            == topoinputs.topo_type.elevation_std
+        )
+        assert test_dict["smoothing_method"] == topoinputs.smoothing_method
+        assert test_dict["smoothing_passes"] == topoinputs.smoothing_passes
+        assert test_dict["sor_iterations"] == topoinputs.sor_iterations
+        assert test_dict["sor_cycles"] == topoinputs.sor_cycles
+        assert test_dict["sor_relax"] == topoinputs.sor_relax
+
+    def test_from_dict(self):
+        topoinputs = self.get_default_test_object()
+        result_dict = topoinputs.to_dict()
+        test_obj = QU_TopoInputs.from_dict(result_dict)
+        assert test_obj == topoinputs
+
+    def test_to_file(self):
+        topoinputs = self.get_default_test_object()
+        topoinputs.to_file("tmp/")
+        with open("tmp/QU_TopoInputs.inp", "r") as file:
+            lines = file.readlines()
+        topo_flag = int(lines[2].strip().split("!")[0])
+        assert topo_flag == topoinputs.topo_type.topo_flag.value
+        add_dict = {
+            0: 0,
+            1: 4,
+            2: 2,
+            3: 3,
+            4: 5,
+            5: 0,
+            6: 3,
+            7: 2,
+            8: 2,
+            9: 0,
+            10: 0,
+            11: 0,
+        }
+        add = add_dict.get(topo_flag)
+        current_line = current_line = 3 + add
+        assert (
+            int(lines[current_line].strip().split("!")[0])
+            == topoinputs.smoothing_method
+        )
+        assert (
+            int(lines[current_line + 1].strip().split("!")[0])
+            == topoinputs.smoothing_passes
+        )
+        assert (
+            int(lines[current_line + 2].strip().split("!")[0])
+            == topoinputs.sor_iterations
+        )
+        assert (
+            int(lines[current_line + 3].strip().split("!")[0]) == topoinputs.sor_cycles
+        )
+        assert (
+            float(lines[current_line + 4].strip().split("!")[0]) == topoinputs.sor_relax
+        )
+
+        topoinputs = self.get_complex_test_object()
+        topoinputs.to_file("tmp/")
+        with open("tmp/QU_TopoInputs.inp", "r") as file:
+            lines = file.readlines()
+        topo_flag = int(lines[2].strip().split("!")[0])
+        assert topo_flag == topoinputs.topo_type.topo_flag.value
+        add_dict = {
+            0: 0,
+            1: 4,
+            2: 2,
+            3: 3,
+            4: 5,
+            5: 0,
+            6: 3,
+            7: 2,
+            8: 2,
+            9: 0,
+            10: 0,
+            11: 0,
+        }
+        add = add_dict.get(topo_flag)
+        assert int(lines[3].strip().split("!")[0]) == topoinputs.topo_type.x_hilltop
+        assert int(lines[4].strip().split("!")[0]) == topoinputs.topo_type.y_hilltop
+        assert int(lines[5].strip().split("!")[0]) == topoinputs.topo_type.elevation_max
+        assert (
+            float(lines[6].strip().split("!")[0]) == topoinputs.topo_type.elevation_std
+        )
+        current_line = current_line = 3 + add
+        assert (
+            int(lines[current_line].strip().split("!")[0])
+            == topoinputs.smoothing_method
+        )
+        assert (
+            int(lines[current_line + 1].strip().split("!")[0])
+            == topoinputs.smoothing_passes
+        )
+        assert (
+            int(lines[current_line + 2].strip().split("!")[0])
+            == topoinputs.sor_iterations
+        )
+        assert (
+            int(lines[current_line + 3].strip().split("!")[0]) == topoinputs.sor_cycles
+        )
+        assert (
+            float(lines[current_line + 4].strip().split("!")[0]) == topoinputs.sor_relax
+        )
+
+    def test_from_file(self):
+        topoinputs = self.get_default_test_object()
+        topoinputs.to_file("tmp/")
+        test_object = QU_TopoInputs.from_file("tmp/")
+        assert isinstance(test_object, QU_TopoInputs)
+        assert topoinputs == test_object
+
+        topoinputs = self.get_complex_test_object()
+        topoinputs.to_file("tmp/")
+        test_object = QU_TopoInputs.from_file("tmp/")
+        assert isinstance(test_object, QU_TopoInputs)
+        assert topoinputs == test_object
+
+
+class TestRuntimeAdvancedUserInputs:
+    def get_test_object(self):
+        return RuntimeAdvancedUserInputs()
+
+    def test_init(self):
+        raui = self.get_test_object()
+        assert isinstance(raui, RuntimeAdvancedUserInputs)
+        assert raui.num_cpus == 8
+        assert raui.use_acw == 0
+
+    def test_from_file(self):
+        raui = self.get_test_object()
+        raui.to_file("tmp/")
+        test_object = RuntimeAdvancedUserInputs.from_file("tmp/")
+        assert raui == test_object
+
+
+class TestQUmovingcoords:
+    def get_test_object(self):
+        return QU_movingcoords()
+
+    def test_init(self):
+        qu_moving = self.get_test_object()
+        assert isinstance(qu_moving, QU_movingcoords)
+
+    def test_from_file(self):
+        qu_moving = self.get_test_object()
+        qu_moving.to_file("tmp/")
+        test_object = QU_movingcoords.from_file("tmp/")
+        assert qu_moving == test_object
+
+
+class TestQUbuildout:
+    def get_test_object(self):
+        return QP_buildout()
+
+    def test_init(self):
+        qp_buildout = self.get_test_object()
+        assert isinstance(qp_buildout, QP_buildout)
+
+    def test_from_file(self):
+        qp_buildout = self.get_test_object()
+        qp_buildout.to_file("tmp/")
+        test_object = QP_buildout.from_file("tmp/")
+        assert qp_buildout == test_object
+
+
+class Test_QU_metparams:
+    def get_test_object(self):
+        return QU_metparams()
+
+    def test_init(self):
+        qu_metparams = self.get_test_object()
+        assert qu_metparams.num_sensors == 1
+        assert qu_metparams.sensor_name == "sensor1"
+
+    def test_to_dict(self):
+        qu_metparams = self.get_test_object()
+        result_dict = qu_metparams.to_dict()
+        assert result_dict["num_sensors"] == qu_metparams.num_sensors
+        assert result_dict["sensor_name"] == qu_metparams.sensor_name
+
+    def test_from_dict(self):
+        qu_metparams = self.get_test_object()
+        result_dict = qu_metparams.to_dict()
+        test_obj = QU_metparams.from_dict(result_dict)
+        assert test_obj == qu_metparams
+
+    def test_to_file(self):
+        qu_metparams = self.get_test_object()
+        qu_metparams.to_file("tmp/")
+
+        # Read the content of the file and check for correctness
+        with open("tmp/QU_metparams.inp", "r") as file:
+            lines = file.readlines()
+        assert int(lines[2].strip().split("!")[0]) == qu_metparams.num_sensors
+        assert str(lines[4].strip().split("!")[0].strip()) == qu_metparams.sensor_name
+
+    def test_from_file(self):
+        qu_metparams = self.get_test_object()
+        qu_metparams.to_file("tmp/")
+        test_object = QU_metparams.from_file("tmp/")
+        assert isinstance(test_object, QU_metparams)
+        assert qu_metparams == test_object
+
+
+class TestSensor1:
+    def get_test_object(self):
+        return Sensor1(time_now=1697555154, wind_speed=5, wind_direction=270)
+
+    def test_init(self):
+        sensor1 = self.get_test_object()
+        assert isinstance(sensor1, Sensor1)
+        assert sensor1.wind_speed == 5.0
+        assert sensor1.wind_direction == 270
+        assert sensor1.sensor_height == 6.1
+
+    def test_error(self):
+        sensor1 = self.get_test_object()
+        with pytest.raises(ValidationError):
+            sensor1.wind_direction = 360
+
+    def test_from_file(self):
+        sensor1 = self.get_test_object()
+        sensor1.to_file("tmp/")
+        test_object = Sensor1.from_file("tmp/")
+        assert sensor1 == test_object
+
+
+class TestSimulationInputs:
+    @staticmethod
+    def get_test_object():
+        topo = GaussianHillTopo(
+            x_hilltop=50, y_hilltop=50, elevation_max=100, elevation_std=20
+        )
+        ignite = RectangleIgnition(x_min=20, y_min=20, x_length=10, y_length=160)
+        return SimulationInputs.setup_simulation(
+            nx=100,
+            ny=100,
+            fire_nz=40,
+            quic_nz=26,
+            quic_height=180,
+            dx=2,
+            dy=2,
+            fire_dz=1,
+            wind_speed=2.7,
+            wind_direction=270,
+            simulation_time=600,
+            output_time=60,
+            topo_type=topo,
+            ignition_type=ignite,
+            fuel_flag=1,
+            fuel_density=0.6,
+            fuel_moisture=0.5,
+            fuel_height=1.0,
+        )
+
+    @staticmethod
+    def get_simple_test_object():
+        return SimulationInputs.setup_simple_simulation(
+            nx=100,
+            ny=100,
+            simulation_time=600,
+            wind_speed=2.7,
+            wind_direction=270,
+        )
+
+    @staticmethod
+    def get_custom_test_object():
+        return SimulationInputs.setup_custom_simulation(
+            nx=100,
+            ny=100,
+            fire_nz=40,
+            simulation_time=600,
+            wind_speed=2.7,
+            wind_direction=270,
+        )
+
+    def test_basic_inputs(self):
+        sim_inputs = self.get_test_object()
+        assert isinstance(sim_inputs, SimulationInputs)
+
+    def test_simple(self):
+        sim_inputs = self.get_simple_test_object()
+        assert isinstance(sim_inputs, SimulationInputs)
+        quic_fire = sim_inputs.get_input("QUIC_fire")
+        topo_inputs = sim_inputs.get_input("QU_TopoInputs")
+        assert quic_fire.fuel_flag == 1
+        assert topo_inputs.topo_type.topo_flag.value == 0
+        assert quic_fire.ignition_type.ignition_flag.value == 1
+
+    def test_custum(self):
+        sim_inputs = self.get_custom_test_object()
+        assert isinstance(sim_inputs, SimulationInputs)
+        quic_fire = sim_inputs.get_input("QUIC_fire")
+        topo_inputs = sim_inputs.get_input("QU_TopoInputs")
+        assert quic_fire.fuel_flag == 4
+        assert topo_inputs.topo_type.topo_flag.value == 5
+        assert quic_fire.ignition_type.ignition_flag.value == 6
+
+    def test_list_inputs(self):
+        sim_inputs = self.get_test_object()
+        inputs = sim_inputs.list_inputs()
+        assert "rasterorigin" in inputs
+
+    def test_get_input(self):
+        sim_inputs = self.get_test_object()
+        rasterorigin = sim_inputs.get_input("rasterorigin")
+        assert isinstance(rasterorigin, RasterOrigin)
+
+    def test_write_inputs(self):
+        sim_inputs = self.get_test_object()
+        sim_inputs.write_inputs("tmp/")
 
-TEST_PARAMS = {
-    "nx": 100,
-    "ny": 100,
-    "nz": 1,
-    "dx": 1.,
-    "dy": 1.,
-    "dz": 1.,
-    "wind_speed": 4.,
-    "wind_direction": 265,
-    "sim_time": 60,
-    "auto_kill": 1,
-    "num_cpus": 1,
-    "fuel_flag": 3,
-    "ignition_flag": 1,
-    "output_time": 10,
-}
-
-SUT = SimulationInputs("pytest-simulation")
-
-
-def test_invalid_input_parameters():
-    # Test missing nx parameter
-    test_custom_params = TEST_PARAMS.copy()
-    _ = test_custom_params.pop("nx")
-    with pytest.raises(KeyError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test non-integer nx parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["nx"] = 1.0
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string nx parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["nx"] = "10"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test nx parameter less than 1
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["nx"] = 0
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string dx parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["dx"] = "1.0"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test dx parameter less than 0
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["dx"] = -1.0
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test dx parameter equal to 0
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["dx"] = 0.0
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test missing wind_speed parameter
-    test_custom_params = TEST_PARAMS.copy()
-    _ = test_custom_params.pop("wind_speed")
-    with pytest.raises(KeyError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string wind_speed parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["wind_speed"] = "4.0"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test wind_speed parameter less than 0
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["wind_speed"] = -4.0
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test wind_direction string parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["wind_direction"] = "265"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test wind_direction parameter less than 0
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["wind_direction"] = -265
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test wind_direction parameter greater than 360
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["wind_direction"] = 365
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test missing sim_time parameter
-    test_custom_params = TEST_PARAMS.copy()
-    _ = test_custom_params.pop("sim_time")
-    with pytest.raises(KeyError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string sim_time parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["sim_time"] = "60"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test float sim_time parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["sim_time"] = 60.0
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test sim_time parameter less than 0
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["sim_time"] = -60
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test sim_time parameter equal to 0
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["sim_time"] = 0
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string auto_kill parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["auto_kill"] = "1"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test auto_kill parameter not 0 or 1
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["auto_kill"] = 2
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string num_cpus parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["num_cpus"] = "1"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test num_cpus parameter less than 1
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["num_cpus"] = 0
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test non-integer output_time parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["output_time"] = 1.0
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string output_time parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["output_time"] = "1"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test output_time parameter less than 1
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["output_time"] = 0
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test non-integer fuel flag parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["fuel_flag"] = 1.0
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test non-supported fuel flag parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["fuel_flag"] = 2
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test fuel flag 1 has fuel_density, fuel_moisture, fuel_height parameters
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["fuel_flag"] = 1
-    with pytest.raises(KeyError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test fuel flag 1 string fuel_density parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["fuel_flag"] = 1
-    test_custom_params["fuel_density"] = "1.0"
-    test_custom_params["fuel_moisture"] = 0.5
-    test_custom_params["fuel_height"] = 0.5
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test fuel flag 1 fuel_density parameter less than 0
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["fuel_flag"] = 1
-    test_custom_params["fuel_density"] = -1.0
-    test_custom_params["fuel_moisture"] = 0.5
-    test_custom_params["fuel_height"] = 0.5
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test string ignition_flag parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["ignition_flag"] = "1"
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test non-supported ignition_flag parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["ignition_flag"] = 2
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test non-integer topo_flag parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["topo_flag"] = 1.0
-    with pytest.raises(TypeError):
-        SUT.setup_input_files(test_custom_params)
-
-    # Test non-supported topo_flag parameter
-    test_custom_params = TEST_PARAMS.copy()
-    test_custom_params["topo_flag"] = 2
-    with pytest.raises(ValueError):
-        SUT.setup_input_files(test_custom_params)
-
-
-# TODO: Update fuel height test
-def test_write_fuel_data():
-    # Test fuel flag 1
-    fuel_data_params = TEST_PARAMS.copy()
-    fuel_data_params["fuel_flag"] = 1
-    fuel_data_params["fuel_density"] = 1.25
-    fuel_data_params["fuel_moisture"] = 0.75
-    fuel_data_params["fuel_height"] = 0.5
-    fuel_params = SUT._write_fuel(fuel_data_params)
-    assert fuel_params == ("\n1.25", "\n0.75", "\n0.5")
-
-    # Test fuel flag 1
-    fuel_data_params = TEST_PARAMS.copy()
-    fuel_data_params["fuel_flag"] = 1
-    fuel_data_params["fuel_density"] = 0.0
-    fuel_data_params["fuel_moisture"] = 0.0
-    fuel_data_params["fuel_height"] = 0.0
-    fuel_params = SUT._write_fuel(fuel_data_params)
-    assert fuel_params == ("\n0.0", "\n0.0", "\n0.0")
-
-    # Test fuel flag 3
-    fuel_data_params = TEST_PARAMS.copy()
-    fuel_data_params["fuel_flag"] = 3
-    fuel_params = SUT._write_fuel(fuel_data_params)
-    assert fuel_params == ("", "", "")
-
-    # Test fuel flag 3 with spurious fuel data
-    fuel_data_params = TEST_PARAMS.copy()
-    fuel_data_params["fuel_flag"] = 3
-    fuel_data_params["fuel_density"] = 1.25
-    fuel_data_params["fuel_moisture"] = 0.75
-    fuel_data_params["fuel_height"] = 0.5
-    fuel_params = SUT._write_fuel(fuel_data_params)
-    assert fuel_params == ("", "", "")
-
-    # Test fuel flag 4
-    fuel_data_params = TEST_PARAMS.copy()
-    fuel_data_params["fuel_flag"] = 4
-    fuel_params = SUT._write_fuel(fuel_data_params)
-    assert fuel_params == ("", "", "")
-
-
-def test_write_ignition_locations():
-    # Test custom ignition flag 6
-    ignition_custom_params = TEST_PARAMS.copy()
-    ignition_custom_params["ignition_flag"] = 6
-    assert SUT._write_ignition_locations(ignition_custom_params) == ""
-
-
-def test_write_line_fire_ignition():
-    ignition_line_params = TEST_PARAMS.copy()
-    ignition_line_params["ignition_flag"] = 1
-
-    # Define default ignition line locations
-    north_wind = "\n10\n89\n80\n1\n100"
-    east_wind = "\n89\n10\n1\n80\n100"
-    south_wind = "\n10\n9\n80\n1\n100"
-    west_wind = "\n9\n10\n1\n80\n100"
-
-    # Test north wind
-    ignition_line_params["wind_direction"] = 0
-    assert SUT._write_line_fire_ignition(ignition_line_params) == north_wind
-
-    # Test east wind
-    ignition_line_params["wind_direction"] = 90
-    assert SUT._write_line_fire_ignition(ignition_line_params) == east_wind
-
-    # Test south wind
-    ignition_line_params["wind_direction"] = 180
-    assert SUT._write_line_fire_ignition(ignition_line_params) == south_wind
-
-    # Test west wind
-    ignition_line_params["wind_direction"] = 270
-    assert SUT._write_line_fire_ignition(ignition_line_params) == west_wind
-
-    # Test 45 degree wind
-    ignition_line_params["wind_direction"] = 45
-    assert SUT._write_line_fire_ignition(ignition_line_params) == north_wind
-
-    # Test 45.01 degree wind
-    ignition_line_params["wind_direction"] = 45.01
-    assert SUT._write_line_fire_ignition(ignition_line_params) == east_wind
-
-    # Test -45 degree wind
-    ignition_line_params["wind_direction"] = -45
-    assert SUT._write_line_fire_ignition(ignition_line_params) == north_wind
-
-    # Test -45.01 degree wind
-    ignition_line_params["wind_direction"] = -45.01
-    assert SUT._write_line_fire_ignition(ignition_line_params) == west_wind
-
-    # Test 134.99 degree wind
-    ignition_line_params["wind_direction"] = 134.99
-    assert SUT._write_line_fire_ignition(ignition_line_params) == east_wind
-
-    # Test 135 degree wind
-    ignition_line_params["wind_direction"] = 135
-    assert SUT._write_line_fire_ignition(ignition_line_params) == south_wind
+    def test_from_directory(self):
+        sim_inputs = SimulationInputs.from_directory("tmp/")
+        assert isinstance(sim_inputs, SimulationInputs)
diff --git a/tests/test_output_module.py b/tests/test_output_module.py
index ce68617..20189aa 100644
--- a/tests/test_output_module.py
+++ b/tests/test_output_module.py
@@ -1,44 +1,25 @@
-import sys
-
-sys.path.append("../quicfire_tools")
-from quicfire_tools import outputs
-from quicfire_tools.parameters import SimulationParameters
-
 import zarr
 import pytest
 import numpy as np
+import xarray as xr
 import dask.array as da
-from scipy.io import FortranFile
 
+# from scipy.io import FortranFile
 from pathlib import Path
 
+from quicfire_tools import outputs
+
+
 DATA_PATH = Path("data")
-SIMULATION_PATH = DATA_PATH / "crazy-canyon-simulation"
-OUTPUT_PATH = SIMULATION_PATH / "Output"
+OUTPUT_PATH = DATA_PATH / "test-output"
 DRAWFIRE_PATH = OUTPUT_PATH / "drawfire"
 
-# Create simulation parameters object
-SIM_PARAMS = SimulationParameters(
-    nx=100,
-    ny=100,
-    nz=56,
-    dx=1,
-    dy=1,
-    dz=1,
-    wind_speed=6.5,
-    wind_direction=270,
-    sim_time=600,
-    auto_kill=0,
-    num_cpus=4,
-    fuel_flag=4,
-    ignition_flag=1,
-    output_time=100,
-    topo_flag=0,
-)
-
 
 class TestSimulationOutputs:
-    sut = outputs.SimulationOutputs(OUTPUT_PATH, SIM_PARAMS)
+    nz = 56
+    ny = 100
+    nx = 100
+    sut = outputs.SimulationOutputs(OUTPUT_PATH, nz, ny, nx)
 
     def test_to_dask(self):
         for output in self.sut.outputs:
@@ -47,390 +28,464 @@ def test_to_dask(self):
             numpy_array = self.sut.to_numpy(output)
             assert np.allclose(numpy_array, dask_array.compute())
 
+    def test_zarr_all_outputs(self):
+        """
+        Run a test to ensure that the zarr output contains all outputs
+        """
+        zarr_with_datasets = self.sut.to_zarr("tmp/test.zarr")
+        assert isinstance(zarr_with_datasets, zarr.hierarchy.Group)
+        for output_name in self.sut.list_available_outputs():
+            output = self.sut.get_output(output_name)
+            assert output_name in zarr_with_datasets
+            assert isinstance(zarr_with_datasets[output_name], zarr.Array)
+            output_data = output.to_numpy()
+            assert zarr_with_datasets[output_name].shape == output_data.shape
+
+    def test_zarr_rechunker(self):
+        pass
+
+    def test_zarr_single_output(self):
+        """
+        Run a test to ensure that the zarr output contains a single output
+        """
+        single_output_name = "mburnt_integ"
+        zarr_with_datasets = self.sut.to_zarr(
+            "tmp/test.zarr", outputs=single_output_name
+        )
+        assert isinstance(zarr_with_datasets, zarr.hierarchy.Group)
+        for output_name in self.sut.list_available_outputs():
+            output = self.sut.get_output(output_name)
+            if output_name == single_output_name:
+                assert output_name in zarr_with_datasets
+                assert isinstance(zarr_with_datasets[output_name], zarr.Array)
+                output_data = output.to_numpy()
+                assert zarr_with_datasets[output_name].shape == output_data.shape
+            else:
+                assert output_name not in zarr_with_datasets
+
+    def test_zarr_multiple_outputs(self):
+        """
+        Run a test to ensure that the zarr output contains multiple outputs
+        """
+        multiple_output_names = ["mburnt_integ", "fuels-dens"]
+        zarr_with_datasets = self.sut.to_zarr(
+            "tmp/test.zarr", outputs=multiple_output_names
+        )
+        assert isinstance(zarr_with_datasets, zarr.hierarchy.Group)
+        for output_name in self.sut.list_available_outputs():
+            output = self.sut.get_output(output_name)
+            if output_name in multiple_output_names:
+                assert output_name in zarr_with_datasets
+                assert isinstance(zarr_with_datasets[output_name], zarr.Array)
+                output_data = output.to_numpy()
+                assert zarr_with_datasets[output_name].shape == output_data.shape
+            else:
+                assert output_name not in zarr_with_datasets
+
+    def test_zarr_xarray_connection(self):
+        """
+        Run a test to ensure that the zarr and xarray outputs are connected
+        """
+
+        """
+        Test datasets approach
+        """
+        # Test: All outputs.
+        # Produces 4D xarray dataset with all 3D outputs
+        self.sut.to_zarr("tmp/test.zarr")
+        ds = xr.open_zarr(
+            "tmp/test.zarr", drop_variables=["groundfuelheight", "mburnt_integ"]
+        )
+        print(ds)
+
+        # Test: Single output
+        # Produces 4D xarray dataset with single 2D output
+        single_output_name = "mburnt_integ"
+        self.sut.to_zarr("tmp/test.zarr", outputs=single_output_name)
+        drop_variables = [
+            output_name
+            for output_name in self.sut.list_available_outputs()
+            if output_name != single_output_name
+        ]
+        ds = xr.open_zarr("tmp/test.zarr", drop_variables=drop_variables)
+        print(ds)
+
+        # Test: Multiple outputs different dimensions causes error
+        multiple_output_names = ["mburnt_integ", "fuels-dens"]
+        self.sut.to_zarr("tmp/test.zarr", outputs=multiple_output_names)
+        drop_variables = [
+            output_name
+            for output_name in self.sut.list_available_outputs()
+            if output_name not in multiple_output_names
+        ]
+        with pytest.raises(ValueError):
+            xr.open_zarr("tmp/test.zarr", drop_variables=drop_variables)
+
 
 class TestOutputFile:
-    simulation_outputs = outputs.SimulationOutputs(OUTPUT_PATH, SIM_PARAMS)
+    nz = 56
+    ny = 100
+    nx = 100
+    simulation_outputs = outputs.SimulationOutputs(OUTPUT_PATH, nz, ny, nx)
 
     def test_output_single_timestep(self):
         # Test 1: 2D gridded data
         output = self.simulation_outputs.get_output("groundfuelheight")
         output_path = output.filepaths[0]
         data = output._get_single_timestep(output_path)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx)
+        assert data.shape == (1, 1, self.ny, self.nx)
 
         # Test 2: 3D gridded data
         output = self.simulation_outputs.get_output("fire-energy_to_atmos")
         output_path = output.filepaths[0]
         data = output._get_single_timestep(output_path)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        assert data.shape == (1, self.nz + 1, self.ny, self.nx)
 
         # Test 3: 3D Compressed data
         output = self.simulation_outputs.get_output("fuels-dens")
         output_path = output.filepaths[0]
         data = output._get_single_timestep(output_path)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        assert data.shape == (1, self.nz + 1, self.ny, self.nx)
 
     def test_get_multiple_timesteps(self):
         # Test 1: 2D gridded data (single timestep)
         output = self.simulation_outputs.get_output("groundfuelheight")
         output_path = output.filepaths
         data = output._get_multiple_timesteps(output_path)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx)
+        assert data.shape == (1, 1, self.ny, self.nx)
 
         # Test 2: 3D gridded data (all timesteps)
         output = self.simulation_outputs.get_output("fire-energy_to_atmos")
         output_path = output.filepaths
         data = output._get_multiple_timesteps(output_path)
-        assert data.shape == (
-            2, SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        assert data.shape == (2, self.nz + 1, self.ny, self.nx)
 
         # Test 3: 3D Compressed data (all timesteps)
         output = self.simulation_outputs.get_output("fuels-dens")
         output_path = output.filepaths
         data = output._get_multiple_timesteps(output_path)
-        assert data.shape == (
-            2, SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        assert data.shape == (2, self.nz + 1, self.ny, self.nx)
 
     def test_to_numpy(self):
         # Test 1: 2D gridded data (single timestep)
         output = self.simulation_outputs.get_output("groundfuelheight")
-        data = self.simulation_outputs.to_numpy(output, 0)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx)
+        data = output.to_numpy(0)
+        assert data.shape == (1, 1, self.ny, self.nx)
 
         # Test 2: 2D gridded data (all timesteps)
-        output = self.simulation_outputs.get_output("groundfuelheight")
-        data = self.simulation_outputs.to_numpy(output)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx)
+        data = output.to_numpy()
+        assert data.shape == (1, 1, self.ny, self.nx)
 
         # Test 3: 3D gridded data (single timestep)
         output = self.simulation_outputs.get_output("fire-energy_to_atmos")
-        data = self.simulation_outputs.to_numpy(output, 0)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        data = output.to_numpy(0)
+        assert data.shape == (1, self.nz + 1, self.ny, self.nx)
 
         # Test 4: 3D gridded data (all timesteps)
-        output = self.simulation_outputs.get_output("fire-energy_to_atmos")
-        data = self.simulation_outputs.to_numpy(output)
-        assert data.shape == (
-            2, SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        data = output.to_numpy()
+        assert data.shape == (2, self.nz + 1, self.ny, self.nx)
 
         # Test 5: 3D gridded data (list timesteps)
-        output = self.simulation_outputs.get_output("fire-energy_to_atmos")
-        data = self.simulation_outputs.to_numpy(output, [0, 1])
-        assert data.shape == (
-            2, SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        data = output.to_numpy([0, 1])
+        assert data.shape == (2, self.nz + 1, self.ny, self.nx)
 
         # Test 6: 3D gridded data (invalid timesteps)
-        output = self.simulation_outputs.get_output("fire-energy_to_atmos")
         with pytest.raises(ValueError):
-            self.simulation_outputs.to_numpy(output, [0, 1, 2])
+            output.to_numpy([0, 1, 2])
 
         # Test 7: 3D compressed data (single timestep)
         output = self.simulation_outputs.get_output("fuels-dens")
-        data = self.simulation_outputs.to_numpy(output, 0)
-        assert data.shape == (SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
+        data = output.to_numpy(0)
+        assert data.shape == (1, self.nz + 1, self.ny, self.nx)
 
         # Test 8: 3D compressed data (all timesteps)
-        output = self.simulation_outputs.get_output("fuels-dens")
-        data = self.simulation_outputs.to_numpy(output)
-        assert data.shape == (
-            2, SIM_PARAMS.ny, SIM_PARAMS.nx, SIM_PARAMS.nz + 1)
-
-
-class TestProcessGriddedBinSlice:
-    nx = 100
-    ny = 100
-    nz = 56
-
-    @staticmethod
-    def _process_gridded_bin_slice(f, ny, nx):
-        return outputs._process_gridded_bin_slice(f, ny, nx)
-
-    def _load_drawfire_data(self, fpath):
-        data = np.load(fpath)
-        if data.shape[-1] == 1:
-            return data.squeeze(axis=-1)
-        return data
-
-    def _load_and_process_input(self, input_fpath):
-        input_fortran_file = FortranFile(input_fpath, "r")
-        input_data = input_fortran_file.read_reals(dtype=np.float32)
-        input_data = input_data.reshape((self.nz, self.ny, self.nx))
-        input_data = np.moveaxis(input_data, 0, 2).astype(np.float32)
-        input_data = input_data[..., 0]
-        input_fortran_file.close()
-        return input_data
-
-    def _assert_data_equality(self, data1, data2):
-        assert data1.shape == data2.shape
-        assert np.allclose(data1, data2)
-
-    def test_groundfuelheight(self):
-        input_data = self._load_and_process_input(
-            SIMULATION_PATH / "treesfueldepth.dat")
-
-        output_fpath = OUTPUT_PATH / "groundfuelheight.bin"
-        with open(output_fpath, "rb") as f:
-            np.fromfile(f, dtype=np.float32, count=1)  # Read header
-            output_data = self._process_gridded_bin_slice(f, self.ny, self.nx)
-
-        input_data[0, :] = 0
-        input_data[-1, :] = 0
-        input_data[:, 0] = 0
-        input_data[:, -1] = 0
-
-        self._assert_data_equality(output_data, input_data)
-
-    def _generic_drawfire_slice_test(self, test_name, dims):
-        for t in (0, 300):
-            # Load drawfire data
-            drawfire_fpath = DRAWFIRE_PATH / f"{test_name}_{t}.npy"
-            drawfire_data = self._load_drawfire_data(drawfire_fpath)
-
-            # Load output data
-            output_fpath = OUTPUT_PATH / f"{test_name}00{t:03}.bin"
-            f = open(output_fpath, "rb")
-            np.fromfile(f, dtype=np.float32, count=1)  # Read header
-
-            # Read in each slice of the output data and compare to the
-            # equivalent slice of the drawfire data
-            for k in range(dims[2]):
-                output_data = self._process_gridded_bin_slice(f, dims[0],
-                                                              dims[1])
-                self._assert_data_equality(drawfire_data[..., k], output_data)
-
-            f.close()
-
-    def test_fire_energy_to_atmos(self):
-        self._generic_drawfire_slice_test("fire-energy_to_atmos-",
-                                          (self.ny, self.nx, self.nz))
-
-    def test_windu(self):
-        self._generic_drawfire_slice_test("windu", (self.ny, self.nx, self.nz))
-
-
-class TestProcessGriddedBin:
-    nx = 100
-    ny = 100
-    nz = 56
-
-    @staticmethod
-    def _process_gridded_bin(f, dims):
-        return outputs._process_gridded_bin(f, dims)
-
-    def _load_fastfuels_data(self):
-        zarray = zarr.open(SIMULATION_PATH / "crazy_canyon_100m", mode="r")
-        return zarray["surface"]["fuel-depth"][...]
-
-    def _load_and_process_input(self, input_fpath):
-        input_fortran_file = FortranFile(input_fpath, "r")
-        input_data = input_fortran_file.read_reals(dtype=np.float32)
-        input_data = input_data.reshape((self.nz, self.ny, self.nx))
-        input_data = np.moveaxis(input_data, 0, 2).astype(np.float32)
-        input_data = input_data[..., 0]
-        input_fortran_file.close()
-        return input_data
-
-    def _load_drawfire_data(self, fpath):
-        data = np.load(fpath)
-        if data.shape[-1] == 1:
-            return data.squeeze(axis=-1)
-        return data
-
-    def _assert_data_equality(self, data1, data2):
-        assert data1.shape == data2.shape
-        assert np.allclose(data1, data2)
-
-    def test_groundfuelheight(self):
-        fuel_depth = self._load_fastfuels_data()
-        input_data = self._load_and_process_input(
-            SIMULATION_PATH / "treesfueldepth.dat")
-
-        self._assert_data_equality(fuel_depth, input_data)
-
-        output_data = self._process_gridded_bin(
-            OUTPUT_PATH / "groundfuelheight.bin", (self.ny, self.nx))
-
-        fuel_depth[0, :] = 0
-        fuel_depth[-1, :] = 0
-        fuel_depth[:, 0] = 0
-        fuel_depth[:, -1] = 0
-
-        self._assert_data_equality(output_data, fuel_depth)
-
-    def test_total_initial_fuel_height(self):
-        fuel_depth = self._load_fastfuels_data()
-        input_data = self._load_and_process_input(
-            SIMULATION_PATH / "treesfueldepth.dat")
-
-        self._assert_data_equality(fuel_depth, input_data)
-
-        output_data = self._process_gridded_bin(
-            OUTPUT_PATH / "totalinitialfuelheight.bin", (self.ny, self.nx))
-
-        fuel_depth[0, :] = 0
-        fuel_depth[-1, :] = 0
-        fuel_depth[:, 0] = 0
-        fuel_depth[:, -1] = 0
-
-        self._assert_data_equality(output_data, fuel_depth)
-
-    def _generic_drawfire_test(self, test_name, dims, *args):
-
-        for t in (0, 300):
-            drawfire_data = self._load_drawfire_data(
-                DRAWFIRE_PATH / f"{test_name}_{t}.npy")
-            if drawfire_data.shape[-1] != dims[-1]:
-                drawfire_data = drawfire_data[..., :dims[2]]
-            output_data = self._process_gridded_bin(
-                OUTPUT_PATH / f"{test_name}00{t:03}.bin", dims)
-
-            self._assert_data_equality(drawfire_data, output_data)
-
-    def test_mburnt_integ(self):
-        self._generic_drawfire_test("mburnt_integ-", (self.ny, self.nx))
-
-    def test_fire_energy_to_atmos(self):
-        self._generic_drawfire_test("fire-energy_to_atmos-",
-                                    (self.ny, self.nx, self.nz))
-
-    def test_windu(self):
-        self._generic_drawfire_test("windu", (self.ny, self.nx, self.nz + 1))
-
-
-class TestProcessCompressedBin:
-    nx = 100
-    ny = 100
-    nz = 56
-    dims = (ny, nx, nz)
-    sut = outputs.SimulationOutputs(OUTPUT_PATH, SIM_PARAMS)
-    fire_indexes = sut._fire_indexes
-
-    def _process_compressed_bin(self, f):
-        return outputs._process_compressed_bin(
-            f, self.dims, self.fire_indexes)
-
-    def test_fuels_dens(self):
-        for t in (0, 300):
-            # Load the drawfire data
-            drawfire_fpath = DRAWFIRE_PATH / f"fuels-dens-_{t}.npy"
-            drawfire_data = np.load(drawfire_fpath)
-
-            # Load the output data
-            output_fpath = OUTPUT_PATH / f"fuels-dens-00{t:03}.bin"
-            output_data = self._process_compressed_bin(output_fpath)
-
-            # Check that the drawfire and output data are the same
-            assert drawfire_data.shape == output_data.shape
-            assert np.allclose(drawfire_data, output_data)
-
-            # Check that the input and output data are the same in the first
-            # time step
-            if t == 0:
-                # Load input data
-                input_fpath = SIMULATION_PATH / "treesrhof.dat"
-                input_fortran_file = FortranFile(input_fpath, "r")
-                input_data = input_fortran_file.read_reals(dtype=np.float32)
-                input_fortran_file.close()
-                input_data = input_data.reshape((self.nz, self.ny, self.nx))
-                input_data = np.moveaxis(input_data, 0, 2).astype(np.float32)
-
-                # Remove edge cells from the input data
-                input_data[0, :] = 0
-                input_data[-1, :] = 0
-                input_data[:, 0] = 0
-                input_data[:, -1] = 0
-
-                # Check that the input and output data are the same
-                assert input_data.shape == output_data.shape
-                assert np.allclose(input_data, output_data, atol=1e-3)
-
-    def test_fuels_moist(self):
-        for t in (0, 300):
-            # Load the drawfire data
-            drawfire_fpath = DRAWFIRE_PATH / f"fuels-moist-_{t}.npy"
-            drawfire_data = np.load(drawfire_fpath)
-
-            # Load the output data
-            output_fpath = OUTPUT_PATH / f"fuels-moist-00{t:03}.bin"
-            output_data = self._process_compressed_bin(output_fpath)
-
-            # Check that the drawfire and output data are the same
-            assert drawfire_data.shape == output_data.shape
-            assert np.allclose(drawfire_data, output_data)
-
-            # Check that the input and output data are the same in the first
-            # time step
-            if t == 0:
-                # Load input data
-                input_fpath = SIMULATION_PATH / "treesmoist.dat"
-                input_fortran_file = FortranFile(input_fpath, "r")
-                input_data = input_fortran_file.read_reals(dtype=np.float32)
-                input_fortran_file.close()
-                input_data = input_data.reshape((self.nz, self.ny, self.nx))
-                input_data = np.moveaxis(input_data, 0, 2).astype(np.float32)
-
-                # Remove edge cells from the input data
-                input_data[0, :] = 0
-                input_data[-1, :] = 0
-                input_data[:, 0] = 0
-                input_data[:, -1] = 0
-
-                # Check that the input and output data are the same
-                assert input_data.shape == output_data.shape
-                # assert np.allclose(input_data, output_data, atol=1e-3)
-
-    def test_array_reaction_rate(self):
-        for t in (0, 300):
-            # Load the drawfire data
-            drawfire_fpath = DRAWFIRE_PATH / f"fire-reaction_rate-_{t}.npy"
-            drawfire_data = np.load(drawfire_fpath)
-
-            # Load the output data
-            output_fpath = OUTPUT_PATH / f"fire-reaction_rate-00{t:03}.bin"
-            output_data = self._process_compressed_bin(output_fpath)
-
-            # Check that the drawfire and output data are the same
-            assert drawfire_data.shape == output_data.shape
-            assert np.allclose(drawfire_data, output_data)
-
-    def test_co_emissions(self):
-        for t in (0, 300):
-            # Load the drawfire data
-            drawfire_fpath = DRAWFIRE_PATH / f"co_emissions-_{t}.npy"
-            drawfire_data = np.load(drawfire_fpath)
-
-            # Load the output data
-            output_fpath = OUTPUT_PATH / f"co_emissions-00{t:03}.bin"
-            output_data = self._process_compressed_bin(output_fpath)
-
-            # Check that the drawfire and output data are the same
-            assert drawfire_data.shape == output_data.shape
-            assert np.allclose(drawfire_data, output_data)
-
-    def test_thermaldose(self):
-        for t in (0, 300):
-            # Load the drawfire data
-            drawfire_fpath = DRAWFIRE_PATH / f"thermaldose-_{t}.npy"
-            drawfire_data = np.load(drawfire_fpath)
-
-            # Load the output data
-            output_fpath = OUTPUT_PATH / f"thermaldose-00{t:03}.bin"
-            output_data = self._process_compressed_bin(output_fpath)
-
-            # Check that the drawfire and output data are the same
-            assert drawfire_data.shape == output_data.shape
-            assert np.allclose(drawfire_data, output_data)
-
-    def test_thermalradiation(self):
-        for t in (0, 300):
-            # Load the drawfire data
-            drawfire_fpath = DRAWFIRE_PATH / f"thermalradiation-_{t}.npy"
-            drawfire_data = np.load(drawfire_fpath)
-
-            # Load the output data
-            output_fpath = OUTPUT_PATH / f"thermalradiation-00{t:03}.bin"
-            output_data = self._process_compressed_bin(output_fpath)
-
-            # Check that the drawfire and output data are the same
-            assert drawfire_data.shape == output_data.shape
-            assert np.allclose(drawfire_data, output_data)
+        data = self.simulation_outputs.to_numpy("fuels-dens")
+        assert data.shape == (2, self.nz + 1, self.ny, self.nx)
+
+
+# class TestProcessGriddedBinSlice:
+#     nx = 100
+#     ny = 100
+#     nz = 56
+#
+#     @staticmethod
+#     def _process_gridded_bin_slice(f, ny, nx):
+#         return outputs._process_gridded_bin_slice(f, ny, nx)
+#
+#     @staticmethod
+#     def _load_drawfire_data(fpath):
+#         data = np.load(fpath)
+#         # Add a 3rd dimension if the data is 2D
+#         if len(data.shape) == 2:
+#             data = data[np.newaxis, ...]
+#
+#         # Move the z-dimension to the first axis
+#         data = data.swapaxes(0, 2)
+#
+#         # Add a fourth dimension to the data
+#         data = data[np.newaxis, ...]
+#
+#         return data
+#
+#     def test_groundfuelheight(self):
+#         output_fpath = OUTPUT_PATH / "groundfuelheight.bin"
+#         with open(output_fpath, "rb") as f:
+#             np.fromfile(f, dtype=np.float32, count=1)  # Read header
+#             output_data = self._process_gridded_bin_slice(f, self.ny, self.nx)
+#
+#         # Drop edges from the data
+#         output_data[0, :] = 0
+#         output_data[-1, :] = 0
+#         output_data[:, 0] = 0
+#         output_data[:, -1] = 0
+#
+#         assert np.allclose(input_data, output_data)
+#
+#     def _generic_drawfire_slice_test(self, test_name, dims):
+#         for t in (0, 300):
+#             # Load drawfire data
+#             drawfire_fpath = DRAWFIRE_PATH / f"{test_name}_{t}.npy"
+#             drawfire_data = self._load_drawfire_data(drawfire_fpath)
+#
+#             # Load output data
+#             output_fpath = OUTPUT_PATH / f"{test_name}00{t:03}.bin"
+#             f = open(output_fpath, "rb")
+#             np.fromfile(f, dtype=np.float32, count=1)  # Read header
+#
+#             # Read in each slice of the output data and compare to the
+#             # equivalent slice of the drawfire data
+#             for k in range(dims[2]):
+#                 output_data = self._process_gridded_bin_slice(f, dims[0], dims[1])
+#                 assert np.allclose(drawfire_data[k, ...], output_data)
+#
+#             f.close()
+#
+#     def test_fire_energy_to_atmos(self):
+#         self._generic_drawfire_slice_test(
+#             "fire-energy_to_atmos-", (self.ny, self.nx, self.nz)
+#         )
+#
+#     def test_windu(self):
+#         self._generic_drawfire_slice_test("windu", (self.ny, self.nx, self.nz))
+
+
+# class TestProcessGriddedBin:
+#     nx = 100
+#     ny = 100
+#     nz = 56
+#     time_steps = (0, 300)
+#
+#     def _generic_drawfire_test(self, test_name, dims, *args):
+#         for t in self.time_steps:
+#             drawfire_data = self._load_drawfire_data(DRAWFIRE_PATH / f"{test_name}_{t}.npy")
+#             output_data = self._process_gridded_bin(
+#                 OUTPUT_PATH / f"{test_name}00{t:03}.bin", dims)
+#
+#             self._assert_data_equality(drawfire_data, output_data)
+#
+#     @staticmethod
+#     def _process_gridded_bin(f, dims):
+#         return outputs._process_gridded_bin(f, dims)
+#
+#     def _load_fastfuels_data(self):
+#         zarray = zarr.open(SIMULATION_PATH / "crazy_canyon_100m", mode="r")
+#         return zarray["surface"]["fuel-depth"][...]
+#
+#     def _load_and_process_input(self, input_fpath):
+#         input_fortran_file = FortranFile(input_fpath, "r")
+#         input_data = input_fortran_file.read_reals(dtype=np.float32)
+#         input_data = input_data.reshape((self.nz, self.ny, self.nx))
+#         input_data = np.moveaxis(input_data, 0, 2).astype(np.float32)
+#         input_data = input_data[..., 0]
+#         input_fortran_file.close()
+#         return input_data
+#
+#     def _load_drawfire_data(self, fpath):
+#         data = np.load(fpath)
+#         return data
+#
+#     def _assert_data_equality(self, data1, data2):
+#         assert np.allclose(data1, data2)
+#
+#     def test_groundfuelheight(self):
+#         fuel_depth = self._load_fastfuels_data()
+#         input_data = self._load_and_process_input(
+#             SIMULATION_PATH / "treesfueldepth.dat")
+#
+#         self._assert_data_equality(fuel_depth, input_data)
+#
+#         output_data = self._process_gridded_bin(
+#             OUTPUT_PATH / "groundfuelheight.bin", (1, self.ny, self.nx))
+#
+#         fuel_depth[0, :] = 0
+#         fuel_depth[-1, :] = 0
+#         fuel_depth[:, 0] = 0
+#         fuel_depth[:, -1] = 0
+#
+#         self._assert_data_equality(output_data, fuel_depth)
+#
+#     def test_total_initial_fuel_height(self):
+#         fuel_depth = self._load_fastfuels_data()
+#         input_data = self._load_and_process_input(
+#             SIMULATION_PATH / "treesfueldepth.dat")
+#
+#         self._assert_data_equality(fuel_depth, input_data)
+#
+#         output_data = self._process_gridded_bin(
+#             OUTPUT_PATH / "totalinitialfuelheight.bin", (76, self.ny, self.nx))
+#
+#         fuel_depth[0, :] = 0
+#         fuel_depth[-1, :] = 0
+#         fuel_depth[:, 0] = 0
+#         fuel_depth[:, -1] = 0
+#
+#         self._assert_data_equality(output_data, fuel_depth)
+#
+#     def test_mburnt_integ(self):
+#         self._generic_drawfire_test("mburnt_integ-",
+#                                     (1, self.ny, self.nx))
+#
+#     def test_fire_energy_to_atmos(self):
+#         self._generic_drawfire_test("fire-energy_to_atmos-",
+#                                     (self.nz, self.ny, self.nx))
+#
+#     def test_windu(self):
+#         self._generic_drawfire_test("windu", ( self.nx + 1, self.nz, self.ny))
+
+
+# class TestProcessCompressedBin:
+#     nx = 100
+#     ny = 100
+#     nz = 56
+#     dims = (nz, ny, nx)
+#     sut = outputs.SimulationOutputs(OUTPUT_PATH, SIM_PARAMS)
+#     fire_indexes = sut._fire_indexes
+#
+#     def _process_compressed_bin(self, f):
+#         return outputs._process_compressed_bin(f, self.dims, self.fire_indexes)
+#
+#     def test_fuels_dens(self):
+#         for t in (0, 300):
+#             # Load the drawfire data
+#             drawfire_fpath = DRAWFIRE_PATH / f"fuels-dens-_{t}.npy"
+#             drawfire_data = np.load(drawfire_fpath)
+#
+#             # Load the output data
+#             output_fpath = OUTPUT_PATH / f"fuels-dens-00{t:03}.bin"
+#             output_data = self._process_compressed_bin(output_fpath)
+#
+#             # Check that the drawfire and output data are the same
+#             assert drawfire_data.shape == output_data.shape
+#             assert np.allclose(drawfire_data, output_data)
+#
+#             # Check that the input and output data are the same in the first
+#             # time step
+#             if t == 0:
+#                 # Load input data
+#                 input_fpath = SIMULATION_PATH / "treesrhof.dat"
+#                 input_fortran_file = FortranFile(input_fpath, "r")
+#                 input_data = input_fortran_file.read_reals(dtype=np.float32)
+#                 input_fortran_file.close()
+#                 input_data = input_data.reshape((self.nz, self.ny, self.nx))
+#                 input_data = np.moveaxis(input_data, 0, 2).astype(np.float32)
+#
+#                 # Remove edge cells from the input data
+#                 input_data[0, :] = 0
+#                 input_data[-1, :] = 0
+#                 input_data[:, 0] = 0
+#                 input_data[:, -1] = 0
+#
+#                 # Check that the input and output data are the same
+#                 assert input_data.shape == output_data.shape
+#                 assert np.allclose(input_data, output_data, atol=1e-3)
+#
+#     def test_fuels_moist(self):
+#         for t in (0, 300):
+#             # Load the drawfire data
+#             drawfire_fpath = DRAWFIRE_PATH / f"fuels-moist-_{t}.npy"
+#             drawfire_data = np.load(drawfire_fpath)
+#
+#             # Load the output data
+#             output_fpath = OUTPUT_PATH / f"fuels-moist-00{t:03}.bin"
+#             output_data = self._process_compressed_bin(output_fpath)
+#
+#             # Check that the drawfire and output data are the same
+#             assert drawfire_data.shape == output_data.shape
+#             assert np.allclose(drawfire_data, output_data)
+#
+#             # Check that the input and output data are the same in the first
+#             # time step
+#             if t == 0:
+#                 # Load input data
+#                 input_fpath = SIMULATION_PATH / "treesmoist.dat"
+#                 input_fortran_file = FortranFile(input_fpath, "r")
+#                 input_data = input_fortran_file.read_reals(dtype=np.float32)
+#                 input_fortran_file.close()
+#                 input_data = input_data.reshape((self.nz, self.ny, self.nx))
+#                 input_data = np.moveaxis(input_data, 0, 2).astype(np.float32)
+#
+#                 # Remove edge cells from the input data
+#                 input_data[0, :] = 0
+#                 input_data[-1, :] = 0
+#                 input_data[:, 0] = 0
+#                 input_data[:, -1] = 0
+#
+#                 # Check that the input and output data are the same
+#                 assert input_data.shape == output_data.shape
+#                 # assert np.allclose(input_data, output_data, atol=1e-3)
+#
+#     def test_array_reaction_rate(self):
+#         for t in (0, 300):
+#             # Load the drawfire data
+#             drawfire_fpath = DRAWFIRE_PATH / f"fire-reaction_rate-_{t}.npy"
+#             drawfire_data = np.load(drawfire_fpath)
+#
+#             # Load the output data
+#             output_fpath = OUTPUT_PATH / f"fire-reaction_rate-00{t:03}.bin"
+#             output_data = self._process_compressed_bin(output_fpath)
+#
+#             # Check that the drawfire and output data are the same
+#             assert drawfire_data.shape == output_data.shape
+#             assert np.allclose(drawfire_data, output_data)
+#
+#     def test_co_emissions(self):
+#         for t in (0, 300):
+#             # Load the drawfire data
+#             drawfire_fpath = DRAWFIRE_PATH / f"co_emissions-_{t}.npy"
+#             drawfire_data = np.load(drawfire_fpath)
+#
+#             # Load the output data
+#             output_fpath = OUTPUT_PATH / f"co_emissions-00{t:03}.bin"
+#             output_data = self._process_compressed_bin(output_fpath)
+#
+#             # Check that the drawfire and output data are the same
+#             assert drawfire_data.shape == output_data.shape
+#             assert np.allclose(drawfire_data, output_data)
+#
+#     def test_thermaldose(self):
+#         for t in (0, 300):
+#             # Load the drawfire data
+#             drawfire_fpath = DRAWFIRE_PATH / f"thermaldose-_{t}.npy"
+#             drawfire_data = np.load(drawfire_fpath)
+#
+#             # Load the output data
+#             output_fpath = OUTPUT_PATH / f"thermaldose-00{t:03}.bin"
+#             output_data = self._process_compressed_bin(output_fpath)
+#
+#             # Check that the drawfire and output data are the same
+#             assert drawfire_data.shape == output_data.shape
+#             assert np.allclose(drawfire_data, output_data)
+#
+#     def test_thermalradiation(self):
+#         for t in (0, 300):
+#             # Load the drawfire data
+#             drawfire_fpath = DRAWFIRE_PATH / f"thermalradiation-_{t}.npy"
+#             drawfire_data = np.load(drawfire_fpath)
+#
+#             # Load the output data
+#             output_fpath = OUTPUT_PATH / f"thermalradiation-00{t:03}.bin"
+#             output_data = self._process_compressed_bin(output_fpath)
+#
+#             # Check that the drawfire and output data are the same
+#             assert drawfire_data.shape == output_data.shape
+#             assert np.allclose(drawfire_data, output_data)