Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions bonsai/Bonsai.config
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Packages>
<Package id="AllenNeuralDynamics.AindBehaviorServices" version="0.13.4" />
<Package id="AllenNeuralDynamics.AindBehaviorServices.Distributions" version="0.2.0" />
<Package id="AllenNeuralDynamics.AindManipulator" version="0.4.0" />
<Package id="AllenNeuralDynamics.AindManipulator" version="0.4.1" />
<Package id="AllenNeuralDynamics.AlicatFlowmeter" version="0.1.0" />
<Package id="AllenNeuralDynamics.Core" version="0.4.1" />
<Package id="AllenNeuralDynamics.Core.Design" version="0.4.0" />
Expand Down Expand Up @@ -114,7 +114,7 @@
<AssemblyLocations>
<AssemblyLocation assemblyName="AllenNeuralDynamics.AindBehaviorServices" processorArchitecture="MSIL" location="Packages/AllenNeuralDynamics.AindBehaviorServices.0.13.4/lib/net472/AllenNeuralDynamics.AindBehaviorServices.dll" />
<AssemblyLocation assemblyName="AllenNeuralDynamics.AindBehaviorServices.Distributions" processorArchitecture="MSIL" location="Packages/AllenNeuralDynamics.AindBehaviorServices.Distributions.0.2.0/lib/net472/AllenNeuralDynamics.AindBehaviorServices.Distributions.dll" />
<AssemblyLocation assemblyName="AllenNeuralDynamics.AindManipulator" processorArchitecture="MSIL" location="Packages/AllenNeuralDynamics.AindManipulator.0.4.0/lib/net48/AllenNeuralDynamics.AindManipulator.dll" />
<AssemblyLocation assemblyName="AllenNeuralDynamics.AindManipulator" processorArchitecture="MSIL" location="Packages/AllenNeuralDynamics.AindManipulator.0.4.1/lib/net48/AllenNeuralDynamics.AindManipulator.dll" />
<AssemblyLocation assemblyName="AllenNeuralDynamics.AlicatFlowmeter" processorArchitecture="MSIL" location="Packages/AllenNeuralDynamics.AlicatFlowmeter.0.1.0/lib/net472/AllenNeuralDynamics.AlicatFlowmeter.dll" />
<AssemblyLocation assemblyName="AllenNeuralDynamics.Core" processorArchitecture="MSIL" location="Packages/AllenNeuralDynamics.Core.0.4.1/lib/net472/AllenNeuralDynamics.Core.dll" />
<AssemblyLocation assemblyName="AllenNeuralDynamics.Core.Design" processorArchitecture="MSIL" location="Packages/AllenNeuralDynamics.Core.Design.0.4.0/lib/net472/AllenNeuralDynamics.Core.Design.dll" />
Expand Down
6 changes: 0 additions & 6 deletions examples/clabe.yml

This file was deleted.

64 changes: 44 additions & 20 deletions examples/olfactometer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,8 @@
from aind_behavior_device_olfactometer import rig, task_logic
from aind_behavior_device_olfactometer.rig import AlicatFlowmeter

olf_calibration = olf.OlfactometerCalibration(
channel_config={
olf.OlfactometerChannel.Channel0: olf.OlfactometerChannelConfig(
channel_index=olf.OlfactometerChannel.Channel0,
channel_type=olf.OlfactometerChannelType.ODOR,
flow_rate=100,
odorant="Banana",
odorant_dilution=0.1,
),
olf.OlfactometerChannel.Channel3: olf.OlfactometerChannelConfig(
channel_index=olf.OlfactometerChannel.Channel3,
channel_type=olf.OlfactometerChannelType.CARRIER,
odorant="Air",
),
}
)


