Skip to content

Commit c547b2d

Browse files
authored
Merge pull request #618 from MetaCell/osb2-dev
Osb2 dev
2 parents bef2eb9 + cde4676 commit c547b2d

26 files changed

Lines changed: 813 additions & 268 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,7 @@ utilities/x86_64
2727
x86_64
2828
.jupyter-config
2929
venv
30+
webapp/build
31+
webapp/.yalc
3032
node_modules
33+
sa_nyhead.mat

Dockerfile

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ ENV NB_UID=jovyan
2020
ENV FOLDER=netpyne
2121
ARG GEPPETTO_VERSION=development
2222
ARG BUILD_ARGS=""
23+
ARG NETPYNE_VERSION=master
24+
ARG WORKSPACE_VERSION=master
2325

2426
ENV FOLDER=/home/jovyan/work/NetPyNE-UI
2527

2628
USER root
2729

2830
RUN rm -rf /var/lib/apt/lists
2931
RUN apt-get update -qq &&\
30-
apt-get install python3-tk vim nano unzip git make libtool g++ -qq pkg-config libfreetype6-dev libpng-dev libopenmpi-dev -y
32+
apt-get install python3-tk vim nano unzip git make libtool g++ -qq pkg-config libfreetype6-dev libpng-dev libopenmpi-dev openjdk-11-jre-headless -y -y
3133
RUN conda install python=3.7 -y
3234

3335

@@ -44,25 +46,22 @@ RUN jupyter nbextension enable --py --sys-prefix jupyter_geppetto
4446
RUN jupyter nbextension enable --py --sys-prefix widgetsnbextension
4547
RUN jupyter serverextension enable --py --sys-prefix jupyter_geppetto
4648

47-
RUN python utilities/install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} --npm-skip
49+
RUN python utilities/install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} --netpyne $NETPYNE_VERSION --workspace WORKSPACE_VERSION --npm-skip
4850

4951
RUN jupyter labextension disable @jupyterlab/hub-extension
5052

5153
RUN chown $NB_UID .
5254
RUN chown -R $NB_UID workspace
5355

5456
# Temp fixes for eeg plots
57+
ENV NEURON_HOME=/opt/conda
5558
# For lfpykit 0.4
5659
# RUN wget -P $(pip show LFPykit | grep "Location:" | awk '{print $2"/lfpykit"}') https://www.parralab.org/nyhead/sa_nyhead.mat
5760
# For lpfykit 0.5
5861
RUN wget --no-check-certificate -P ${FOLDER}/workspace https://www.parralab.org/nyhead/sa_nyhead.mat
5962

6063
USER $NB_UID
6164

62-
6365
EXPOSE 8888
6466

6567

66-
67-
68-

NetPyNE-UI

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/sh
22
CONFIG=$(pwd)/.jupyter-config
33
export JUPYTER_CONFIG_DIR=$CONFIG
4-
exec jupyter notebook --NotebookApp.default_url=/geppetto --NotebookApp.token='' --library=netpyne_ui --NotebookApp.disable_check_xsrf=True
4+
exec jupyter notebook --NotebookApp.default_url=/geppetto --NotebookApp.token='' --NotebookApp.notebook_dir=workspace --library=netpyne_ui --NotebookApp.disable_check_xsrf=True

netpyne_ui/api.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ def allowed_file(filename, allowed_extensions=ALLOWED_EXTENSIONS):
1919
def send_files(handler, file_path, filename):
2020
with open(file_path, "rb") as f:
2121
handler.set_header('Content-Type', 'application/force-download')
22-
handler.set_header('Content-Disposition', f"attachment; filename={filename}")
22+
handler.set_header('Content-Disposition',
23+
f"attachment; filename={filename}")
2324

2425
try:
2526
while True:
@@ -36,7 +37,8 @@ def get_file_paths(handler):
3637
file_paths = False
3738
if 'uri' in handler.request.arguments:
3839
file_paths = []
39-
tmp_file_paths = [path.decode('utf-8') for path in handler.request.arguments['uri']]
40+
tmp_file_paths = [path.decode('utf-8')
41+
for path in handler.request.arguments['uri']]
4042
for path in tmp_file_paths:
4143
if os.path.exists(path):
4244
file_paths.append(path)
@@ -69,12 +71,14 @@ def uploads(handler: IPythonHandler):
6971
files_saved = 0
7072

