Reference#
cleo module#
- class cleo.CLSimulator(network: brian2.core.network.Network)[source]#
Bases:
cleo.base.NeoExportable
The centerpiece of cleo. Integrates simulation components and runs.
Method generated by attrs for class CLSimulator.
- devices: set[cleo.base.InterfaceDevice]#
- get_state() dict [source]#
Return current recorder measurements.
- Returns
A dictionary of name: state pairs for all recorders in the simulator.
- Return type
dict
- inject(device: cleo.base.InterfaceDevice, *neuron_groups: brian2.groups.neurongroup.NeuronGroup, **kwparams: Any) cleo.base.CLSimulator [source]#
Inject InterfaceDevice into the network, connecting to specified neurons.
Calls
connect_to_neuron_group()
for each group with kwparams and adds the device’sbrian_objects
to the simulator’snetwork
.- Parameters
device (InterfaceDevice) – Device to inject
- Returns
self
- Return type
- io_processor: cleo.base.IOProcessor#
- network: brian2.core.network.Network#
The Brian network forming the core model
- recorders: dict[str, cleo.base.Recorder]#
- reset(**kwargs)[source]#
Reset the simulator to a neutral state
Restores the Brian Network to where it was when the CLSimulator was last modified (last injection, IOProcessor change). Calls reset() on devices and IOProcessor.
- run(duration: brian2.units.fundamentalunits.Quantity, **kwparams) None [source]#
Run simulation.
- Parameters
duration (brian2 temporal Quantity) – Length of simulation
**kwparams (additional arguments passed to brian2.run()) – level has a default value of 1
- set_io_processor(io_processor, communication_period=None) cleo.base.CLSimulator [source]#
Set simulator IO processor
Will replace any previous IOProcessor so there is only one at a time. A Brian NetworkOperation is created to govern communication between the Network and the IOProcessor.
- Parameters
io_processor (IOProcessor) –
- Returns
self
- Return type
- stimulators: dict[str, cleo.base.Stimulator]#
- to_neo() neo.core.block.Block [source]#
Return a neo.core.AnalogSignal object with the device’s data
- Returns
Neo object representing exported data
- Return type
neo.core.BaseNeo
- update_stimulators(ctrl_signals) None [source]#
Update stimulators with output from the
IOProcessor
- Parameters
ctrl_signals (dict) – {stimulator_name: ctrl_signal} dictionary with values to update each stimulator.
- class cleo.IOProcessor[source]#
Bases:
abc.ABC
Abstract class for implementing sampling, signal processing and control
This must be implemented by the user with their desired closed-loop use case, though most users will find the
LatencyIOProcessor()
class more useful, since delay handling is already defined.- abstract get_ctrl_signal(time) dict [source]#
Get per-stimulator control signal from the
IOProcessor
.- Parameters
time (Brian 2 temporal Unit) – Current timestep
- Returns
A {‘stimulator_name’: value} dictionary for updating stimulators.
- Return type
dict
- abstract is_sampling_now(time) bool [source]#
Determines whether the processor will take a sample at this timestep.
- Parameters
time (Brian 2 temporal Unit) – Current timestep.
- Return type
bool
- abstract put_state(state_dict: dict, time) None [source]#
Deliver network state to the
IOProcessor
.- Parameters
state_dict (dict) – A dictionary of recorder measurements, as returned by
get_state()
time (brian2 temporal Unit) – The current simulation timestep. Essential for simulating control latency and for time-varying control.
- sample_period_ms: float#
Determines how frequently the processor takes samples
- class cleo.InterfaceDevice(*, name: str = NOTHING)[source]#
Bases:
abc.ABC
Base class for devices to be injected into the network
Method generated by attrs for class InterfaceDevice.
- add_self_to_plot(ax: mpl_toolkits.mplot3d.axes3d.Axes3D, axis_scale_unit: brian2.units.fundamentalunits.Unit, **kwargs) list[matplotlib.artist.Artist] [source]#
Add device to an existing plot
Should only be called by
plot()
.- Parameters
ax (Axes3D) – The existing matplotlib Axes object
axis_scale_unit (Unit) – The unit used to label axes and define chart limits
**kwargs (optional) –
- Returns
A list of artists used to render the device. Needed for use in conjunction with
VideoVisualizer
.- Return type
list[Artist]
- brian_objects: set#
All the Brian objects added to the network by this device. Must be kept up-to-date in
connect_to_neuron_group()
and other functions so that those objects can be automatically added to the network when the device is injected.
- abstract connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams) None [source]#
Connect device to given neuron_group.
If your device introduces any objects which Brian must keep track of, such as a NeuronGroup, Synapses, or Monitor, make sure to add these to self.brian_objects.
- Parameters
neuron_group (NeuronGroup) –
**kwparams (optional, passed from inject or) – inject
- init_for_simulator(simulator: cleo.base.CLSimulator) None [source]#
Initialize device for simulator on initial injection
This function is called only the first time a device is injected into a simulator and performs any operations that are independent of the individual neuron groups it is connected to.
- Parameters
simulator (CLSimulator) – simulator being injected into
- name: str#
Unique identifier for device, used in sampling, plotting, etc. Name of the class by default.
- sim: cleo.base.CLSimulator#
The simulator the device is injected into
- update_artists(artists: list[matplotlib.artist.Artist], *args, **kwargs) list[matplotlib.artist.Artist] [source]#
Update the artists used to render the device
Used to set the artists’ state at every frame of a video visualization. The current state would be passed in *args or **kwargs
- Parameters
artists (list[Artist]) – the artists used to render the device originally, i.e., which were returned from the first
add_self_to_plot()
call.- Returns
The artists that were actually updated. Needed for efficient blit rendering, where only updated artists are re-rendered.
- Return type
list[Artist]
- class cleo.Recorder(*, name: str = NOTHING)[source]#
Bases:
cleo.base.InterfaceDevice
Device for taking measurements of the network.
Method generated by attrs for class Recorder.
- class cleo.Stimulator(default_value: Any = 0, save_history: bool = True, *, name: str = NOTHING)[source]#
Bases:
cleo.base.InterfaceDevice
,cleo.base.NeoExportable
Device for manipulating the network
Method generated by attrs for class Stimulator.
- t_ms: list[float]#
Times stimulator was updated, stored if
save_history
- to_neo()[source]#
Return a neo.core.AnalogSignal object with the device’s data
- Returns
Neo object representing exported data
- Return type
neo.core.BaseNeo
- update(ctrl_signal) None [source]#
Set the stimulator value.
By default this simply sets value to ctrl_signal. You will want to implement this method if your stimulator requires additional logic. Use super.update(self, value) to preserve the self.value attribute logic
- Parameters
ctrl_signal (any) – The value the stimulator is to take.
- value: Any#
The current value of the stimulator device
- values: list[Any]#
Values taken by the stimulator at each
update()
call, stored ifsave_history
cleo.coords module#
Contains functions for assigning neuron coordinates and visualizing
- cleo.coords.assign_coords(neuron_group: brian2.groups.neurongroup.NeuronGroup, x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray, unit: brian2.units.fundamentalunits.Unit = mmetre)[source]#
Assign arbitrary coordinates to neuron group.
- Parameters
neuron_group (NeuronGroup) – neurons to be assigned coordinates
x (np.ndarray) – x positions to assign (preferably 1D with no unit)
y (np.ndarray) – y positions to assign (preferably 1D with no unit)
z (np.ndarray) – z positions to assign (preferably 1D with no unit)
unit (Unit, optional) – Brian unit determining what scale to use for coordinates, by default mm
- cleo.coords.assign_coords_grid_rect_prism(neuron_group: brian2.groups.neurongroup.NeuronGroup, xlim: Tuple[float, float], ylim: Tuple[float, float], zlim: Tuple[float, float], shape: Tuple[int, int, int], unit: brian2.units.fundamentalunits.Unit = mmetre) None [source]#
Assign grid coordinates to neurons in a rectangular grid
- Parameters
neuron_group (NeuronGroup) – The neuron group to assign coordinates to
xlim (Tuple[float, float]) – xmin, xmax, with no unit
ylim (Tuple[float, float]) – ymin, ymax, with no unit
zlim (Tuple[float, float]) – zmin, zmax with no unit
shape (Tuple[int, int, int]) – n_x, n_y, n_z tuple representing the shape of the resulting grid
unit (Unit, optional) – Brian unit determining what scale to use for coordinates, by default mm
- Raises
ValueError – When the shape is incompatible with the number of neurons in the group
- cleo.coords.assign_coords_rand_cylinder(neuron_group: brian2.groups.neurongroup.NeuronGroup, xyz_start: Tuple[float, float, float], xyz_end: Tuple[float, float, float], radius: float, unit: brian2.units.fundamentalunits.Unit = mmetre) None [source]#
Assign random coordinates within a cylinder.
- Parameters
neuron_group (NeuronGroup) – neurons to assign coordinates to
xyz_start (Tuple[float, float, float]) – starting position of cylinder without unit
xyz_end (Tuple[float, float, float]) – ending position of cylinder without unit
radius (float) – radius of cylinder without unit
unit (Unit, optional) – Brian unit to scale other params, by default mm
- cleo.coords.assign_coords_rand_rect_prism(neuron_group: brian2.groups.neurongroup.NeuronGroup, xlim: Tuple[float, float], ylim: Tuple[float, float], zlim: Tuple[float, float], unit: brian2.units.fundamentalunits.Unit = mmetre) None [source]#
Assign random coordinates to neurons within a rectangular prism
- Parameters
neuron_group (NeuronGroup) – neurons to assign coordinates to
xlim (Tuple[float, float]) – xmin, xmax without unit
ylim (Tuple[float, float]) – ymin, ymax without unit
zlim (Tuple[float, float]) – zmin, zmax without unit
unit (Unit, optional) – Brian unit to specify scale implied in limits, by default mm
- cleo.coords.assign_coords_uniform_cylinder(neuron_group: brian2.groups.neurongroup.NeuronGroup, xyz_start: Tuple[float, float, float], xyz_end: Tuple[float, float, float], radius: float, unit: brian2.units.fundamentalunits.Unit = mmetre) None [source]#
Assign uniformly spaced coordinates within a cylinder.
- Parameters
neuron_group (NeuronGroup) – neurons to assign coordinates to
xyz_start (Tuple[float, float, float]) – starting position of cylinder without unit
xyz_end (Tuple[float, float, float]) – ending position of cylinder without unit
radius (float) – radius of cylinder without unit
unit (Unit, optional) – Brian unit to scale other params, by default mm
cleo.ephys module#
Contains probes, coordinate convenience functions, signals, spiking, and LFP
- class cleo.ephys.MultiUnitSpiking(r_perfect_detection: brian2.units.fundamentalunits.Quantity, r_half_detection: brian2.units.fundamentalunits.Quantity, cutoff_probability: float = 0.01, save_history: bool = True, *, name: str = NOTHING)[source]#
Bases:
cleo.ephys.spiking.Spiking
Detects spikes per channel, that is, unsorted.
Method generated by attrs for class MultiUnitSpiking.
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams) None [source]#
Configure signal to record from specified neuron group
- Parameters
neuron_group (NeuronGroup) – group to record from
- get_state() tuple[NDArray[Any, ..., UInt[64]], NDArray[Any, ..., Float[64]], NDArray[Any, ..., UInt[64]]] [source]#
Return spikes since method was last called (i, t_ms, y)
- Returns
(i, t_ms, y) where i is channel (for multi-unit) or neuron (for sorted) spike indices, t_ms is spike times, and y is a spike count vector suitable for control- theoretic uses—i.e., a 0 for every channel/neuron that hasn’t spiked and a 1 for a single spike.
- Return type
tuple[NDArray[np.uint], NDArray[float], NDArray[np.uint]]
- to_neo() neo.core.group.Group [source]#
Return a neo.core.AnalogSignal object with the device’s data
- Returns
Neo object representing exported data
- Return type
neo.core.BaseNeo
- class cleo.ephys.Probe(coords: brian2.units.fundamentalunits.Quantity, signals: list[cleo.ephys.probes.Signal] = NOTHING, *, name: str = NOTHING)[source]#
Bases:
cleo.base.Recorder
,cleo.base.NeoExportable
Picks up specified signals across an array of electrodes.
- Visualization kwargs
marker (str, optional) – The marker used to represent each contact. “x” by default.
size (float, optional) – The size of each contact marker. 40 by default.
color (Any, optional) – The color of contact markers. “xkcd:dark gray” by default.
Method generated by attrs for class Probe.
- add_self_to_plot(ax: mpl_toolkits.mplot3d.axes3d.Axes3D, axis_scale_unit: brian2.units.fundamentalunits.Unit, **kwargs) list[matplotlib.artist.Artist] [source]#
Add device to an existing plot
Should only be called by
plot()
.- Parameters
ax (Axes3D) – The existing matplotlib Axes object
axis_scale_unit (Unit) – The unit used to label axes and define chart limits
**kwargs (optional) –
- Returns
A list of artists used to render the device. Needed for use in conjunction with
VideoVisualizer
.- Return type
list[Artist]
- add_signals(*signals: cleo.ephys.probes.Signal) None [source]#
Add signals to the probe for recording
- Parameters
*signals (Signal) – signals to add
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams: Any) None [source]#
Configure probe to record from given neuron group
Will call
Signal.connect_to_neuron_group()
for each signal- Parameters
neuron_group (NeuronGroup) – neuron group to connect to, i.e., record from
**kwparams (Any) – Passed in to signals’ connect functions, needed for some signals
- coords: Quantity#
Coordinates of n electrodes. Must be an n x 3 array (with unit) where columns represent x, y, and z
- get_state() dict [source]#
Get current state from probe, i.e., all signals
- Returns
{‘signal_name’: value} dict with signal states
- Return type
dict
- property n#
Number of electrode contacts in the probe
- signals: list[Signal]#
Signals recorded by the probe. Can be added to post-init with
add_signals()
.
- to_neo() neo.core.group.Group [source]#
Return a neo.core.AnalogSignal object with the device’s data
- Returns
Neo object representing exported data
- Return type
neo.core.BaseNeo
- property xs: brian2.units.fundamentalunits.Quantity#
x coordinates of recording contacts
- Returns
x coordinates represented as a Brian quantity, that is, including units. Should be like a 1D array.
- Return type
Quantity
- property ys: brian2.units.fundamentalunits.Quantity#
y coordinates of recording contacts
- Returns
y coordinates represented as a Brian quantity, that is, including units. Should be like a 1D array.
- Return type
Quantity
- property zs: brian2.units.fundamentalunits.Quantity#
z coordinates of recording contacts
- Returns
z coordinates represented as a Brian quantity, that is, including units. Should be like a 1D array.
- Return type
Quantity
- class cleo.ephys.Signal(*, name: str = NOTHING)[source]#
Bases:
abc.ABC
Base class representing something an electrode can record
Method generated by attrs for class Signal.
- brian_objects: set#
All Brian objects created by the signal. Must be kept up-to-date for automatic injection into the network
- abstract connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams)[source]#
Configure signal to record from specified neuron group
- Parameters
neuron_group (NeuronGroup) – group to record from
- init_for_probe(probe: cleo.ephys.probes.Probe) None [source]#
Called when attached to a probe.
Ensures signal can access probe and is only attached to one
- Parameters
probe (Probe) – Probe to attach to
- Raises
ValueError – When signal already attached to another probe
- name: str#
Unique identifier used to organize probe output. Name of the class by default.
- probe: cleo.ephys.probes.Probe#
The probe the signal is configured to record for.
- class cleo.ephys.SortedSpiking(r_perfect_detection: brian2.units.fundamentalunits.Quantity, r_half_detection: brian2.units.fundamentalunits.Quantity, cutoff_probability: float = 0.01, save_history: bool = True, *, name: str = NOTHING)[source]#
Bases:
cleo.ephys.spiking.Spiking
Detect spikes identified by neuron indices.
The indices used by the probe do not correspond to those coming from neuron groups, since the probe must consider multiple potential groups and within a group ignores those neurons that are too far away to be easily detected.
Method generated by attrs for class SortedSpiking.
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams) None [source]#
Configure sorted spiking signal to record from given neuron group
- Parameters
neuron_group (NeuronGroup) – group to record from
- get_state() tuple[NDArray[Any, ..., UInt[64]], NDArray[Any, ..., Float[64]], NDArray[Any, ..., UInt[64]]] [source]#
Return spikes since method was last called (i, t_ms, y)
- Returns
(i, t_ms, y) where i is channel (for multi-unit) or neuron (for sorted) spike indices, t_ms is spike times, and y is a spike count vector suitable for control- theoretic uses—i.e., a 0 for every channel/neuron that hasn’t spiked and a 1 for a single spike.
- Return type
tuple[NDArray[np.uint], NDArray[float], NDArray[np.uint]]
- class cleo.ephys.Spiking(r_perfect_detection: brian2.units.fundamentalunits.Quantity, r_half_detection: brian2.units.fundamentalunits.Quantity, cutoff_probability: float = 0.01, save_history: bool = True, *, name: str = NOTHING)[source]#
Bases:
cleo.ephys.probes.Signal
,cleo.base.NeoExportable
Base class for probabilistically detecting spikes
Method generated by attrs for class Spiking.
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams) numpy.ndarray [source]#
Configure signal to record from specified neuron group
- Parameters
neuron_group (NeuronGroup) – Neuron group to record from
- Returns
num_neurons_to_consider x num_channels array of spike detection probabilities, for use in subclasses
- Return type
np.ndarray
- cutoff_probability: float#
Spike detection probability below which neurons will not be considered. For computational efficiency.
- abstract get_state() tuple[NDArray[Any, ..., UInt[64]], NDArray[Any, ..., Float[64]], NDArray[Any, ..., UInt[64]]] [source]#
Return spikes since method was last called (i, t_ms, y)
- Returns
(i, t_ms, y) where i is channel (for multi-unit) or neuron (for sorted) spike indices, t_ms is spike times, and y is a spike count vector suitable for control- theoretic uses—i.e., a 0 for every channel/neuron that hasn’t spiked and a 1 for a single spike.
- Return type
tuple[NDArray[np.uint], NDArray[float], NDArray[np.uint]]
- i: NDArray[Any, np.uint]#
Channel (for multi-unit) or neuron (for sorted) indices of spikes, stored if
save_history
- i_probe_by_i_ng: bidict#
(neuron_group, i_ng) keys, i_probe values. bidict for converting between neuron group indices and the indices the probe uses
- r_half_detection: Quantity#
Radius (with Brian unit) within which half of all spikes are detected
- r_perfect_detection: Quantity#
Radius (with Brian unit) within which all spikes are detected
- t_ms: NDArray[Any, float]#
Spike times in ms, stored if
save_history
- t_samp_ms: NDArray[Any, float]#
Sample times in ms when each spike was recorded, stored if
save_history
- to_neo() neo.core.group.Group [source]#
Return a neo.core.AnalogSignal object with the device’s data
- Returns
Neo object representing exported data
- Return type
neo.core.BaseNeo
- class cleo.ephys.TKLFPSignal(uLFP_threshold_uV: float = 0.001, save_history: bool = True, *, name: str = NOTHING)[source]#
Bases:
cleo.ephys.probes.Signal
,cleo.base.NeoExportable
Records the Teleńczuk kernel LFP approximation.
Requires
tklfp_type='exc'|'inh'
to specify cell type on injection.An
orientation
keyword argument can also be specified on injection, which should be an array of shape(n_neurons, 3)
representing which way is “up,” that is, towards the surface of the cortex, for each neuron. If a single vector is given, it is taken to be the orientation for all neurons in the group. [0, 0, -1] is the default, meaning the negative z axis is “up.” As stated elsewhere, Cleo’s convention is that z=0 corresponds to the cortical surface and increasing z values represent increasing depth.TKLFP is computed from spikes using the tklfp package.
Method generated by attrs for class TKLFPSignal.
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams)[source]#
Configure signal to record from specified neuron group
- Parameters
neuron_group (NeuronGroup) – group to record from
- init_for_probe(probe: cleo.ephys.probes.Probe)[source]#
Called when attached to a probe.
Ensures signal can access probe and is only attached to one
- Parameters
probe (Probe) – Probe to attach to
- Raises
ValueError – When signal already attached to another probe
- lfp_uV: nptyping.types._ndarray.NDArray[Any, Any, nptyping.types._number.Float]#
Approximated LFP from every call to
get_state()
, recorded ifsave_history
. Shape is (n_samples, n_channels).
- save_history: bool#
Whether to record output from every timestep in
lfp_uV
. Output is stored every timeget_state()
is called.
- t_ms: nptyping.types._ndarray.NDArray[Any, nptyping.types._number.Float]#
Times at which LFP is recorded, in ms, stored if
save_history
- to_neo() neo.AnalogSignal [source]#
Return a neo.core.AnalogSignal object with the device’s data
- Returns
Neo object representing exported data
- Return type
neo.core.BaseNeo
- uLFP_threshold_uV: float#
Threshold, in microvolts, above which the uLFP for a single spike is guaranteed to be considered, by default 1e-3. This determines the buffer length of past spikes, since the uLFP from a long-past spike becomes negligible and is ignored.
- cleo.ephys.concat_coords(*coords: brian2.units.fundamentalunits.Quantity) brian2.units.fundamentalunits.Quantity [source]#
Combine multiple coordinate Quantity arrays into one
- Parameters
*coords (Quantity) – Multiple coordinate n x 3 Quantity arrays to combine
- Returns
A single n x 3 combined Quantity array
- Return type
Quantity
- cleo.ephys.linear_shank_coords(array_length: brian2.units.fundamentalunits.Quantity, channel_count: int, start_location: brian2.units.fundamentalunits.Quantity = array([0., 0., 0.]) * metre, direction: Tuple[float, float, float] = (0, 0, 1)) brian2.units.fundamentalunits.Quantity [source]#
Generate coordinates in a linear pattern
- Parameters
array_length (Quantity) – Distance from the first to the last contact (with a Brian unit)
channel_count (int) – Number of coordinates to generate, i.e. electrode contacts
start_location (Quantity, optional) – x, y, z coordinate (with unit) for the start of the electrode array, by default (0, 0, 0)*mm
direction (Tuple[float, float, float], optional) – x, y, z vector indicating the direction in which the array extends, by default (0, 0, 1), meaning pointing straight down
- Returns
channel_count x 3 array of coordinates, where the 3 columns represent x, y, and z
- Return type
Quantity
- cleo.ephys.poly2_shank_coords(array_length: brian2.units.fundamentalunits.Quantity, channel_count: int, intercol_space: brian2.units.fundamentalunits.Quantity, start_location: brian2.units.fundamentalunits.Quantity = array([0., 0., 0.]) * metre, direction: Tuple[float, float, float] = (0, 0, 1)) brian2.units.fundamentalunits.Quantity [source]#
Generate NeuroNexus-style Poly2 array coordinates
Poly2 refers to 2 parallel columns with staggered contacts. See https://www.neuronexus.com/products/electrode-arrays/up-to-15-mm-depth for more detail.
- Parameters
array_length (Quantity) – Length from the beginning to the end of the two-column array, as measured in the center
channel_count (int) – Total (not per-column) number of coordinates (recording contacts) desired
intercol_space (Quantity) – Distance between columns (with Brian unit)
start_location (Quantity, optional) – Where to place the beginning of the array, by default (0, 0, 0)*mm
direction (Tuple[float, float, float], optional) – x, y, z vector indicating the direction in which the two columns extend; by default (0, 0, 1), meaning straight down.
- Returns
channel_count x 3 array of coordinates, where the 3 columns represent x, y, and z
- Return type
Quantity
- cleo.ephys.poly3_shank_coords(array_length: brian2.units.fundamentalunits.Quantity, channel_count: int, intercol_space: brian2.units.fundamentalunits.Quantity, start_location: brian2.units.fundamentalunits.Quantity = array([0., 0., 0.]) * metre, direction: Tuple[float, float, float] = (0, 0, 1)) brian2.units.fundamentalunits.Quantity [source]#
Generate NeuroNexus Poly3-style array coordinates
Poly3 refers to three parallel columns of electrodes. The middle column will be longest if the channel count isn’t divisible by three and the side columns will be centered vertically with respect to the middle.
- Parameters
array_length (Quantity) – Length from beginning to end of the array as measured along the center column
channel_count (int) – Total (not per-column) number of coordinates to generate (i.e., electrode contacts)
intercol_space (Quantity) – Spacing between columns, with Brian unit
start_location (Quantity, optional) – Location of beginning of the array, that is, the first contact in the center column, by default (0, 0, 0)*mm
direction (Tuple[float, float, float], optional) – x, y, z vector indicating the direction along which the array extends, by default (0, 0, 1), meaning straight down
- Returns
channel_count x 3 array of coordinates, where the 3 columns represent x, y, and z
- Return type
Quantity
- cleo.ephys.tetrode_shank_coords(array_length: brian2.units.fundamentalunits.Quantity, tetrode_count: int, start_location: brian2.units.fundamentalunits.Quantity = array([0., 0., 0.]) * metre, direction: Tuple[float, float, float] = (0, 0, 1), tetrode_width: brian2.units.fundamentalunits.Quantity = 25. * umetre) brian2.units.fundamentalunits.Quantity [source]#
Generate coordinates for a linear array of tetrodes
See https://www.neuronexus.com/products/electrode-arrays/up-to-15-mm-depth to visualize NeuroNexus-style arrays.
- Parameters
array_length (Quantity) – Distance from the center of the first tetrode to the last (with a Brian unit)
tetrode_count (int) – Number of tetrodes desired
start_location (Quantity, optional) – Center location of the first tetrode in the array, by default (0, 0, 0)*mm
direction (Tuple[float, float, float], optional) – x, y, z vector determining the direction in which the linear array extends, by default (0, 0, 1), meaning straight down.
tetrode_width (Quantity, optional) – Distance between contacts in a single tetrode. Not the diagonal distance, but the length of one side of the square. By default 25*umeter, as in NeuroNexus probes.
- Returns
(tetrode_count*4) x 3 array of coordinates, where 3 columns represent x, y, and z
- Return type
Quantity
- cleo.ephys.tile_coords(coords: brian2.units.fundamentalunits.Quantity, num_tiles: int, tile_vector: brian2.units.fundamentalunits.Quantity) brian2.units.fundamentalunits.Quantity [source]#
Tile (repeat) coordinates to produce multi-shank/matrix arrays
- Parameters
coords (Quantity) – The n x 3 coordinates array to tile
num_tiles (int) – Number of times to tile (repeat) the coordinates. For example, if you are tiling linear shank coordinates to produce multi-shank coordinates, this would be the desired number of shanks
tile_vector (Quantity) – x, y, z array with Brian unit determining both the length and direction of the tiling
- Returns
(n * num_tiles) x 3 array of coordinates, where the 3 columns represent x, y, and z
- Return type
Quantity
cleo.opto module#
Contains opsin models, light sources, and some parameters
- class cleo.opto.BansalFourStateOpsin(action_spectrum: list[tuple[float, float]] = NOTHING, action_spectrum_interpolator: typing.Callable = <function cubic_interpolator>, extra_namespace: dict = NOTHING, Gd1: brian2.units.fundamentalunits.Quantity = 66. * hertz, Gd2: brian2.units.fundamentalunits.Quantity = 10. * hertz, Gr0: brian2.units.fundamentalunits.Quantity = 0.333 * hertz, g0: brian2.units.fundamentalunits.Quantity = 3.2 * nsiemens, phim: brian2.units.fundamentalunits.Quantity = 1.e+22 * metre ** -2 * second ** -1, k1: brian2.units.fundamentalunits.Quantity = 0.4 * khertz, k2: brian2.units.fundamentalunits.Quantity = 120. * hertz, Gf0: brian2.units.fundamentalunits.Quantity = 18. * hertz, Gb0: brian2.units.fundamentalunits.Quantity = 8. * hertz, kf: brian2.units.fundamentalunits.Quantity = 10. * hertz, kb: brian2.units.fundamentalunits.Quantity = 8. * hertz, gamma: brian2.units.fundamentalunits.Quantity = 0.05, p: brian2.units.fundamentalunits.Quantity = 1, q: brian2.units.fundamentalunits.Quantity = 1, E: brian2.units.fundamentalunits.Quantity = 0. * volt, *, name: str = NOTHING)[source]#
Bases:
cleo.opto.opsins.MarkovOpsin
4-state model from Bansal et al. 2020.
The difference from the PyRhO model is that there is no voltage dependence.
rho_rel is channel density relative to standard model fit; modifying it post-injection allows for heterogeneous opsin expression.
IOPTO_VAR_NAME and V_VAR_NAME are substituted on injection.
Method generated by attrs for class BansalFourStateOpsin.
- E: Quantity#
- Gb0: Quantity#
- Gd1: Quantity#
- Gd2: Quantity#
- Gf0: Quantity#
- Gr0: Quantity#
- g0: Quantity#
- gamma: Quantity#
- init_opto_syn_vars(opto_syn: brian2.synapses.synapses.Synapses) None [source]#
Initializes appropriate variables in Synapses implementing the model
Can also be used to reset the variables.
- Parameters
opto_syn (Synapses) – The synapses object implementing this model
- k1: Quantity#
- k2: Quantity#
- kb: Quantity#
- kf: Quantity#
- model: str#
Basic Brian model equations string.
Should contain a rho_rel term reflecting relative expression levels. Will likely also contain special NeuronGroup-dependent symbols such as V_VAR_NAME to be replaced on injection in
modify_model_and_params_for_ng()
.
- p: Quantity#
- phim: Quantity#
- q: Quantity#
- class cleo.opto.FiberModel(R0: brian2.units.fundamentalunits.Quantity = 100. * umetre, NAfib: brian2.units.fundamentalunits.Quantity = 0.37, wavelength: brian2.units.fundamentalunits.Quantity = 0.473 * umetre, K: brian2.units.fundamentalunits.Quantity = 125. * metre ** - 1, S: brian2.units.fundamentalunits.Quantity = 7370. * metre ** - 1, ntis: brian2.units.fundamentalunits.Quantity = 1.36)[source]#
Bases:
cleo.opto.light.LightModel
Optic fiber light model from Foutz et al., 2012.
Defaults are from paper for 473 nm wavelength.
Method generated by attrs for class FiberModel.
- K: brian2.units.fundamentalunits.Quantity#
absorbance coefficient (wavelength/tissue dependent)
- NAfib: brian2.units.fundamentalunits.Quantity#
optical fiber numerical aperture
- R0: brian2.units.fundamentalunits.Quantity#
optical fiber radius
- S: brian2.units.fundamentalunits.Quantity#
scattering coefficient (wavelength/tissue dependent)
- model = '\n Irr = Irr0*T : watt/meter**2\n Irr0 : watt/meter**2 \n T : 1\n phi = Irr / Ephoton : 1/second/meter**2\n '#
- ntis: brian2.units.fundamentalunits.Quantity#
tissue index of refraction (wavelength/tissue dependent)
- transmittance(source_coords: brian2.units.fundamentalunits.Quantity, source_dir_uvec: nptyping.types._ndarray.NDArray[Any, 3, Any], target_coords: brian2.units.fundamentalunits.Quantity) nptyping.types._ndarray.NDArray[Any, Any, nptyping.types._number.Float] [source]#
Output must be between 0 and shape (n_sources, n_targets).
- viz_points(coords: brian2.units.fundamentalunits.Quantity, direction: nptyping.types._ndarray.NDArray[Any, 3, Any], n_points_per_source: int, T_threshold: float, **kwargs) brian2.units.fundamentalunits.Quantity [source]#
Outputs m x n_points_per_source x 3 array
- wavelength: brian2.units.fundamentalunits.Quantity#
light wavelength
- class cleo.opto.FourStateOpsin(action_spectrum: list[tuple[float, float]] = NOTHING, action_spectrum_interpolator: typing.Callable = <function cubic_interpolator>, g0: brian2.units.fundamentalunits.Quantity = 114. * nsiemens, gamma: brian2.units.fundamentalunits.Quantity = 0.00742, phim: brian2.units.fundamentalunits.Quantity = 2.33e+23 * metre ** -2 * second ** -1, k1: brian2.units.fundamentalunits.Quantity = 4.15 * khertz, k2: brian2.units.fundamentalunits.Quantity = 0.868 * khertz, p: brian2.units.fundamentalunits.Quantity = 0.833, Gf0: brian2.units.fundamentalunits.Quantity = 37.3 * hertz, kf: brian2.units.fundamentalunits.Quantity = 58.1 * hertz, Gb0: brian2.units.fundamentalunits.Quantity = 16.1 * hertz, kb: brian2.units.fundamentalunits.Quantity = 63. * hertz, q: brian2.units.fundamentalunits.Quantity = 1.94, Gd1: brian2.units.fundamentalunits.Quantity = 105. * hertz, Gd2: brian2.units.fundamentalunits.Quantity = 13.8 * hertz, Gr0: brian2.units.fundamentalunits.Quantity = 0.33 * hertz, E: brian2.units.fundamentalunits.Quantity = 0. * volt, v0: brian2.units.fundamentalunits.Quantity = 43. * mvolt, v1: brian2.units.fundamentalunits.Quantity = 17.1 * mvolt, *, name: str = NOTHING)[source]#
Bases:
cleo.opto.opsins.MarkovOpsin
4-state model from PyRhO (Evans et al. 2016).
rho_rel is channel density relative to standard model fit; modifying it post-injection allows for heterogeneous opsin expression.
IOPTO_VAR_NAME and V_VAR_NAME are substituted on injection.
Defaults are for ChR2.
Method generated by attrs for class FourStateOpsin.
- E: Quantity#
- Gb0: Quantity#
- Gd1: Quantity#
- Gd2: Quantity#
- Gf0: Quantity#
- Gr0: Quantity#
- extra_namespace: dict[str, Any]#
Additional items (beyond parameters) to be added to the opto synapse namespace
- g0: Quantity#
- gamma: Quantity#
- init_opto_syn_vars(opto_syn: brian2.synapses.synapses.Synapses) None [source]#
Initializes appropriate variables in Synapses implementing the model
Can also be used to reset the variables.
- Parameters
opto_syn (Synapses) – The synapses object implementing this model
- k1: Quantity#
- k2: Quantity#
- kb: Quantity#
- kf: Quantity#
- model: str#
Basic Brian model equations string.
Should contain a rho_rel term reflecting relative expression levels. Will likely also contain special NeuronGroup-dependent symbols such as V_VAR_NAME to be replaced on injection in
modify_model_and_params_for_ng()
.
- p: Quantity#
- phim: Quantity#
- q: Quantity#
- v0: Quantity#
- v1: Quantity#
- class cleo.opto.Light(save_history: bool = True, coords=array([0., 0., 0.]) * metre, direction: brian2.units.fundamentalunits.Quantity = (0, 0, 1), *, name: str = NOTHING, light_model: cleo.opto.light.LightModel, max_Irr0_mW_per_mm2: Optional[float] = None, max_Irr0_mW_per_mm2_viz: Optional[float] = None, default_value: nptyping.types._ndarray.NDArray[Any, nptyping.types._number.Float] = NOTHING)[source]#
Bases:
cleo.base.Stimulator
Delivers photostimulation of the network.
Essentially “transfects” neurons and provides a light source. Under the hood, it delivers current via a Brian
Synapses
object.Requires neurons to have 3D spatial coordinates already assigned. Also requires that the neuron model has a current term (by default Iopto) which is assumed to be positive (unlike the convention in many opsin modeling papers, where the current is described as negative).
See
connect_to_neuron_group()
for optional keyword parameters that can be specified when callingcleo.CLSimulator.inject()
.- Visualization kwargs
n_points_per_source (int, optional) – The number of points per light source used to represent light intensity in space. By default 1e4. Alias
n_points
.T_threshold (float, optional) – The transmittance below which no points are plotted. By default 1e-3.
intensity (float, optional) – How bright the light appears, should be between 0 and 1. By default 0.5.
rasterized (bool, optional) – Whether to render as rasterized in vector output, True by default. Useful since so many points makes later rendering and editing slow.
Method generated by attrs for class Light.
- add_self_to_plot(ax, axis_scale_unit, **kwargs) list[matplotlib.collections.PathCollection] [source]#
Add device to an existing plot
Should only be called by
plot()
.- Parameters
ax (Axes3D) – The existing matplotlib Axes object
axis_scale_unit (Unit) – The unit used to label axes and define chart limits
**kwargs (optional) –
- Returns
A list of artists used to render the device. Needed for use in conjunction with
VideoVisualizer
.- Return type
list[Artist]
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams: Any) None [source]#
Connect device to given neuron_group.
If your device introduces any objects which Brian must keep track of, such as a NeuronGroup, Synapses, or Monitor, make sure to add these to self.brian_objects.
- Parameters
neuron_group (NeuronGroup) –
**kwparams (optional, passed from inject or) – inject
- coords: Quantity#
(x, y, z) coords with Brian unit specifying where to place the base of the light source, by default (0, 0, 0)*mm. Can also be an nx3 array for multiple sources.
- default_value: NDArray[Any, float]#
The default value of the device—used on initialization and on
reset()
- direction: NDArray[Any, 3, Any]#
(x, y, z) vector specifying direction in which light source is pointing, by default (0, 0, 1).
Will be converted to unit magnitude.
- init_for_simulator(sim: CLSimulator) None [source]#
Initialize device for simulator on initial injection
This function is called only the first time a device is injected into a simulator and performs any operations that are independent of the individual neuron groups it is connected to.
- Parameters
simulator (CLSimulator) – simulator being injected into
- light_model: LightModel#
LightModel object defining how light is emitted. See
FiberModel
for an example.
- max_Irr0_mW_per_mm2: float#
The maximum irradiance the light source can emit.
Usually determined by hardware in a real experiment.
- max_Irr0_mW_per_mm2_viz: float#
Maximum irradiance for visualization purposes.
i.e., the level at or above which the light appears maximally bright. Only relevant in video visualization.
- property n#
Number of light sources
- property source: brian2.groups.subgroup.Subgroup#
- to_neo()[source]#
Return a neo.core.AnalogSignal object with the device’s data
- Returns
Neo object representing exported data
- Return type
neo.core.BaseNeo
- update(Irr0_mW_per_mm2: Union[float, numpy.ndarray]) None [source]#
Set the light intensity, in mW/mm2 (without unit)
- Parameters
Irr0_mW_per_mm2 (float) – Desired light intensity for light source
- update_artists(artists: list[matplotlib.artist.Artist], value, *args, **kwargs) list[matplotlib.artist.Artist] [source]#
Update the artists used to render the device
Used to set the artists’ state at every frame of a video visualization. The current state would be passed in *args or **kwargs
- Parameters
artists (list[Artist]) – the artists used to render the device originally, i.e., which were returned from the first
add_self_to_plot()
call.- Returns
The artists that were actually updated. Needed for efficient blit rendering, where only updated artists are re-rendered.
- Return type
list[Artist]
- class cleo.opto.LightModel(wavelength: brian2.units.fundamentalunits.Quantity)[source]#
Bases:
abc.ABC
Method generated by attrs for class LightModel.
- abstract transmittance(source_coords: brian2.units.fundamentalunits.Quantity, source_direction: nptyping.types._ndarray.NDArray[Any, 3, Any], target_coords: brian2.units.fundamentalunits.Quantity) nptyping.types._ndarray.NDArray[Any, Any, nptyping.types._number.Float] [source]#
Output must be between 0 and shape (n_sources, n_targets).
- abstract viz_points(coords: brian2.units.fundamentalunits.Quantity, direction: nptyping.types._ndarray.NDArray[Any, 3, Any], n_points_per_source: int, T_threshold: float, **kwargs) brian2.units.fundamentalunits.Quantity [source]#
Outputs m x n_points_per_source x 3 array
- wavelength: brian2.units.fundamentalunits.Quantity#
light wavelength
- class cleo.opto.LightOpsinRegistry(sim: cleo.base.CLSimulator)[source]#
Bases:
object
Facilitates the creation and maintenance of ‘neurons’ and ‘synapses’ implementing many-to-many light-opsin optogenetics
Method generated by attrs for class LightOpsinRegistry.
- connections: set[Tuple['Light', 'Opsin', NeuronGroup]]#
- light_prop_model = '\n T : 1\n epsilon : 1\n Ephoton : joule\n Irr_post = epsilon * T * Irr0_pre : watt/meter**2 (summed)\n phi_post = Irr_post / Ephoton : 1/second/meter**2 (summed)\n # phi_post = epsilon * T * Irr0_pre / Ephoton : 1/second/meter**2 (summed)\n '#
- light_prop_syns: dict[Tuple['Opsin', NeuronGroup], Synapses]#
- light_source_ng: NeuronGroup#
Represents ALL light sources (multiple devices)
- lights_for_ng: dict[NeuronGroup, set['Light']]#
- opsins_for_ng: dict[NeuronGroup, set['Opsin']]#
- register_light(light: Light, ng: NeuronGroup)[source]#
Connects light to opsins already injected into this neuron group
- register_opsin(opsin: Opsin, ng: NeuronGroup)[source]#
Connects lights previously injected into this neuron group to this opsin
- sim: CLSimulator#
- subgroup_idx_for_light: dict['Light', slice]#
- class cleo.opto.Opsin(action_spectrum: list[tuple[float, float]] = NOTHING, action_spectrum_interpolator: typing.Callable = <function cubic_interpolator>, extra_namespace: dict = NOTHING, *, name: str = NOTHING)[source]#
Bases:
cleo.base.InterfaceDevice
Base class for opsin model.
We approximate dynamics under multiple wavelengths using a weighted sum of photon fluxes, where the \(\varepsilon\) factor indicates the activation relative to the peak-sensitivy wavelength for an equivalent number of photons (see Mager et al, 2018). This weighted sum is an approximation of a nonlinear peak-non-peak wavelength relation; see notebooks/multi_wavelength_model.ipynb for details.
Method generated by attrs for class Opsin.
- action_spectrum: list[tuple[float, float]]#
List of (wavelength, epsilon) tuples representing the action spectrum.
- action_spectrum_interpolator: Callable#
Function of signature (lambdas_nm, epsilons, lambda_new_nm) that interpolates the action spectrum data and returns \(\varepsilon \in [0,1]\) for the new wavelength.
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams) None [source]#
Transfect neuron group with opsin.
- Parameters
neuron_group (NeuronGroup) – The neuron group to stimulate with the given opsin and light source
- Keyword Arguments
p_expression (float) – Probability (0 <= p <= 1) that a given neuron in the group will express the opsin. 1 by default.
rho_rel (float) – The expression level, relative to the standard model fit, of the opsin. 1 by default. For heterogeneous expression, this would have to be modified in the opsin synapse post-injection, e.g.,
opto.opto_syns["neuron_group_name"].rho_rel = ...
Iopto_var_name (str) – The name of the variable in the neuron group model representing current from the opsin
v_var_name (str) – The name of the variable in the neuron group model representing membrane potential
- epsilon(lambda_new) float [source]#
Returns the epsilon value for a given lambda (in nm) representing the relative sensitivity of the opsin to that wavelength.
- extra_namespace: dict#
Additional items (beyond parameters) to be added to the opto synapse namespace
- init_opto_syn_vars(opto_syn: brian2.synapses.synapses.Synapses) None [source]#
Initializes appropriate variables in Synapses implementing the model
Can also be used to reset the variables.
- Parameters
opto_syn (Synapses) – The synapses object implementing this model
- light_agg_ngs: dict[str, NeuronGroup]#
light_agg_ng} dict of light aggregator neuron groups.
- Type
{target_ng.name
- model: str#
Basic Brian model equations string.
Should contain a rho_rel term reflecting relative expression levels. Will likely also contain special NeuronGroup-dependent symbols such as V_VAR_NAME to be replaced on injection in
modify_model_and_params_for_ng()
.
- modify_model_and_params_for_ng(neuron_group: brian2.groups.neurongroup.NeuronGroup, injct_params: dict) Tuple[brian2.equations.equations.Equations, dict] [source]#
Adapt model for given neuron group on injection
This enables the specification of variable names differently for each neuron group, allowing for custom names and avoiding conflicts.
- Parameters
neuron_group (NeuronGroup) – NeuronGroup this opsin model is being connected to
injct_params (dict) – kwargs passed in on injection, could contain variable names to plug into the model
- Keyword Arguments
model (str, optional) – Model to start with, by default that defined for the class. This allows for prior string manipulations before it can be parsed as an Equations object.
- Returns
A tuple containing an Equations object and a parameter dictionary, constructed from
model
andparams
, respectively, with modified names for use inopto_syns
- Return type
Equations, dict
- opto_syns: dict[NeuronGroup, Synapses]#
Stores the synapse objects implementing the opsin model, with NeuronGroup keys and Synapse values.
- property params: dict#
Returns a dictionary of parameters for the model
- per_ng_unit_replacements: list[Tuple[str, str]]#
List of (UNIT_NAME, neuron_group_specific_unit_name) tuples to be substituted in the model string on injection and before checking required variables.
- required_vars: list[Tuple[str, Unit]]#
Default names of state variables required in the neuron group, along with units, e.g., [(‘Iopto’, amp)].
It is assumed that non-default values can be passed in on injection as a keyword argument
[default_name]_var_name=[non_default_name]
and that these are found in the model string as[DEFAULT_NAME]_VAR_NAME
before replacement.
- class cleo.opto.ProportionalCurrentOpsin(action_spectrum: list[tuple[float, float]] = NOTHING, action_spectrum_interpolator: typing.Callable = <function cubic_interpolator>, extra_namespace: dict = NOTHING, *, name: str = NOTHING, I_per_Irr: brian2.units.fundamentalunits.Quantity)[source]#
Bases:
cleo.opto.opsins.Opsin
A simple model delivering current proportional to light intensity
Method generated by attrs for class ProportionalCurrentOpsin.
- I_per_Irr: Quantity#
How much current (in amps or unitless, depending on neuron model) to deliver per mW/mm2.
- model: str#
Basic Brian model equations string.
Should contain a rho_rel term reflecting relative expression levels. Will likely also contain special NeuronGroup-dependent symbols such as V_VAR_NAME to be replaced on injection in
modify_model_and_params_for_ng()
.
- required_vars: list[Tuple[str, Unit]]#
Default names of state variables required in the neuron group, along with units, e.g., [(‘Iopto’, amp)].
It is assumed that non-default values can be passed in on injection as a keyword argument
[default_name]_var_name=[non_default_name]
and that these are found in the model string as[DEFAULT_NAME]_VAR_NAME
before replacement.
- cleo.opto.chr2_4s() cleo.opto.opsins.FourStateOpsin [source]#
Returns a 4-state ChR2 model.
Params taken from try.projectpyrho.org’s default 4-state configuration. Action spectrum from Nagel et al., 2003, Fig. 4a, extracted using Plot Digitizer.
Parameters can be changed after initialization but before injection.
- cleo.opto.chr2_b4s() cleo.opto.opsins.BansalFourStateOpsin [source]#
Returns a 4-state Vf-Chrimson model.
Params given in Bansal et al., 2020. Action spectrum from Nagel et al., 2003, Fig. 4a, extracted using Plot Digitizer.
Parameters can be changed after initialization but before injection.
- cleo.opto.chrimson_4s() cleo.opto.opsins.BansalFourStateOpsin [source]#
Returns a 4-state Chrimson model.
Params given in Bansal et al., 2020. Action spectrum from Mager et al., 2018, Supp. Fig. 1a, extracted using Plot Digitizer.
Parameters can be changed after initialization but before injection.
- cleo.opto.fiber473nm(R0=100. * umetre, NAfib=0.37, wavelength=0.473 * umetre, K=125. * metre ** - 1, S=7370. * metre ** - 1, ntis=1.36) cleo.opto.light.FiberModel [source]#
Light parameters for 473 nm wavelength delivered via an optic fiber.
From Foutz et al., 2012. See
FiberModel
for parameter descriptions.
- cleo.opto.gtacr2_4s() cleo.opto.opsins.BansalFourStateOpsin [source]#
Returns a 4-state model of GtACR2, an anion channel.
Params given in Bansal et al., 2020. Action spectra from Govorunova et al., 2015, Fig. 1f, extracted using Plot Digitizer.
Parameters can be changed after initialization but before injection.
- cleo.opto.lor_for_sim(sim: cleo.base.CLSimulator) cleo.opto.registry.LightOpsinRegistry [source]#
Returns the registry for the given simulator
- cleo.opto.plot_action_spectra(*opsins: cleo.opto.opsins.Opsin)[source]#
- cleo.opto.vfchrimson_4s() cleo.opto.opsins.BansalFourStateOpsin [source]#
Returns a 4-state Vf-Chrimson model.
Params given in Bansal et al., 2020. Action spectrum from Mager et al., 2018, Supp. Fig. 1a, extracted using Plot Digitizer.
Parameters can be changed after initialization but before injection.
cleo.ioproc module#
Classes and functions for constructing and configuring an IOProcessor
.
- class cleo.ioproc.ConstantDelay(delay_ms: float)[source]#
Bases:
cleo.ioproc.delays.Delay
Simply adds a constant delay to the computation
- Parameters
delay_ms (float) – Desired delay in milliseconds
- class cleo.ioproc.FiringRateEstimator(tau_ms: float, sample_period_ms: float, **kwargs)[source]#
Bases:
cleo.ioproc.base.ProcessingBlock
Exponential filter to estimate firing rate.
Requires sample_time_ms kwarg when process is called.
- Parameters
tau_ms (float) – Time constant of filter
sample_period_ms (float) – Sampling period in milliseconds
- compute_output(input: nptyping.types._ndarray.NDArray[Any, nptyping.types._number.UInt], **kwargs) nptyping.types._ndarray.NDArray[Any, nptyping.types._number.Float] [source]#
Estimate firing rate given past and current spikes.
- Parameters
input (NDArray[(n,), np.uint]) – n-length vector of spike counts
- Keyword Arguments
sample_time_ms (float) – Time measurement was taken in milliseconds
- Returns
n-length vector of firing rates
- Return type
NDArray[(n,), float]
- t_in_ms: list[float]#
The walltime the block received each input. Only recorded if
save_history
- t_out_ms: list[float]#
The walltime of each of the block’s outputs. Only recorded if
save_history
- values: list[Any]#
Each of the block’s outputs. Only recorded if
save_history
- class cleo.ioproc.GaussianDelay(loc: float, scale: float)[source]#
Bases:
cleo.ioproc.delays.Delay
Generates normal-distributed delay.
Will return 0 when a negative value is sampled.
- Parameters
loc (float) – Center of distribution
scale (float) – Standard deviation of delay distribution
- class cleo.ioproc.LatencyIOProcessor(sample_period_ms: float, **kwargs)[source]#
Bases:
cleo.base.IOProcessor
IOProcessor capable of delivering stimulation some time after measurement.
- Parameters
sample_period_ms (float) – Determines how frequently samples are taken from the network.
- Keyword Arguments
sampling (str) –
“fixed” or “when idle”; “fixed” by default
”fixed” sampling means samples are taken on a fixed schedule, with no exceptions.
”when idle” sampling means no samples are taken before the previous sample’s output has been delivered. A sample is taken ASAP after an over-period computation: otherwise remains on schedule.
processing (str) –
“parallel” or “serial”; “parallel” by default
”parallel” computes the output time by adding the delay for a sample onto the sample time, so if the delay is 2 ms, for example, while the sample period is only 1 ms, some of the processing is happening in parallel. Output order matches input order even if the computed output time for a sample is sooner than that for a previous sample.
”serial” computes the output time by adding the delay for a sample onto the output time of the previous sample, rather than the sampling time. Note this may be of limited utility because it essentially means the entire round trip cannot be in parallel at all. More realistic is that simply each block or phase of computation must be serial. If anyone cares enough about this, it will have to be implemented in the future.
Note
It doesn’t make much sense to combine parallel computation with “when idle” sampling, because “when idle” sampling only produces one sample at a time to process.
- Raises
ValueError – For invalid sampling or processing kwargs
- get_ctrl_signal(query_time_ms)[source]#
Get per-stimulator control signal from the
IOProcessor
.- Parameters
time (Brian 2 temporal Unit) – Current timestep
- Returns
A {‘stimulator_name’: value} dictionary for updating stimulators.
- Return type
dict
- is_sampling_now(query_time_ms)[source]#
Determines whether the processor will take a sample at this timestep.
- Parameters
time (Brian 2 temporal Unit) – Current timestep.
- Return type
bool
- abstract process(state_dict: dict, sample_time_ms: float) Tuple[dict, float] [source]#
Process network state to generate output to update stimulators.
This is the function the user must implement to define the signal processing pipeline.
- Parameters
state_dict (dict) – {recorder_name: state} dictionary from
get_state()
time_ms (float) –
- Returns
{‘stim_name’: ctrl_signal} dictionary and output time in milliseconds.
- Return type
Tuple[dict, float]
- put_state(state_dict: dict, sample_time_ms)[source]#
Deliver network state to the
IOProcessor
.- Parameters
state_dict (dict) – A dictionary of recorder measurements, as returned by
get_state()
time (brian2 temporal Unit) – The current simulation timestep. Essential for simulating control latency and for time-varying control.
- t_samp_ms: list[float]#
Record of sampling times—each time
put_state()
is called.
- class cleo.ioproc.PIController(ref_signal: callable, Kp: float, Ki: float = 0, sample_period_ms: float = 0, **kwargs: Any)[source]#
Bases:
cleo.ioproc.base.ProcessingBlock
Simple PI controller.
compute_output()
requires asample_time_ms
keyword argument. Only tested on controlling scalar values, but could be easily adapted to controlling a multi-dimensional state.- Parameters
ref_signal (callable) – Must return the target as a function of time in ms
Kp (float) – Gain on the proportional error
Ki (float, optional) – Gain on the integral error, by default 0
sample_period_ms (float, optional) – Rate at which processor takes samples, by default 0. Only used to compute integrated error on first sample
- compute_output(input: float, **kwargs) float [source]#
Compute control input to the system using previously specified gains.
- Parameters
input (Any) – Current system state
- Returns
Control signal
- Return type
float
- ref_signal: callable[[float], Any]#
Callable returning the target as a function of time in ms
- class cleo.ioproc.ProcessingBlock(**kwargs)[source]#
Bases:
abc.ABC
Abstract signal processing stage or control block.
It’s important to use super().__init__(**kwargs) in the base class to use the parent-class logic here.
- Keyword Arguments
delay (Delay) – Delay object which adds to the compute time
- Raises
TypeError – When delay is not a Delay object.
- abstract compute_output(input: Any, **kwargs) Any [source]#
Computes output for given input.
This is where the user will implement the desired functionality of the ProcessingBlock without regard for latency.
- Parameters
- Returns
output
- Return type
Any
- delay: cleo.ioproc.delays.Delay#
The delay object determining compute latency for the block
- process(input: Any, t_in_ms: float, **kwargs) Tuple[Any, float] [source]#
Computes and saves output and output time given input and input time.
The user should implement
compute_output()
for their child classes, which performs the computation itself without regards for timing or saving variables.- Parameters
input (Any) – Data to be processed
t_in_ms (float) – Time the block receives the input data
**kwargs (Any) – Key-value list of arguments passed to
compute_output()
- Returns
output, out time in milliseconds
- Return type
Tuple[Any, float]
- t_in_ms: list[float]#
The walltime the block received each input. Only recorded if
save_history
- t_out_ms: list[float]#
The walltime of each of the block’s outputs. Only recorded if
save_history
- values: list[Any]#
Each of the block’s outputs. Only recorded if
save_history
- class cleo.ioproc.RecordOnlyProcessor(sample_period_ms, **kwargs)[source]#
Bases:
cleo.ioproc.base.LatencyIOProcessor
Take samples without performing any control.
Use this if all you are doing is recording.
- Parameters
sample_period_ms (float) – Determines how frequently samples are taken from the network.
- Keyword Arguments
sampling (str) –
“fixed” or “when idle”; “fixed” by default
”fixed” sampling means samples are taken on a fixed schedule, with no exceptions.
”when idle” sampling means no samples are taken before the previous sample’s output has been delivered. A sample is taken ASAP after an over-period computation: otherwise remains on schedule.
processing (str) –
“parallel” or “serial”; “parallel” by default
”parallel” computes the output time by adding the delay for a sample onto the sample time, so if the delay is 2 ms, for example, while the sample period is only 1 ms, some of the processing is happening in parallel. Output order matches input order even if the computed output time for a sample is sooner than that for a previous sample.
”serial” computes the output time by adding the delay for a sample onto the output time of the previous sample, rather than the sampling time. Note this may be of limited utility because it essentially means the entire round trip cannot be in parallel at all. More realistic is that simply each block or phase of computation must be serial. If anyone cares enough about this, it will have to be implemented in the future.
Note
It doesn’t make much sense to combine parallel computation with “when idle” sampling, because “when idle” sampling only produces one sample at a time to process.
- Raises
ValueError – For invalid sampling or processing kwargs
- process(state_dict: dict, sample_time_ms: float) Tuple[dict, float] [source]#
Process network state to generate output to update stimulators.
This is the function the user must implement to define the signal processing pipeline.
- Parameters
state_dict (dict) – {recorder_name: state} dictionary from
get_state()
time_ms (float) –
- Returns
{‘stim_name’: ctrl_signal} dictionary and output time in milliseconds.
- Return type
Tuple[dict, float]
- sample_period_ms: float#
Determines how frequently the processor takes samples
- t_samp_ms: list[float]#
Record of sampling times—each time
put_state()
is called.
cleo.viz module#
Tools for visualizing models and simulations
- class cleo.viz.VideoVisualizer(devices: collections.abc.Iterable[Union[cleo.base.InterfaceDevice, Tuple[cleo.base.InterfaceDevice, dict]]] = NOTHING, dt: brian2.units.fundamentalunits.Quantity = 1. * msecond, *, name: str = NOTHING)[source]#
Bases:
cleo.base.InterfaceDevice
Device for visualizing a simulation.
Must be injected after all other devices and before the simulation is run.
Method generated by attrs for class VideoVisualizer.
- connect_to_neuron_group(neuron_group: brian2.groups.neurongroup.NeuronGroup, **kwparams) None [source]#
Connect device to given neuron_group.
If your device introduces any objects which Brian must keep track of, such as a NeuronGroup, Synapses, or Monitor, make sure to add these to self.brian_objects.
- Parameters
neuron_group (NeuronGroup) –
**kwparams (optional, passed from inject or) – inject
- devices: collections.abc.Iterable[Union[cleo.base.InterfaceDevice, Tuple[cleo.base.InterfaceDevice, dict]]]#
list of devices or (device, vis_kwargs) tuples to include in the plot, just as in the
plot()
function, by default “all”, which will include all recorders and stimulators currently injected when this visualizer is injected into the simulator.
- dt: brian2.units.fundamentalunits.Quantity#
length of each frame—that is, every
dt
the visualizer takes a snapshot of the network, by default 1*ms
- generate_Animation(plotargs: dict, slowdown_factor: float = 10, **figargs: Any) matplotlib.animation.Animation [source]#
Create a matplotlib Animation object from the recorded simulation
- Parameters
plotargs (dict) – dictionary of arguments as taken by
plot()
. can include xlim, ylim, zlim, colors, axis_scale_unit, invert_z, and/or scatterargs. neuron groups and devices are automatically added and **figargs are specified separately.slowdown_factor (float, optional) – how much slower the animation will be rendered, as a multiple of real-time, by default 10
**figargs (Any, optional) – keyword arguments passed to plt.figure(), such as figsize
- Returns
An Animation object capturing the desired visualization. See matplotlib’s docs for saving and rendering options.
- Return type
- init_for_simulator(simulator: cleo.base.CLSimulator)[source]#
Initialize device for simulator on initial injection
This function is called only the first time a device is injected into a simulator and performs any operations that are independent of the individual neuron groups it is connected to.
- Parameters
simulator (CLSimulator) – simulator being injected into
- neuron_groups: list[brian2.groups.neurongroup.NeuronGroup]#
- cleo.viz.plot(*neuron_groups: brian2.groups.neurongroup.NeuronGroup, xlim: Optional[Tuple[float, float]] = None, ylim: Optional[Tuple[float, float]] = None, zlim: Optional[Tuple[float, float]] = None, colors: Optional[collections.abc.Iterable] = None, axis_scale_unit: brian2.units.fundamentalunits.Unit = mmetre, devices: collections.abc.Iterable[Union[cleo.base.InterfaceDevice, Tuple[cleo.base.InterfaceDevice, dict]]] = [], invert_z: bool = True, scatterargs: dict = {}, sim: Optional[cleo.base.CLSimulator] = None, **figargs: Any) None [source]#
Visualize neurons and interface devices
- Parameters
xlim (Tuple[float, float], optional) – xlim for plot, determined automatically by default
ylim (Tuple[float, float], optional) – ylim for plot, determined automatically by default
zlim (Tuple[float, float], optional) – zlim for plot, determined automatically by default
colors (Iterable, optional) – colors, one for each neuron group, automatically determined by default
axis_scale_unit (Unit, optional) – Brian unit to scale lim params, by default mm
devices (Iterable[Union[InterfaceDevice, Tuple[InterfaceDevice, dict]]], optional) – devices to add to the plot or (device, kwargs) tuples.
add_self_to_plot()
is called for each, using the kwargs dict if given. By default []invert_z (bool, optional) – whether to invert z-axis, by default True to reflect the convention that +z represents depth from cortex surface
scatterargs (dict, optional) – arguments passed to plt.scatter() for each neuron group, such as marker
sim (CLSimulator, optional) – Optional shortcut to include all neuron groups and devices
**figargs (Any, optional) – keyword arguments passed to plt.figure(), such as figsize
- Raises
ValueError – When neuron group doesn’t have x, y, and z already defined
cleo.recorders module#
Contains basic recorders.
- class cleo.recorders.GroundTruthSpikeRecorder(*, name: str = NOTHING)[source]#
Bases:
cleo.base.Recorder
Reports the number of spikes seen since last queried for each neuron.
This amounts effectively to the number of spikes per control period. Note: this will only work for one neuron group at the moment.
Method generated by attrs for class GroundTruthSpikeRecorder.
- connect_to_neuron_group(neuron_group)[source]#
Connect device to given neuron_group.
If your device introduces any objects which Brian must keep track of, such as a NeuronGroup, Synapses, or Monitor, make sure to add these to self.brian_objects.
- Parameters
neuron_group (NeuronGroup) –
**kwparams (optional, passed from inject or) – inject
- get_state() nptyping.types._ndarray.NDArray[Any, nptyping.types._number.UInt] [source]#
- Returns
n_neurons-length array with spike counts over the latest control period.
- Return type
NDArray[(n_neurons,), np.uint]
- neuron_group: brian2.groups.neurongroup.NeuronGroup#
- class cleo.recorders.RateRecorder(i: int, *, name: str = NOTHING)[source]#
Bases:
cleo.base.Recorder
Records firing rate from a single neuron.
Firing rate comes from Brian’s
PopulationRateMonitor
Method generated by attrs for class RateRecorder.
- connect_to_neuron_group(neuron_group)[source]#
Connect device to given neuron_group.
If your device introduces any objects which Brian must keep track of, such as a NeuronGroup, Synapses, or Monitor, make sure to add these to self.brian_objects.
- Parameters
neuron_group (NeuronGroup) –
**kwparams (optional, passed from inject or) – inject
- i: int#
index of neuron to record
- class cleo.recorders.VoltageRecorder(voltage_var_name: str = 'v', *, name: str = NOTHING)[source]#
Bases:
cleo.base.Recorder
Records the voltage of a single neuron group.
Method generated by attrs for class VoltageRecorder.
- connect_to_neuron_group(neuron_group)[source]#
Connect device to given neuron_group.
If your device introduces any objects which Brian must keep track of, such as a NeuronGroup, Synapses, or Monitor, make sure to add these to self.brian_objects.
- Parameters
neuron_group (NeuronGroup) –
**kwparams (optional, passed from inject or) – inject
- get_state() brian2.units.fundamentalunits.Quantity [source]#
- Returns
Current voltage of target neuron group
- Return type
Quantity
- voltage_var_name: str#
Name of variable representing membrane voltage
cleo.stimulators module#
Contains basic stimulators.
- class cleo.stimulators.StateVariableSetter(default_value: Any = 0, save_history: bool = True, *, name: str = NOTHING, variable_to_ctrl: str, unit: Unit)[source]#
Bases:
cleo.base.Stimulator
Sets the given state variable of target neuron groups.
Method generated by attrs for class StateVariableSetter.
- connect_to_neuron_group(neuron_group)[source]#
Connect device to given neuron_group.
If your device introduces any objects which Brian must keep track of, such as a NeuronGroup, Synapses, or Monitor, make sure to add these to self.brian_objects.
- Parameters
neuron_group (NeuronGroup) –
**kwparams (optional, passed from inject or) – inject
- neuron_groups: list[NeuronGroup]#
- update(ctrl_signal: float) None [source]#
Set state variable of target neuron groups
- Parameters
ctrl_signal (float) – Value to update variable to, without unit. The unit provided on initialization is automatically multiplied.
- variable_to_ctrl: str#
Name of state variable to control
cleo.utilities module#
Assorted utilities for developers.
- cleo.utilities.add_to_neo_segment(segment: neo.core.segment.Segment, *objects: neo.core.dataobject.DataObject)[source]#
Taken from neo.core.group.Group.
- cleo.utilities.get_orth_vectors_for_V(V)[source]#
For nx3 block of row vectors V, return nx3 W1, W2 orthogonal vector blocks
- cleo.utilities.modify_model_with_eqs(neuron_group, eqs_to_add)[source]#
Adapted from _create_variables() from neurongroup.py from Brian2 source code v2.3.0.2
- cleo.utilities.normalize_coords(coords: brian2.units.fundamentalunits.Quantity) brian2.units.fundamentalunits.Quantity [source]#
Normalize coordinates to unit vectors.
- cleo.utilities.wavelength_to_rgb(wavelength_nm, gamma=0.8)[source]#
taken from http://www.noah.org/wiki/Wavelength_to_RGB_in_Python This converts a given wavelength of light to an approximate RGB color value. The wavelength must be given in nanometers in the range from 380 nm through 750 nm (789 THz through 400 THz).
Based on code by Dan Bruton http://www.physics.sfasu.edu/astro/color/spectra.html