Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
def reportCoreBug(self):
QtGui.QDesktopServices.openUrl(QtCore.QUrl(config.MOOSE_CORE_BUG_URL))
'''
def reportBug(self):
QtGui.QDesktopServices.openUrl(QtCore.QUrl(config.MOOSE_REPORT_BUG_URL))
'''
def showBuiltInDocumentation(self):
self.showDocumentation('moose_builtins.html')
# openEditorView, openPlotView and openRunView are identical
# except the view they ask from the plugin. Consider using a
# mapper.
def openEditorView(self):
"""Switch to the editor view of current plugin. If there is
already a subwindow for this, make that the active
one. Otherwise create a new one.
"""
self.setCurrentView('editor')
def openPlotView(self):
self.setCurrentView('plot')
def openRunView(self):
self.setCurrentView('run')
def resetAndStartSimulation(self):
"""TODO this should provide a clean scheduling through all kinds
of simulation or default scheduling should be implemented in MOOSE
itself. We need to define a policy for handling scheduling. It can
be pushed to the plugin-developers who should have knowledge of
the scheduling criteria for their domain."""
settings = config.MooseSetting()
try:
simdt_kinetics = float(settings[config.KEY_KINETICS_SIMDT])
except ValueError:
simdt_kinetics = 0.1
try:
simdt_electrical = float(settings[config.KEY_ELECTRICAL_SIMDT])
except ValueError:
simdt_electrical = 0.25e-4
try:
plotdt_kinetics = float(settings[config.KEY_KINETICS_PLOTDT])
except ValueError:
plotdt_kinetics = 0.1
try:
plotdt_electrical = float(settings[config.KEY_ELECTRICAL_PLOTDT])
except ValueError:
plotdt_electrical = 0.25e-3
try:
simtime = float(settings[config.KEY_SIMTIME])
except ValueError:
simtime = 1.0
moose.reinit()
view = self.plugin.getRunView()
moose.start(simtime)
if view.getCentralWidget().plotAll:
view.getCentralWidget().plotAllData()
self.setCurrentView('run')
def pauseSimulation(self):
moose.stop()
'''
def continueSimulation(self):
"""TODO implement this somewhere else"""
try:
simtime = float(config.MooseSetting()[config.KEY_SIMTIME])
except ValueError:
simtime = 1.0
moose.start(simtime)
'''
#Harsha: added visible=True so that loadModelDialogSlot and NewModelDialogSlot call this function
# to clear out object path
def objectEditSlot(self, mobj, visible=True):
"""Slot for switching the current object in object editor."""
self.objectEditDockWidget.setObject(mobj)
self.objectEditDockWidget.setVisible(visible)
# def objectEditClearSlot(self):
# #clearning the views which is stored
# self.objectEditDockWidget.clearDict()
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
def loadedModelsAction(self,modelPath,pluginName):
#Harsha: added under file Menu, Recently Loaded Models
#All the previously loaded chemical models, solver's and table's ticks are made -1
for model in self._loadedModels:
self.disableModel(model[0])
action = QAction(modelPath[1:],self)
action.triggered.connect(lambda : self.setPlugin(pluginName, modelPath))
compt = moose.wildcardFind(modelPath + '/##[ISA=ChemCompt]')
c = moose.Clock('/clock')
self.simulationdt = c.tickDt[7]
self.plotdt = c.tickDt[8]
if compt:
self.simulationdt = c.tickDt[11]
self.plotdt = c.tickDt[16]
#index = [(ind, self._loadedModels[ind].index(modelPath)) for ind in xrange(len(self.loadedModels)) if item in self._loadedModels[ind]]
# for i,j in enumerate(self._loadedModels):
# if j[0] == modelPath:
# #del(self._loadedModels[i])
# pass
# break
self._loadedModels.append([modelPath,pluginName,action,self.simulationdt,self.plotdt])
if len(self._loadedModels)>5:
self._loadedModels.pop(0)
def disableModel(self, modelPath):
compt = moose.wildcardFind(modelPath + '/##[ISA=ChemCompt]')
if compt:
if moose.exists(compt[0].path+'/ksolve'):
ksolve = moose.Ksolve( compt[0].path+'/ksolve' )
ksolve.tick = -1
if moose.exists(compt[0].path+'/gsolve'):
gsolve = moose.Gsolve( compt[0].path+'/gsolve' )
gsolve.tick = -1
if moose.exists(compt[0].path+'/stoich'):
stoich = moose.Stoich( compt[0].path+'/stoich' )
stoich.tick = -1
else :
neurons = moose.wildcardFind(modelPath + "/model/cells/##[ISA=Neuron]")
for neuron in neurons:
solver = moose.element(neuron.path + "/hsolve")
solver.tick = -1
for table in moose.wildcardFind( modelPath+'/data/graph#/#' ):
table.tick = -1
def loadModelDialogSlot(self):
"""Start a file dialog to choose a model file.
Once the dialog succeeds, we should hand-over the duty of
actual model loading to something else. Then refresh the
views. Things to check from the user:
1) The file type
2) Target element
3) Whether we should update the current window or start a new
window.
4) Plugin to use for displaying this model (can be automated
by looking into the model file for a regular expression)
"""
self.popup.close()
activeWindow = None # This to be used later to refresh the current widget with newly loaded model
dialog = LoaderDialog(self,
self.tr('Load model from file'))
if dialog.exec_():
valid = False
ret = []
ret,pluginName = self.checkPlugin(dialog)
if pluginName == 'kkit':
if (ret['subtype'] == 'sbml' and ret['foundlib'] == False):
reply = QtGui.QMessageBox.question(self, "python-libsbml is not found.","\n Read SBML is not possible.\n This can be installed using \n \n pip python-libsbml or \n apt-get install python-libsbml",
QtGui.QMessageBox.Ok)
if reply == QtGui.QMessageBox.Ok:
QtGui.QApplication.restoreOverrideCursor()
if ret['loaderror'] != "":
reply = QtGui.QMessageBox.question(self, "Model can't be loaded", ret['loaderror']+" \n \n Do you want another file",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
dialog = LoaderDialog(self,self.tr('Load model from file'))
if dialog.exec_():
valid = False
ret = []
pluginName = None
ret,pluginName = self.checkPlugin(dialog)
valid, ret = self.dialog_check(ret)
else:
QtGui.QApplication.restoreOverrideCursor()
return valid
else:
valid = True
modelAnno = moose.Annotator(ret['model'].path+'/info')
if ret['subtype']:
modelAnno.modeltype = ret['subtype']
else:
modelAnno.modeltype = ret['modeltype']
modelAnno.dirpath = str(dialog.directory().absolutePath())
self.loadedModelsAction(ret['model'].path,pluginName)
self.setPlugin(pluginName, ret['model'].path)
if pluginName == 'kkit':
QtCore.QCoreApplication.sendEvent(self.plugin.getEditorView().getCentralWidget().view, QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Qt.Key_A, Qt.Qt.NoModifier))
noOfCompt = len(moose.wildcardFind(ret['model'].path+'/##[ISA=ChemCompt]'))
grp = 0
for c in moose.wildcardFind(ret['model'].path+'/##[ISA=ChemCompt]'):
noOfGrp = moose.wildcardFind(moose.element(c).path+'/#[TYPE=Neutral]')
grp = grp+len(noOfGrp)
noOfPool = len(moose.wildcardFind(ret['model'].path+'/##[ISA=PoolBase]'))
noOfFunc = len(moose.wildcardFind(ret['model'].path+'/##[ISA=Function]'))
noOfReac = len(moose.wildcardFind(ret['model'].path+'/##[ISA=ReacBase]'))
noOfEnz = len(moose.wildcardFind(ret['model'].path+'/##[ISA=EnzBase]'))
noOfStimtab = len(moose.wildcardFind(ret['model'].path+'/##[ISA=StimulusTable]'))
reply = QtGui.QMessageBox.information(self,"Model Info","Model has : \n %s Compartment \t \n %s Group \t \n %s Pool \t \n %s Function \t \n %s reaction \t \n %s Enzyme \t \n %s StimulusTable" %(noOfCompt, grp, noOfPool, noOfFunc, noOfReac, noOfEnz, noOfStimtab))
if reply == QtGui.QMessageBox.Ok:
QtGui.QApplication.restoreOverrideCursor()
return
def checkPlugin(self,dialog):
fileNames = dialog.selectedFiles()
for fileName in fileNames:
modelName = dialog.getTargetPath()
if '/' in modelName:
raise mexception.ElementNameError('Model name cannot contain `/`')
ret = loadFile(str(fileName),'%s' %(modelName),merge=False)
#ret = loadFile(str(fileName), '/model/%s' % (modelName), merge=False)
#This will clear out object editor's objectpath and make it invisible
self.objectEditSlot('/',False)
#if subtype is None, in case of cspace then pluginLookup = /cspace/None
# which will not call kkit plugin so cleaning to /cspace
#pluginLookup = '%s/%s' % (ret['modeltype'], ret['subtype'])
try:
pluginName = subtype_plugin_map['%s/%s' % (ret['modeltype'], ret['subtype'])]
except KeyError:
pluginName = 'default'
if ret['foundlib']:
print ('Loaded model %s' %(ret['model']))
return ret,pluginName
def dialog_check(self,ret):
pluginLookup = '%s/%s' % (ret['modeltype'], ret['subtype'])
try:
pluginName = subtype_plugin_map['%s/%s' % (ret['modeltype'], ret['subtype'])]
except KeyError:
pluginName = 'default'
if pluginName == 'kkit':
if (ret['subtype'] == 'sbml' and ret['foundlib'] == False):
reply = QtGui.QMessageBox.question(self, "python-libsbml is not found.","\n Read SBML is not possible.\n This can be installed using \n \n pip python-libsbml or \n apt-get install python-libsbml",
QtGui.QMessageBox.Ok)
if reply == QtGui.QMessageBox.Ok:
QtGui.QApplication.restoreOverrideCursor()
return valid, ret
if ret['loaderror'] != "":
reply = QtGui.QMessageBox.question(self, "Model can't be loaded", ret['loaderror']+" \n \n Do you want another file",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
dialog = LoaderDialog(self,self.tr('Load model from file'))
if dialog.exec_():
pluginName = None
ret,pluginName = self.checkPlugin(dialog)
valid,ret = self.dialog_check(ret)
else:
QtGui.QApplication.restoreOverrideCursor()
return valid,ret
else:
valid = True
return valid,ret
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
def newModelDialogSlot(self):
#Harsha: Create a new dialog widget for model building
self.popup.close()
newModelDialog = DialogWidget()
if newModelDialog.exec_():
modelPath = str(newModelDialog.modelPathEdit.text()).strip()
if len(modelPath) == 0:
raise mexception.ElementNameError('Model path cannot be empty')
if re.search('[ /]',modelPath) is not None:
raise mexception.ElementNameError('Model path should not containe / or whitespace')
#plugin = str(newModelDialog.submenu.currentText())
plugin = str(newModelDialog.getcurrentRadioButton())
#Harsha: All model will be forced to load/build under /model,
#2014 sep 10: All the model will be forced to load/build model under /modelName/model
'''
modelContainer = moose.Neutral('/model')
modelRoot = moose.Neutral('%s/%s' % (modelContainer.path, modelPath))
'''
if moose.exists(modelPath+'/model'):
moose.delete(modelPath)
modelContainer = moose.Neutral('%s' %(modelPath))
modelRoot = moose.Neutral('%s/%s' %(modelContainer.path,"model"))
if not moose.exists(modelRoot.path+'/info'):
moose.Annotator(modelRoot.path+'/info')
modelAnno = moose.element(modelRoot.path+'/info')
modelAnno.modeltype = "new_kkit"
modelAnno.dirpath = " "
self.loadedModelsAction(modelRoot.path,plugin)
self.setPlugin(plugin, modelRoot.path)
#Harsha: This will clear out object editor's objectpath and make it invisible
self.objectEditSlot('/', False)
def main():
# create the GUI application
app = QtGui.QApplication(sys.argv)
QtGui.qApp = app
#icon = QtGui.QIcon(os.path.join(config.KEY_ICON_DIR,'moose_icon.png'))
#app.setWindowIcon(icon)
# instantiate the main window
#moose.loadModel('../Demos/Genesis_files/Kholodenko.g','/kho')
mWindow = MWindow()
mWindow.setWindowState(QtCore.Qt.WindowMaximized)
sys.excepthook = mWindow.handleException
# show it
mWindow.show()
# start the Qt main loop execution, exiting from this script
#http://code.google.com/p/subplot/source/browse/branches/mzViewer/PyMZViewer/mpl_custom_widget.py
#http://eli.thegreenplace.net/files/prog_code/qt_mpl_bars.py.txt
#http://lionel.textmalaysia.com/a-simple-tutorial-on-gui-programming-using-qt-designer-with-pyqt4.html
#http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg13241.html
# with the same return code of Qt application
config.settings[config.KEY_FIRSTTIME] = 'False' # string not boolean
sys.exit(app.exec_())
if __name__ == '__main__':
main()
#
# mgui.py ends here