7173
if len(files) == 0 or 'file' not in files:
72-
handler.set_status(400, f"Can't find 'file' or filename is empty. Files received {len(files)}")
74+
handler.set_status(
75+
400, f"Can't find 'file' or filename is empty. Files received {len(files)}")
7376
else:
7477

7578
for f in files['file']:
7679
if not allowed_file(f.filename):
77-
logging.warn(f"Can't store file {f.filename}. Extension not allowed")
80+
logging.warn(
81+
f"Can't store file {f.filename}. Extension not allowed")
7882
continue
7983

8084
# Save to file
@@ -120,8 +124,42 @@ def downloads(handler: IPythonHandler):
120124
tar_gz_file_path = os.path.join(dir_path, tar_gz_file_name)
121125
with tarfile.open(tar_gz_file_path, mode='w:gz') as tar:
122126
for file_path in file_paths:
123-
tar.add(file_path, os.path.join('download', file_path.split('/')[-1]))
127+
tar.add(file_path, os.path.join(
128+
'download', file_path.split('/')[-1]))
124129

125130
send_files(handler, tar_gz_file_path, tar_gz_file_name)
126131

127132
handler.finish()
133+
134+
135+
def create_notebook(filename):
136+
import nbformat as nbf
137+
from nbformat.v4.nbbase import new_notebook
138+
from nbformat import sign
139+
import codecs
140+
141+
directory = os.path.dirname(filename)
142+
if not os.path.exists(directory):
143+
os.makedirs(directory)
144+
nb0 = new_notebook(cells=[nbf.v4.new_markdown_cell("""# Welcome to the NetPyNE-ui!
145+
146+
"""),
147+
nbf.v4.new_code_cell(
148+
'netpyne_geppetto.netParams'),
149+
nbf.v4.new_code_cell(
150+
'netpyne_geppetto.simConfig')
151+
], metadata={"kernelspec": {
152+
"display_name": "Python 3",
153+
"language": "python",
154+
"name": "python3"
155+
}})
156+
157+
f = codecs.open(filename, encoding='utf-8', mode='w')
158+
159+
nbf.write(nb0, filename)
160+
f.close()
161+
162+
163+
# TODO move to jupyter geppetto, using notebook dir path
164+
if os.path.exists('workspace') and not os.path.exists('workspace/notebook.ipynb'):
165+
create_notebook('workspace/notebook.ipynb')

netpyne_ui/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
TEMPLATE_FILENAME_BATCH_RUN = "batch_run_single.py"
1212
TEMPLATE_FILENAME_BATCH = "batch.py"
1313

14-
ALLOWED_EXTENSIONS = ["py", "zip", "gz", ".tar.gz", "pdf", "txt", "xls", "png", "jpeg", "hoc", "json"]
14+
ALLOWED_EXTENSIONS = ["py", "zip", "gz", ".tar.gz", "pdf", "txt", "xls", "png", "jpeg", "hoc", "json", "xml", "nml"]
1515
HERE = os.path.dirname(os.path.abspath(__file__))
1616
ROOT = os.path.dirname(HERE)
1717
UPLOAD_FOLDER_PATH = os.path.join(ROOT, NETPYNE_WORKDIR, UPLOAD_FOLDER_NAME)

