larvaworld.lib.model.envs.valuegrid

Classes

SpatialEntity

Base class for spatial entities in simulation environment.

Grid

Base grid class with spatial resolution configuration.

GridOverSpace

Grid mapped over agentpy simulation space.

ValueGrid

Grid storing scalar values at each cell position.

FoodGrid

Food distribution grid for agent feeding behavior.

OdorScape

Odor landscape grid for chemotaxis simulations.

AnalyticalValueLayer

Analytical odor gradient computation layer.

GaussianValueLayer

Gaussian odor diffusion model.

DiffusionValueLayer

Physical odor diffusion model with evaporation and wind.

WindScape

Wind and air-puff simulation layer.

ThermoScape

Temperature gradient grid for thermotaxis simulations.

Module Contents

class larvaworld.lib.model.envs.valuegrid.SpatialEntity

Bases: larvaworld.lib.param.Viewable, larvaworld.lib.model.Object

Base class for spatial entities in simulation environment.

Combines visualization and object properties for entities that exist in spatial coordinates and can be rendered on screen.

Attributes:

color: Display color (default: white) visible: Whether entity is visible on screen

Example:
>>> entity = SpatialEntity(color="blue", visible=True)
>>> entity.record_positions(label="pos")
color
visible
record_positions(label: str = 'p') None

Records the positions of each agent.

Arguments:
label (string, optional):

Name under which to record each position (default p). A number will be added for each coordinate (e.g. p1, p2, …).

class larvaworld.lib.model.envs.valuegrid.Grid

Bases: SpatialEntity

Base grid class with spatial resolution configuration.

Provides grid dimensionality and resolution for spatial discretization of continuous environments.

Attributes:

grid_dims: Grid resolution tuple (X, Y), default (51, 51) X: Grid width (number of cells in X dimension) Y: Grid height (number of cells in Y dimension)

Example:
>>> grid = Grid(grid_dims=(100, 100))
>>> print(grid.X, grid.Y)  # 100 100
grid_dims
property X: int
property Y: int
class larvaworld.lib.model.envs.valuegrid.GridOverSpace(model: Any, **kwargs: Any)

Bases: Grid, agentpy.Grid

Grid mapped over agentpy simulation space.

Extends Grid and agentpy.Grid to create a discretized grid overlay on top of continuous simulation space, enabling spatial indexing and cell-based computations.

Attributes:

unique_id: Identifier for grid instance (default: “GridOverArena”) space: Reference to model’s agentpy.Space meshgrid: Numpy meshgrid for grid coordinates grid_vertices: Vertex positions for each grid cell

Example:
>>> grid = GridOverSpace(model=sim_model, grid_dims=(50, 50))
>>> cell = grid.get_grid_cell((0.1, 0.2))
unique_id
color
visible
XY
xy
cell_radius
meshgrid
grid_vertices
property space: Any
get_grid_cell(p: Any) tuple[int, int]
generate_grid_vertices() numpy.ndarray
cell_vertices(i: int, j: int) numpy.ndarray
class larvaworld.lib.model.envs.valuegrid.ValueGrid(sources: list[Any] | None = None, max_value: float | None = None, min_value: float = 0.0, **kwargs: Any)

Bases: Grid

Grid storing scalar values at each cell position.

Base class for value-based grids (food, odor, temperature) that maintain a 2D array of scalar values with methods for adding, retrieving, and visualizing spatial distributions.

Attributes:

initial_value: Default value for all grid cells (default: 0.0) fixed_max: Whether maximum value is kept constant (default: False) grid: 2D numpy array storing cell values max_value: Maximum value in grid (for normalization) min_value: Minimum value in grid (for clipping) sources: List of source objects contributing to grid values

