Custom behavioral modules

This tutorial demonstrates how to use the larvaworld library interface to create, modify and launch virtual experiments. Larvaworld ships with a comprehensive set of preconfigured experiments that reflect many types of dish experiments that are conducted by experimental researchers.

A larvaworld experiment is a set of configuration variables that describe and control various aspects of the overall virtual experiment. This includes:

  • the environment definition (dish geometry and dimensions)

  • location, shape and intensity of sensory objects (food patches, odor sources …)

  • the number, size and placement of larva groups

  • the larva agent configuration per group

    • body physics

    • behavioral modules and their parameters

    • initial states (ie. metabolic state)

As one can see the number of available parameters is quite large. There are several preconfigured experiments available that can be launched instantly. In order to create your own custom experiment we recommend to start off with one of the available preconfigured experiments that best match the type of experiment you want to ran. And then modify any specific parameters you would like to customize.

Let’s walk through the steps to create a custom experiment where we want to customize the intensity of the odor landscape available in the dish. First define all required imports:

%load_ext param.ipython
import panel as pn

pn.extension()

import larvaworld as lw
from larvaworld.lib import reg, sim
from larvaworld.lib.reg.generators import ExpConf

# Tutorial safety switches (avoid GUI/media by default)
RUN_GUI_DEMO = False
SAVE_MEDIA = False
MEDIA_DIR = "videos"

# Verbosity
lw.VERBOSE = 1

Larvaworld uses mostly dictionary structures to store and manage the configuration parameters of experiments. It also supports iPython magic commands to explore these. For example here we print out all parameters and settings that are available in an experiment via the ExpConf class:

This includes:

  • General simulation arguments (duration, timestep etc)

  • Environment configuration (dish, geometry, size)

  • Parameters to be recorded from larva agents and their post-simulation analysis

  • Larva groups

# Show the attributes of the ExpConf class with iPython magic
%params ExpConf

# Show the attributes of the ExpConf class as a nested dictionary
ExpConf.param

Each preconfigured experiment that comes with larvaworld can be referenced by a unique experiment ID. Use this ID to load the corresponding configuration from the registry.

Since configrations are essentially just nested dictionary you can easily access and print out a specific setting of interest using a dot syntax.

# load predefined experiment
expID = "chemorbit"
exp_conf = reg.conf.Exp.getID(expID)
# explore some experiment settings
print(
    f"Experiment odor intensity: {exp_conf.env_params.food_params.source_units.Source.odor}"
)

In order to modify a specific parameter in the loaded experiment configuration you simply assign a new value to it like you would do with a regular Python dictionary:

# customize odor intensity of above source
exp_conf.env_params.food_params.source_units.Source.odor.spread = 0.01
print(
    f"Adjusted odor intensity: {exp_conf.env_params.food_params.source_units.Source.odor}"
)

Next we want to investigate what larva grous the experiment defines. Larva groups is the setting which allows you to control the number and type of larva agents you want to place into the experiment.

Each group has its own configuration with regard to the larva agent, the number of agent instances to place and the initial locations. Each group will be assigned a dedicated color such that when you run a simulation you can immediately tell which agent instance belongs to which group. Similarly to how genetic mutations in real experiments work - just without all the lab hassle.

larva_group = exp_conf.larva_groups
# Print the entire larva group config
print("Larva group configuration:")
print(larva_group)

print(f"Available larva group IDs/names: {larva_group.keylist}")
# get the "name" of the first larva group
# this defaults to the larva agent model ID used by this group if none is provided
larva_group_id = larva_group.keylist[0]
# larva_group_id and model ID are both the same thing if no custom larva_group name is provided
print(larva_group_id, larva_group[larva_group_id].model)

Each group has its own larva agent model configuration which is defined by a model ID. That model ID can be used to retrieve the model configuration from the registry.

Again you can customize a model configuration like a regular Python dictionary:

# Launch a simulation run of the customized experiment

run_id = "my-custom-run"

screen_kws = {}
if RUN_GUI_DEMO or SAVE_MEDIA:
    screen_kws = {
        "vis_mode": "video",
        "show_display": RUN_GUI_DEMO,
        "save_video": SAVE_MEDIA,
        "fps": 20,
        # saved as {media_dir}/larva-sim-{run_id}.mp4
        "video_file": f"larva-sim-{run_id}",
        "media_dir": MEDIA_DIR,
    }

erun = sim.ExpRun(
    experiment=expID,
    modelIDs=["navigator", "Levy_navigator"],
    screen_kws=screen_kws,
    N=2,
    duration=0.5,  # minutes
)

erun.simulate()
print(f"Run_id: {run_id} completed")

# Analysis can be slow; keep it optional
# erun.analyze()