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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the OS, Python version, and other tools you might need
build:
os: ubuntu-24.04
tools:
python: "3.12"
apt_packages:
- libsndfile1
- libglu1-mesa

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py

# Optionally set the version of Python and requirements required to build your docs
python:
install:
- method: pip
path: ".[docs]"
2 changes: 2 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
auto_examples/
sg_execution_times.rst
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
35 changes: 35 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@ECHO OFF

pushd %~dp0

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)

if "%1" == "" goto help

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd
67 changes: 67 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = "CHORAS simulation-backend"
copyright = "2026, The CHORAS developers"
author = "The CHORAS developers"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
"sphinx.ext.duration",
"sphinx.ext.doctest",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"myst_parser",
"sphinx_design",
"sphinx_copybutton",
'sphinx_gallery.gen_gallery',
]
source_suffix = [".rst", ".md"]

templates_path = ["_templates"]
exclude_patterns = []

# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = "pydata_sphinx_theme"
html_static_path = ["_static"]
html_title = "CHORAS simulators"

html_theme_options = {
"navbar_start": ["navbar-logo"],
"navbar_end": ["navbar-icon-links", "theme-switcher"],
"navbar_align": "left",
"icon_links": [
{
"name": "GitHub",
"url": "https://github.com/choras-org/simulation-backend",
"icon": "fa-brands fa-square-github",
"type": "fontawesome",
},
],
# Configure secondary (right) side bar
"show_toc_level": 3, # Show all subsections of notebooks
"secondary_sidebar_items": ["page-toc"], # Omit 'show source' link that that shows notebook in json format
"navigation_with_keys": True,
# Configure navigation depth for section navigation
"navigation_depth": 2,
}

html_context = {
"default_mode": "light"
}

# -- Gallery configuration -------------------------------------------------
sphinx_gallery_conf = {
"examples_dirs": "../../examples", # path to your example scripts
"gallery_dirs": "auto_examples", # path to where to save gallery generated output
"image_scrapers": ("matplotlib",),
}
13 changes: 13 additions & 0 deletions docs/source/includes/contributing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Contributing
============

This section provides guidelines for contributing a new simulation method to CHORAS.
The following steps will help you navigate the process.


.. toctree::
:maxdepth: 1

contributing/setup_dev.rst
contributing/contribute_method.rst
contributing/configuring.rst
121 changes: 121 additions & 0 deletions docs/source/includes/contributing/configuring.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
Integrating a new Method
========================

Add Example Settings
--------------------

Add a JSON file describing your method's adjustable parameters in ``example_settings/``. This will be used by the frontend to generate the UI for the method. Follow the format of ``mynewmethod_setting.json``.

This file would have the following structure:

- At the top level there would be an object with the two fields:

- ``type``: Specified as ``"SimulationSettings"``
- ``options``: Array of objects for settings options

- Each object in that array describes one configurable parameter and uses the following fields:

- ``name``: Human-readable label shown in the UI, e.g. ``"MyNewMethod parameter 1"``
- ``id``: Internal identifier used in backend/frontend logic, e.g. ``"mnm_1"``. This must be unique per method.
- ``type``: Data type of the parameter value, e.g. ``"float"`` (other types can be added if the system supports them, such as ``"int"``, ``"bool"``, ``"string"``).
- ``display``: How this parameter is rendered in the UI, e.g. ``"text"`` for a text/number input field (could be other widgets if supported, such as sliders, dropdowns, etc.).
- ``min``: Minimum allowed value for numeric types. Used for validation and UI constraints.
- ``max``: Maximum allowed value for numeric types. Also used for validation and UI constraints.
- ``default``: Default value if the user does not provide one. Can be ``null`` if you want to force the user or backend to set it explicitly.
- ``step``: Increment used in the UI for numeric inputs (e.g. how much the value changes when the user uses arrow keys or a slider).
- ``endAdornment`` *(optional)*: Optional string shown next to the field in the UI, often for units (e.g. ``"dB"``, ``"m"``, ``"s"``). Empty string if not needed.

Update Method Configuration
---------------------------

Update the file ``methods-config.json`` in the ``simulation-backend`` directory with a new entry.

This file lists all available simulation methods, so CHORAS can recognize yours.

- ``simulationType``: The short name of the simulation acting as an identifier
- ``containerImage``: Name for the container image to be made
- ``envVars``: Dictionary of specific environment variables (if required) for Docker containers
- ``label``: Name of the method
- ``entryFile``: Python entry point to start execution
- ``setting``: Setting file name so that it can be loaded in frontend and backend
- ``repositoryURL``: Link to the original repository of the simulation method
- ``documentationURL``: Link to the documentation of the simulation method

Update CHORAS
-------------

Docker Image Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~

Open the ``docker-compose.yml`` in the CHORAS root directory and add your method under ``services``:

.. code-block:: yaml

services:
# ... existing services ...
mynew-method: # ← Your method name (kept as service name)
platform: linux/amd64 # ← Keep unchanged
build:
context: ./simulation-backend # ← Keep unchanged
dockerfile: new_method/Dockerfile # ← Path to your Dockerfile
image: mynew_image:latest # ← EXACTLY match methods-config.json
profiles:
- sim_method # ← Keep unchanged

Modify the Build Script
~~~~~~~~~~~~~~~~~~~~~~~

In the root directory, go to the ``CHORAS_BUILD.sh`` file and add the following commands based on your method before the ``docker compose up`` command:

.. code-block:: bash

# Export new method image for backend executor
echo "📦 Exporting MyNewMethod image..."
docker save -o backend/app/services/executors/mynew_image.tar mynew_image:latest
echo "✅ Docker image exported: mynew_image.tar"

.. note::
**Replace**: ``mynew_image.tar`` & ``mynew_image:latest`` with your actual image name.

After this, delete the DB volume and all containers, and run the ``CHORAS_BUILD.sh`` bash command again.

Debugging Execution
-------------------

If a simulation fails (you see a **"Simulation Failed"** alert at the top of the screen),
you can inspect the underlying container logs.

1. Open ``backend/app/services/executors/local_executor.py``.

2. Locate the line that removes the container after execution (for example, a call that
stops or removes the container when it finishes):

.. code-block:: python

try:
client = docker.from_env()
container = client.containers.run(
image=image,
environment=env, # JSON_PATH is the container path, valid in child too
volumes={
host_uploads_dir: {
"bind": container_uploads_dir, # same path in child container
"mode": "rw",
}
},
detach=True,
working_dir=self.work_dir,
name=container_name,
# remove = True, # ← Comment This one
)
return container

except Exception as e:
logger.error(f"Failed to start Docker container: {e}")
raise

3. Temporarily comment out that line so the container is not removed automatically.

4. Rebuild the image and container. With the container kept alive after the simulation ends, you can open your container
runtime (e.g., Docker) and inspect the container logs to see detailed error messages
and tracebacks for the simulation method execution.
Loading
Loading