Skip to content
Snippets Groups Projects
Commit 55aa9773 authored by Simon Oehrl's avatar Simon Oehrl
Browse files

Merge branch 'release/0.1.0'

parents d692548f 6b02a779
Branches
Tags 0.1.0
No related merge requests found
Pipeline #163382 failed
Showing
with 1368 additions and 254 deletions
# include:
# - project: 'vr-group/in-situ-pipeline/insite'
# ref: develop
# file: '/test-setup.yml'
# variables:
# ACCESS_NODE_COMMIT: $CI_COMMIT_SHA
# api_test:
# extends: .api_test
deploy:develop:
tags:
- docker
- centos
only:
- develop
script:
- docker build -t rwthvr/insite-access-node:develop .
- docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- docker push rwthvr/insite-access-node:develop
deploy:master:
tags:
- docker
- centos
only:
- master
script:
- docker build -t rwthvr/insite-access-node .
- VERSION=$(git tag --points-at $CI_COMMIT_SHA)
- >
[[ $VERSION =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]
- docker tag rwthvr/insite-access-node rwthvr/access-node:$VERSION
- docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- docker push rwthvr/insite-access-node
...@@ -23,4 +23,4 @@ ...@@ -23,4 +23,4 @@
#!docs/README.md #!docs/README.md
README.md README.md
requirements.txt requirements.txt
access_node/controllers/nest_controller.py #access_node/controllers/nest_controller.py
\ No newline at end of file \ No newline at end of file
FROM python:3-alpine FROM python:3.6-slim
RUN mkdir -p /usr/src/app RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app WORKDIR /usr/src/app
......
...@@ -3,7 +3,7 @@ Public access server providing a REST API for the in-situ pipeline. ...@@ -3,7 +3,7 @@ Public access server providing a REST API for the in-situ pipeline.
To generate execute this from the projects root dir: To generate execute this from the projects root dir:
``` ```
java -jar <path/to/swagger-codegen-cli.2.4.8.jar> generate -i access_node/swagger/swagger.yaml -l python-flask -c config.json java -jar swagger-codegen-cli-2.4.8.jar generate -i access_node/swagger/swagger.yaml -l python-flask -c config.json
``` ```
# Swagger generated server # Swagger generated server
......
...@@ -3,12 +3,48 @@ ...@@ -3,12 +3,48 @@
import connexion import connexion
from access_node import encoder from access_node import encoder
from flask_cors import CORS
from access_node.models.nodes import nodes
import json
import time
import requests
import psycopg2
def ConnectToDatabase(postgres_username, postgres_password):
database_host = 'database'
try:
with open('database_host.txt') as database_host_file:
database_host = database_host_file.readline().rstrip('\n')
except:
pass
return psycopg2.connect(database="postgres", user="postgres",
password="postgres", host=database_host, port="5432")
def main(): def main():
# Wait for simulation nodes to post to database
time.sleep(5)
# get simulation nodes
con = ConnectToDatabase('postgres', 'postgres')
cur = con.cursor()
# NEST
cur.execute("SELECT address FROM nest_simulation_node")
nodes.nest_simulation_nodes = [i[0] for i in cur.fetchall()]
# Arbor
cur.execute("SELECT address FROM nest_simulation_node")
nodes.arbor_simulation_nodes = [i[0] for i in cur.fetchall()]
con.close()
# run acces_node
app = connexion.App(__name__, specification_dir='./swagger/') app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = encoder.JSONEncoder app.app.json_encoder = encoder.JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'In-Situ Pipeline REST API'}) app.add_api('swagger.yaml', arguments={
'title': 'In-Situ Pipeline REST API'})
CORS(app.app)
app.run(port=8080) app.run(port=8080)
......
import connexion
import six
from access_node.models.arbor_cell_properties import ArborCellProperties # noqa: E501
from access_node.models.arbor_measurement import ArborMeasurement # noqa: E501
from access_node.models.probe import Probe # noqa: E501
from access_node.models.simulation_time_info import SimulationTimeInfo # noqa: E501
from access_node.models.spikes import Spikes # noqa: E501
from access_node import util
from access_node.models.nodes import nodes
import requests
import psycopg2
import numpy as np
def connect_to_database():
database_host = 'database'
try:
with open('database_host.txt') as database_host_file:
database_host = database_host_file.readline().rstrip('\n')
except:
pass
return psycopg2.connect(database="postgres", user="postgres",
password="postgres", host=database_host, port="5432")
def arbor_get_attributes(): # noqa: E501
"""Retrieves the list of all attributes.
# noqa: E501
:rtype: List[str]
"""
con = connect_to_database()
cur = con.cursor()
cur.execute("SELECT name FROM arbor_attribute")
attributes = [i[0] for i in cur.fetchall()]
con.close()
return attributes
def arbor_get_cell_ids(): # noqa: E501
"""Retrieves the list of all cell ids.
# noqa: E501
:rtype: List[int]
"""
con = connect_to_database()
cur = con.cursor()
cur.execute("SELECT id FROM arbor_cell")
cell_ids = [i[0] for i in cur.fetchall()]
con.close()
return cell_ids
def arbor_get_cell_properties(cell_ids=None): # noqa: E501
"""Retrieves the properties of the specified cells.
# noqa: E501
:param cell_ids: A list of cell IDs queried for properties.
:type cell_ids: List[int]
:rtype: List[ArborCellProperties]
"""
con = connect_to_database()
cur = con.cursor()
if cell_ids == None:
cur.execute("SELECT cell_id, property FROM cell_property")
else:
cur.execute("SELECT cell_id, property FROM cell_property WHERE cell_property.cell_id IN %s", (tuple(cell_ids),))
properties = np.array(cur.fetchall())
cell_ids = np.unique(properties[:,0])
cell_properties = []
for i in range(len(cell_ids)):
per_cell_properties = []
for prop in properties:
if prop[0] == cell_ids[i]:
per_cell_properties.append(prop)
cell_properties.append(ArborCellProperties(cell_ids[i], per_cell_properties))
con.close()
return cell_properties
def arbor_get_measurements(attribute, probe_ids=None, _from=None, to=None, offset=None, limit=None): # noqa: E501
"""Retrieves the measurements for given probes (optional).
# noqa: E501
:param attribute: The attribute to query (e.g., &#39;V_m&#39; for the membrane potential)
:type attribute: str
:param probe_ids: A list of probes ids queried for data.
:type probe_ids: List[int]
:param _from: The start time (including) to be queried.
:type _from: float
:param to: The end time (excluding) to be queried.
:type to: float
:param offset: The offset into the result.
:type offset: int
:param limit: The maximum of entries to be result.
:type limit: int
:rtype: ArborMeasurement
"""
if probe_ids == None:
probes = arbor_get_probes()
probe_ids = []
for probe in probes:
probe_ids.append(probe.id)
init = True
sim_times = []
measurement = ArborMeasurement([], [], [])
for node in nodes.arbor_simulation_nodes:
response = requests.get(
'http://'+node+'/arbor/measurements', params={"attribute": attribute, "probe_ids": probe_ids, "_from": _from, "to": to}).json()
if init:
sim_times = response['simulation_times']
measurement = ArborMeasurement(
sim_times, probe_ids, [None for x in range(0, (len(sim_times)*len(probe_ids)))])
init = False
for x in range(len(response['probe_ids'])):
m_id = response['probe_ids'][x]
index = measurement.probe_ids.index(m_id)
index_offset = index * len(sim_times)
for y in range(len(sim_times)):
measurement.values[index_offset +
y] = response['values'][x*len(sim_times)+y]
# offset and limit
if (offset is None):
offset = 0
if (limit is None or (limit + offset) > len(measurement.probe_ids)):
limit = len(measurement.probe_ids) - offset
measurement.probe_ids = measurement.probe_ids[offset:offset+limit]
measurement.values = measurement.values[offset *
len(sim_times):(offset+limit)*len(sim_times)]
return measurement
def arbor_get_probes(attribute=None): # noqa: E501
"""Retrieves the list of all probes for a given attribute (optional).
# noqa: E501
:param attribute: The attribute measured for which existing probes will be returned.
:type attribute: str
:rtype: List[Probe]
"""
con = connect_to_database()
cur = con.cursor()
if attribute == None:
cur.execute('''SELECT
arbor_probe.id,
arbor_probe.cell_id,
arbor_probe.segment_id,
arbor_probe.position,
FROM arbor_probe''')
else:
cur.execute('''SELECT
arbor_probe.id,
arbor_probe.cell_id,
arbor_probe.segment_id,
arbor_probe.position,
FROM arbor_probe INNER JOIN arbor_attribute
ON arbor_probe.attribute_id = arbor_attribute.id
WHERE arbor_attribute.name = %s''', (attribute,))
probes = np.array(cur.fetchall())
con.close()
return [Probe(*probe) for probe in probes]
def arbor_get_simulation_time_info(): # noqa: E501
"""Retrieves simulation time information.
# noqa: E501
:rtype: SimulationTimeInfo
"""
con = connect_to_database()
cur = con.cursor()
cur.execute("SELECT MIN(current_simulation_time) FROM arbor_simulation_node")
current_time = cur.fetchall()[0][0]
con.close()
# TODO Add Start and End time when available
time_info = SimulationTimeInfo(current=current_time)
return time_info
def arbor_get_spikes(_from=None, to=None, cell_ids=None, segment_ids=None, offset=None, limit=None): # noqa: E501
"""Retrieves the spikes for the given simulation times (optional), cell and segment (optional).
# noqa: E501
:param _from: The start time (including) to be queried.
:type _from: float
:param to: The end time (excluding) to be queried.
:type to: float
:param cell_ids: A list of cell ids queried for spike data.
:type cell_ids: List[int]
:param segment_ids: A list of segment ids queried for spike data.
:type segment_ids: List[int]
:param offset: The offset into the result.
:type offset: int
:param limit: The maximum of entries to be result.
:type limit: int
:rtype: Spikes
"""
spikes = Spikes([], [])
for node in nodes.arbor_simulation_nodes:
response = requests.get(
'http://'+node+'/arbor/spikes', params={"from": _from, "to": to, "cell_ids": cell_ids, "segment_ids": segment_ids}).json()
for x in range(len(response['simulation_times'])):
spikes.simulation_times.append(response['simulation_times'][x])
spikes.gids.append(response['gids'][x])
# sort
sorted_ids = [x for _, x in sorted(
zip(spikes.simulation_times, spikes.gids))]
spikes.gids = sorted_ids
spikes.simulation_times.sort()
# offset and limit
if (offset is None):
offset = 0
if (limit is None or (limit + offset) > len(spikes.gids)):
limit = len(spikes.gids) - offset
spikes.gids = spikes.gids[offset:offset+limit]
spikes.simulation_times = spikes.simulation_times[offset:offset+limit]
return spikes
import connexion import connexion
import six import six
from access_node.models.attribute import Attribute # noqa: E501 from access_node.models.multimeter_info import MultimeterInfo # noqa: E501
from access_node.models.data import Data # noqa: E501 from access_node.models.multimeter_measurement import MultimeterMeasurement # noqa: E501
from access_node.models.error import Error # noqa: E501 from access_node.models.nest_neuron_properties import NestNeuronProperties # noqa: E501
from access_node.models.simulation_time_info import SimulationTimeInfo # noqa: E501
from access_node.models.spikes import Spikes # noqa: E501 from access_node.models.spikes import Spikes # noqa: E501
from access_node import util from access_node import util
# My imports from access_node.models.nodes import nodes
import json
import requests import requests
import psycopg2
import numpy as np
def get_attributes(): # noqa: E501 def connect_to_database():
"""Retrieves the details of per-neuron attributes. database_host = 'database'
try:
with open('database_host.txt') as database_host_file:
database_host = database_host_file.readline().rstrip('\n')
except:
pass
return psycopg2.connect(database="postgres", user="postgres",
password="postgres", host=database_host, port="5432")
def nest_get_gids(): # noqa: E501
"""Retrieves the list of all GID.
# noqa: E501 # noqa: E501
:rtype: List[Attribute] :rtype: List[int]
""" """
with open('access_node//distribution_nodes.json', 'r') as f: con = connect_to_database()
dist_nodes = json.load(f) cur = con.cursor()
information_node = dist_nodes['addresses'][0]
cur.execute("SELECT id FROM nest_neuron")
gids = [i[0] for i in cur.fetchall()]
response = requests.get(information_node+'/attributes').json() con.close()
return response return gids
def get_data(attribute, simulation_steps=None, neuron_ids=None): # noqa: E501 def nest_get_gids_in_population(population_id): # noqa: E501
"""Retrieves the per-neuron attributes for the given attribute name, simulation steps (optional) and neuron IDs (optional). """Retrieves the list of all neuron IDs within the population.
# noqa: E501
:param population_id: The identifier of the population
:type population_id: int
:rtype: List[int]
"""
con = connect_to_database()
cur = con.cursor()
cur.execute("SELECT id FROM nest_neuron WHERE nest_neuron.population_id ="+str(population_id))
gids = [i[0] for i in cur.fetchall()]
con.close()
return gids
def nest_get_multimeter_info(): # noqa: E501
"""Retreives the available multimeters and their properties.
# noqa: E501 # noqa: E501
:param attribute: Attribute name.
:type attribute: str
:param simulation_steps: Simulation steps (leave empty for all steps).
:type simulation_steps: List[]
:param neuron_ids: Neuron IDs (leave empty for all neurons).
:type neuron_ids: List[]
:rtype: Data :rtype: MultimeterInfo
""" """
# Replace this with request to information_node con = connect_to_database()
with open('access_node//distribution_nodes.json', 'r') as f: cur = con.cursor()
dist_nodes = json.load(f)
addresses = dist_nodes['addresses'] cur.execute("SELECT * FROM nest_multimeter;")
attributes = np.array(cur.fetchall())
if simulation_steps != None:
num_ts = len(simulation_steps)
first_ts = simulation_steps[0] gids = []
if len(attributes) > 0:
for id in attributes[:,0]:
cur.execute("SELECT neuron_id FROM nest_neuron_multimeter WHERE multimeter_id = %s", (id,))
gids.append([i[0] for i in cur.fetchall()])
mult_info = []
for i in range(len(attributes)):
mult_info.append({"id": attributes[i][0],
"attributes": attributes[i][1],
"gids": gids[i]})
con.close()
return mult_info
def nest_get_multimeter_measurements(multimeter_id, attribute, _from=None, to=None, gids=None, offset=None, limit=None): # noqa: E501
"""Retrieves the measurements for a multimeter, attribute and GIDS (optional).
# noqa: E501
:param multimeter_id: The multimeter to query
:type multimeter_id:
:param attribute: The attribute to query (e.g., &#39;V_m&#39; for the membrane potential)
:type attribute: str
:param _from: The start time (including) to be queried.
:type _from: float
:param to: The end time (excluding) to be queried.
:type to: float
:param gids: A list of GIDs queried for spike data.
:type gids: List[int]
:param offset: The offset into the result.
:type offset: int
:param limit: The maximum of entries to be result.
:type limit: int
:rtype: MultimeterMeasurement
"""
mult_info = nest_get_multimeter_info()
mult_gids = []
multimeter_exists = False
for mult in mult_info:
if mult['id'] == multimeter_id:
multimeter_exists = True
if attribute not in mult['attributes']:
return "Given multimeter does not measure given attribute", 400
mult_gids = mult['gids']
break
if not multimeter_exists:
return "Given multimeter does not exist", 400
if gids == None:
gids = mult_gids
else: else:
num_ts = get_simulation_step_count() for gid in gids:
first_ts = get_timestep() if gid not in mult_gids:
return "Gid "+str(gid)+" is not measured by given Multimeter", 400
init = True
sim_times = []
measurement = MultimeterMeasurement([], [], [])
for node in nodes.nest_simulation_nodes:
response = requests.get(
node+'/multimeter_measurement', params={"multimeter_id": multimeter_id, "attribute": attribute, "from": _from, "to": to, "gids": gids}).json()
if init:
sim_times = response['simulation_times']
measurement = MultimeterMeasurement(
sim_times, gids, [None for x in range(0, (len(sim_times)*len(gids)))])
init = False
for x in range(len(response['gids'])):
gid = response['gids'][x]
index = measurement.gids.index(gid)
index_offset = index * len(sim_times)
for y in range(len(sim_times)):
measurement.values[index_offset +
y] = response['values'][x*len(sim_times)+y]
# offset and limit
if (offset is None):
offset = 0
if (limit is None or (limit + offset) > len(measurement.gids)):
limit = len(measurement.gids) - offset
measurement.gids = measurement.gids[offset:offset+limit]
measurement.values = measurement.values[offset *
len(sim_times):(offset+limit)*len(sim_times)]
return measurement
def nest_get_neuron_properties(gids=None): # noqa: E501
"""Retrieves the properties of the specified neurons.
# noqa: E501
:param gids: A list of GIDs queried for properties.
:type gids: List[int]
:rtype: List[NestNeuronProperties]
"""
con = connect_to_database()
cur = con.cursor()
cur.execute("Select * FROM nest_neuron LIMIT 0")
colnames = np.array([desc[0] for desc in cur.description])
# column 1 and 2 contain the Node_id/Population_id and thus are removed
colnames = np.delete(colnames, [1,2])
if neuron_ids != None: if gids == None:
ids = neuron_ids cur.execute("Select * FROM nest_neuron")
else: else:
ids = get_neuron_ids() cur.execute("Select * FROM nest_neuron WHERE id IN %s", (tuple(gids),))
data = Data(first_ts, num_ts, ids, nest_properties = []
[[None]*num_ts for x in range(len(ids))]) properties = np.array(cur.fetchall())
for address in addresses: if properties.size != 0:
response = requests.get(address+'/data', params={ properties = np.delete(properties, [1,2], 1)
"attribute": attribute, "simulation_steps": simulation_steps, "neuron_ids": neuron_ids}).json() for k in range(len(properties[:,0])):
for x in range(len(response['neuron_ids'])): props = {}
data.values[data.neuron_ids.index( id = properties[k,0]
response['neuron_ids'][x])] = response['data'][x] for i in range(1, len(colnames)):
return data props.update({colnames[i]: properties[k,i] if properties[k,i] != None else []})
nest_properties.append(NestNeuronProperties(id, props))
con.close()
return nest_properties
def get_neuron_ids(): # noqa: E501
"""Retrieves the list of all neuron IDs. def nest_get_populations(): # noqa: E501
"""Retrieves the list of all population IDs.
# noqa: E501 # noqa: E501
:rtype: List[float] :rtype: List[int]
""" """
with open('access_node//distribution_nodes.json', 'r') as f: con = connect_to_database()
dist_nodes = json.load(f) cur = con.cursor()
information_node = dist_nodes['addresses'][0]
cur.execute("SELECT DISTINCT (population_id) FROM nest_neuron")
populations = [i[0] for i in cur.fetchall()]
response = requests.get(information_node+'/neuron_ids').json() con.close()
return response return populations
def get_simulation_step_count(): # noqa: E501 def nest_get_simulation_time_info(): # noqa: E501
"""Retrieves the number of simulation steps. """Retrieves simulation time information.
# noqa: E501 # noqa: E501
:rtype: float :rtype: SimulationTimeInfo
""" """
with open('access_node//distribution_nodes.json', 'r') as f:
dist_nodes = json.load(f)
information_node = dist_nodes['addresses'][0]
response = requests.get(information_node+'/simulation_step_count').json() current_time = float('inf')
return response print("Hello")
for node in nodes.nest_simulation_nodes:
response = requests.get(
node+'/current_simulation_time').json()
current_time = min(current_time, response)
# TODO Add Start and End time when available
time_info = SimulationTimeInfo(current=current_time)
return time_info
def get_spikes(simulation_steps=None, neuron_ids=None): # noqa: E501
"""Retrieves the spikes for the given simulation steps (optional) and neuron IDs (optional). def nest_get_spikes(_from=None, to=None, gids=None, offset=None, limit=None): # noqa: E501
"""Retrieves the spikes for the given simulation steps (optional) and GIDS (optional).
# noqa: E501 # noqa: E501
:param simulation_steps: Simulation steps (leave empty for all steps). :param _from: The start time (including) to be queried.
:type simulation_steps: List[] :type _from: float
:param neuron_ids: Neuron IDs (leave empty for all neurons). :param to: The end time (excluding) to be queried.
:type neuron_ids: List[] :type to: float
:param gids: A list of GIDs queried for spike data.
:type gids: List[int]
:param offset: The offset into the result.
:type offset: int
:param limit: The maximum of entries to be result.
:type limit: int
:rtype: Spikes :rtype: Spikes
""" """
# Replace this with request to information_node
with open('access_node//distribution_nodes.json', 'r') as f:
dist_nodes = json.load(f)
addresses = dist_nodes['addresses']
spikes = Spikes([], []) spikes = Spikes([], [])
for address in addresses: for node in nodes.nest_simulation_nodes:
response = requests.get( response = requests.get(
address+'/spikes', params={"simulation_steps": simulation_steps, "neuron_ids": neuron_ids}).json() node+'/spikes', params={"from": _from, "to": to, "gids": gids}).json()
for x in range(len(response['simulation_steps'])): for x in range(len(response['simulation_times'])):
spikes.simulation_steps.append(response['simulation_steps'][x]) spikes.simulation_times.append(response['simulation_times'][x])
spikes.neuron_ids.append(response['neuron_ids'][x]) spikes.gids.append(response['gids'][x])
# sort
sorted_ids = [x for _, x in sorted(
zip(spikes.simulation_times, spikes.gids))]
spikes.gids = sorted_ids
spikes.simulation_times.sort()
# offset and limit
if (offset is None):
offset = 0
if (limit is None or (limit + offset) > len(spikes.gids)):
limit = len(spikes.gids) - offset
spikes.gids = spikes.gids[offset:offset+limit]
spikes.simulation_times = spikes.simulation_times[offset:offset+limit]
# Sort this?
return spikes return spikes
def get_timestep(): # noqa: E501 def nest_get_spikes_by_population(population_id, _from=None, to=None, offset=None, limit=None): # noqa: E501
"""Retrieves the time between two simulation steps. """Retrieves the spikes for the given simulation steps (optional) and population.
# noqa: E501 # noqa: E501
:param population_id: The identifier of the population.
:type population_id: int
:param _from: The start time (including) to be queried.
:type _from: float
:param to: The end time (excluding) to be queried.
:type to: float
:param offset: The offset into the result.
:type offset: int
:param limit: The maximum of entries to be result.
:type limit: int
:rtype: float :rtype: Spikes
""" """
with open('access_node//distribution_nodes.json', 'r') as f: spikes = Spikes([], [])
dist_nodes = json.load(f) for node in nodes.nest_simulation_nodes:
information_node = dist_nodes['addresses'][0] response = requests.get(
node+'/spikes', params={"from": _from, "to": to, "population": population_id})
try:
response_json = response.json()
spikes.simulation_times.extend(response_json['simulation_times'])
spikes.gids.extend(response_json['gids'])
except:
pass
# # sort
# sorted_ids = [x for _, x in sorted(
# zip(spikes.simulation_times, spikes.gids))]
# spikes.gids = sorted_ids
# spikes.simulation_times.sort()
# # offset and limit
# if (offset is None):
# offset = 0
# if (limit is None or (limit + offset) > len(spikes.gids)):
# limit = len(spikes.gids) - offset
# spikes.gids = spikes.gids[offset:offset+limit]
# spikes.simulation_times = spikes.simulation_times[offset:offset+limit]
return spikes
# spikes = Spikes([], [])
# for node in nodes.nest_simulation_nodes:
# response = requests.get(
# node+'/population/$'+str(population_id)+'/spikes', params={"from": _from, "to": to}).json()
# for x in range(len(response['simulation_times'])):
# spikes.simulation_times.append(response['simulation_times'][x])
# spikes.gids.append(response['gids'][x])
# # sort
# sorted_ids = [x for _, x in sorted(
# zip(spikes.simulation_times, spikes.gids))]
# spikes.gids = sorted_ids
# spikes.simulation_times.sort()
# # offset and limit
# if (offset is None):
# offset = 0
# if (limit is None or (limit + offset) > len(spikes.gids)):
# limit = len(spikes.gids) - offset
# spikes.gids = spikes.gids[offset:offset+limit]
# spikes.simulation_times = spikes.simulation_times[offset:offset+limit]
# return spikes
\ No newline at end of file
response = requests.get(information_node+'/timestep').json()
return response
{
"port": 5000,
"addresses" : [
"http://127.0.0.1:5000",
"http://127.0.0.1:5000"
]
}
\ No newline at end of file
{
"address": "http://info-node:8080"
}
\ No newline at end of file
...@@ -3,8 +3,12 @@ ...@@ -3,8 +3,12 @@
# flake8: noqa # flake8: noqa
from __future__ import absolute_import from __future__ import absolute_import
# import models into model package # import models into model package
from access_node.models.attribute import Attribute from access_node.models.arbor_cell_properties import ArborCellProperties
from access_node.models.data import Data from access_node.models.arbor_measurement import ArborMeasurement
from access_node.models.error import Error from access_node.models.multimeter_info import MultimeterInfo
from access_node.models.precision import Precision from access_node.models.multimeter_info_inner import MultimeterInfoInner
from access_node.models.multimeter_measurement import MultimeterMeasurement
from access_node.models.nest_neuron_properties import NestNeuronProperties
from access_node.models.probe import Probe
from access_node.models.simulation_time_info import SimulationTimeInfo
from access_node.models.spikes import Spikes from access_node.models.spikes import Spikes
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model
from access_node import util
class ArborCellProperties(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, neuron_id: int=None, properties: object=None): # noqa: E501
"""ArborCellProperties - a model defined in Swagger
:param neuron_id: The neuron_id of this ArborCellProperties. # noqa: E501
:type neuron_id: int
:param properties: The properties of this ArborCellProperties. # noqa: E501
:type properties: object
"""
self.swagger_types = {
'neuron_id': int,
'properties': object
}
self.attribute_map = {
'neuron_id': 'neuron_id',
'properties': 'properties'
}
self._neuron_id = neuron_id
self._properties = properties
@classmethod
def from_dict(cls, dikt) -> 'ArborCellProperties':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The ArborCellProperties of this ArborCellProperties. # noqa: E501
:rtype: ArborCellProperties
"""
return util.deserialize_model(dikt, cls)
@property
def neuron_id(self) -> int:
"""Gets the neuron_id of this ArborCellProperties.
:return: The neuron_id of this ArborCellProperties.
:rtype: int
"""
return self._neuron_id
@neuron_id.setter
def neuron_id(self, neuron_id: int):
"""Sets the neuron_id of this ArborCellProperties.
:param neuron_id: The neuron_id of this ArborCellProperties.
:type neuron_id: int
"""
self._neuron_id = neuron_id
@property
def properties(self) -> object:
"""Gets the properties of this ArborCellProperties.
:return: The properties of this ArborCellProperties.
:rtype: object
"""
return self._properties
@properties.setter
def properties(self, properties: object):
"""Sets the properties of this ArborCellProperties.
:param properties: The properties of this ArborCellProperties.
:type properties: object
"""
self._properties = properties
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model
from access_node import util
class ArborMeasurement(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, simulation_times: List[float]=None, gids: List[int]=None, values: List[float]=None): # noqa: E501
"""ArborMeasurement - a model defined in Swagger
:param simulation_times: The simulation_times of this ArborMeasurement. # noqa: E501
:type simulation_times: List[float]
:param gids: The gids of this ArborMeasurement. # noqa: E501
:type gids: List[int]
:param values: The values of this ArborMeasurement. # noqa: E501
:type values: List[float]
"""
self.swagger_types = {
'simulation_times': List[float],
'gids': List[int],
'values': List[float]
}
self.attribute_map = {
'simulation_times': 'simulation_times',
'gids': 'gids',
'values': 'values'
}
self._simulation_times = simulation_times
self._gids = gids
self._values = values
@classmethod
def from_dict(cls, dikt) -> 'ArborMeasurement':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The ArborMeasurement of this ArborMeasurement. # noqa: E501
:rtype: ArborMeasurement
"""
return util.deserialize_model(dikt, cls)
@property
def simulation_times(self) -> List[float]:
"""Gets the simulation_times of this ArborMeasurement.
This array is always sorted. # noqa: E501
:return: The simulation_times of this ArborMeasurement.
:rtype: List[float]
"""
return self._simulation_times
@simulation_times.setter
def simulation_times(self, simulation_times: List[float]):
"""Sets the simulation_times of this ArborMeasurement.
This array is always sorted. # noqa: E501
:param simulation_times: The simulation_times of this ArborMeasurement.
:type simulation_times: List[float]
"""
self._simulation_times = simulation_times
@property
def gids(self) -> List[int]:
"""Gets the gids of this ArborMeasurement.
:return: The gids of this ArborMeasurement.
:rtype: List[int]
"""
return self._gids
@gids.setter
def gids(self, gids: List[int]):
"""Sets the gids of this ArborMeasurement.
:param gids: The gids of this ArborMeasurement.
:type gids: List[int]
"""
self._gids = gids
@property
def values(self) -> List[float]:
"""Gets the values of this ArborMeasurement.
This array contains the measured values for each gid and time to get the value for gid n at time t you have to use the index n * length(simulation_times) + t # noqa: E501
:return: The values of this ArborMeasurement.
:rtype: List[float]
"""
return self._values
@values.setter
def values(self, values: List[float]):
"""Sets the values of this ArborMeasurement.
This array contains the measured values for each gid and time to get the value for gid n at time t you have to use the index n * length(simulation_times) + t # noqa: E501
:param values: The values of this ArborMeasurement.
:type values: List[float]
"""
self._values = values
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model
from access_node import util
class ArborNeuronProperties(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, neuron_id: int=None, properties: object=None): # noqa: E501
"""ArborNeuronProperties - a model defined in Swagger
:param neuron_id: The neuron_id of this ArborNeuronProperties. # noqa: E501
:type neuron_id: int
:param properties: The properties of this ArborNeuronProperties. # noqa: E501
:type properties: object
"""
self.swagger_types = {
'neuron_id': int,
'properties': object
}
self.attribute_map = {
'neuron_id': 'neuron_id',
'properties': 'properties'
}
self._neuron_id = neuron_id
self._properties = properties
@classmethod
def from_dict(cls, dikt) -> 'ArborNeuronProperties':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The ArborNeuronProperties of this ArborNeuronProperties. # noqa: E501
:rtype: ArborNeuronProperties
"""
return util.deserialize_model(dikt, cls)
@property
def neuron_id(self) -> int:
"""Gets the neuron_id of this ArborNeuronProperties.
:return: The neuron_id of this ArborNeuronProperties.
:rtype: int
"""
return self._neuron_id
@neuron_id.setter
def neuron_id(self, neuron_id: int):
"""Sets the neuron_id of this ArborNeuronProperties.
:param neuron_id: The neuron_id of this ArborNeuronProperties.
:type neuron_id: int
"""
self._neuron_id = neuron_id
@property
def properties(self) -> object:
"""Gets the properties of this ArborNeuronProperties.
:return: The properties of this ArborNeuronProperties.
:rtype: object
"""
return self._properties
@properties.setter
def properties(self, properties: object):
"""Sets the properties of this ArborNeuronProperties.
:param properties: The properties of this ArborNeuronProperties.
:type properties: object
"""
self._properties = properties
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model
from access_node import util
class Data(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, first_simulation_step: float=None, num_simulation_steps: float=None, neuron_ids: List[float]=None, values: List[List[float]]=None): # noqa: E501
"""Data - a model defined in Swagger
:param first_simulation_step: The first_simulation_step of this Data. # noqa: E501
:type first_simulation_step: float
:param num_simulation_steps: The num_simulation_steps of this Data. # noqa: E501
:type num_simulation_steps: float
:param neuron_ids: The neuron_ids of this Data. # noqa: E501
:type neuron_ids: List[float]
:param values: The values of this Data. # noqa: E501
:type values: List[List[float]]
"""
self.swagger_types = {
'first_simulation_step': float,
'num_simulation_steps': float,
'neuron_ids': List[float],
'values': List[List[float]]
}
self.attribute_map = {
'first_simulation_step': 'first_simulation_step',
'num_simulation_steps': 'num_simulation_steps',
'neuron_ids': 'neuron_ids',
'values': 'values'
}
self._first_simulation_step = first_simulation_step
self._num_simulation_steps = num_simulation_steps
self._neuron_ids = neuron_ids
self._values = values
@classmethod
def from_dict(cls, dikt) -> 'Data':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The Data of this Data. # noqa: E501
:rtype: Data
"""
return util.deserialize_model(dikt, cls)
@property
def first_simulation_step(self) -> float:
"""Gets the first_simulation_step of this Data.
:return: The first_simulation_step of this Data.
:rtype: float
"""
return self._first_simulation_step
@first_simulation_step.setter
def first_simulation_step(self, first_simulation_step: float):
"""Sets the first_simulation_step of this Data.
:param first_simulation_step: The first_simulation_step of this Data.
:type first_simulation_step: float
"""
self._first_simulation_step = first_simulation_step
@property
def num_simulation_steps(self) -> float:
"""Gets the num_simulation_steps of this Data.
:return: The num_simulation_steps of this Data.
:rtype: float
"""
return self._num_simulation_steps
@num_simulation_steps.setter
def num_simulation_steps(self, num_simulation_steps: float):
"""Sets the num_simulation_steps of this Data.
:param num_simulation_steps: The num_simulation_steps of this Data.
:type num_simulation_steps: float
"""
self._num_simulation_steps = num_simulation_steps
@property
def neuron_ids(self) -> List[float]:
"""Gets the neuron_ids of this Data.
:return: The neuron_ids of this Data.
:rtype: List[float]
"""
return self._neuron_ids
@neuron_ids.setter
def neuron_ids(self, neuron_ids: List[float]):
"""Sets the neuron_ids of this Data.
:param neuron_ids: The neuron_ids of this Data.
:type neuron_ids: List[float]
"""
self._neuron_ids = neuron_ids
@property
def values(self) -> List[List[float]]:
"""Gets the values of this Data.
:return: The values of this Data.
:rtype: List[List[float]]
"""
return self._values
@values.setter
def values(self, values: List[List[float]]):
"""Sets the values of this Data.
:param values: The values of this Data.
:type values: List[List[float]]
"""
self._values = values
...@@ -6,23 +6,18 @@ from datetime import date, datetime # noqa: F401 ...@@ -6,23 +6,18 @@ from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401 from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model from access_node.models.base_model_ import Model
from access_node.models.multimeter_info_inner import MultimeterInfoInner # noqa: F401,E501
from access_node import util from access_node import util
class Precision(Model): class MultimeterInfo(Model):
"""NOTE: This class is auto generated by the swagger code generator program. """NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually. Do not edit the class manually.
""" """
"""
allowed enum values
"""
DOUBLE = "double"
INTEGER = "integer"
def __init__(self): # noqa: E501 def __init__(self): # noqa: E501
"""Precision - a model defined in Swagger """MultimeterInfo - a model defined in Swagger
""" """
self.swagger_types = { self.swagger_types = {
...@@ -32,12 +27,12 @@ class Precision(Model): ...@@ -32,12 +27,12 @@ class Precision(Model):
} }
@classmethod @classmethod
def from_dict(cls, dikt) -> 'Precision': def from_dict(cls, dikt) -> 'MultimeterInfo':
"""Returns the dict as a model """Returns the dict as a model
:param dikt: A dict. :param dikt: A dict.
:type: dict :type: dict
:return: The Precision of this Precision. # noqa: E501 :return: The MultimeterInfo of this MultimeterInfo. # noqa: E501
:rtype: Precision :rtype: MultimeterInfo
""" """
return util.deserialize_model(dikt, cls) return util.deserialize_model(dikt, cls)
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model
from access_node import util
class MultimeterInfoInner(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, id: int=None, attributes: List[str]=None, gids: List[int]=None): # noqa: E501
"""MultimeterInfoInner - a model defined in Swagger
:param id: The id of this MultimeterInfoInner. # noqa: E501
:type id: int
:param attributes: The attributes of this MultimeterInfoInner. # noqa: E501
:type attributes: List[str]
:param gids: The gids of this MultimeterInfoInner. # noqa: E501
:type gids: List[int]
"""
self.swagger_types = {
'id': int,
'attributes': List[str],
'gids': List[int]
}
self.attribute_map = {
'id': 'id',
'attributes': 'attributes',
'gids': 'gids'
}
self._id = id
self._attributes = attributes
self._gids = gids
@classmethod
def from_dict(cls, dikt) -> 'MultimeterInfoInner':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The MultimeterInfo_inner of this MultimeterInfoInner. # noqa: E501
:rtype: MultimeterInfoInner
"""
return util.deserialize_model(dikt, cls)
@property
def id(self) -> int:
"""Gets the id of this MultimeterInfoInner.
:return: The id of this MultimeterInfoInner.
:rtype: int
"""
return self._id
@id.setter
def id(self, id: int):
"""Sets the id of this MultimeterInfoInner.
:param id: The id of this MultimeterInfoInner.
:type id: int
"""
self._id = id
@property
def attributes(self) -> List[str]:
"""Gets the attributes of this MultimeterInfoInner.
:return: The attributes of this MultimeterInfoInner.
:rtype: List[str]
"""
return self._attributes
@attributes.setter
def attributes(self, attributes: List[str]):
"""Sets the attributes of this MultimeterInfoInner.
:param attributes: The attributes of this MultimeterInfoInner.
:type attributes: List[str]
"""
self._attributes = attributes
@property
def gids(self) -> List[int]:
"""Gets the gids of this MultimeterInfoInner.
:return: The gids of this MultimeterInfoInner.
:rtype: List[int]
"""
return self._gids
@gids.setter
def gids(self, gids: List[int]):
"""Sets the gids of this MultimeterInfoInner.
:param gids: The gids of this MultimeterInfoInner.
:type gids: List[int]
"""
self._gids = gids
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model
from access_node import util
class MultimeterMeasurement(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, simulation_times: List[float]=None, gids: List[int]=None, values: List[float]=None): # noqa: E501
"""MultimeterMeasurement - a model defined in Swagger
:param simulation_times: The simulation_times of this MultimeterMeasurement. # noqa: E501
:type simulation_times: List[float]
:param gids: The gids of this MultimeterMeasurement. # noqa: E501
:type gids: List[int]
:param values: The values of this MultimeterMeasurement. # noqa: E501
:type values: List[float]
"""
self.swagger_types = {
'simulation_times': List[float],
'gids': List[int],
'values': List[float]
}
self.attribute_map = {
'simulation_times': 'simulation_times',
'gids': 'gids',
'values': 'values'
}
self._simulation_times = simulation_times
self._gids = gids
self._values = values
@classmethod
def from_dict(cls, dikt) -> 'MultimeterMeasurement':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The MultimeterMeasurement of this MultimeterMeasurement. # noqa: E501
:rtype: MultimeterMeasurement
"""
return util.deserialize_model(dikt, cls)
@property
def simulation_times(self) -> List[float]:
"""Gets the simulation_times of this MultimeterMeasurement.
This array is always sorted. # noqa: E501
:return: The simulation_times of this MultimeterMeasurement.
:rtype: List[float]
"""
return self._simulation_times
@simulation_times.setter
def simulation_times(self, simulation_times: List[float]):
"""Sets the simulation_times of this MultimeterMeasurement.
This array is always sorted. # noqa: E501
:param simulation_times: The simulation_times of this MultimeterMeasurement.
:type simulation_times: List[float]
"""
self._simulation_times = simulation_times
@property
def gids(self) -> List[int]:
"""Gets the gids of this MultimeterMeasurement.
:return: The gids of this MultimeterMeasurement.
:rtype: List[int]
"""
return self._gids
@gids.setter
def gids(self, gids: List[int]):
"""Sets the gids of this MultimeterMeasurement.
:param gids: The gids of this MultimeterMeasurement.
:type gids: List[int]
"""
self._gids = gids
@property
def values(self) -> List[float]:
"""Gets the values of this MultimeterMeasurement.
This array contains the measured values for each probe and time to get the value for probe n at time t you have to use the index n * length(simulation_times) + t # noqa: E501
:return: The values of this MultimeterMeasurement.
:rtype: List[float]
"""
return self._values
@values.setter
def values(self, values: List[float]):
"""Sets the values of this MultimeterMeasurement.
This array contains the measured values for each probe and time to get the value for probe n at time t you have to use the index n * length(simulation_times) + t # noqa: E501
:param values: The values of this MultimeterMeasurement.
:type values: List[float]
"""
self._values = values
...@@ -9,82 +9,82 @@ from access_node.models.base_model_ import Model ...@@ -9,82 +9,82 @@ from access_node.models.base_model_ import Model
from access_node import util from access_node import util
class Error(Model): class NestNeuronProperties(Model):
"""NOTE: This class is auto generated by the swagger code generator program. """NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually. Do not edit the class manually.
""" """
def __init__(self, code: float=None, message: str=None): # noqa: E501 def __init__(self, gid: int=None, properties: object=None): # noqa: E501
"""Error - a model defined in Swagger """NestNeuronProperties - a model defined in Swagger
:param code: The code of this Error. # noqa: E501 :param gid: The gid of this NestNeuronProperties. # noqa: E501
:type code: float :type gid: int
:param message: The message of this Error. # noqa: E501 :param properties: The properties of this NestNeuronProperties. # noqa: E501
:type message: str :type properties: object
""" """
self.swagger_types = { self.swagger_types = {
'code': float, 'gid': int,
'message': str 'properties': object
} }
self.attribute_map = { self.attribute_map = {
'code': 'code', 'gid': 'gid',
'message': 'message' 'properties': 'properties'
} }
self._code = code self._gid = gid
self._message = message self._properties = properties
@classmethod @classmethod
def from_dict(cls, dikt) -> 'Error': def from_dict(cls, dikt) -> 'NestNeuronProperties':
"""Returns the dict as a model """Returns the dict as a model
:param dikt: A dict. :param dikt: A dict.
:type: dict :type: dict
:return: The Error of this Error. # noqa: E501 :return: The NestNeuronProperties of this NestNeuronProperties. # noqa: E501
:rtype: Error :rtype: NestNeuronProperties
""" """
return util.deserialize_model(dikt, cls) return util.deserialize_model(dikt, cls)
@property @property
def code(self) -> float: def gid(self) -> int:
"""Gets the code of this Error. """Gets the gid of this NestNeuronProperties.
:return: The code of this Error. :return: The gid of this NestNeuronProperties.
:rtype: float :rtype: int
""" """
return self._code return self._gid
@code.setter @gid.setter
def code(self, code: float): def gid(self, gid: int):
"""Sets the code of this Error. """Sets the gid of this NestNeuronProperties.
:param code: The code of this Error. :param gid: The gid of this NestNeuronProperties.
:type code: float :type gid: int
""" """
self._code = code self._gid = gid
@property @property
def message(self) -> str: def properties(self) -> object:
"""Gets the message of this Error. """Gets the properties of this NestNeuronProperties.
:return: The message of this Error. :return: The properties of this NestNeuronProperties.
:rtype: str :rtype: object
""" """
return self._message return self._properties
@message.setter @properties.setter
def message(self, message: str): def properties(self, properties: object):
"""Sets the message of this Error. """Sets the properties of this NestNeuronProperties.
:param message: The message of this Error. :param properties: The properties of this NestNeuronProperties.
:type message: str :type properties: object
""" """
self._message = message self._properties = properties
...@@ -6,86 +6,85 @@ from datetime import date, datetime # noqa: F401 ...@@ -6,86 +6,85 @@ from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401 from typing import List, Dict # noqa: F401
from access_node.models.base_model_ import Model from access_node.models.base_model_ import Model
from access_node.models.precision import Precision # noqa: F401,E501
from access_node import util from access_node import util
class Attribute(Model): class NeuronProperties(Model):
"""NOTE: This class is auto generated by the swagger code generator program. """NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually. Do not edit the class manually.
""" """
def __init__(self, name: str=None, precision: Precision=None): # noqa: E501 def __init__(self, gid: int=None, properties: object=None): # noqa: E501
"""Attribute - a model defined in Swagger """NeuronProperties - a model defined in Swagger
:param name: The name of this Attribute. # noqa: E501 :param gid: The gid of this NeuronProperties. # noqa: E501
:type name: str :type gid: int
:param precision: The precision of this Attribute. # noqa: E501 :param properties: The properties of this NeuronProperties. # noqa: E501
:type precision: Precision :type properties: object
""" """
self.swagger_types = { self.swagger_types = {
'name': str, 'gid': int,
'precision': Precision 'properties': object
} }
self.attribute_map = { self.attribute_map = {
'name': 'name', 'gid': 'gid',
'precision': 'precision' 'properties': 'properties'
} }
self._name = name self._gid = gid
self._precision = precision self._properties = properties
@classmethod @classmethod
def from_dict(cls, dikt) -> 'Attribute': def from_dict(cls, dikt) -> 'NeuronProperties':
"""Returns the dict as a model """Returns the dict as a model
:param dikt: A dict. :param dikt: A dict.
:type: dict :type: dict
:return: The Attribute of this Attribute. # noqa: E501 :return: The NeuronProperties of this NeuronProperties. # noqa: E501
:rtype: Attribute :rtype: NeuronProperties
""" """
return util.deserialize_model(dikt, cls) return util.deserialize_model(dikt, cls)
@property @property
def name(self) -> str: def gid(self) -> int:
"""Gets the name of this Attribute. """Gets the gid of this NeuronProperties.
:return: The name of this Attribute. :return: The gid of this NeuronProperties.
:rtype: str :rtype: int
""" """
return self._name return self._gid
@name.setter @gid.setter
def name(self, name: str): def gid(self, gid: int):
"""Sets the name of this Attribute. """Sets the gid of this NeuronProperties.
:param name: The name of this Attribute. :param gid: The gid of this NeuronProperties.
:type name: str :type gid: int
""" """
self._name = name self._gid = gid
@property @property
def precision(self) -> Precision: def properties(self) -> object:
"""Gets the precision of this Attribute. """Gets the properties of this NeuronProperties.
:return: The precision of this Attribute. :return: The properties of this NeuronProperties.
:rtype: Precision :rtype: object
""" """
return self._precision return self._properties
@precision.setter @properties.setter
def precision(self, precision: Precision): def properties(self, properties: object):
"""Sets the precision of this Attribute. """Sets the properties of this NeuronProperties.
:param precision: The precision of this Attribute. :param properties: The properties of this NeuronProperties.
:type precision: Precision :type properties: object
""" """
self._precision = precision self._properties = properties
from typing import List
class Nodes(object):
def __init__(self, info_node: str=None, nest_simulation_nodes: List[str]=None, arbor_simulation_nodes: List[str]=None):
self.info_node = info_node
self.nest_simulation_nodes = nest_simulation_nodes
self.arbor_simulation_nodes = arbor_simulation_nodes
nodes = Nodes()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment