A framework for agent-based modeling of dynamic spatial processes.
Project description
NexusSim
NexusSim is a flexible and powerful Python framework for agent-based modeling of dynamic spatial processes. Designed for modularity and scientific reproducibility, it allows users to simulate complex emergent phenomena on customizable landscapes - from disease epidemics and invasive species to wildlife spread and information diffusion.
The framework is built on a decoupled, file-based architecture: the simulation engine produces a series of GeoTIFF raster files, which are then consumed by a comprehensive analysis toolbox to generate plots, animations, and statistics.
Key Features
- Agent-Centric Simulation: Models complex behaviors by focusing on individual agent states and interactions (
nexussim.core). - Raster-Based I/O: Works seamlessley with standard geospatial data formats for defining landscapes and initial conditions.
- Comprehensive Analysis Suite: A rich set of tools (
nexussim.analysis) to generate epidemic curves, animations, persistence "hotspot" maps, and calculate the rate of spread. - Reproducibility First: The file-based output creates a permanent, reproducible record of every simulation run.
- Scalable: By not holding the entire simulation history in memory, NexusSim can hanlde longer and larger simulations.
Installation
NexusSim is available on PyPI. Install it using pip:
pip install nexussim
To install the latest development version directly from GitHub:
pip install git+https://github.com/mrmarcelino/nexussim.git
Quickstart: From Simulation to Analysis
This example demonstrates the complete NexusSim workflow. It will:
- Create dummy input rasters for a landscape and initial infections.
- Run a 50-step simulation, saving the output to a results/ directory.
- Use the analysis module to generate an epidemic curve plot and an animated GIF from the results.
import os
import shutil
import numpy as np
import rasterio
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# nexussim/
# |- __init__.py
# |- core.py
# |- analysis.py
from nexussim.core import DiseaseModel
import nexussim.analysis as nxs_analysis
# Helper function to create dummy input data
def create_dummy_raster(path, width, height, data, crs='EPSG:3857'):
"""
Creates a simple GeoTIFF file for demonstration purposes.
"""
profile ={
'driver': 'GTiff',
'dtype': 'float32',
'width': width,
'height': height,
'count': 1,
'crs': crs,
'transform': rasterio.transform.from_origin(0, height, 1, 1),
'nodata': -9999
}
with rasterio.open(path, 'w', **profile) as dst:
dst.write(data.astype(profile['dtype']), 1)
# 1. Setup Environment and Input Data
print("--- Setting up simulation environment ---")
# Create directories for inputs, simulation outputs, and analysis outputs
os.makedirs('inputs', exist_ok=True)
os.makedirs('sim_results', exist_ok=True)
os.makedirs('analysis_outputs', exist_ok=True)
# Define file paths
cost_path = 'inputs/cost.tif'
initial_infection_path = 'inputs/initial_infection.tif'
width, height = 100, 100
# Create a uniform cost surface (all areas are equally passable)
cost_data = np.ones((height, width))
create_dummy_raster(cost_path, width, height, cost_data)
# Create an initial infection raster with a small cluster of infected cells
initial_infection_data = np.zeros((height, width))
initial_infection_data[45:55, 45:55] = 1
create_dummy_raster(initial_infection_path, width, height, initial_infection_data)
print(" > Dummy input rasters created.")
# 2. Run the Simulation
print("\n--- Running the NexusSim simulation ---")
model_params = {
'cost_threshold': 1.0, # Agents can move anywhere
'spread_probability': 0.6,
'infection_duration': 5,
'recovery_time_min': 10,
'recovery_time_max': 20
}
# Initialize the model
model = DiseaseModel(cost_path, initial_infection_path, model_params)
# Run the simulation, which saves raster files to 'sim_results/'
model.run_simulation(time_steps=50, output_dir='sim_results')
# 3. Analyze the Results
print("\n--- Analyzing simulation results ---")
# First, get the list of generated files
tif_files = nxs_analysis.get_simulation_files('sim_results')
if tif_files:
# Generate and save an epidemic curve plot
curve_plot_path = 'analysis_outputs/epidemic_curve.png'
nxs_analysis.generate_epidemic_curve(tif_files, curve_plot_path)
# Create and save an animation
animation_path = 'analysis_outputs/animation.gif'
nxs_analysis.create_animation(tif_files, animation_path, duration=0.1)
print(" > Analysis complete. Outputs are in 'analysis_outputs\'.")
# 4. Display one of the generated plots
print("\n--- Displaying generated epidemic curve ---")
img = mpimg.imread(curve_plot_path)
plt.figure(figsize=(10, 6))
plt.imshow(img)
plt.axis('off') # Hide axes as the image already has them
plt.show()
else:
print("Analysis skipped: No simulation files were found.")
The NexusSim Workflow
NexusSim is intentionally designed to separate the simulation from the analysis. This provides several key advantages for scientific modeling:
- Reproducibility: The output rasters serve as a permanent, shareable record of the simulation.
- Flexibility: You can run multiple analyses on a single simulation output without having to re-run the entire model.
- Extensibility: It's easy to write your own custom analysis functions that operate on the standardized GeoTIFF outputs.
The standard workflow looks like this:
[Input Rasters]→nexussim.core.DiseaseModel→[Output Rasters]→nexussim.analysis→[Plots, GIFs, & Stats]
Core Components
nexussim.core: Contains the Agent and DiseaseModel classes. This is the heart of the simulation engine responsible for running the model and saving the state at each time step.nexussim.analysis: A toolbox of standalone functions that take a list of raster file paths as input and produce high-level outputs like plots, statistics, or animations.
Contributing
Contributions are welcome! If you have ideas for new features, analysis tools, or improvements, please open an issue or submit a pull request.
License
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0) - see the LICENSE.md file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nexussim-0.1.1.tar.gz.
File metadata
- Download URL: nexussim-0.1.1.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad8effd561ef704982dbbfe69947b716ffa4316f2ce6599d9aff8871a23ac75f
|
|
| MD5 |
469c9b97326de771ccc63bca16847bb6
|
|
| BLAKE2b-256 |
0b322ec4cc8ebb10bed5ae78d178a5d14a2e3940f82eaa8e7783725f35275ff0
|
File details
Details for the file nexussim-0.1.1-py3-none-any.whl.
File metadata
- Download URL: nexussim-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d29f34a9d50126a9120d0beae7d73c343b48b43fc6be9da8dcefa7fb18e2aecb
|
|
| MD5 |
11b12a4612d399c18eaa25894f590ebb
|
|
| BLAKE2b-256 |
e1a5fc622b6c187a568937026f1a741524beb7bb11d347c4644f2187195b8324
|