Visualizing sensory landscapes
Sensory landscapes of diverse modalities are available :
Olfactory (Odorscape)
Temperature (Thermoscape)
Wind (Windscape)
Initialize the larvaworld registry. This loads some components from disc and builds the rest on the fly.
import numpy as np
from larvaworld.lib import reg, sim, util
# Tutorial safety switches (set True to run interactive demos)
RUN_SINGLE_DEMO = False
RUN_ALL_COMBINATIONS = False
RUN_OLD_METHOD = False
SAVE_MEDIA = False
MEDIA_DIR = "./media"
from larvaworld.lib.param.composition import Odor
def get_odorscape(m):
if m == "Diffusion":
oS = reg.gen.DiffusionValueLayer(gaussian_sigma=(0.95, 0.5), evap_const=0.9)
oR = Odor.oD(id="Odor_R")
oL = Odor.oD(id="Odor_L")
elif m == "Gaussian":
oS = reg.gen.GaussianValueLayer()
oR = Odor.oG(id="Odor_R")
oL = Odor.oG(id="Odor_L")
else:
raise ValueError("Not implemented")
kws = {
"group": "Source",
"radius": 0.003,
"amount": 0.0,
}
sus = {
**reg.gen.Food(
unique_id="Source_L", c="blue", odor=oL, pos=(-0.01, 0.0), **kws
).entry(),
**reg.gen.Food(
unique_id="Source_R", c="cyan", odor=oR, pos=(0.01, 0.0), **kws
).entry(),
}
return util.AttrDict(
{"food_params": reg.gen.FoodConf(source_units=sus), "odorscape": oS}
)
def get_windscape(m):
kws = {
"duration": 5,
"speed": 50,
}
Npuffs = 10
if m == "single":
puffs = {
i: reg.gen.AirPuff(
direction=i / Npuffs * 2 * np.pi, start_time=5 + 10 * i, **kws
).nestedConf
for i in range(Npuffs)
}
ws = 0.0
elif m == "repetitive":
puffs = {
"puff_group": reg.gen.AirPuff(
direction=np.pi / 4, start_time=5, N=Npuffs, interval=10.0, **kws
).nestedConf
}
ws = 0.0
elif m == "no":
puffs = {}
ws = 10.0
else:
raise ValueError("Not implemented")
wS = reg.gen.WindScape(wind_direction=0.0, wind_speed=ws, puffs=puffs)
bl = {"Border": reg.gen.Border(vertices=[(-0.03, 0.02), (0.03, 0.02)])}
bl = {}
return util.AttrDict({"windscape": wS, "border_list": bl})
def get_env(Om=None, Pm=None):
dO = get_odorscape(m=Om) if Om is not None else {}
dW = get_windscape(m=Pm) if Pm is not None else {}
return reg.gen.Env(**dO, **dW)
def get_id(Om=None, Pm=None, Wm=None):
if Om is not None and Pm is None:
filename = f"{Om}_odorscape"
elif Om is None and Pm is not None:
filename = f"{Pm}_air-puffs_variable_wind_{Wm}"
else:
filename = f"{Om}_odorscape_{Pm}_air-puffs_variable_wind_{Wm}"
return filename
# New method
def run_scape(Om=None, Pm=None, Wm=None, duration=0.15, **kwargs):
def func1(model):
model.windscape.set_wind_direction((model.t / 10 / np.pi) % (2 * np.pi))
def func2(model):
model.windscape.wind_speed = model.t % 100
dic = {"direction": func1, "speed": func2}
func = dic[Wm] if Wm in dic.keys() else None
id = get_id(Om=Om, Pm=Pm, Wm=Wm)
env = get_env(Om=Om, Pm=Pm)
env.visualize(
duration=duration,
id=id,
screen_kws={
"vis_mode": "video",
"save_video": SAVE_MEDIA,
"media_dir": MEDIA_DIR,
"video_file": id,
},
func=func,
**kwargs,
)
if RUN_SINGLE_DEMO:
# Run single scape
run_scape(Om="Diffusion", Pm="repetitive", Wm="speed", duration=2)
if RUN_ALL_COMBINATIONS:
# Run all scape combinations
# exp='Wind&Odorscape visualization'
# exp='dish'
for Om in ["Gaussian", "Diffusion", None]:
for Pm in [None, "single", "repetitive", "no"]:
for Wm in [None, "direction", "speed", "no"]:
if Pm is None and Wm is not None:
continue
elif Pm is not None and Wm is None:
continue
elif Om is None and Pm is None:
continue
run_scape(Om=Om, Pm=Pm, Wm=Wm)
# print(conf.screen_kws.video_file)
if RUN_OLD_METHOD:
# Old method
def run_scape(Om=None, Pm=None, Wm=None, duration=0.3, **kwargs):
p = util.AttrDict({"env_params": get_env(Om=Om, Pm=Pm).nestedConf})
id = get_id(Om=Om, Pm=Pm, Wm=Wm)
conf = util.AttrDict(
{
"id": id,
"parameters": p,
"screen_kws": {
"vis_mode": "video",
"fps": 10,
"show_display": True,
"save_video": True,
"media_dir": "./media",
"video_file": id,
"odor_aura": True,
},
}
)
m = sim.base_run.BaseRun(
**conf, runtype="Exp", experiment="dish", duration=duration, **kwargs
)
m.build_env(m.p.env_params)
# print(m.p.steps)
m.sim_setup(steps=m.p.steps, seed=None)
if Om is not None:
m.odor_layers["Odor_L"].visible = True
# env.odor_layers['Odor_R'].visible = True
# env.screen_manager.odor_aura = True
if Pm is not None:
m.windscape.visible = True
while m.running:
if Wm == "direction":
m.windscape.set_wind_direction((m.t / 10 / np.pi) % (2 * np.pi))
elif Wm == "speed":
m.windscape.wind_speed = m.t % 100
m.sim_step()
m.end()
m.screen_manager.close()
from larvaworld.lib.model.envs import *
(
GaussianValueLayer.default_color,
WindScape.default_color,
DiffusionValueLayer.default_color,
ThermoScape.default_color,
)
# GaussianValueLayer.__bases__[0].default_color='yellow'
OdorScape().default_color, GaussianValueLayer().default_color
# OdorScape.default_color='grey'