Example:
>>> vgrid = ValueGrid(sources=[food1, food2], max_value=100.0)
>>> value = vgrid.get_value((0.5, 0.5))
>>> vgrid.add_value((0.1, 0.2), 10.0)
initial_value
fixed_max
sources = None
XY0
grid
max_value = None
min_value = 0.0
match_space(space: Any) None
update_values() None
add_value(p: Any, value: float) float
get_value(p: Any) float
get_grid_cell(p: Any) tuple[int, int]
add_cell_value(cell: tuple[int, int], value: float) float
generate_grid_vertices() numpy.ndarray
cell_vertices(i: int, j: int) numpy.ndarray
cel_pos(i: int, j: int) tuple[float, float]
reset() None
empty_grid() None
draw_peak(v: Any) None
draw(v: Any, **kwargs: Any) None
draw_isocontours(v: Any) None
get_color_grid() numpy.ndarray
class larvaworld.lib.model.envs.valuegrid.FoodGrid(**kwargs: Any)

Bases: ValueGrid

Food distribution grid for agent feeding behavior.

Specialized ValueGrid for food resources with substrate properties, green color visualization, and fixed maximum value behavior. Agents can consume food from grid cells during simulation.

Attributes:

unique_id: Grid identifier (default: “FoodGrid”) color: Visualization color (default: green) fixed_max: Maximum value kept constant (default: True) initial_value: Starting food amount per cell (default: 10^-6) substrate: Substrate configuration for feeding interactions

Example:
>>> food_grid = FoodGrid(initial_value=0.001, max_value=1.0)
>>> color = food_grid.get_color(0.5)
unique_id
color
fixed_max
initial_value
substrate
get_color(v: float) numpy.ndarray
draw(v: Any, **kwargs: Any) None
class larvaworld.lib.model.envs.valuegrid.OdorScape(subclass_initialized: bool = False, **kwargs: Any)

Bases: ValueGrid

Odor landscape grid for chemotaxis simulations.

Factory class that dispatches to specific odor diffusion algorithms (Gaussian, Diffusion, or Analytical). Provides base infrastructure for modeling chemical gradients from odor sources.

Attributes:

unique_id: Grid identifier (default: “Odorscape”) odorscape: Algorithm type (“Gaussian”, “Diffusion”, or “Analytical”)

Example:
>>> odor = OdorScape(odorscape="Gaussian", sources=[source1, source2])
>>> # Automatically creates GaussianValueLayer instance
unique_id
odorscape
class larvaworld.lib.model.envs.valuegrid.AnalyticalValueLayer(**kwargs: Any)

Bases: OdorScape

Analytical odor gradient computation layer.

Computes odor values analytically using customizable value functions for each source. Default uses Gaussian distribution but supports arbitrary analytical formulations via value_function callback.

Attributes:

odorscape: Algorithm type (default: “Analytical”) value_function: Callable for computing grid values from sources

Signature: (source, value, pos, rel_pos) -> float

Example:
>>> layer = AnalyticalValueLayer(sources=[odor_source])
>>> value = layer.get_value((0.5, 0.5))
>>> grid = layer.get_grid()
odorscape
value_function
get_value(pos: tuple[float, float]) float
get_grid() numpy.ndarray
draw_isocontours(v: Any) None
class larvaworld.lib.model.envs.valuegrid.GaussianValueLayer(**kwargs: Any)

Bases: AnalyticalValueLayer

Gaussian odor diffusion model.

Implements odor gradients using Gaussian distributions centered at each source. Standard choice for analytical odor modeling.

Attributes:

odorscape: Algorithm type (default: “Gaussian”)

Example:
>>> gaussian = GaussianValueLayer(sources=[source1, source2])
>>> odor_value = gaussian.get_value((0.5, 0.5))
odorscape
get_value(pos: tuple[float, float]) float
class larvaworld.lib.model.envs.valuegrid.DiffusionValueLayer(**kwargs: Any)

Bases: OdorScape

Physical odor diffusion model with evaporation and wind.

Implements realistic odor plume dynamics using Gaussian filtering for diffusion, evaporation decay, and optional wind-driven advection. Computationally intensive but physically accurate.

Attributes:

odorscape: Algorithm type (default: “Diffusion”) evap_const: Evaporation decay factor per timestep (default: 0.9) gaussian_sigma: Gaussian filter sigma for diffusion (default: (0.95, 0.95))

Note:

Diffusion coefficients for gas-phase molecules: 10^-6 to 10^-5 m²/s. Sigma is automatically scaled based on grid resolution.