netpyne_ui/helpers/neuroml.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import os
2+
import sys
3+
import logging
4+
from netpyne.specs import simConfig
5+
6+
from pyneuroml import pynml
7+
from pyneuroml.lems import generate_lems_file_for_neuroml
8+
from pyneuroml.pynml import read_neuroml2_file
9+
10+
from netpyne_ui.mod_utils import loadModMechFiles
11+
12+
13+
def convertLEMSSimulation(lemsFileName, compileMod=True):
14+
"""Converts a LEMS Simulation file
15+
16+
Converts a LEMS Simulation file (https://docs.neuroml.org/Userdocs/LEMSSimulation.html)
17+
pointing to a NeuroML 2 file into the equivalent in NetPyNE
18+
Returns:
19+
simConfig, netParams for the model in NetPyNE
20+
"""
21+
current_path = os.getcwd()
22+
try:
23+
24+
fullLemsFileName = os.path.abspath(lemsFileName)
25+
tmp_path = os.path.dirname(fullLemsFileName)
26+
if tmp_path:
27+
os.chdir(tmp_path)
28+
logging.info(
29+
"Importing LEMSSimulation with NeuroML 2 network from: %s"
30+
% fullLemsFileName
31+
)
32+
33+
result = pynml.run_lems_with_jneuroml_netpyne(
34+
lemsFileName, only_generate_json=True, exit_on_fail=False)
35+
36+
if result == False:
37+
raise Exception("Error loading lems file")
38+
lems = pynml.read_lems_file(lemsFileName)
39+
40+
np_json_fname = fullLemsFileName.replace('.xml','_netpyne_data.json')
41+
42+
return np_json_fname
43+
finally:
44+
os.chdir(current_path)
45+
46+
47+
48+
49+
def convertNeuroML2(nml2FileName, compileMod=True):
50+
"""Loads a NeuroML 2 file into NetPyNE
51+
Loads a NeuroML 2 file into NetPyNE by creating a new LEMS Simulation
52+
file (https://docs.neuroml.org/Userdocs/LEMSSimulation.html) and using jNeuroML
53+
to convert it.
54+
55+
Returns:
56+
simConfig, netParams for the model in NetPyNE
57+
"""
58+
current_path = os.getcwd()
59+
try:
60+
fullNmlFileName = os.path.abspath(nml2FileName)
61+
work_path = os.path.dirname(fullNmlFileName)
62+
if not os.path.exists(work_path):
63+
os.makedirs(work_path)
64+
os.chdir(work_path)
65+
sys.path.append(work_path)
66+
67+
68+
logging.info(
69+
"Importing NeuroML 2 network from: %s"
70+
% fullNmlFileName
71+
)
72+
nml_model = read_neuroml2_file(fullNmlFileName)
73+
74+
target = nml_model.networks[0].id
75+
sim_id = "Sim_%s" % target
76+
duration = 1000
77+
dt = 0.025
78+
lems_file_name = os.path.join(os.path.dirname(fullNmlFileName), "LEMS_%s.xml" % sim_id)
79+
lems_file_name = "LEMS_%s.xml" % sim_id
80+
target_dir = os.path.dirname(fullNmlFileName)
81+
target_dir = "."
82+
83+
generate_lems_file_for_neuroml(
84+
sim_id,
85+
fullNmlFileName,
86+
target,
87+
duration,
88+
dt,
89+
lems_file_name,
90+
target_dir,
91+
include_extra_files=["PyNN.xml"],
92+
gen_plots_for_all_v=True,
93+
plot_all_segments=False,
94+
gen_plots_for_quantities={}, # Dict with displays vs lists of quantity paths
95+
gen_plots_for_only_populations=[], # List of populations, all pops if = []
96+
gen_saves_for_all_v=True,
97+
save_all_segments=False,
98+
gen_saves_for_only_populations=[], # List of populations, all pops if = []
99+
gen_saves_for_quantities={}, # Dict with file names vs lists of quantity paths
100+
gen_spike_saves_for_all_somas=True,
101+
report_file_name="report.txt",
102+
copy_neuroml=True,
103+
verbose=True,
104+
)
105+
os.chdir(work_path)
106+
res = convertLEMSSimulation(lems_file_name, compileMod=compileMod)
107+
finally:
108+
os.chdir(current_path)
109+
return res
110+
111+
112+
if __name__ == "__main__":
113+
114+
if '-nml' in sys.argv:
115+
convertNeuroML2("../../NeuroML2/Spikers.net.nml")
116+
else:
117+
convertLEMSSimulation("LEMS_HHSimple.xml")

netpyne_ui/mod_utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def is_loaded_mechanisms():
2626
return True
2727

2828

29-
def compileModMechFiles(compileMod, modFolder):
29+
def loadModMechFiles(compileMod, modFolder):
3030
# Create Symbolic link
3131
if compileMod:
3232
modPath = os.path.join(str(modFolder), "x86_64")
@@ -38,7 +38,7 @@ def compileModMechFiles(compileMod, modFolder):
3838
subprocess.call(["nrnivmodl"])
3939
os.chdir('..')
4040

41-
try:
42-
neuron.load_mechanisms(str(modFolder))
43-
except:
44-
raise
41+
try:
42+
neuron.load_mechanisms(str(modFolder))
43+
except:
44+
raise

0 commit comments

Comments
 (0)