File size: 11,464 Bytes
0558c72 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | import os
import pylab as plt
import numpy as np
import ui_widget
import ipywidgets
from pyneuroml import pynml
from neuroml.loaders import read_neuroml2_file
import neuroml.writers as writers
#python helper class for updating NeuroML files and running it from Jupyter Notebook
class nml2jupyter():
def __init__(self, path2source, fname_LEMS, fname_net):
self.path2source = path2source
self.fname_LEMS = fname_LEMS
self.fname_net = fname_net
self.nml_file = 'NeuroMLProject.nml'
#Function to load neuroml file in python object
def loadnml(self):
pathfilename=os.path.join(self.path2source, self.fname_net)
nml_doc= read_neuroml2_file(pathfilename, include_includes=True,already_included=[])
return nml_doc
#function to write NeuroML file based on widget inputs
def writeNMLinputFile(self,nml_doc):
writers.NeuroMLWriter.write(nml_doc, self.nml_file)
display("Written in NeuroML2 format to : " + self.nml_file)
#Fuction to create accordions for given neuroml object
def createAccordions(self,nmlObj,title):
mydict=nmlObj.info(True,return_format='dict')
emptyKeys=[]
subwidget_list=[]
textBoxList=[]
#Two loops to keep text boxes on top and accordion on bottom
#Need to find alternate way to avoid looping twice
#Loop 1
#create text box widgets for values of dictionary of type str, int or float
#make a list of empty keys
for key,values in mydict.items():
# check if the member is set to None
# if it's a container (list), it will not be set to None, it
# will be empty, []
# if it's a scalar, it will be set to None or to a non
# container value
if values['members'] is None or (isinstance(values['members'], list) and len(values['members']) == 0):
emptyKeys.append(key)
continue
if isinstance(values['members'],str) or isinstance(values['members'],int) or isinstance(values['members'],float):
textBox_key = ipywidgets.Text(value=key,disabled=True,layout=ipywidgets.Layout(width='20%'))
textBox_value = ipywidgets.Text(value=str(values['members']),layout=ipywidgets.Layout(width='50%'))
textBoxList.append(ipywidgets.HBox([textBox_key, textBox_value]))
if (key=='id'): title_id=values['members']
#remove empty keys from dicitonary (to reduce iteration in 2nd loop)
for key in emptyKeys:
mydict.pop(key)
#Loop 2
#create sub-accordions for list of values
for key,values in mydict.items():
if isinstance(values['members'],str) or isinstance(values['members'],int) or isinstance(values['members'],float): continue
if isinstance(values['members'],list):
for idx, val in enumerate(values['members']):
if isinstance(val,str) or isinstance(val,int) or isinstance(val,float):
textBox_key = ipywidgets.Text(value=key,disabled=True,layout=ipywidgets.Layout(width='20%'))
textBox_value = ipywidgets.Text(value=str(val),layout=ipywidgets.Layout(width='50%'))
textBoxList.append(ipywidgets.HBox([textBox_key, textBox_value]))
if (key=='id'): title_id=values['members']
else:
child_accord=self.createAccordions(val,key)
textBoxList.append(child_accord)
else:
child_accord=self.createAccordions(values['members'],key)
textBoxList.append(child_accord)
subwidget_list.append(ipywidgets.VBox(textBoxList))
accordion = ipywidgets.Accordion(children=subwidget_list, selected_index=None)
try:
title_with_id = title + ' (' + title_id + ') '
accordion.set_title(0, title_with_id)
except:
accordion.set_title(0, title)
return accordion
#Function to load LEMS life in python object then get component list to create accordions
def createAccordionsLEMS(self):
pathfilename=os.path.join(self.path2source,self.fname_LEMS)
lems_doc=pynml.read_lems_file(pathfilename)
mydict=lems_doc.get_component_list()
accordList=[]
component=['id', 'type', 'parameters', 'parent_id']
for key,values in mydict.items():
textBoxList=[]
for attr in component:
val = getattr(mydict[key],attr)
if isinstance(val,dict):
for k,v in val.items():
textBox_key = ipywidgets.Text(value=k,disabled=True,layout=ipywidgets.Layout(width='20%'))
textBox_value = ipywidgets.Text(value=v,layout=ipywidgets.Layout(width='50%'))
textBoxList.append(ipywidgets.HBox([textBox_key, textBox_value]))
continue
textBox_key = ipywidgets.Text(value=attr,disabled=True,layout=ipywidgets.Layout(width='20%'))
textBox_value = ipywidgets.Text(value=val,layout=ipywidgets.Layout(width='50%'))
textBoxList.append(ipywidgets.HBox([textBox_key, textBox_value]))
accordList.append(ipywidgets.VBox(textBoxList))
accordion = ipywidgets.Accordion(children=accordList, selected_index=None)
for i,key in enumerate(mydict.keys()):
accordion.set_title(i,key)
return accordion
#Function to create GUI by nesting accordions with first level of neruoml object as Tabs
def createTabWithAccordions(self,nml_doc):
parent=nml_doc.info(True,return_format='dict')
masterTab=ipywidgets.Tab()
masterTab_titles=[]
masterTab_child=[]
#create LEMS tab for simulation parameters (using get_component_list)
lemsTab=self.createAccordionsLEMS()
masterTab_child.append(lemsTab)
masterTab_titles.append('LEMS')
for key,values in parent.items():
if values['members'] is None or (isinstance(values['members'], list) and len(values['members']) == 0): continue #skip empty elements
sub_child=[]
if isinstance(values['members'],list):
for val in values['members']:
sub_child.append(self.createAccordions(val,key))
elif isinstance(values['members'],str) or isinstance(values['members'],int) or isinstance(values['members'],float):
sub_child.append(ipywidgets.Text(value=str(values['members'])))
else:
sub_child.append(self.createAccordions(values['members'],key))
masterTab_child.append(ipywidgets.VBox(sub_child))
masterTab_titles.append(key)
masterTab.children=masterTab_child
for i in range(len(masterTab_titles)):
masterTab.set_title(i,masterTab_titles[i])
display(masterTab)
#function to setup full dashboard/gui
def loadGUI(self,nml_doc):
#function to run NeuroML with given inputs
def runNMLmodel(b):
out_log.clear_output()
out_plot.clear_output()
out_validStatus.clear_output()
with out_log:
display('Running NeuroML Model...')
LEMS_file=os.path.join(self.path2source, self.fname_LEMS)
self.nmlOutput = pynml.run_lems_with_jneuroml(LEMS_file, nogui=True, load_saved_data=True)
#shell_cmd=['pynml', LEMS, LEMSoption]
#subprocess.run(shell_cmd)
display('Completed !!!')
#function to validate NeuroML model
def validateNMLmodel(b):
out_log.clear_output()
out_validStatus.clear_output()
with out_log:
display('Validating NeuroML Input File...')
#pathfilename=os.path.join(self.path2source, self.nml_file)
checkStatus=pynml.validate_neuroml2(self.nml_file)
#shell_cmd=['pynml', pathfilename,'-validate']
#subprocess.run(shell_cmd)
if checkStatus==True:
valid_widget=ipywidgets.Valid(value=True,description='')
with out_validStatus:
display(ipywidgets.HBox([ipywidgets.HTML(value=self.nml_file,disabled=True),valid_widget]))
else:
valid_widget=ipywidgets.Valid(value=False,description='')
with out_validStatus:
display(ipywidgets.HBox([ipywidgets.HTML(value=self.nml_file,disabled=True),valid_widget]))
display('Completed !!!')
#function to display plot in notebook
def plotOutput(b):
out_plot.clear_output()
with out_plot:
self.plotData()
#function to update NeuroML files from widget inputs
def updateNMLfiles(b):
out_log.clear_output()
out_plot.clear_output()
out_validStatus.clear_output()
with out_log:
#display('Updating NeuroML Files from GUI inputs...')
display('Writing NeuroML python model to file ')
#display(type(self.filelist),len(self.filelist))
#display(type(self.trees),len(self.trees))
self.writeNMLinputFile(nml_doc)
display('Completed !!!')
#output windows
out_log = ipywidgets.Output(layout={'border': '1px solid'}) #for displaying output log from NeuroMl execution
out_plot = ipywidgets.Output() #for displaying plots
out_validStatus = ipywidgets.Output() #for displaying valid widgets after running validate button
ui_widget.run_button.on_click(runNMLmodel)
ui_widget.validate_button.on_click(validateNMLmodel)
ui_widget.plot_button.on_click(plotOutput)
ui_widget.update_button.on_click(updateNMLfiles)
display(ui_widget.buttons,out_validStatus,out_log,ui_widget.plot_button,out_plot)
#function to plot data generated by NeuroML
def plotData(self):
plt.close('all')
for key in self.nmlOutput.keys():
if key == "t":
continue
plt.ioff() #suppress plot console window (plot only at display call)
fig=plt.figure(figsize=(8,2))
fig.canvas.header_visible = False
htmlBox_tittle = ipywidgets.HTML(value='<b><p style="text-align:center">{}</p></b>'.format(key),layout=ipywidgets.Layout(border='solid 1px black',width='60%'))
plt.xlabel("Time (ms)")
plt.ylabel("")
plt.grid(True,linestyle="--")
#plt.xlim(min(self.nmlOutput["t"]),max(self.nmlOutput["t"]))
#plt.ylim(min(self.nmlOutput[key]),max(self.nmlOutput[key]))
plt.plot(self.nmlOutput["t"], self.nmlOutput[key], linewidth=1)
plotBox=ipywidgets.VBox([htmlBox_tittle,fig.canvas])
display(plotBox)
#end of class |