Example:
>>> diffusion = DiffusionValueLayer(
...     sources=[source], evap_const=0.95, gaussian_sigma=(1.0, 1.0)
... )
>>> diffusion.update_values()  # Called each simulation step
odorscape
evap_const
gaussian_sigma

A typical diffusion coefficient for a molecule in the gas phase is in the range of 10-6 to 10-5 m2/sigma

Yes, it does that automatically based on the sigma and truncate parameters. Indeed, the function gaussian_filter is implemented by applying multiples 1D gaussian filters (you can see that here). This function uses gaussian_filter1d which generate itself the kernel using _gaussian_kernel1d with a radius of int(truncate * sigma + 0.5).

Doing the math, sigma ends up reeeeally small

update_values() None
class larvaworld.lib.model.envs.valuegrid.WindScape(**kwargs: Any)

Bases: SpatialEntity

Wind and air-puff simulation layer.

Models constant wind or pulsed air-puff stimuli affecting agent navigation. Supports wind direction, speed, temporal puffs, and obstacle occlusion. Visualized with animated arrow lines.

Attributes:

unique_id: Grid identifier (default: “WindScape”) color: Visualization color (default: red) wind_direction: Wind direction in radians (default: π) wind_speed: Wind velocity magnitude (default soft-max: 100) puffs: Dict of scheduled air-puff events with timing parameters scapelines: Arrow line positions for visualization

Example:
>>> wind = WindScape(wind_direction=0.0, wind_speed=10.0)
>>> wind.add_puff(duration=5.0, speed=20.0, start_time=10.0)
>>> value = wind.get_value(agent)
unique_id
color
wind_direction
wind_speed
puffs
max_dim
N = 40
draw_phi = 0
scapelines
events
get_value(agent: Any) float
obstructed(pos: tuple[float, float]) bool
draw(v: Any, **kwargs: Any) None
generate_scapelines(D: float, N: int, A: float) list[tuple[Any, Any]]
set_wind_direction(A: float) None
add_puff(duration: float, speed: float, direction: float | None = None, start_time: float | None = None, N: int | None = 1, interval: float = 10.0) None
update() None
class larvaworld.lib.model.envs.valuegrid.ThermoScape(plate_temp: float = 22, spread: float = 0.1, thermo_sources: list[list[float]] | None = None, thermo_source_dTemps: list[float] | None = None, **kwargs: Any)

Bases: ValueGrid

Temperature gradient grid for thermotaxis simulations.

Models spatial temperature distributions with multiple hot/cold sources using multivariate Gaussian spreads. Returns thermal gains (warming/cooling) at each position for agent thermosensation.

Attributes:

unique_id: Grid identifier (default: “ThermoScape”) plate_temp: Baseline plate temperature in °C (default: 22) thermo_spread: Gaussian spread parameter for temperature sources thermo_sources: List of [x, y] positions for temperature sources thermo_source_dTemps: Temperature delta for each source (°C) thermoscape_layers: Multivariate normal distributions per source

Example:
>>> thermo = ThermoScape(
...     plate_temp=22,
...     thermo_sources=[[0.5, 0.5], [0.2, 0.8]],
...     thermo_source_dTemps=[8, -8]  # Hot and cold sources
... )
>>> gain = thermo.get_value((0.5, 0.5))  # {'warm': ..., 'cool': ...}
unique_id
plate_temp = 22
thermo_sources
thermo_source_dTemps
thermo_spread = 0.1
generate_thermoscape() None

size is the length of the square arena in mm. rezo is the resolution with 1 being a mm, 0.1 being a 10th of a mm. spread is the spread put into the multivariate_normal function. pTem is the plate Temp i.e. the standard temperature of the plate - default is 22˚C. origins are the coordinate locations on the size x size plate of the heat or cold sources. type: list tempDiff needs to be a list the same length as origins, and determines if that source will be cold or hot and by how much. In other words a <ptemp> of 22 and a <origins> of [[10,20], [30,40]] and <tempDiff> of [8,-8] would make a temperature source at [10,20] that is ~30˚C and a source at [30,40] that is ~14˚C. The mean is taken where the temperatures of multiple sources overlap.

get_value(pos: tuple[float, float]) dict[str, float]
get_grid() numpy.ndarray
draw_isocontours(v: Any)