diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..4c4b6134968f43ae12d65f185a89cc226dde028c --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,36 @@ +# 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 diff --git a/.swagger-codegen-ignore b/.swagger-codegen-ignore index 740abad13e6f094e438aaecd285b0614f46d98ab..19e32ada7d435e9440b2031105940cfa8b5fff00 100644 --- a/.swagger-codegen-ignore +++ b/.swagger-codegen-ignore @@ -23,4 +23,4 @@ #!docs/README.md README.md requirements.txt -access_node/controllers/nest_controller.py \ No newline at end of file +#access_node/controllers/nest_controller.py \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e879fcc560ce44570318342b7c965539b1f10db9..25a520c95ebb80aad13c696963ce55f5649bfad9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3-alpine +FROM python:3.6-slim RUN mkdir -p /usr/src/app WORKDIR /usr/src/app diff --git a/README.md b/README.md index 6b54a5ee028b52d2f4505c5c36e7aaa15f8c72ba..b276b37c9e62518e3224a3702efd253fb9f371b3 100644 --- a/README.md +++ b/README.md @@ -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: ``` -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 diff --git a/access_node/__main__.py b/access_node/__main__.py index d96cc1630eae64e8bace757db08bebe2bb3c67b3..a7919408701e8fe108583dcd287bfe87d9739d0a 100644 --- a/access_node/__main__.py +++ b/access_node/__main__.py @@ -3,12 +3,48 @@ import connexion 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(): + # 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.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) diff --git a/access_node/controllers/arbor_controller.py b/access_node/controllers/arbor_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..5ce7f7706e8d94b57be933da8153fd8dea1ec1bd --- /dev/null +++ b/access_node/controllers/arbor_controller.py @@ -0,0 +1,252 @@ +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., 'V_m' 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 diff --git a/access_node/controllers/nest_controller.py b/access_node/controllers/nest_controller.py index c3144b15f24b14f1bca181101f698b0b1a5790dd..e4d52ca51689e3d66b4554d6323bdecc2e02fd15 100644 --- a/access_node/controllers/nest_controller.py +++ b/access_node/controllers/nest_controller.py @@ -1,147 +1,359 @@ import connexion import six -from access_node.models.attribute import Attribute # noqa: E501 -from access_node.models.data import Data # noqa: E501 -from access_node.models.error import Error # noqa: E501 +from access_node.models.multimeter_info import MultimeterInfo # noqa: E501 +from access_node.models.multimeter_measurement import MultimeterMeasurement # 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 import util -# My imports -import json +from access_node.models.nodes import nodes import requests +import psycopg2 +import numpy as np -def get_attributes(): # noqa: E501 - """Retrieves the details of per-neuron attributes. +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 nest_get_gids(): # noqa: E501 + """Retrieves the list of all GID. # noqa: E501 - :rtype: List[Attribute] + :rtype: List[int] """ - with open('access_node//distribution_nodes.json', 'r') as f: - dist_nodes = json.load(f) - information_node = dist_nodes['addresses'][0] + con = connect_to_database() + cur = con.cursor() + + cur.execute("SELECT id FROM nest_neuron") + gids = [i[0] for i in cur.fetchall()] - response = requests.get(information_node+'/attributes').json() - return response + con.close() + return gids -def get_data(attribute, simulation_steps=None, neuron_ids=None): # noqa: E501 - """Retrieves the per-neuron attributes for the given attribute name, simulation steps (optional) and neuron IDs (optional). +def nest_get_gids_in_population(population_id): # noqa: E501 + """Retrieves the list of all neuron IDs within the population. # 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[] + :param population_id: The identifier of the population + :type population_id: int - :rtype: Data + :rtype: List[int] """ - # 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'] - - if simulation_steps != None: - num_ts = len(simulation_steps) - first_ts = simulation_steps[0] - else: - num_ts = get_simulation_step_count() - first_ts = get_timestep() + 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 + + + :rtype: MultimeterInfo + """ + con = connect_to_database() + cur = con.cursor() + + cur.execute("SELECT * FROM nest_multimeter;") + attributes = np.array(cur.fetchall()) + + + 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 + - if neuron_ids != None: - ids = neuron_ids +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., 'V_m' 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: - ids = get_neuron_ids() + for gid in gids: + 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. - data = Data(first_ts, num_ts, ids, - [[None]*num_ts for x in range(len(ids))]) - for address in addresses: - response = requests.get(address+'/data', params={ - "attribute": attribute, "simulation_steps": simulation_steps, "neuron_ids": neuron_ids}).json() - for x in range(len(response['neuron_ids'])): - data.values[data.neuron_ids.index( - response['neuron_ids'][x])] = response['data'][x] - return data + # noqa: E501 + :param gids: A list of GIDs queried for properties. + :type gids: List[int] -def get_neuron_ids(): # noqa: E501 - """Retrieves the list of all neuron IDs. + :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 gids == None: + cur.execute("Select * FROM nest_neuron") + else: + cur.execute("Select * FROM nest_neuron WHERE id IN %s", (tuple(gids),)) + + nest_properties = [] + properties = np.array(cur.fetchall()) + if properties.size != 0: + properties = np.delete(properties, [1,2], 1) + for k in range(len(properties[:,0])): + props = {} + id = properties[k,0] + for i in range(1, len(colnames)): + 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 nest_get_populations(): # noqa: E501 + """Retrieves the list of all population IDs. # noqa: E501 - :rtype: List[float] + :rtype: List[int] """ - with open('access_node//distribution_nodes.json', 'r') as f: - dist_nodes = json.load(f) - information_node = dist_nodes['addresses'][0] + con = connect_to_database() + cur = con.cursor() + + 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() - return response + con.close() + return populations -def get_simulation_step_count(): # noqa: E501 - """Retrieves the number of simulation steps. +def nest_get_simulation_time_info(): # noqa: E501 + """Retrieves simulation time information. # 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() - return response + current_time = float('inf') + 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 - :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[] + :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: 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([], []) - for address in addresses: + for node in nodes.nest_simulation_nodes: response = requests.get( - address+'/spikes', params={"simulation_steps": simulation_steps, "neuron_ids": neuron_ids}).json() - for x in range(len(response['simulation_steps'])): - spikes.simulation_steps.append(response['simulation_steps'][x]) - spikes.neuron_ids.append(response['neuron_ids'][x]) + node+'/spikes', params={"from": _from, "to": to, "gids": gids}).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] - # Sort this? return spikes -def get_timestep(): # noqa: E501 - """Retrieves the time between two simulation steps. +def nest_get_spikes_by_population(population_id, _from=None, to=None, offset=None, limit=None): # noqa: E501 + """Retrieves the spikes for the given simulation steps (optional) and population. # 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: - dist_nodes = json.load(f) - information_node = dist_nodes['addresses'][0] + spikes = Spikes([], []) + for node in nodes.nest_simulation_nodes: + 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] - response = requests.get(information_node+'/timestep').json() - return response + 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 diff --git a/access_node/distribution_nodes.json b/access_node/distribution_nodes.json deleted file mode 100644 index 2264e66aef662b9df86be4f71bf0ad0dbf9ee03f..0000000000000000000000000000000000000000 --- a/access_node/distribution_nodes.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "port": 5000, - "addresses" : [ - "http://127.0.0.1:5000", - "http://127.0.0.1:5000" - ] -} \ No newline at end of file diff --git a/access_node/info_node.json b/access_node/info_node.json new file mode 100644 index 0000000000000000000000000000000000000000..2b61657b69999462f43bdc92b4401bfb53355fe4 --- /dev/null +++ b/access_node/info_node.json @@ -0,0 +1,3 @@ +{ + "address": "http://info-node:8080" +} \ No newline at end of file diff --git a/access_node/models/__init__.py b/access_node/models/__init__.py index 6102b118485d89364cfc3cd127110498f6bcbd65..dfeebbec167737c6865bdcec6dd2fa7431f7d8d8 100644 --- a/access_node/models/__init__.py +++ b/access_node/models/__init__.py @@ -3,8 +3,12 @@ # flake8: noqa from __future__ import absolute_import # import models into model package -from access_node.models.attribute import Attribute -from access_node.models.data import Data -from access_node.models.error import Error -from access_node.models.precision import Precision +from access_node.models.arbor_cell_properties import ArborCellProperties +from access_node.models.arbor_measurement import ArborMeasurement +from access_node.models.multimeter_info import MultimeterInfo +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 diff --git a/access_node/models/arbor_cell_properties.py b/access_node/models/arbor_cell_properties.py new file mode 100644 index 0000000000000000000000000000000000000000..4a574fc6f38ac9e18b7cd07dc48a53eab5f4281a --- /dev/null +++ b/access_node/models/arbor_cell_properties.py @@ -0,0 +1,90 @@ +# 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 diff --git a/access_node/models/arbor_measurement.py b/access_node/models/arbor_measurement.py new file mode 100644 index 0000000000000000000000000000000000000000..98146c824b1a436058204e4390f398072d16b481 --- /dev/null +++ b/access_node/models/arbor_measurement.py @@ -0,0 +1,120 @@ +# 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 diff --git a/access_node/models/arbor_neuron_properties.py b/access_node/models/arbor_neuron_properties.py new file mode 100644 index 0000000000000000000000000000000000000000..f3d2d80e073ae5748198bd19fa63ca0d78b2e150 --- /dev/null +++ b/access_node/models/arbor_neuron_properties.py @@ -0,0 +1,90 @@ +# 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 diff --git a/access_node/models/attribute.py b/access_node/models/attribute.py deleted file mode 100644 index 8270b5a50819005149825b84dbd40f209e4b6627..0000000000000000000000000000000000000000 --- a/access_node/models/attribute.py +++ /dev/null @@ -1,91 +0,0 @@ -# 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.models.precision import Precision # noqa: F401,E501 -from access_node import util - - -class Attribute(Model): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - """ - - def __init__(self, name: str=None, precision: Precision=None): # noqa: E501 - """Attribute - a model defined in Swagger - - :param name: The name of this Attribute. # noqa: E501 - :type name: str - :param precision: The precision of this Attribute. # noqa: E501 - :type precision: Precision - """ - self.swagger_types = { - 'name': str, - 'precision': Precision - } - - self.attribute_map = { - 'name': 'name', - 'precision': 'precision' - } - - self._name = name - self._precision = precision - - @classmethod - def from_dict(cls, dikt) -> 'Attribute': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The Attribute of this Attribute. # noqa: E501 - :rtype: Attribute - """ - return util.deserialize_model(dikt, cls) - - @property - def name(self) -> str: - """Gets the name of this Attribute. - - - :return: The name of this Attribute. - :rtype: str - """ - return self._name - - @name.setter - def name(self, name: str): - """Sets the name of this Attribute. - - - :param name: The name of this Attribute. - :type name: str - """ - - self._name = name - - @property - def precision(self) -> Precision: - """Gets the precision of this Attribute. - - - :return: The precision of this Attribute. - :rtype: Precision - """ - return self._precision - - @precision.setter - def precision(self, precision: Precision): - """Sets the precision of this Attribute. - - - :param precision: The precision of this Attribute. - :type precision: Precision - """ - - self._precision = precision diff --git a/access_node/models/data.py b/access_node/models/data.py deleted file mode 100644 index 690de2176f9f622be308932bbcfe7dca22af9797..0000000000000000000000000000000000000000 --- a/access_node/models/data.py +++ /dev/null @@ -1,142 +0,0 @@ -# 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 diff --git a/access_node/models/error.py b/access_node/models/error.py deleted file mode 100644 index 563f5979be751e7eb69da0aea3a4c888e8ae01bf..0000000000000000000000000000000000000000 --- a/access_node/models/error.py +++ /dev/null @@ -1,90 +0,0 @@ -# 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 Error(Model): - """NOTE: This class is auto generated by the swagger code generator program. - - Do not edit the class manually. - """ - - def __init__(self, code: float=None, message: str=None): # noqa: E501 - """Error - a model defined in Swagger - - :param code: The code of this Error. # noqa: E501 - :type code: float - :param message: The message of this Error. # noqa: E501 - :type message: str - """ - self.swagger_types = { - 'code': float, - 'message': str - } - - self.attribute_map = { - 'code': 'code', - 'message': 'message' - } - - self._code = code - self._message = message - - @classmethod - def from_dict(cls, dikt) -> 'Error': - """Returns the dict as a model - - :param dikt: A dict. - :type: dict - :return: The Error of this Error. # noqa: E501 - :rtype: Error - """ - return util.deserialize_model(dikt, cls) - - @property - def code(self) -> float: - """Gets the code of this Error. - - - :return: The code of this Error. - :rtype: float - """ - return self._code - - @code.setter - def code(self, code: float): - """Sets the code of this Error. - - - :param code: The code of this Error. - :type code: float - """ - - self._code = code - - @property - def message(self) -> str: - """Gets the message of this Error. - - - :return: The message of this Error. - :rtype: str - """ - return self._message - - @message.setter - def message(self, message: str): - """Sets the message of this Error. - - - :param message: The message of this Error. - :type message: str - """ - - self._message = message diff --git a/access_node/models/precision.py b/access_node/models/multimeter_info.py similarity index 66% rename from access_node/models/precision.py rename to access_node/models/multimeter_info.py index 5d4b1e389c11f6a5ab7d7ff3a211c7fffd02c415..d66278e6d45a5dd9b862265eda003b7e951ceb61 100644 --- a/access_node/models/precision.py +++ b/access_node/models/multimeter_info.py @@ -6,23 +6,18 @@ 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.models.multimeter_info_inner import MultimeterInfoInner # noqa: F401,E501 from access_node import util -class Precision(Model): +class MultimeterInfo(Model): """NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. """ - """ - allowed enum values - """ - DOUBLE = "double" - INTEGER = "integer" - def __init__(self): # noqa: E501 - """Precision - a model defined in Swagger + """MultimeterInfo - a model defined in Swagger """ self.swagger_types = { @@ -32,12 +27,12 @@ class Precision(Model): } @classmethod - def from_dict(cls, dikt) -> 'Precision': + def from_dict(cls, dikt) -> 'MultimeterInfo': """Returns the dict as a model :param dikt: A dict. :type: dict - :return: The Precision of this Precision. # noqa: E501 - :rtype: Precision + :return: The MultimeterInfo of this MultimeterInfo. # noqa: E501 + :rtype: MultimeterInfo """ return util.deserialize_model(dikt, cls) diff --git a/access_node/models/multimeter_info_inner.py b/access_node/models/multimeter_info_inner.py new file mode 100644 index 0000000000000000000000000000000000000000..fff3b96048fb1f578bca87fa076de688c483d89f --- /dev/null +++ b/access_node/models/multimeter_info_inner.py @@ -0,0 +1,116 @@ +# 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 diff --git a/access_node/models/multimeter_measurement.py b/access_node/models/multimeter_measurement.py new file mode 100644 index 0000000000000000000000000000000000000000..aa8bbb50b73f6710c728bf5f0f0f1f825bc83796 --- /dev/null +++ b/access_node/models/multimeter_measurement.py @@ -0,0 +1,120 @@ +# 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 diff --git a/access_node/models/nest_neuron_properties.py b/access_node/models/nest_neuron_properties.py new file mode 100644 index 0000000000000000000000000000000000000000..335e6862ba1881d78ddb1cb30f0bd667ef0773fb --- /dev/null +++ b/access_node/models/nest_neuron_properties.py @@ -0,0 +1,90 @@ +# 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 NestNeuronProperties(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, gid: int=None, properties: object=None): # noqa: E501 + """NestNeuronProperties - a model defined in Swagger + + :param gid: The gid of this NestNeuronProperties. # noqa: E501 + :type gid: int + :param properties: The properties of this NestNeuronProperties. # noqa: E501 + :type properties: object + """ + self.swagger_types = { + 'gid': int, + 'properties': object + } + + self.attribute_map = { + 'gid': 'gid', + 'properties': 'properties' + } + + self._gid = gid + self._properties = properties + + @classmethod + def from_dict(cls, dikt) -> 'NestNeuronProperties': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The NestNeuronProperties of this NestNeuronProperties. # noqa: E501 + :rtype: NestNeuronProperties + """ + return util.deserialize_model(dikt, cls) + + @property + def gid(self) -> int: + """Gets the gid of this NestNeuronProperties. + + + :return: The gid of this NestNeuronProperties. + :rtype: int + """ + return self._gid + + @gid.setter + def gid(self, gid: int): + """Sets the gid of this NestNeuronProperties. + + + :param gid: The gid of this NestNeuronProperties. + :type gid: int + """ + + self._gid = gid + + @property + def properties(self) -> object: + """Gets the properties of this NestNeuronProperties. + + + :return: The properties of this NestNeuronProperties. + :rtype: object + """ + return self._properties + + @properties.setter + def properties(self, properties: object): + """Sets the properties of this NestNeuronProperties. + + + :param properties: The properties of this NestNeuronProperties. + :type properties: object + """ + + self._properties = properties diff --git a/access_node/models/neuron_properties.py b/access_node/models/neuron_properties.py new file mode 100644 index 0000000000000000000000000000000000000000..75f78592d6a0961e4cf403e0e99d1de161e6c770 --- /dev/null +++ b/access_node/models/neuron_properties.py @@ -0,0 +1,90 @@ +# 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 NeuronProperties(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, gid: int=None, properties: object=None): # noqa: E501 + """NeuronProperties - a model defined in Swagger + + :param gid: The gid of this NeuronProperties. # noqa: E501 + :type gid: int + :param properties: The properties of this NeuronProperties. # noqa: E501 + :type properties: object + """ + self.swagger_types = { + 'gid': int, + 'properties': object + } + + self.attribute_map = { + 'gid': 'gid', + 'properties': 'properties' + } + + self._gid = gid + self._properties = properties + + @classmethod + def from_dict(cls, dikt) -> 'NeuronProperties': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The NeuronProperties of this NeuronProperties. # noqa: E501 + :rtype: NeuronProperties + """ + return util.deserialize_model(dikt, cls) + + @property + def gid(self) -> int: + """Gets the gid of this NeuronProperties. + + + :return: The gid of this NeuronProperties. + :rtype: int + """ + return self._gid + + @gid.setter + def gid(self, gid: int): + """Sets the gid of this NeuronProperties. + + + :param gid: The gid of this NeuronProperties. + :type gid: int + """ + + self._gid = gid + + @property + def properties(self) -> object: + """Gets the properties of this NeuronProperties. + + + :return: The properties of this NeuronProperties. + :rtype: object + """ + return self._properties + + @properties.setter + def properties(self, properties: object): + """Sets the properties of this NeuronProperties. + + + :param properties: The properties of this NeuronProperties. + :type properties: object + """ + + self._properties = properties diff --git a/access_node/models/nodes.py b/access_node/models/nodes.py new file mode 100644 index 0000000000000000000000000000000000000000..f9c7d136e4838bdf71173810ece63065fd7744d6 --- /dev/null +++ b/access_node/models/nodes.py @@ -0,0 +1,9 @@ +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() diff --git a/access_node/models/probe.py b/access_node/models/probe.py new file mode 100644 index 0000000000000000000000000000000000000000..d2b3c0caeb87117f5b68440d3f9b2014d9de7556 --- /dev/null +++ b/access_node/models/probe.py @@ -0,0 +1,142 @@ +# 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 Probe(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, cell_id: int=None, segment_id: int=None, position: float=None): # noqa: E501 + """Probe - a model defined in Swagger + + :param id: The id of this Probe. # noqa: E501 + :type id: int + :param cell_id: The cell_id of this Probe. # noqa: E501 + :type cell_id: int + :param segment_id: The segment_id of this Probe. # noqa: E501 + :type segment_id: int + :param position: The position of this Probe. # noqa: E501 + :type position: float + """ + self.swagger_types = { + 'id': int, + 'cell_id': int, + 'segment_id': int, + 'position': float + } + + self.attribute_map = { + 'id': 'id', + 'cell_id': 'cell_id', + 'segment_id': 'segment_id', + 'position': 'position' + } + + self._id = id + self._cell_id = cell_id + self._segment_id = segment_id + self._position = position + + @classmethod + def from_dict(cls, dikt) -> 'Probe': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Probe of this Probe. # noqa: E501 + :rtype: Probe + """ + return util.deserialize_model(dikt, cls) + + @property + def id(self) -> int: + """Gets the id of this Probe. + + + :return: The id of this Probe. + :rtype: int + """ + return self._id + + @id.setter + def id(self, id: int): + """Sets the id of this Probe. + + + :param id: The id of this Probe. + :type id: int + """ + + self._id = id + + @property + def cell_id(self) -> int: + """Gets the cell_id of this Probe. + + + :return: The cell_id of this Probe. + :rtype: int + """ + return self._cell_id + + @cell_id.setter + def cell_id(self, cell_id: int): + """Sets the cell_id of this Probe. + + + :param cell_id: The cell_id of this Probe. + :type cell_id: int + """ + + self._cell_id = cell_id + + @property + def segment_id(self) -> int: + """Gets the segment_id of this Probe. + + + :return: The segment_id of this Probe. + :rtype: int + """ + return self._segment_id + + @segment_id.setter + def segment_id(self, segment_id: int): + """Sets the segment_id of this Probe. + + + :param segment_id: The segment_id of this Probe. + :type segment_id: int + """ + + self._segment_id = segment_id + + @property + def position(self) -> float: + """Gets the position of this Probe. + + + :return: The position of this Probe. + :rtype: float + """ + return self._position + + @position.setter + def position(self, position: float): + """Sets the position of this Probe. + + + :param position: The position of this Probe. + :type position: float + """ + + self._position = position diff --git a/access_node/models/simulation_time_info.py b/access_node/models/simulation_time_info.py new file mode 100644 index 0000000000000000000000000000000000000000..5d379a4a3335875e3e97af0cac6201e960738cb4 --- /dev/null +++ b/access_node/models/simulation_time_info.py @@ -0,0 +1,116 @@ +# 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 SimulationTimeInfo(Model): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + + def __init__(self, start: float=None, end: float=None, current: float=None): # noqa: E501 + """SimulationTimeInfo - a model defined in Swagger + + :param start: The start of this SimulationTimeInfo. # noqa: E501 + :type start: float + :param end: The end of this SimulationTimeInfo. # noqa: E501 + :type end: float + :param current: The current of this SimulationTimeInfo. # noqa: E501 + :type current: float + """ + self.swagger_types = { + 'start': float, + 'end': float, + 'current': float + } + + self.attribute_map = { + 'start': 'start', + 'end': 'end', + 'current': 'current' + } + + self._start = start + self._end = end + self._current = current + + @classmethod + def from_dict(cls, dikt) -> 'SimulationTimeInfo': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The SimulationTimeInfo of this SimulationTimeInfo. # noqa: E501 + :rtype: SimulationTimeInfo + """ + return util.deserialize_model(dikt, cls) + + @property + def start(self) -> float: + """Gets the start of this SimulationTimeInfo. + + + :return: The start of this SimulationTimeInfo. + :rtype: float + """ + return self._start + + @start.setter + def start(self, start: float): + """Sets the start of this SimulationTimeInfo. + + + :param start: The start of this SimulationTimeInfo. + :type start: float + """ + + self._start = start + + @property + def end(self) -> float: + """Gets the end of this SimulationTimeInfo. + + + :return: The end of this SimulationTimeInfo. + :rtype: float + """ + return self._end + + @end.setter + def end(self, end: float): + """Sets the end of this SimulationTimeInfo. + + + :param end: The end of this SimulationTimeInfo. + :type end: float + """ + + self._end = end + + @property + def current(self) -> float: + """Gets the current of this SimulationTimeInfo. + + + :return: The current of this SimulationTimeInfo. + :rtype: float + """ + return self._current + + @current.setter + def current(self, current: float): + """Sets the current of this SimulationTimeInfo. + + + :param current: The current of this SimulationTimeInfo. + :type current: float + """ + + self._current = current diff --git a/access_node/models/spikes.py b/access_node/models/spikes.py index d63abc26cd103bd04e74dde0726c0511d982fe4b..b46505f539aa7f1ae3d4dddd98418c7bec009600 100644 --- a/access_node/models/spikes.py +++ b/access_node/models/spikes.py @@ -15,26 +15,26 @@ class Spikes(Model): Do not edit the class manually. """ - def __init__(self, simulation_steps: List[float]=None, neuron_ids: List[float]=None): # noqa: E501 + def __init__(self, simulation_times: List[float]=None, gids: List[int]=None): # noqa: E501 """Spikes - a model defined in Swagger - :param simulation_steps: The simulation_steps of this Spikes. # noqa: E501 - :type simulation_steps: List[float] - :param neuron_ids: The neuron_ids of this Spikes. # noqa: E501 - :type neuron_ids: List[float] + :param simulation_times: The simulation_times of this Spikes. # noqa: E501 + :type simulation_times: List[float] + :param gids: The gids of this Spikes. # noqa: E501 + :type gids: List[int] """ self.swagger_types = { - 'simulation_steps': List[float], - 'neuron_ids': List[float] + 'simulation_times': List[float], + 'gids': List[int] } self.attribute_map = { - 'simulation_steps': 'simulation_steps', - 'neuron_ids': 'neuron_ids' + 'simulation_times': 'simulation_times', + 'gids': 'gids' } - self._simulation_steps = simulation_steps - self._neuron_ids = neuron_ids + self._simulation_times = simulation_times + self._gids = gids @classmethod def from_dict(cls, dikt) -> 'Spikes': @@ -48,43 +48,45 @@ class Spikes(Model): return util.deserialize_model(dikt, cls) @property - def simulation_steps(self) -> List[float]: - """Gets the simulation_steps of this Spikes. + def simulation_times(self) -> List[float]: + """Gets the simulation_times of this Spikes. + This array is always sorted. # noqa: E501 - :return: The simulation_steps of this Spikes. + :return: The simulation_times of this Spikes. :rtype: List[float] """ - return self._simulation_steps + return self._simulation_times - @simulation_steps.setter - def simulation_steps(self, simulation_steps: List[float]): - """Sets the simulation_steps of this Spikes. + @simulation_times.setter + def simulation_times(self, simulation_times: List[float]): + """Sets the simulation_times of this Spikes. + This array is always sorted. # noqa: E501 - :param simulation_steps: The simulation_steps of this Spikes. - :type simulation_steps: List[float] + :param simulation_times: The simulation_times of this Spikes. + :type simulation_times: List[float] """ - self._simulation_steps = simulation_steps + self._simulation_times = simulation_times @property - def neuron_ids(self) -> List[float]: - """Gets the neuron_ids of this Spikes. + def gids(self) -> List[int]: + """Gets the gids of this Spikes. - :return: The neuron_ids of this Spikes. - :rtype: List[float] + :return: The gids of this Spikes. + :rtype: List[int] """ - return self._neuron_ids + return self._gids - @neuron_ids.setter - def neuron_ids(self, neuron_ids: List[float]): - """Sets the neuron_ids of this Spikes. + @gids.setter + def gids(self, gids: List[int]): + """Sets the gids of this Spikes. - :param neuron_ids: The neuron_ids of this Spikes. - :type neuron_ids: List[float] + :param gids: The gids of this Spikes. + :type gids: List[int] """ - self._neuron_ids = neuron_ids + self._gids = gids diff --git a/access_node/swagger/swagger.yaml b/access_node/swagger/swagger.yaml index a5d4fab16aadb32053eab0cb411efd9c1b48b0da..41798d174191a894534adef35403d71b644cffc1 100644 --- a/access_node/swagger/swagger.yaml +++ b/access_node/swagger/swagger.yaml @@ -10,12 +10,259 @@ schemes: - "https" - "http" paths: - /timestep: + /arbor/spikes: + get: + tags: + - "arbor" + summary: "Retrieves the spikes for the given simulation times (optional), cell\ + \ and segment (optional)." + operationId: "arbor_get_spikes" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - name: "from" + in: "query" + description: "The start time (including) to be queried." + required: false + type: "number" + format: "double" + - name: "to" + in: "query" + description: "The end time (excluding) to be queried." + required: false + type: "number" + format: "double" + - name: "cell_ids" + in: "query" + description: "A list of cell ids queried for spike data." + required: false + type: "array" + items: + type: "integer" + format: "uint64" + - name: "segment_ids" + in: "query" + description: "A list of segment ids queried for spike data." + required: false + type: "array" + items: + type: "integer" + format: "uint64" + - name: "offset" + in: "query" + description: "The offset into the result." + required: false + type: "integer" + format: "uint64" + - name: "limit" + in: "query" + description: "The maximum of entries to be result." + required: false + type: "integer" + format: "uint64" + responses: + 200: + description: "Operation successful." + schema: + $ref: "#/definitions/Spikes" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.arbor_controller" + /arbor/cell_ids: + get: + tags: + - "arbor" + summary: "Retrieves the list of all cell ids." + operationId: "arbor_get_cell_ids" + produces: + - "application/json" + parameters: [] + responses: + 200: + description: "Operation successful." + schema: + type: "array" + items: + type: "integer" + format: "uint64" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.arbor_controller" + /arbor/probes: + get: + tags: + - "arbor" + summary: "Retrieves the list of all probes for a given attribute (optional)." + operationId: "arbor_get_probes" + produces: + - "application/json" + parameters: + - name: "attribute" + in: "query" + description: "The attribute measured for which existing probes will be returned." + required: false + type: "string" + responses: + 200: + description: "Operation successful." + schema: + type: "array" + items: + $ref: "#/definitions/Probe" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.arbor_controller" + /arbor/attributes: + get: + tags: + - "arbor" + summary: "Retrieves the list of all attributes." + operationId: "arbor_get_attributes" + produces: + - "application/json" + parameters: [] + responses: + 200: + description: "Operation successful." + schema: + type: "array" + items: + type: "string" + example: + - "Voltage" + - "Current" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.arbor_controller" + /arbor/measurements: + get: + tags: + - "arbor" + summary: "Retrieves the measurements for given probes (optional)." + operationId: "arbor_get_measurements" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - name: "attribute" + in: "query" + description: "The attribute to query (e.g., 'V_m' for the membrane potential)" + required: true + type: "string" + - name: "probe_ids" + in: "query" + description: "A list of probes ids queried for data." + required: false + type: "array" + items: + type: "integer" + format: "uint64" + - name: "from" + in: "query" + description: "The start time (including) to be queried." + required: false + type: "number" + format: "double" + - name: "to" + in: "query" + description: "The end time (excluding) to be queried." + required: false + type: "number" + format: "double" + - name: "offset" + in: "query" + description: "The offset into the result." + required: false + type: "integer" + format: "uint64" + - name: "limit" + in: "query" + description: "The maximum of entries to be result." + required: false + type: "integer" + format: "uint64" + responses: + 200: + description: "Operation successful." + schema: + $ref: "#/definitions/ArborMeasurement" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.arbor_controller" + /arbor/simulation_time_info: + get: + tags: + - "arbor" + summary: "Retrieves simulation time information." + operationId: "arbor_get_simulation_time_info" + produces: + - "application/json" + parameters: [] + responses: + 200: + description: "Operation successful." + schema: + $ref: "#/definitions/SimulationTimeInfo" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.arbor_controller" + /arbor/cell_properties: + get: + tags: + - "arbor" + summary: "Retrieves the properties of the specified cells." + operationId: "arbor_get_cell_properties" + produces: + - "application/json" + parameters: + - name: "cell_ids" + in: "query" + description: "A list of cell IDs queried for properties." + required: false + type: "array" + items: + type: "integer" + format: "uint64" + responses: + 200: + description: "Operation successful." + schema: + type: "array" + items: + $ref: "#/definitions/ArborCellProperties" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.arbor_controller" + /nest/simulation_time_info: get: tags: - "nest" - summary: "Retrieves the time between two simulation steps." - operationId: "get_timestep" + summary: "Retrieves simulation time information." + operationId: "nest_get_simulation_time_info" produces: - "application/json" parameters: [] @@ -23,19 +270,19 @@ paths: 200: description: "Operation successful." schema: - type: "number" - format: "double" + $ref: "#/definitions/SimulationTimeInfo" 400: description: "Operation failed." schema: - $ref: "#/definitions/Error" + type: "string" + example: "Error message" x-swagger-router-controller: "access_node.controllers.nest_controller" - /simulation_step_count: + /nest/gids: get: tags: - "nest" - summary: "Retrieves the number of simulation steps." - operationId: "get_simulation_step_count" + summary: "Retrieves the list of all GID." + operationId: "nest_get_gids" produces: - "application/json" parameters: [] @@ -43,41 +290,52 @@ paths: 200: description: "Operation successful." schema: - type: "number" - format: "int64" + type: "array" + items: + type: "integer" + format: "uint64" 400: description: "Operation failed." schema: - $ref: "#/definitions/Error" + type: "string" + example: "Error message" x-swagger-router-controller: "access_node.controllers.nest_controller" - /neuron_ids: + /nest/neuron_properties: get: tags: - "nest" - summary: "Retrieves the list of all neuron IDs." - operationId: "get_neuron_ids" + summary: "Retrieves the properties of the specified neurons." + operationId: "nest_get_neuron_properties" produces: - "application/json" - parameters: [] + parameters: + - name: "gids" + in: "query" + description: "A list of GIDs queried for properties." + required: false + type: "array" + items: + type: "integer" + format: "uint64" responses: 200: description: "Operation successful." schema: type: "array" items: - type: "number" - format: "int64" + $ref: "#/definitions/NestNeuronProperties" 400: description: "Operation failed." schema: - $ref: "#/definitions/Error" + type: "string" + example: "Error message" x-swagger-router-controller: "access_node.controllers.nest_controller" - /attributes: + /nest/populations: get: tags: - "nest" - summary: "Retrieves the details of per-neuron attributes." - operationId: "get_attributes" + summary: "Retrieves the list of all population IDs." + operationId: "nest_get_populations" produces: - "application/json" parameters: [] @@ -87,170 +345,417 @@ paths: schema: type: "array" items: - $ref: "#/definitions/Attribute" + type: "integer" + format: "uint64" 400: description: "Operation failed." schema: - $ref: "#/definitions/Error" + type: "string" + example: "Error message" x-swagger-router-controller: "access_node.controllers.nest_controller" - /data: + /nest/spikes: get: tags: - "nest" - summary: "Retrieves the per-neuron attributes for the given attribute name,\ - \ simulation steps (optional) and neuron IDs (optional)." - operationId: "get_data" + summary: "Retrieves the spikes for the given simulation steps (optional) and\ + \ GIDS (optional)." + operationId: "nest_get_spikes" consumes: - "application/json" produces: - "application/json" parameters: - - name: "attribute" + - name: "from" in: "query" - description: "Attribute name." - required: true - type: "string" - - name: "simulation_steps" + description: "The start time (including) to be queried." + required: false + type: "number" + format: "double" + - name: "to" in: "query" - description: "Simulation steps (leave empty for all steps)." + description: "The end time (excluding) to be queried." required: false - type: "array" - items: - type: "number" - format: "double" - collectionFormat: "multi" - - name: "neuron_ids" + type: "number" + format: "double" + - name: "gids" in: "query" - description: "Neuron IDs (leave empty for all neurons)." + description: "A list of GIDs queried for spike data." required: false type: "array" items: - type: "number" - format: "int64" - collectionFormat: "multi" + type: "integer" + format: "uint64" + - name: "offset" + in: "query" + description: "The offset into the result." + required: false + type: "integer" + format: "uint64" + - name: "limit" + in: "query" + description: "The maximum of entries to be result." + required: false + type: "integer" + format: "uint64" responses: 200: description: "Operation successful." schema: - $ref: "#/definitions/Data" + $ref: "#/definitions/Spikes" 400: description: "Operation failed." schema: - $ref: "#/definitions/Error" + type: "string" + example: "Error message" x-swagger-router-controller: "access_node.controllers.nest_controller" - /spikes: + /nest/population/${population_id}/spikes: get: tags: - "nest" summary: "Retrieves the spikes for the given simulation steps (optional) and\ - \ neuron IDs (optional)." - operationId: "get_spikes" + \ population." + operationId: "nest_get_spikes_by_population" consumes: - "application/json" produces: - "application/json" parameters: - - name: "simulation_steps" + - name: "population_id" + in: "path" + description: "The identifier of the population." + required: true + type: "integer" + format: "uint64" + - name: "from" in: "query" - description: "Simulation steps (leave empty for all steps)." + description: "The start time (including) to be queried." required: false - type: "array" - items: - type: "number" - format: "int64" - collectionFormat: "multi" - - name: "neuron_ids" + type: "number" + format: "double" + - name: "to" + in: "query" + description: "The end time (excluding) to be queried." + required: false + type: "number" + format: "double" + - name: "offset" + in: "query" + description: "The offset into the result." + required: false + type: "integer" + format: "uint64" + - name: "limit" + in: "query" + description: "The maximum of entries to be result." + required: false + type: "integer" + format: "uint64" + responses: + 200: + description: "Operation successful." + schema: + $ref: "#/definitions/Spikes" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.nest_controller" + /nest/multimeter_info: + get: + tags: + - "nest" + summary: "Retreives the available multimeters and their properties." + operationId: "nest_get_multimeter_info" + consumes: + - "application/json" + produces: + - "application/json" + parameters: [] + responses: + 200: + description: "Operation successful." + schema: + $ref: "#/definitions/MultimeterInfo" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.nest_controller" + /nest/multimeter_measurement: + get: + tags: + - "nest" + summary: "Retrieves the measurements for a multimeter, attribute and GIDS (optional)." + operationId: "nest_get_multimeter_measurements" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - name: "multimeter_id" + in: "query" + description: "The multimeter to query" + required: true + type: "number" + format: "integer" + - name: "attribute" + in: "query" + description: "The attribute to query (e.g., 'V_m' for the membrane potential)" + required: true + type: "string" + - name: "from" in: "query" - description: "Neuron IDs (leave empty for all neurons)." + description: "The start time (including) to be queried." + required: false + type: "number" + format: "double" + - name: "to" + in: "query" + description: "The end time (excluding) to be queried." + required: false + type: "number" + format: "double" + - name: "gids" + in: "query" + description: "A list of GIDs queried for spike data." required: false type: "array" items: - type: "number" - format: "int64" - collectionFormat: "multi" + type: "integer" + format: "uint64" + - name: "offset" + in: "query" + description: "The offset into the result." + required: false + type: "integer" + format: "uint64" + - name: "limit" + in: "query" + description: "The maximum of entries to be result." + required: false + type: "integer" + format: "uint64" responses: 200: description: "Operation successful." schema: - $ref: "#/definitions/Spikes" + $ref: "#/definitions/MultimeterMeasurement" + 400: + description: "Operation failed." + schema: + type: "string" + example: "Error message" + x-swagger-router-controller: "access_node.controllers.nest_controller" + /nest/population/${population_id}/gids: + get: + tags: + - "nest" + summary: "Retrieves the list of all neuron IDs within the population." + operationId: "nest_get_gids_in_population" + produces: + - "application/json" + parameters: + - name: "population_id" + in: "path" + description: "The identifier of the population" + required: true + type: "integer" + format: "uint64" + responses: + 200: + description: "Operation successful." + schema: + type: "array" + items: + type: "integer" + format: "uint64" 400: description: "Operation failed." schema: - $ref: "#/definitions/Error" + type: "string" + example: "Error message" x-swagger-router-controller: "access_node.controllers.nest_controller" definitions: - Precision: - type: "string" - enum: - - "double" - - "integer" - Attribute: + Spikes: type: "object" properties: - name: - type: "string" - precision: - $ref: "#/definitions/Precision" + simulation_times: + type: "array" + description: "This array is always sorted." + items: + type: "number" + format: "double" + gids: + type: "array" + items: + type: "integer" + format: "uint64" + example: + simulation_times: + - 0.8008281904610115 + - 0.8008281904610115 + gids: + - 6.027456183070403 + - 6.027456183070403 + MultimeterInfo: + type: "array" + items: + $ref: "#/definitions/MultimeterInfo_inner" example: - precision: {} - name: "name" - Data: + - id: 0 + attributes: + - "V_m" + MultimeterMeasurement: type: "object" properties: - first_simulation_step: - type: "number" - format: "int64" - num_simulation_steps: - type: "number" - format: "int64" - neuron_ids: + simulation_times: type: "array" + description: "This array is always sorted." items: type: "number" - format: "int64" + format: "double" + gids: + type: "array" + items: + type: "integer" + format: "uint64" values: type: "array" + description: "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" items: - type: "array" - items: - type: "number" + type: "number" example: - first_simulation_step: + simulation_times: + - 0.1 + - 0.2 + gids: - 1 - num_simulation_steps: - 2 + - 3 values: - - - 61.48 - - 45.23 - - - 13.46 - - 23.77 - neuron_ids: - - 1 - - 2 - Spikes: + - 0.123 + - 0.123 + - 0.123 + - 0.123 + - 0.123 + - 0.123 + ArborMeasurement: type: "object" properties: - simulation_steps: + simulation_times: type: "array" + description: "This array is always sorted." items: type: "number" - format: "int64" - neuron_ids: + format: "double" + gids: type: "array" + items: + type: "integer" + format: "uint64" + values: + type: "array" + description: "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" items: type: "number" - format: "int64" example: - simulation_steps: - - 2 - - 5 - neuron_ids: + simulation_times: + - 0.1 + - 0.2 + gids: - 1 - 2 - Error: + - 3 + values: + - 0.123 + - 0.123 + - 0.123 + - 0.123 + - 0.123 + - 0.123 + Probe: type: "object" properties: - code: + id: + type: "integer" + format: "uint64" + cell_id: + type: "integer" + format: "uint64" + segment_id: + type: "integer" + format: "uint64" + position: type: "number" - message: - type: "string" + format: "double" + example: + id: 1 + cell_id: 2 + segment_id: 1 + position: 0.4 + ArborCellProperties: + type: "object" + properties: + neuron_id: + type: "integer" + format: "uint64" + properties: + type: "object" + properties: {} + example: + population: "pop1" + position: + - 0.1 + - 0.1 + - 0.1 + NestNeuronProperties: + type: "object" + properties: + gid: + type: "integer" + format: "uint64" + properties: + type: "object" + properties: {} + example: + population: "pop1" + position: + - 0.1 + - 0.1 + - 0.1 + SimulationTimeInfo: + type: "object" + properties: + start: + type: "number" + format: "double" + end: + type: "number" + format: "double" + current: + type: "number" + format: "double" + example: + current: 1.4658129805029452 + start: 0.8008281904610115 + end: 6.027456183070403 + MultimeterInfo_inner: + properties: + id: + type: "integer" + format: "uint64" + attributes: + type: "array" + items: + type: "string" + gids: + type: "array" + items: + type: "integer" + format: "uint64" diff --git a/access_node/test/test_arbor_controller.py b/access_node/test/test_arbor_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..951543a6098a102923e3c33c3741fe51c6f5163c --- /dev/null +++ b/access_node/test/test_arbor_controller.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +from __future__ import absolute_import + +from flask import json +from six import BytesIO + +from access_node.models.arbor_measurement import ArborMeasurement # noqa: E501 +from access_node.models.arbor_neuron_properties import ArborNeuronProperties # 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.test import BaseTestCase + + +class TestArborController(BaseTestCase): + """ArborController integration test stubs""" + + def test_arbor_get_attributes(self): + """Test case for arbor_get_attributes + + Retrieves a list of measurable attributes + """ + response = self.client.open( + '//arbor/attributes', + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_arbor_get_measurements(self): + """Test case for arbor_get_measurements + + Retrieves the measurements for given attribute and neuron_ids (optional). + """ + query_string = [('attribute', 'attribute_example'), + ('_from', 1.2), + ('to', 1.2), + ('neuron_ids', 56), + ('offset', 56), + ('limit', 56)] + response = self.client.open( + '//arbor/measurements', + method='GET', + content_type='application/json', + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_arbor_get_neuron_ids(self): + """Test case for arbor_get_neuron_ids + + Retrieves the list of all neuron ids. + """ + response = self.client.open( + '//arbor/neuron_ids', + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_arbor_get_neuron_properties(self): + """Test case for arbor_get_neuron_properties + + Retrieves the properties of the specified neurons. + """ + query_string = [('neuron_ids', 56)] + response = self.client.open( + '//arbor/neuron_properties', + method='GET', + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_arbor_get_simulation_time_info(self): + """Test case for arbor_get_simulation_time_info + + Retrieves simulation time information. + """ + response = self.client.open( + '//arbor/simulation_time_info', + method='GET') + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + def test_arbor_get_spikes(self): + """Test case for arbor_get_spikes + + Retrieves the spikes for the given simulation steps (optional) and GIDS (optional). + """ + query_string = [('_from', 1.2), + ('to', 1.2), + ('gids', 56), + ('offset', 56), + ('limit', 56)] + response = self.client.open( + '//arbor/spikes', + method='GET', + content_type='application/json', + query_string=query_string) + self.assert200(response, + 'Response body is : ' + response.data.decode('utf-8')) + + +if __name__ == '__main__': + import unittest + unittest.main() diff --git a/requirements.txt b/requirements.txt index ab2054f6aaacb80352542836269590f0f3f1bb09..76172a29d0dc257df30e3c662f78d10acbee6092 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ -connexion == 1.1.15 +connexion == 2.6.0 python_dateutil == 2.6.0 setuptools >= 21.0.0 -json requests +flask_cors +psycopg2-binary +numpy \ No newline at end of file