|
@@ -1,113 +1,65 @@
|
|
|
-import json
|
|
|
-import os
|
|
|
-
|
|
|
import numpy as np
|
|
|
+from brian2 import BrianLogger
|
|
|
from brian2.units import *
|
|
|
+import warnings
|
|
|
+warnings.simplefilter(action='ignore', category=FutureWarning) # Otherwise pypet's FutureWarning spams the console output
|
|
|
from pypet import Environment, cartesian_product, Trajectory
|
|
|
from pypet.brian2.parameter import Brian2MonitorResult
|
|
|
|
|
|
-from scripts.spatial_network import create_grid_of_excitatory_neurons, \
|
|
|
+from scripts.spatial_maps.spatial_network_layout import create_grid_of_excitatory_neurons, \
|
|
|
create_interneuron_sheet_entropy_max_orientation, get_excitatory_neurons_in_inhibitory_axonal_clouds
|
|
|
-from scripts.ring_network.head_direction import ex_in_network
|
|
|
+from scripts.spatial_network.spatial_network_setup import get_synaptic_weights, \
|
|
|
+ create_head_direction_input, ex_in_network
|
|
|
+from scripts.spatial_network.models import *
|
|
|
from scripts.spatial_maps.supplement_pinwheel_map.pinwheel_map import PinwheelMap
|
|
|
-from scripts.spatial_maps.supplement_pinwheel_map.pinwheel_map_generator import TRAJ_NAME_ORIENTATION_MAPS
|
|
|
-from scripts.spatial_network.spatial_network_setup import excitatory_eqs, excitatory_params, \
|
|
|
- lif_interneuron_eqs, lif_interneuron_params, lif_interneuron_options, ei_synapse_model, ei_synapse_on_pre, \
|
|
|
- ei_synapse_param, ie_synapse_model, ie_synapse_on_pre, ie_synapse_param, get_synaptic_weights, \
|
|
|
- create_head_direction_input
|
|
|
+
|
|
|
|
|
|
POLARIZED = 'ellipsoid'
|
|
|
CIRCULAR = 'circular'
|
|
|
NO_SYNAPSES = 'no conn'
|
|
|
-
|
|
|
-def get_local_data_folder():
|
|
|
- data_folder = "../../../data/"
|
|
|
- config_file_name = ".config.json"
|
|
|
- if os.path.isfile(config_file_name):
|
|
|
- with open(config_file_name) as config_file:
|
|
|
- config_dict = json.load(config_file)
|
|
|
- data_folder = os.path.abspath(config_dict["data"])
|
|
|
- print(data_folder)
|
|
|
-
|
|
|
- return data_folder
|
|
|
-
|
|
|
-
|
|
|
DATA_FOLDER = "../../../data/"
|
|
|
LOG_FOLDER = "../../../logs/"
|
|
|
-SEED_RANGE = range(10)
|
|
|
-SCALE_RANGE = np.linspace(1.0, 650.0, 24, endpoint=True).tolist()
|
|
|
-
|
|
|
-TRAJ_NAME = "full_figure_orientation_map"
|
|
|
-
|
|
|
-
|
|
|
-def get_orientation_map(correlation_length, seed, sheet_size, N_E, data_folder=None):
|
|
|
- if data_folder is None:
|
|
|
- data_folder = DATA_FOLDER
|
|
|
-
|
|
|
- traj = Trajectory(filename=data_folder + TRAJ_NAME_ORIENTATION_MAPS + ".hdf5")
|
|
|
+TRAJ_NAME = "spatial_network_pinwheel_map"
|
|
|
+TRAJ_NAME_PINWHEEL_MAPS = "precalculated_pinwheel_maps"
|
|
|
|
|
|
- traj.f_load(index=-1, load_parameters=2, load_results=2)
|
|
|
-
|
|
|
- available_lengths = sorted(list(set(traj.f_get("corr_len").f_get_range())))
|
|
|
- closest_length = available_lengths[np.argmin(np.abs(np.array(available_lengths)-correlation_length))]
|
|
|
- if closest_length!=correlation_length:
|
|
|
- print("Warning: desired correlation length {:.1f} not available. Taking {:.1f} instead".format(
|
|
|
- correlation_length, closest_length))
|
|
|
- corr_len = closest_length
|
|
|
- seed = seed
|
|
|
-
|
|
|
- map_by_params = lambda x, y: x == corr_len and y == seed
|
|
|
-
|
|
|
- idx_iterator = traj.f_find_idx(['corr_len', 'seed'], map_by_params)
|
|
|
-
|
|
|
- # TODO: Since it has only one entry, maybe iterator can be replaced
|
|
|
- for idx in idx_iterator:
|
|
|
- traj.v_idx = idx
|
|
|
- map_angle_grid = traj.crun.map
|
|
|
+# SCALE_RANGE = [200.0]
|
|
|
+# SEED_RANGE = [1]
|
|
|
|
|
|
- number_of_excitatory_neurons_per_row = int(np.sqrt(N_E))
|
|
|
+SCALE_RANGE = np.linspace(1.0, 650.0, 24, endpoint=True).tolist()
|
|
|
+SEED_RANGE = range(10)
|
|
|
|
|
|
- map = PinwheelMap(number_of_excitatory_neurons_per_row, number_of_excitatory_neurons_per_row,
|
|
|
- corr_len, sheet_size, sheet_size, seed)
|
|
|
- map.angle_grid = map_angle_grid
|
|
|
|
|
|
- return map.tuning
|
|
|
|
|
|
-def get_uniform_orientation_map(correlation_length, seed, sheet_size, N_E, data_folder=None):
|
|
|
+def get_uniform_pinwheel_map(scale, seed, sheet_size, N_E, data_folder=None):
|
|
|
if data_folder is None:
|
|
|
data_folder = DATA_FOLDER
|
|
|
|
|
|
- traj = Trajectory(filename=data_folder + TRAJ_NAME_ORIENTATION_MAPS + ".hdf5")
|
|
|
+ traj = Trajectory(filename=data_folder + TRAJ_NAME_PINWHEEL_MAPS + ".hdf5")
|
|
|
|
|
|
traj.f_load(index=-1, load_parameters=2, load_results=2)
|
|
|
|
|
|
- available_lengths = sorted(list(set(traj.f_get("corr_len").f_get_range())))
|
|
|
- closest_length = available_lengths[np.argmin(np.abs(np.array(available_lengths)-correlation_length))]
|
|
|
- if closest_length!=correlation_length:
|
|
|
+ available_scales = sorted(list(set(traj.f_get("scale").f_get_range())))
|
|
|
+ closest_scale = available_scales[np.argmin(np.abs(np.array(available_scales)-scale))]
|
|
|
+ if closest_scale != scale:
|
|
|
print("Warning: desired correlation length {:.1f} not available. Taking {:.1f} instead".format(
|
|
|
- correlation_length, closest_length))
|
|
|
- corr_len = closest_length
|
|
|
- seed = seed
|
|
|
+ scale, closest_scale))
|
|
|
|
|
|
- map_by_params = lambda x, y: x == corr_len and y == seed
|
|
|
+ map_by_params = lambda x, y: x == scale and y == seed
|
|
|
|
|
|
- idx_iterator = traj.f_find_idx(['corr_len', 'seed'], map_by_params)
|
|
|
+ idx_iterator = traj.f_find_idx(['scale', 'seed'], map_by_params)
|
|
|
|
|
|
- # TODO: Since it has only one entry, maybe iterator can be replaced
|
|
|
for idx in idx_iterator:
|
|
|
traj.v_idx = idx
|
|
|
- map_angle_grid = traj.crun.map
|
|
|
+ map_angle_grid = traj.crun.pinwheel_map
|
|
|
|
|
|
number_of_excitatory_neurons_per_row = int(np.sqrt(N_E))
|
|
|
|
|
|
map = PinwheelMap(number_of_excitatory_neurons_per_row, number_of_excitatory_neurons_per_row,
|
|
|
- corr_len, sheet_size, sheet_size, seed)
|
|
|
+ scale, sheet_size, sheet_size, seed)
|
|
|
|
|
|
- # Uniformize orientation map
|
|
|
+ # Uniformize pinwheel map
|
|
|
|
|
|
nrow = number_of_excitatory_neurons_per_row
|
|
|
- size = sheet_size
|
|
|
- scale = corr_len # TODO: Probably this needs to be a linear interpolation
|
|
|
|
|
|
n = map_angle_grid / np.pi
|
|
|
m = np.concatenate(n)
|
|
@@ -118,34 +70,35 @@ def get_uniform_orientation_map(correlation_length, seed, sheet_size, N_E, data_
|
|
|
m[sorted_idx[ii * idx:(ii + 1) * idx]] = val
|
|
|
p_map = (m - nrow) / nrow
|
|
|
map.angle_grid = p_map.reshape(nrow, -1) * np.pi
|
|
|
- # self.map *= np.pi
|
|
|
-
|
|
|
- # map.angle_grid = map_angle_grid
|
|
|
|
|
|
return map.tuning
|
|
|
|
|
|
|
|
|
+def get_input_head_directions(traj):
|
|
|
+ directions = np.linspace(-np.pi, np.pi, traj.input.number_of_directions, endpoint=False)
|
|
|
+ return directions
|
|
|
+
|
|
|
+
|
|
|
def spatial_network_with_entropy_maximisation(traj):
|
|
|
- sheet_size = traj.map.sheet_size
|
|
|
+ sheet_size = traj.input_map.sheet_size
|
|
|
|
|
|
N_E = traj.network.N_E
|
|
|
N_I = traj.network.N_I
|
|
|
|
|
|
- orientation_map = get_uniform_orientation_map(traj.map.correlation_length, traj.map.seed, sheet_size, N_E)
|
|
|
- ex_positions, ex_tunings = create_grid_of_excitatory_neurons(sheet_size,
|
|
|
- sheet_size,
|
|
|
- int(np.sqrt(N_E)), orientation_map)
|
|
|
+ pinwheel_map = get_uniform_pinwheel_map(traj.input_map.scale, traj.input_map.seed, sheet_size, N_E)
|
|
|
+
|
|
|
+ ex_positions, ex_tunings = create_grid_of_excitatory_neurons(sheet_size, int(np.sqrt(N_E)), pinwheel_map)
|
|
|
|
|
|
inhibitory_axon_long_axis = traj.morphology.long_axis
|
|
|
inhibitory_axon_short_axis = traj.morphology.short_axis
|
|
|
|
|
|
- entropy_maximisation_steps = traj.simulation.entropy_maximisation.steps if inhibitory_axon_long_axis != \
|
|
|
- inhibitory_axon_short_axis else 1
|
|
|
+ entropy_maximisation_trial_orientations = traj.interneuron.entropy_maximisation.trial_orientations if \
|
|
|
+ inhibitory_axon_long_axis != inhibitory_axon_short_axis else 0
|
|
|
|
|
|
inhibitory_axonal_clouds, ellipse_single_trial_entropy = create_interneuron_sheet_entropy_max_orientation(
|
|
|
ex_positions, ex_tunings, N_I, inhibitory_axon_long_axis,
|
|
|
inhibitory_axon_short_axis, sheet_size,
|
|
|
- sheet_size, trial_orientations=entropy_maximisation_steps)
|
|
|
+ sheet_size, trial_orientations=entropy_maximisation_trial_orientations)
|
|
|
|
|
|
ie_connections = get_excitatory_neurons_in_inhibitory_axonal_clouds(ex_positions, inhibitory_axonal_clouds)
|
|
|
|
|
@@ -166,21 +119,29 @@ def spatial_network_with_entropy_maximisation(traj):
|
|
|
ex_in_weights, in_ex_weights = get_synaptic_weights(N_E, N_I, ie_connections, excitatory_synapse_strength,
|
|
|
inhibitory_synapse_strength)
|
|
|
|
|
|
- sharpness = 1.0 / (traj.input.width) ** 2
|
|
|
-
|
|
|
- directions = get_input_head_directions(traj)
|
|
|
- for idx, dir in enumerate(directions):
|
|
|
+ input_directions = get_input_head_directions(traj)
|
|
|
+ for idx, direction in enumerate(input_directions):
|
|
|
# We recreate the network here for every dir, which slows down the simulation quite considerably. Otherwise,
|
|
|
# we get a problem with saving and restoring the spike times (0s spike for neuron 0)
|
|
|
- net = ex_in_network(N_E, N_I, excitatory_eqs, excitatory_params, lif_interneuron_eqs,
|
|
|
+
|
|
|
+ net = ex_in_network(N_E, N_I,
|
|
|
+ hodgkin_huxley_eqs_with_synaptic_conductance,
|
|
|
+ hodgkin_huxley_params,
|
|
|
+ lif_interneuron_eqs,
|
|
|
lif_interneuron_params,
|
|
|
- lif_interneuron_options, ei_synapse_model, ei_synapse_on_pre,
|
|
|
- ei_synapse_param,
|
|
|
- ex_in_weights, ie_synapse_model, ie_synapse_on_pre,
|
|
|
- ie_synapse_param, in_ex_weights, random_seed=2)
|
|
|
+ lif_interneuron_options,
|
|
|
+ delta_synapse_model,
|
|
|
+ delta_synapse_on_pre,
|
|
|
+ delta_synapse_param,
|
|
|
+ ex_in_weights,
|
|
|
+ exponential_synapse,
|
|
|
+ exponential_synapse_on_pre,
|
|
|
+ exponential_synapse_params,
|
|
|
+ in_ex_weights,
|
|
|
+ random_seed=traj.input_map.seed)
|
|
|
input_to_excitatory_population = create_head_direction_input(traj.input.baseline * nA, ex_tunings,
|
|
|
- sharpness,
|
|
|
- traj.input.amplitude * nA, dir)
|
|
|
+ traj.input.phase_dispersion,
|
|
|
+ traj.input.amplitude * nA, direction)
|
|
|
|
|
|
excitatory_neurons = net["excitatory_neurons"]
|
|
|
excitatory_neurons.I = input_to_excitatory_population
|
|
@@ -216,25 +177,21 @@ def spatial_network_with_entropy_maximisation(traj):
|
|
|
return 1
|
|
|
|
|
|
|
|
|
-def get_input_head_directions(traj):
|
|
|
- directions = np.linspace(-np.pi, np.pi, traj.input.number_of_directions, endpoint=False)
|
|
|
- return directions
|
|
|
-
|
|
|
-
|
|
|
def main():
|
|
|
+ BrianLogger.suppress_name('method_choice')
|
|
|
+
|
|
|
+ # TODO: Set ncores to the desired number of processes to use by pypet
|
|
|
env = Environment(trajectory=TRAJ_NAME,
|
|
|
- comment="Compare the head direction tuning for circular and ellipsoid interneuron morphology, "
|
|
|
+ comment="Compare the head direction tuning for circular and polarized interneuron morphology, "
|
|
|
"when tuning orientations to maximise entropy of connected excitatory tunings.",
|
|
|
- multiproc=True, filename=DATA_FOLDER, ncores=0, overwrite_file=True, log_folder=LOG_FOLDER)
|
|
|
+ multiproc=True, filename=DATA_FOLDER, ncores=24, overwrite_file=True, log_folder=LOG_FOLDER)
|
|
|
|
|
|
traj = env.trajectory
|
|
|
|
|
|
- traj.f_add_parameter_group("map")
|
|
|
-
|
|
|
- traj.f_add_parameter("map.correlation_length", 200.0,
|
|
|
- comment="Correlation length of orientations in um")
|
|
|
- traj.f_add_parameter("map.seed", 1, comment="Random seed for map generation.")
|
|
|
- traj.f_add_parameter("map.sheet_size", 900, comment="Sheet size in um")
|
|
|
+ traj.f_add_parameter_group("input_map")
|
|
|
+ traj.f_add_parameter("input_map.scale", 200.0, comment="Scaling factor of the input map")
|
|
|
+ traj.f_add_parameter("input_map.seed", 1, comment="Random seed for input map generation.")
|
|
|
+ traj.f_add_parameter("input_map.sheet_size", 900, comment="Sheet size in um")
|
|
|
|
|
|
traj.f_add_parameter_group("network")
|
|
|
traj.f_add_parameter("network.N_E", 3600, comment="Number of excitatory neurons")
|
|
@@ -242,13 +199,15 @@ def main():
|
|
|
|
|
|
traj.f_add_parameter_group("interneuron")
|
|
|
traj.f_add_parameter("interneuron.tau", 7., comment="Interneuron timescale in ms")
|
|
|
+ traj.f_add_parameter("interneuron.entropy_maximisation.trial_orientations", 30,
|
|
|
+ comment="Steps for entropy maximisation")
|
|
|
|
|
|
traj.f_add_parameter_group("synapse")
|
|
|
traj.f_add_parameter("synapse.inhibitory", 30.0, "Strength of conductance-based inhibitory synapse in nS.")
|
|
|
traj.f_add_parameter("synapse.excitatory", 2.5, "Strength of conductance-based inhibitory synapse in mV.")
|
|
|
|
|
|
traj.f_add_parameter_group("input")
|
|
|
- traj.f_add_parameter("input.width", 1. / np.sqrt(2.5), comment="Standard deviation of incoming head direction input.")
|
|
|
+ traj.f_add_parameter("input.phase_dispersion", 2.5, comment="Standard deviation of incoming head direction input.")
|
|
|
traj.f_add_parameter("input.baseline", 0.05, comment="Head direction input baseline")
|
|
|
traj.f_add_parameter("input.amplitude", 0.6, comment="Head direction input amplitude")
|
|
|
traj.f_add_parameter("input.number_of_directions", 12, comment="Number of probed directions")
|
|
@@ -262,23 +221,19 @@ def main():
|
|
|
traj.f_add_parameter("morphology.short_axis", 25.0, comment="Short axis of axon ellipsoid")
|
|
|
|
|
|
traj.f_add_parameter_group("simulation")
|
|
|
- traj.f_add_parameter("simulation.entropy_maximisation.steps", 30, comment="Steps for entropy maximisation")
|
|
|
traj.f_add_parameter("simulation.dt", 0.1, comment="Network simulation time step in ms")
|
|
|
traj.f_add_parameter("simulation.duration", 1000, comment="Network simulation duration in ms")
|
|
|
|
|
|
- correlation_length_range = SCALE_RANGE
|
|
|
- # correlation_length_range = [200.0]
|
|
|
+ scale_range = SCALE_RANGE
|
|
|
seed_range = SEED_RANGE
|
|
|
- # seed_range = [1]
|
|
|
|
|
|
ellipsoid_parameter_exploration = {
|
|
|
"morphology.long_axis": [100.0],
|
|
|
"morphology.short_axis": [25.0],
|
|
|
- "map.correlation_length": correlation_length_range,
|
|
|
- "map.seed": seed_range,
|
|
|
+ "input_map.scale": scale_range,
|
|
|
+ "input_map.seed": seed_range,
|
|
|
"synapse.inhibitory": [30.],
|
|
|
"synapse.excitatory": [2.5]
|
|
|
- # "map.correlation_length": np.arange(0.0, 200.0, 50).tolist()
|
|
|
}
|
|
|
|
|
|
corresponding_circular_radius = float(np.sqrt(ellipsoid_parameter_exploration[
|
|
@@ -288,8 +243,8 @@ def main():
|
|
|
circle_parameter_exploration = {
|
|
|
"morphology.long_axis": [corresponding_circular_radius],
|
|
|
"morphology.short_axis": [corresponding_circular_radius],
|
|
|
- "map.correlation_length": ellipsoid_parameter_exploration["map.correlation_length"],
|
|
|
- "map.seed": ellipsoid_parameter_exploration["map.seed"],
|
|
|
+ "input_map.scale": ellipsoid_parameter_exploration["input_map.scale"],
|
|
|
+ "input_map.seed": ellipsoid_parameter_exploration["input_map.seed"],
|
|
|
"synapse.inhibitory": ellipsoid_parameter_exploration["synapse.inhibitory"],
|
|
|
"synapse.excitatory": ellipsoid_parameter_exploration["synapse.excitatory"]
|
|
|
}
|
|
@@ -297,8 +252,8 @@ def main():
|
|
|
no_conn_parameter_exploration = {
|
|
|
"morphology.long_axis": [corresponding_circular_radius],
|
|
|
"morphology.short_axis": [corresponding_circular_radius],
|
|
|
- "map.correlation_length": ellipsoid_parameter_exploration["map.correlation_length"],
|
|
|
- "map.seed": ellipsoid_parameter_exploration["map.seed"],
|
|
|
+ "input_map.scale": ellipsoid_parameter_exploration["input_map.scale"],
|
|
|
+ "input_map.seed": ellipsoid_parameter_exploration["input_map.seed"],
|
|
|
"synapse.inhibitory": [0.],
|
|
|
"synapse.excitatory": [0.]
|
|
|
}
|
|
@@ -317,5 +272,6 @@ def main():
|
|
|
|
|
|
env.disable_logging()
|
|
|
|
|
|
+
|
|
|
if __name__ == "__main__":
|
|
|
- main()
|
|
|
+ main()
|