Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
817e629
first draft
ahms5 May 11, 2026
00694c5
allow multiple receivers
ahms5 May 11, 2026
7b55d7f
add patch length to settings
ahms5 May 11, 2026
ef49870
give plausible inputs activate direct sound
ahms5 May 11, 2026
f97fbd5
add notes
ahms5 May 11, 2026
0337235
fix normal calculation
ahms5 May 12, 2026
57b4c5f
add config fowllowing guidelines
ahms5 May 12, 2026
a6f7753
fix settings
ahms5 May 12, 2026
f413ff8
fix repo url in docs
ahms5 May 12, 2026
36658e8
Revert "fix repo url in docs"
ahms5 May 12, 2026
62acee1
add progressbar in infos
ahms5 May 12, 2026
9441035
remove -inf from results
ahms5 May 12, 2026
c31cc9d
fix no inf
ahms5 May 12, 2026
805bc19
set more useful db lim
ahms5 May 12, 2026
3325d4b
fix lim for etc resoltuion
ahms5 May 12, 2026
a591ed7
add parameters calciualtoon
ahms5 May 12, 2026
bc8a0c9
add center time
ahms5 May 12, 2026
ee631d8
asd
ahms5 May 12, 2026
e742db2
fix
ahms5 May 12, 2026
1ebc33a
fix scattering
ahms5 May 12, 2026
6d3081e
fix test
ahms5 May 12, 2026
bd95478
fix parameters
ahms5 May 12, 2026
e7763f4
asd
ahms5 May 12, 2026
6e21b9d
kkkk
ahms5 May 12, 2026
cfaa824
add edt
ahms5 May 12, 2026
d547c85
fix
ahms5 May 12, 2026
d8c40d5
change limits
ahms5 May 12, 2026
c273e20
fix edc conversion bug
ahms5 May 12, 2026
f832f6c
fix
ahms5 May 12, 2026
b7c63ab
add sound_power_W
ahms5 May 12, 2026
d492d98
etc duration lim fix
ahms5 May 12, 2026
9b426d7
asda
ahms5 May 12, 2026
332c0fb
add sparrowpy simulation interface
ahms5 May 11, 2026
4c5057f
Merge branch 'dev_sparrowpy' of https://github.com/ahms5/simulation-b…
ahms5 May 12, 2026
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
72 changes: 72 additions & 0 deletions example_settings/sparrowpy_setting.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"type": "simulationSettings",
"options": [
{
"name": "Speed of sound",
"id": "speed_of_sound",
"type": "float",
"display": "text",
"min": 100,
"max": 500,
"default": 343,
"step": 1,
"endAdornment": "m/s"
},
{
"name": "ETC time resolution",
"id": "etc_time_resolution_s",
"type": "float",
"display": "text",
"min": 0.0001,
"max": 0.1,
"step": 0.001,
"default": 0.001,
"endAdornment": "s"
},
{
"name": "ETC duration",
"id": "etc_duration_s",
"type": "float",
"display": "text",
"min": 0.1,
"max": 10,
"step": 0.1,
"default": 1,
"endAdornment": "s"
},
{
"name": "Maximum reflection order",
"id": "max_reflection_order",
"type": "int",
"display": "text",
"min": 1,
"max": 500,
"step": 1,
"default": 30,
"endAdornment": ""
},
{
"name": "Patch size",
"id": "patch_length",
"type": "float",
"display": "text",
"min": 0.01,
"max": 10,
"step": 0.01,
"default": 3,
"endAdornment": "m"
},
{
"name": "Source Power",
"id": "sound_power_W",
"type": "float",
"display": "text",
"min": 0,
"max": 10,
"step": 0.01,
"default": 0.0796,
"endAdornment": "W"
}

]
}
10 changes: 10 additions & 0 deletions methods-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
"repositoryURL":"https://github.com/Building-acoustics-TU-Eindhoven/acousticDE/",
"documentationURL":"https://building-acoustics-tu-eindhoven.github.io/acousticDE/index.html"
},
{
"simulationType": "sparrowpy",
"containerImage": "sparrowpy_image:latest",
"envVars": {},
"label": "Acoustic Radiance Transfer assuming diffuse reflections",
"settings":"sparrowpy_setting.json",
"entryFile":"sparrowpy_interface.py",
"repositoryURL":"https://github.com/sparrow-acoustics/sparrowpy",
"documentationURL":"https://sparrowpy.readthedocs.io/en/stable"
},
{
"simulationType": "MyNewMethod",
"containerImage": "mynewmethod_image:latest",
Expand Down
22 changes: 22 additions & 0 deletions sparrowpy_method/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM python:3.11.13-slim

# Set working directory
WORKDIR /app

# Install system dependencies for mesh generation and scientific computing
RUN apt-get update && apt-get install -y \
git \
build-essential \
gmsh \
&& rm -rf /var/lib/apt/lists/*

# Copy method package directory
COPY sparrowpy_method /app/sparrowpy_method

# Install the method package
RUN pip install --no-cache-dir /app/sparrowpy_method

WORKDIR /app/sparrowpy_method

# Default command to run the containerized sparrowpy method
CMD ["python", "-m", "sparrowpy_interface"]
21 changes: 21 additions & 0 deletions sparrowpy_method/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2026, The sparrowpy developers

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
78 changes: 78 additions & 0 deletions sparrowpy_method/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
[project]
name = "sparrowpy_interface"
version = "0.1.0"
description = "Sound Propagation with Acoustic Radiosity for Realistic Outdoor Worlds"
requires-python = ">=3.11,<3.15"
authors = [
{ name = "Anne Heimes", email = "ahe@akustik.rwth-aachen.de" },
]
keywords = [
"acoustic simulation",
"geometrical acoustics",
"acoustic radiance transfer",
"brdf",
"scattering",
]

classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"numpy>=1.23.0",
"sparrowpy>=1",
"requests",
"gmsh",
"trimesh",
"pyfar",
"pyrato",
]

[project.optional-dependencies]
deploy = [
"twine",
"wheel",
"build",
"setuptools",
"bump-my-version",
]

tests = [
"pytest",
"pytest-cov",
"watchdog",
"ruff",
"coverage",
]

docs = [
"sphinx",
"autodocsumm>=0.2.14",
"pydata-sphinx-theme",
"sphinx_mdinclude",
"sphinx-design",
"sphinx-favicon",
"sphinx-reredirects",
]

dev = ["sparrowpy_interface[deploy,tests,docs]"]

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[tool.setuptools]
packages = ["sparrowpy_interface"]

[project.scripts]
sparrowpy_interface = "sparrowpy_interface:main"

[tool.pytest.ini_options]
testpaths = ["tests"]
19 changes: 19 additions & 0 deletions sparrowpy_method/sparrowpy_interface/__cli__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""CLI module for sparrowpy method."""
import os
from .sparrowpy_interface import sparrowpyMethod


def main() -> None:
"""Run the sparrowpy method simulation."""
# JSON path in the uploads folder. This variable is set for the
# container when it is started up.
json_file_path = os.environ.get("JSON_PATH")

print(f"Running sparrowpy method with JSON_PATH={json_file_path}")
sparrowpy_method_object = sparrowpyMethod(json_file_path)
sparrowpy_method_object.run_simulation()

# Save the results to a separate file
sparrowpy_method_object.save_results()

print("sparrowpy container finished.")
8 changes: 8 additions & 0 deletions sparrowpy_method/sparrowpy_interface/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""sparrowpyMethod package."""
from .__main__ import main
from .sparrowpy_interface import sparrowpyMethod

__all__ = [
"main",
"sparrowpyMethod"
]
5 changes: 5 additions & 0 deletions sparrowpy_method/sparrowpy_interface/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Main module for sparrowpy method."""
from .__cli__ import main

if __name__ == "__main__":
main()
92 changes: 92 additions & 0 deletions sparrowpy_method/sparrowpy_interface/definition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"""Base class implementation of the SimulationMethod interface class."""
from abc import ABC, abstractmethod
from pathlib import Path
import time

import requests


class SimulationMethod(ABC):
"""Abstract base class for simulation methods.

This class serves as a template for methods required to run a simulation
and return results to the simulation service executor.

"""

def __init__(self, input_json_path: str | Path | None):
"""Initialize the simulation method.

Parameters
----------
input_json_path : str | Path | None, optional
The path to the input JSON file, by default None

Raises
------
FileNotFoundError
If the input JSON file does not exist.

"""
if input_json_path is None or (
isinstance(input_json_path, str) and input_json_path == ""):
raise FileNotFoundError("input_json_path cannot be None or empty")

input_path = Path(input_json_path)
if not input_path.exists():
raise FileNotFoundError(
f"Input JSON file not found: {input_json_path}")

self._input_json_path = input_json_path

@property
def input_json_path(self) -> str | Path:
"""The input JSON file."""
return self._input_json_path

@abstractmethod
def run_simulation(self):
"""Run the simulation for the given a JSON file."""
pass

def save_results(
self,
url="http://host.docker.internal:5001/receive",
max_retries=5,
delay=2,
):
"""Return the results back to the simulation service executor.

Parameters
----------
url : str, optional
The URL of the results server,
by default "http://host.docker.internal:5001/receive" which
is the default address for local execution via Docker.
max_retries : int, optional
The maximum number of retries if the request fails, by default 5
delay : int, optional
The delay in seconds between retries, by default 2

"""

json_tmp_file = self.input_json_path
for attempt in range(1, max_retries + 1):
try:
with open(json_tmp_file, "rb") as f:
response = requests.post(url, files={"file": f})

if response.status_code == 200:
print("Successfully sent file.")
return True

print(
f"Attempt {attempt}: ",
f"Server returned {response.status_code}")
except requests.RequestException as exc:
print(f"Attempt {attempt}: Request failed - {exc}")

time.sleep(delay)

print("Max retries reached. Giving up.")
return False
Loading