calibration_logic = task_logic.OlfactometerCalibrationLogic(
task_parameters=task_logic.OlfactometerCalibrationParameters(
channel_config=olf_calibration.channel_config,
full_flow_rate=1000,
n_repeats_per_stimulus=10,
time_on=2,
Expand Down Expand Up @@ -57,11 +38,54 @@
initial_position=man.ManipulatorPosition(y1=0, y2=0, x=0, z=0),
)


olf_calibration = olf.OlfactometerCalibration(
channel_config={
olf.OlfactometerChannel.Channel0: olf.OlfactometerChannelConfig(
channel_index=olf.OlfactometerChannel.Channel0,
channel_type=olf.OlfactometerChannelType.ODOR,
flow_rate=100,
odorant="Banana",
odorant_dilution=0.1,
),
olf.OlfactometerChannel.Channel1: olf.OlfactometerChannelConfig(
channel_index=olf.OlfactometerChannel.Channel1,
channel_type=olf.OlfactometerChannelType.ODOR,
flow_rate=100,
odorant="None",
odorant_dilution=0.0,
),
olf.OlfactometerChannel.Channel2: olf.OlfactometerChannelConfig(
channel_index=olf.OlfactometerChannel.Channel2,
channel_type=olf.OlfactometerChannelType.ODOR,
flow_rate=100,
odorant="None",
odorant_dilution=0.0,
),
olf.OlfactometerChannel.Channel3: olf.OlfactometerChannelConfig(
channel_index=olf.OlfactometerChannel.Channel3,
channel_type=olf.OlfactometerChannelType.CARRIER,
odorant="Air",
flow_rate_capacity=1000,
),
}
)

extra_olf = olf_calibration.model_copy(deep=True)
extra_olf.channel_config[olf.OlfactometerChannel.Channel3] = olf.OlfactometerChannelConfig(
channel_index=olf.OlfactometerChannel.Channel3,
channel_type=olf.OlfactometerChannelType.ODOR,
flow_rate=100,
odorant="Vanilla",
)

print(olf_calibration)
_rig = rig.OlfactometerCalibrationRig(
computer_name="TestPC",
data_directory="c:/data",
data_directory=r"C:/data",
rig_name="OlfactometerRig",
harp_olfactometer=olf.Olfactometer(port_name="COM10", calibration=olf_calibration),
harp_olfactometer_extension=[olf.Olfactometer(port_name="COM11", calibration=extra_olf)],
harp_analog_input=HarpAnalogInput(port_name="COM8"),
harp_clock_generator=HarpWhiteRabbit(port_name="COM9"),
harp_manipulator=man.AindManipulator(port_name="COM7", calibration=manipulator_calibration),
Expand Down
29 changes: 13 additions & 16 deletions schema/aind_behavior_device_olfactometer.json
Original file line number Diff line number Diff line change
Expand Up @@ -675,22 +675,11 @@
"title": "Rng Seed"
},
"aind_behavior_services_pkg_version": {
"default": "0.13.6",
"default": "0.13.7",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
"title": "aind_behavior_services package version",
"type": "string"
},
"channel_config": {
"additionalProperties": {
"$ref": "#/$defs/OlfactometerChannelConfig"
},
"description": "Configuration of olfactometer channels",
"propertyNames": {
"$ref": "#/$defs/OlfactometerChannel"
},
"title": "Channel Config",
"type": "object"
},
"full_flow_rate": {
"default": 1000,
"description": "Full flow rate of the olfactometer",
Expand Down Expand Up @@ -727,7 +716,7 @@
"OlfactometerCalibrationRig": {
"properties": {
"aind_behavior_services_pkg_version": {
"default": "0.13.6",
"default": "0.13.7",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
"title": "aind_behavior_services package version",
"type": "string"
Expand Down Expand Up @@ -758,6 +747,14 @@
"$ref": "#/$defs/Olfactometer",
"title": "Olfactometer device"
},
"harp_olfactometer_extension": {
"description": "A collection of subordinate olfactometers that can be added to increase the number of independently delivered odors. The order of the list determines the order by which odors are numbered",
"items": {
"$ref": "#/$defs/Olfactometer"
},
"title": "Harp Olfactometer Extension",
"type": "array"
},
"harp_analog_input": {
"$ref": "#/$defs/HarpAnalogInput",
"title": "Analog input device"
Expand Down Expand Up @@ -882,14 +879,14 @@
"Session": {
"properties": {
"aind_behavior_services_pkg_version": {
"default": "0.13.6",
"default": "0.13.7",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
"title": "aind_behavior_services package version",
"type": "string"
},
"version": {
"const": "0.13.6",
"default": "0.13.6",
"const": "0.13.7",
"default": "0.13.7",
"title": "Version",
"type": "string"
},
Expand Down
61 changes: 24 additions & 37 deletions scripts/aind_launcher.py → scripts/aind-launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
from clabe.data_transfer.robocopy import RobocopyService, RobocopySettings
from clabe.launcher import Launcher, LauncherCliArgs, experiment
from clabe.pickers import DefaultBehaviorPicker, DefaultBehaviorPickerSettings
from clabe.utils import utcnow
from pydantic_settings import CliApp

from aind_behavior_device_olfactometer.rig import OlfactometerCalibrationRig
from aind_behavior_device_olfactometer.task_logic import OlfactometerCalibrationLogic
from aind_behavior_device_olfactometer.task_logic import OlfactometerCalibrationLogic, OlfactometerCalibrationParameters

logger = logging.getLogger(__name__)

Expand All @@ -25,13 +26,30 @@ async def calibration_experiment(launcher: Launcher) -> None:
settings=DefaultBehaviorPickerSettings(
config_library_dir=r"\\allen\aind\scratch\AindBehavior.db\AindBehaviorDeviceOlfactometer",
),
experimenter_validator=None,
)
experimenter = picker.prompt_experimenter()
assert experimenter is not None and len(experimenter) > 0, (
"Experimenter selection is required to proceed with the experiment setup."
)
# Pick and register session
session = Session(
subject="CALIBRATION",
experiment="CALIBRATION",
date=utcnow(),
allow_dirty_repo=False,
experimenter=experimenter,
notes="Session for rig calibration. No actual experiment data will be recorded.",
)

task_logic = OlfactometerCalibrationLogic(task_parameters=OlfactometerCalibrationParameters())
launcher.ui_helper.print(f"Loading task logic with default parameters: {task_logic.task_parameters}")
skip_manual_task = launcher.ui_helper.prompt_yes_no_question(
"Skip manual task parameter configuration and use defaults?"
)
if not skip_manual_task:
task_logic = picker.pick_task(OlfactometerCalibrationLogic)

session = picker.pick_session(Session)
task_logic = picker.pick_task(OlfactometerCalibrationLogic)
rig = picker.pick_rig(OlfactometerCalibrationRig)
ensure_rig_and_computer_name(rig)

launcher.register_session(session, rig.data_directory)

Expand Down Expand Up @@ -67,7 +85,7 @@ async def calibration_experiment(launcher: Launcher) -> None:
runner.run_all_with_progress(reporter=reporter)
webbrowser.open(qc_path.as_uri(), new=2)
except Exception as e:
logger.error(f"Failed to run data QC: {e}")
logger.error("Failed to run data QC: %s", e)

# Transfer data
is_transfer = picker.ui_helper.prompt_yes_no_question("Would you like to transfer data?")
Expand All @@ -80,37 +98,6 @@ async def calibration_experiment(launcher: Launcher) -> None:
return


def ensure_rig_and_computer_name(rig: OlfactometerCalibrationRig) -> None:
"""Ensures rig and computer name are set from environment variables if available, otherwise defaults to rig configuration values."""

import os

rig_name = os.environ.get("aibs_comp_id", None)
computer_name = os.environ.get("hostname", None)

if rig_name is None:
logger.warning(
"'aibs_comp_id' environment variable not set. Defaulting to rig name from configuration. %s", rig.rig_name
)
rig_name = rig.rig_name
if computer_name is None:
computer_name = rig.computer_name
logger.warning(
"'hostname' environment variable not set. Defaulting to computer name from configuration. %s",
rig.computer_name,
)

if rig_name != rig.rig_name or computer_name != rig.computer_name:
logger.warning(
"Rig name or computer name from environment variables do not match the rig configuration. "
"Forcing rig name: %s and computer name: %s from environment variables.",
rig_name,
computer_name,
)
rig.rig_name = rig_name
rig.computer_name = computer_name


class ClabeCli(LauncherCliArgs):
def cli_cmd(self):
launcher = Launcher(settings=self)
Expand Down
3 changes: 2 additions & 1 deletion src/Extensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Bonsai.Core" Version="2.8.1" />
<PackageReference Include="Bonsai.Core" Version="2.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Bonsai.Harp" Version="3.6.1" />
<PackageReference Include="AllenNeuralDynamics.AindBehaviorServices" Version="0.13.4" />
<PackageReference Include="AllenNeuralDynamics.AindBehaviorServices.Distributions" Version="0.2.0" />
<PackageReference Include="AllenNeuralDynamics.AindManipulator" Version="0.3.0" />
<PackageReference Include="Harp.Olfactometer" Version="0.4.0" />
</ItemGroup>

</Project>
Loading
Loading