diff --git a/.travis.yml b/.travis.yml index 15779bf198d587255777bc0c0afe4c636ee06f89..b296745728e24698a436b5a6a30529f0504037cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ install: - sudo apt-get -y update - sudo apt-get -y --force-yes install python3 python-pip - sudo apt-get -y --force-yes install moose - - sudo pip install python-libsbml + - sudo -H pip install python-libsbml script: - # Making sure no python incompatible file is added. diff --git a/PlotWidgetContainer.py b/PlotWidgetContainer.py index f42e0a87e27ba9fe891b53344957d2f43a29b402..d51ab81e106837737f6d422d6282ed01af263395 100644 --- a/PlotWidgetContainer.py +++ b/PlotWidgetContainer.py @@ -4,14 +4,14 @@ from __future__ import print_function """ """ - -__author__ = "Aviral Goel" __credits__ = ["Upi Lab"] +__author__ = "Aviral Goel" __license__ = "GPL3" __version__ = "1.0.0" -__maintainer__ = "Aviral Goel" +__maintainer__ = "Aviral Goel", "HarshaRani" __email__ = "goel.aviral@gmail.com" __status__ = "Development" +__updated__ = "Jul 26 2017" import sys @@ -49,6 +49,7 @@ class PlotWidgetContainer(QWidget): self.model = moose.element(self.modelRoot) if self.modelRoot != "/": + self.modelRoot = self.findModelPath(self.modelRoot) if moose.exists(modelRoot + "/data"): self.data = moose.element(self.modelRoot + "/data") else: @@ -87,6 +88,17 @@ class PlotWidgetContainer(QWidget): if len(self.data.children) == 0: self.addPlotWidget() + def mooseIsInstance(self,element, classNames): + return moose.element(element).__class__.__name__ in classNames + + + def findModelPath(self,element): + child = element + while not self.mooseIsInstance(element, "Shell"): + child = moose.element(element).path + element = moose.element(element).parent + return child + def deleteWidget(self, graphWidget): # print("Deleted => ", graphWidget) self.graphWidgets.remove(graphWidget) diff --git a/defaults.py b/defaults.py index 458f7b389e3f566a83ce0e2fc6c98cfaa3e1ac74..f7a513804c8fa5024216e12b00d46b5e7c4e8ceb 100644 --- a/defaults.py +++ b/defaults.py @@ -1,3 +1,11 @@ +__credits__ = ["Upi Lab"] +__author__ = "Subhasis" +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "Subhasis", "HarshaRani","Aviral Goel" +__email__ = "goel.aviral@gmail.com" +__status__ = "Development" +__updated__ = "Jul 26 2017" PLOT_FIELDS={ 'LeakyIaF':['Vm'], @@ -11,8 +19,11 @@ PLOT_FIELDS={ FIELD_UNITS={ 'volume':'m3', 'Kd' : 'mM', - 'Km':'mM', + 'Km' :'mM', 'kcat':'s-1', + 'k1' :'1/# s', + 'k2' :'s-1', + 'k3' :'s-1', 'Vm':'V', 'conc':'mM', 'concInit':'mM', diff --git a/mgui.py b/mgui.py index 9f201303e2db36f325e27661637b37fbcfb7504a..24d2bf83bc575b109adbda5837de124d4a8cc587 100644 --- a/mgui.py +++ b/mgui.py @@ -2,13 +2,13 @@ # # Filename: mgui.py # Description: -# Author: -# Maintainer: +# Author: "Subhasis", "HarshaRani","Aviral Goel" +# Maintainer: HarshaRani # Created: Mon Nov 12 09:38:09 2012 (+0530) # Version: -# Last-Updated: Fri Oct 30 11:54:33 2015 (+0530) +# Last-Updated: Thu Oct 5 14:54:33 2017 (+0530) # By: Harsha -# Update #: 1338 +# Update #: # URL: # Keywords: # Compatibility: @@ -43,6 +43,10 @@ # # +'''' +Oct 5: clean up with round trip of dialog_exe + +''' # Code: import imp import inspect @@ -206,7 +210,7 @@ class MWindow(QtGui.QMainWindow): ("Fig5A (20s)", "../moose-examples/paper-2015/Fig5_CellMultiscale/Fig5A.py"), ("Fig5BCD (240s)" , "../moose-examples/paper-2015/Fig5_CellMultiscale/Fig5BCD.py"), ("Fig6A (60s)", "../moose-examples/paper-2015/Fig6_NetMultiscale/Fig6A.py" ), - ("Reduced6 (200s)", "../moose-examples/paper-2015/Fig6_NetMultiscale/ReducedModel.py"), + ("ReducedModel (200s)", "../moose-examples/paper-2015/Fig6_NetMultiscale/ReducedModel.py"), ("Squid" , "../moose-examples/squid/squid_demo.py") ]) layout.setContentsMargins(QtCore.QMargins(20,20,20,20)) @@ -246,7 +250,7 @@ class MWindow(QtGui.QMainWindow): button.setToolTip("<span style=\"color:black;\">Illustrates building a panel of multiscale models to test neuronal plasticity in different contexts</span>") elif k[0] == "Fig6A (60s)": button.setToolTip("<span style=\"color:black;\">This LIF network with Ca plasticity is based on: Memory Maintenance in Synapses with Calcium-Based Plasticity in the Presence of Background Activity PLOS Computational Biology, 2014</span>") - elif k[0] == "Reduced6 (200s)": + elif k[0] == "ReducedModel (200s)": button.setToolTip("<span style=\"color:black;\">This is the Reduced version of LIF network with Ca plasticity model based on: Memory Maintenance in Synapses with Calcium-Based Plasticity in the Presence of Background Activity PLOS Computational Biology, 2014</span>") elif k[0] == "Squid": button.setToolTip("<span style=\"color:black;\">squid Demo</span>") @@ -258,7 +262,7 @@ class MWindow(QtGui.QMainWindow): layout4.addWidget(button) elif k[0] in ["Fig5A (20s)","Fig5BCD (240s)"]: layout5.addWidget(button) - elif k[0] in ["Fig6A (60s)","Reduced6 (200s)"]: + elif k[0] in ["Fig6A (60s)","ReducedModel (200s)"]: layout6.addWidget(button) elif k[0] in ["Squid"]: layout7.addWidget(button) @@ -292,6 +296,7 @@ class MWindow(QtGui.QMainWindow): self.popup.hide() abspath = os.path.abspath(filepath) directory, modulename = os.path.split(abspath) + modelName = os.path.splitext(modulename)[0] ret = loadFile(str(abspath),'%s' %(modelName),solver,merge=False) self.setPlugin("kkit", ret["model"].path) @@ -641,22 +646,64 @@ class MWindow(QtGui.QMainWindow): ("Fig5A (20s)", "../moose-examples/paper-2015/Fig5_CellMultiscale/Fig5A.py"), ("Fig5BCD (240s)" , "../moose-examples/paper-2015/Fig5_CellMultiscale/Fig5BCD.py"), ("Fig6A (60s)", "../moose-examples/paper-2015/Fig6_NetMultiscale/Fig6A.py" ), - ("Reduced6 (200s)", "../moose-examples/paper-2015/Fig6_NetMultiscale/ReducedModel.py"), + ("ReducedModel (200s)", "../moose-examples/paper-2015/Fig6_NetMultiscale/ReducedModel.py"), ("Squid" , "../moose-examples/squid/squid_demo.py") ]) - self.subMenu = QtGui.QMenu('Paper_2015_Demos') + self.subMenu = QtGui.QMenu('Demos') for i in range(0,len(self.menuitems)): k = self.menuitems.popitem(0) - t = "self."+k[0]+"Action" - t = QtGui.QAction(k[0],self) - self.subMenu.addAction(t) - if k[0] == "Fig3C_Gsl (2s)": - t.connect(t,QtCore.SIGNAL('triggered()'),lambda script = k[1]: self.run_genesis_script(script,"gsl")) + if k[0] == "Fig2C (6s)": + self.Fig2Caction = QtGui.QAction('Fig2C (6s)', self) + self.Fig2Caction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig2_elecModels/Fig2C.py')) + self.subMenu.addAction(self.Fig2Caction) + elif k[0] == "Fig2D (35s)": + self.Fig2Daction = QtGui.QAction('Fig2D (35s)', self) + self.Fig2Daction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig2_elecModels/Fig2D.py')) + self.subMenu.addAction(self.Fig2Daction) + elif k[0] == "Fig2E (5s)": + self.Fig2Eaction = QtGui.QAction('Fig2E (5s)', self) + self.Fig2Eaction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig2_elecModels/Fig2E.py')) + self.subMenu.addAction(self.Fig2Eaction) elif k[0] == "Fig3B_Gssa (2s)": - t.connect(t,QtCore.SIGNAL('triggered()'),lambda script = k[1]: self.run_genesis_script(script,"gssa")) + self.Fig3B_Gssaaction = QtGui.QAction('Fig3B_Gssa (2s)', self) + self.Fig3B_Gssaaction.triggered.connect(lambda :self.run_genesis_script('../moose-examples/paper-2015/Fig3_chemModels/Fig3ABC.g',"gssa")) + self.subMenu.addAction(self.Fig3B_Gssaaction) + elif k[0] == "Fig3C_Gsl (2s)": + self.Fig3C_Gslaction = QtGui.QAction('Fig3C_Gsl (2s)', self) + self.Fig3C_Gslaction.triggered.connect(lambda :self.run_genesis_script('../moose-examples/paper-2015/Fig3_chemModels/Fig3ABC.g',"gsl")) + self.subMenu.addAction(self.Fig3C_Gslaction) + elif k[0] == "Fig3D (1s)": + self.Fig3Daction = QtGui.QAction('Fig3D (1s)', self) + self.Fig3Daction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig3_chemModels/Fig3D.py')) + self.subMenu.addAction(self.Fig3Daction) + elif k[0] == "Fig4B (10s)": + self.Fig4Baction = QtGui.QAction('Fig4B (10s)', self) + self.Fig4Baction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig4_ReacDiff/Fig4B.py')) + self.subMenu.addAction(self.Fig4Baction) + elif k[0] == "Fig4K": + self.Fig4Kaction = QtGui.QAction('Fig4K', self) + self.Fig4Kaction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig4_ReacDiff/rxdSpineSize.py')) + self.subMenu.addAction(self.Fig4Kaction) + elif k[0] == "Fig5A (20s)": + self.Fig5Aaction = QtGui.QAction('Fig5A (20s)', self) + self.Fig5Aaction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig5_CellMultiscale/Fig5A.py')) + self.subMenu.addAction(self.Fig5Aaction) + elif k[0] == "Fig5BCD (240s)": + self.Fig5BCDaction = QtGui.QAction('Fig5BCD (240s)', self) + self.Fig5BCDaction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig5_CellMultiscale/Fig5BCD.py')) + self.subMenu.addAction(self.Fig5BCDaction) + elif k[0] == "Fig6A (60s)": + self.Fig6Aaction = QtGui.QAction('Fig6A (60s)', self) + self.Fig6Aaction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig6_NetMultiscale/Fig6A.py')) + self.subMenu.addAction(self.Fig6Aaction) + elif k[0] == "ReducedModel (200s)": + self.ReducedModelaction = QtGui.QAction('ReducedModel (200s)', self) + self.ReducedModelaction.triggered.connect(lambda :self.run_python_script('../moose-examples/paper-2015/Fig6_NetMultiscale/ReducedModel.py')) + self.subMenu.addAction(self.ReducedModelaction) else: - t.connect(t,QtCore.SIGNAL('triggered()'),lambda : self.run_python_script(k[1])) - self.subMenu.addAction(t) + self.Squidaction = QtGui.QAction('Squid', self) + self.Squidaction.triggered.connect(lambda :self.run_python_script('../moose-examples/squid/squid_demo.py')) + self.subMenu.addAction(self.Squidaction) self.fileMenu.addMenu(self.subMenu) if not hasattr(self,'loadedModels'): @@ -1030,6 +1077,11 @@ class MWindow(QtGui.QMainWindow): self.objectEditDockWidget.setObject(mobj) self.objectEditDockWidget.setVisible(visible) + # def objectEditClearSlot(self): + # #clearning the views which is stored + # self.objectEditDockWidget.clearDict() + + 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 @@ -1105,20 +1157,31 @@ class MWindow(QtGui.QMainWindow): ret = [] ret,pluginName = self.checkPlugin(dialog) if pluginName == 'kkit': - compt = moose.wildcardFind(ret['model'].path+'/##[ISA=ChemCompt]') - if not len(compt): - reply = QtGui.QMessageBox.question(self, "Model is empty","Model has no compartment, atleast one compartment should exist to display the widget\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_(): - ret,pluginName = self.checkPlugin(dialog) - ret,valid = self.dialog_check(ret) - else: - QtGui.QApplication.restoreOverrideCursor() + 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 else: - valid = True + 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 if valid == True: modelAnno = moose.Annotator(ret['model'].path+'/info') if ret['subtype']: @@ -1160,34 +1223,47 @@ class MWindow(QtGui.QMainWindow): 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']) + #pluginLookup = '%s/%s' % (ret['modeltype'], ret['subtype']) try: pluginName = subtype_plugin_map['%s/%s' % (ret['modeltype'], ret['subtype'])] except KeyError: pluginName = 'default' - print 'Loaded model', ret['model'].path + if ret['foundlib']: + print ('Loaded model %s' %(ret['model'])) return ret,pluginName def dialog_check(self,ret): + valid = False 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': - compt = moose.wildcardFind(ret['model'].path+'/##[ISA=ChemCompt]') - if not len(compt): - reply = QtGui.QMessageBox.question(self, "Model is empty","Model has no compartment, atleast one compartment should exist to display the widget\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_(): - ret,pluginName = self.checkPlugin(dialog) - else: - QtGui.QApplication.restoreOverrideCursor() - return + 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 else: - return ret,True + 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 + def newModelDialogSlot(self): #Harsha: Create a new dialog widget for model building self.popup.close() diff --git a/mload.py b/mload.py index 257daa9410909a3fb8eb877afdf8ef7ff7d125b5..9fc753e64551b388f7b605d0fe326fc75738e930 100644 --- a/mload.py +++ b/mload.py @@ -2,12 +2,12 @@ # # Filename: mload.py # Description: -# Author: -# Maintainer: +# Author: Subhasis +# Maintainer:HarshaRani # Created: Fri Feb 8 09:38:40 2013 (+0530) # Version: -# Last-Updated: Wed May 22 12:16:35 2013 (+0530) -# By: subha +# Last-Updated: Wed Oct 5 15:16:35 2017 (+0530) +# By: HarshaRani # Update #: 213 # URL: # Keywords: @@ -44,7 +44,12 @@ # # Code: - +''' +Oct 5 : check is made for kkit model + -- Atleast one compartment should exists + -- Atleast 2 pool should exists +Oct 4 : clean up for python3 +''' import moose from moose import neuroml import mtypes @@ -118,7 +123,10 @@ def loadFile(filename, target, solver="gsl", merge=True): modelroot: root element of the model, None if could not be located - as is the case with Python scripts """ + loaderror = "" num = 1 + libsfound = True + model = '/' newTarget = target while moose.exists(newTarget): newTarget = target + "-" + str(num) @@ -128,7 +136,7 @@ def loadFile(filename, target, solver="gsl", merge=True): with open(filename, 'rb') as infile: istext = mtypes.istextfile(infile) if not istext: - print 'Cannot handle any binary formats yet' + print ('Cannot handle any binary formats yet') return None # parent, child = posixpath.split(target) # p = moose.Neutral(parent) @@ -149,31 +157,42 @@ def loadFile(filename, target, solver="gsl", merge=True): model,modelpath = loadGenCsp(target,filename,solver) xcord,ycord = [],[] if moose.exists(moose.element(modelpath).path): - mObj = moose.wildcardFind(moose.element(modelpath).path+'/##[ISA=PoolBase]'+','+ - moose.element(modelpath).path+'/##[ISA=ReacBase]'+','+ - moose.element(modelpath).path+'/##[ISA=EnzBase]'+','+ - moose.element(modelpath).path+'/##[ISA=StimulusTable]') - for p in mObj: - if not isinstance(moose.element(p.parent),moose.CplxEnzBase): - xcord.append(moose.element(p.path+'/info').x) - ycord.append(moose.element(p.path+'/info').y) - recalculatecoordinatesforKkit(mObj,xcord,ycord) - - for ememb in moose.wildcardFind(moose.element(modelpath).path+'/##[ISA=EnzBase]'): - objInfo = ememb.path+'/info' - #Enzyme's textcolor (from kkit) will be bgcolor (in moose) - if moose.exists(objInfo): - bgcolor = moose.element(objInfo).color - moose.element(objInfo).color = moose.element(objInfo).textColor - moose.element(objInfo).textColor = bgcolor - - moose.Annotator(moose.element(modelpath).path+'/info').modeltype = "kkit" - else: - print " path doesn't exists" - moose.le(modelpath) + process = True + compt = len(moose.wildcardFind(modelpath+'/##[ISA=CubeMesh]')) + if not compt: + loaderror = "Model has no compartment, atleast one compartment should exist to display the widget" + process = False + else: + p = len(moose.wildcardFind(modelpath+'/##[ISA=PoolBase]')) + if p < 2: + loaderror = "Model has no pool, atleast two pool should exist to display the widget" + process = False + if process: + if moose.exists(moose.element(modelpath).path): + mObj = moose.wildcardFind(moose.element(modelpath).path+'/##[ISA=PoolBase]'+','+ + moose.element(modelpath).path+'/##[ISA=ReacBase]'+','+ + moose.element(modelpath).path+'/##[ISA=EnzBase]'+','+ + moose.element(modelpath).path+'/##[ISA=StimulusTable]') + for p in mObj: + if not isinstance(moose.element(p.parent),moose.CplxEnzBase): + xcord.append(moose.element(p.path+'/info').x) + ycord.append(moose.element(p.path+'/info').y) + recalculatecoordinatesforKkit(mObj,xcord,ycord) + + for ememb in moose.wildcardFind(moose.element(modelpath).path+'/##[ISA=EnzBase]'): + objInfo = ememb.path+'/info' + #Enzyme's textcolor (from kkit) will be bgcolor (in moose) + if moose.exists(objInfo): + bgcolor = moose.element(objInfo).color + moose.element(objInfo).color = moose.element(objInfo).textColor + moose.element(objInfo).textColor = bgcolor + moose.Annotator(moose.element(modelpath).path+'/info').modeltype = "kkit" + else: + print (" path doesn't exists") + moose.le(modelpath) else: - print 'Only kkit and prototype files can be loaded.' - + print ('Only kkit and prototype files can be loaded.') + elif modeltype == 'cspace': model,modelpath = loadGenCsp(target,filename) @@ -205,7 +224,7 @@ def loadFile(filename, target, solver="gsl", merge=True): # moose.move("cells/", cell.path) elif subtype == 'sbml': - foundLibtaSBML_ = False + foundLibSBML_ = False try: import libsbml foundLibSBML_ = True @@ -215,7 +234,7 @@ def loadFile(filename, target, solver="gsl", merge=True): if target != '/': if moose.exists(target): moose.delete(target) - model = mooseReadSBML(filename,target) + model,loaderror = mooseReadSBML(filename,target) if moose.exists(moose.element(model).path): moose.Annotator(moose.element(model).path+'/info').modeltype = "sbml" addSolver(target,'gsl') @@ -229,7 +248,9 @@ def loadFile(filename, target, solver="gsl", merge=True): # app.restoreOverrideCursor() return {'modeltype': modeltype, 'subtype': subtype, - 'model': model} + 'model': model, + 'foundlib' : libsfound, + 'loaderror' : loaderror} # diff --git a/objectedit.py b/objectedit.py index a98294cc3f3fa619651e8ccf70f011bba1122810..dcb019a4d50d3faaf86e33d5cfdb1265f27302b4 100644 --- a/objectedit.py +++ b/objectedit.py @@ -6,7 +6,7 @@ # Maintainer: # Created: Wed Jun 30 11:18:34 2010 (+0530) # Version: -# Last-Updated: Friday May 17 23:45:59 2017 (+0530) +# Last-Updated: Thu Jul 27 11:05:59 2017 (+0530) # By: Harsha # Update #: # URL: @@ -193,7 +193,6 @@ class ObjectEditModel(QtCore.QAbstractTableModel): def setData(self, index, value, role=QtCore.Qt.EditRole): if not index.isValid() or index.row () >= len(self.fields) or index.column() != 1: return False - print(value) field = self.fields[index.row()] if (role == QtCore.Qt.CheckStateRole): if (index.column() == 1): @@ -236,8 +235,17 @@ class ObjectEditModel(QtCore.QAbstractTableModel): else: oldValue = self.mooseObject.getField(field) - value = type(oldValue)(value) - tt = self.mooseObject.setField(field, value) + if field != "isBuffered": + value = type(oldValue)(value) + self.mooseObject.setField(field, value) + else: + if self.mooseObject.className == "ZombiePool" or self.mooseObject.className =="ZombieBufPool": + QtGui.QMessageBox.warning(None,'Solver is set, Could not set the value','\n Unset the solver by clicking \n run widget -> Preferences -> Exponential Euler->Apply') + else: + if value.lower() in ("yes", "true", "t", "1"): + self.mooseObject.setField(field, True) + else: + self.mooseObject.setField(field, False) self.undoStack.append((index, oldValue)) if field == 'name': self.emit(QtCore.SIGNAL('objectNameChanged(PyQt_PyObject)'), self.mooseObject) @@ -247,7 +255,7 @@ class ObjectEditModel(QtCore.QAbstractTableModel): return True def undo(self): - print 'Undo' + print ('Undo') if len(self.undoStack) == 0: raise Info('No more undo information') index, oldvalue, = self.undoStack.pop() @@ -417,7 +425,7 @@ class ObjectEditView(QtGui.QTableView): self.setColor(getColor(self.model().mooseObject.path+'/info')[1]) except: pass - print 'Created view with', mobject + print ('Created view with %s' %(mobject)) def setColor(self, color): self.colorButton.setStyleSheet( @@ -431,8 +439,6 @@ class ObjectEditView(QtGui.QTableView): QtGui.QTableView.dataChanged(self, tl, br) self.viewport().update() - - class ObjectEditDockWidget(QtGui.QDockWidget): """A dock widget whose title is set by the current moose object. Allows switching the moose object. It stores the created @@ -461,7 +467,8 @@ class ObjectEditDockWidget(QtGui.QDockWidget): self.setWindowTitle('Edit: %s' % (mobj.path)) # self.view.colorDialog.colorSelected.connect(self.colorChangedEmit) - + # def clearDict(self): + # self.view_dict.clear() def setObject(self, mobj): element = moose.element(mobj) diff --git a/plugins/constants.py b/plugins/constants.py index 558b5fc518e205f7536551e6f3d2580c4b889915..3596f2c5180bb71b02e5d145e3e8470630d6d9e3 100644 --- a/plugins/constants.py +++ b/plugins/constants.py @@ -1,16 +1,24 @@ -INVALID = 6 -INTERIOR = 7 -BOUNDARY = 8 -SAME_OBJECT = 9 -OTHER_OBJECT = 10 -NO_OBJECT = 11 -RUBBERBAND_SELECTION = 12 -VALID = 13 +INVALID = 6 + +INTERIOR = 7 +BOUNDARY = 8 + +SAME_OBJECT = 9 +OTHER_OBJECT = 10 +NO_OBJECT = 11 + +RUBBERBAND_SELECTION = 12 +VALID = 13 ITEM = 0 CONNECTOR = 1 CONNECTION = 2 EMPTY = 3 + COMPARTMENT = 14 COMPARTMENT_BOUNDARY = 4 COMPARTMENT_INTERIOR = 5 + +GROUP = 15 +GROUP_BOUNDARY = 16 +GROUP_INTERIOR = 17 diff --git a/plugins/default.py b/plugins/default.py index ccf8846d94ebcdd5197672590f7110283a0d9930..788e8349a82ca1f7d89b155a3a30eef333072a6e 100644 --- a/plugins/default.py +++ b/plugins/default.py @@ -6,9 +6,9 @@ # Maintainer: # Created: Tue Nov 13 15:58:31 2012 (+0530) # Version: -# Last-Updated: Thu Jul 18 10:35:00 2013 (+0530) -# By: subha -# Update #: 2244 +# Last-Updated: Thu Oct 5 12:35:00 2013 (+0530) +# By: Harsha +# Update #: # URL: # Keywords: # Compatibility: @@ -44,7 +44,11 @@ # # Code: +''' +Oct 5: could not recreate if object already exist in moose which was allowed earlier + now if object exist need to use element which is cleaned here +''' import sys import config import pickle @@ -331,9 +335,15 @@ class RunView(RunBase): self.dataRoot = modelRoot + '/data' else: self.dataRoot = "/data" - self.setModelRoot(moose.Neutral(self.plugin.modelRoot).path) - self.setDataRoot(moose.Neutral('/data').path) - self.setDataRoot(moose.Neutral(self.plugin.modelRoot).path) + if not moose.exists(self.plugin.modelRoot): + moose.Neutral(self.plugin.modelroot) + self.setModelRoot(moose.element(self.plugin.modelRoot).path) + if not moose.exists('/data'): + moose.Neutral('/data') + self.setDataRoot(moose.element('/data').path) + if not moose.exists(self.plugin.modelRoot): + moose.Neutral(self.plugin.modelRoot) + self.setDataRoot(moose.element(self.plugin.modelRoot).path) self.plugin.modelRootChanged.connect(self.setModelRoot) self.plugin.dataRootChanged.connect(self.setDataRoot) # self.getCentralWidget() @@ -709,19 +719,34 @@ class SchedulingWidget(QtGui.QWidget): else: stoich = moose.Stoich(compt[0].path+'/stoich') status = int(stoich.status) + # Flag to track status of Stoich object. + # -1: No path yet assigned. + # 0: Success + # 1: Warning: Missing reactant in Reac or Enz + # 2: Warning: Missing substrate in MMenz + # 4: Warning: Compartment not defined + # 8: Warning: Neither Ksolve nor Dsolve defined + # 16: Warning: No objects found on path + # print("Status =>", status) + + if status == 1 or status == 2: + nameRE = "\n\nclassName --> parent --> name " + for res in moose.wildcardFind(self.modelRoot+'/##[ISA=ReacBase],'+self.modelRoot+'/##[ISA=EnzBase]'): + if not len(res.neighbors["sub"]) or not len(res.neighbors["prd"]): + nameRE = nameRE+"\n "+res.className + " --> "+res.parent.name+ " --> "+res.name + if status == -1: QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Reaction path not yet assigned.\n ") return -1 if status == 1: - QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Missing a reactant in a Reac or Enz.\n ") + #QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Missing a reactant in a Reac or Enz.\n ") + QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Missing a reactant in %s " %(nameRE)) return 1 elif status == 2: - QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Missing a substrate in an MMenz.\n ") + QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Missing a substrate in an MMenz %s " %(nameRE)) + #QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Missing a substrate in an MMenz.\n ") return 2 - elif status == 3: - QtGui.QMessageBox.warning(None,"Could not Run the model","Warning: Missing substrates as well as reactants.\n ") - return 3 elif status == 4: QtGui.QMessageBox.warning(None,"Could not Run the model"," Warning: Compartment not defined.\n ") return 4 diff --git a/plugins/kkit.py b/plugins/kkit.py index 68bfd85ee77dcfb1a38c00ffea00e794363bc74a..b6f7fb5a4a249931a336f7a2e576ab4d6b87bea0 100644 --- a/plugins/kkit.py +++ b/plugins/kkit.py @@ -6,19 +6,20 @@ __version__ = "1.0.0" __maintainer__ = "HarshaRani" __email__ = "hrani@ncbs.res.in" __status__ = "Development" -__updated__ = "Mar 7 2017" +__updated__ = "Oct 18 2017" +''' + +''' import math import sys from PyQt4 import QtGui, QtCore, Qt from default import * from moose import * -#from moose.genesis import write from moose import SBML from moose.genesis.writeKkit import mooseWriteKkit -#sys.path.append('plugins') from mplugin import * from kkitUtil import * -from kkitQGraphics import PoolItem, ReacItem,EnzItem,CplxItem,ComptItem +from kkitQGraphics import * from kkitViewcontrol import * from kkitCalcArrow import * from kkitOrdinateUtil import * @@ -77,11 +78,16 @@ class KkitPlugin(MoosePlugin): if filters[str(filter_)] == 'SBML': self.sceneObj = KkitEditorView(self).getCentralWidget().mooseId_GObj self.coOrdinates = {} + self.plugin = KkitEditorView(self).getCentralWidget().plugin + self.defaultScenewidth = KkitEditorView(self).getCentralWidget().defaultScenewidth + self.defaultSceneheight = KkitEditorView(self).getCentralWidget().defaultSceneheight for k,v in self.sceneObj.items(): if moose.exists(moose.element(k).path+'/info'): annoInfo = Annotator(k.path+'/info') - self.coOrdinates[k] = {'x':annoInfo.x, 'y':annoInfo.y} - + if moose.element(self.plugin.modelRoot+'/info').modeltype == 'kkit': + self.coOrdinates[k] = {'x':annoInfo.x*self.defaultScenewidth, 'y':annoInfo.y*self.defaultSceneheight} + else: + self.coOrdinates[k] = {'x':annoInfo.x, 'y':annoInfo.y} #writeerror = moose.writeSBML(self.modelRoot,str(filename),self.coOrdinates) writeerror = -2 conisitencyMessages = "" @@ -105,12 +111,12 @@ class KkitPlugin(MoosePlugin): if moose.exists(moose.element(k).path+'/info'): annoInfo = Annotator(k.path+'/info') #co-ordinates will be in decimals converting to int which should be b/w 0 to 10 - x = annoInfo.x *10 - y = -annoInfo.y *10 + x = annoInfo.x * 10 + y = -annoInfo.y * 10 self.coOrdinates[k] = {'x':x, 'y':y} - error,writen = mooseWriteKkit(self.modelRoot,str(filename),self.coOrdinates) - if writen == False: + error,written = mooseWriteKkit(self.modelRoot,str(filename),self.coOrdinates) + if written == False: QtGui.QMessageBox.information(None,'Could not save the Model','\nCheck the file') else: if error == "": @@ -329,22 +335,16 @@ class KineticsWidget(EditorWidgetBase): self.arrowsize = 2 self.reset() - self.defaultSceneheight = 500 - self.defaultScenewidth = 1000 + self.defaultSceneheight = 800#1000 + self.defaultScenewidth = 1000#2400 self.positionInfoExist = True self.defaultComptsize = 5 self.srcdesConnection = {} - + self.meshEntry = {} self.mooseId_GObj = {} self.qGraCompt = {} self.xyCord = {} self.editor = None - # self.xmin = 0.0 - # self.xmax = 1.0 - # self.ymin = 0.0 - # self.ymax = 1.0 - # self.xratio = 1.0 - # self.yratio = 1.0 def reset(self): self.createdItem = {} @@ -419,22 +419,50 @@ class KineticsWidget(EditorWidgetBase): self.m = wildcardFind(self.modelRoot+'/##[ISA=ChemCompt]') if self.m: self.srcdesConnection = {} + if self.meshEntry: + self.meshEntry.clear() + else: + self.meshEntry = {} #self.meshEntry.clear= {} # Compartment and its members are setup #self.meshEntry,self.xmin,self.xmax,self.ymin,self.ymax,self.noPositionInfo = setupMeshObj(self.modelRoot) - self.meshEntry,xcord,ycord = setupMeshObj(self.modelRoot) - self.positionInfoExist = not(len(np.nonzero(xcord)[0]) == 0 \ - and len(np.nonzero(ycord)[0]) == 0) - + #self.meshEntry,xcord,ycord = setupMeshObj(self.modelRoot) + #self.positionInfoExist = not(len(np.nonzero(xcord)[0]) == 0 \ + # and len(np.nonzero(ycord)[0]) == 0) + self.objPar,self.meshEntry,self.xmin,self.xmax,self.ymin,self.ymax,self.noPositionInfo = setupMeshObj(self.modelRoot) + self.autocoordinates = False if self.srcdesConnection: self.srcdesConnection.clear() else: self.srcdesConnection = {} + setupItem(self.modelRoot,self.srcdesConnection) - if not self.positionInfoExist: + + # if not self.positionInfoExist: + # autoCoordinates(self.meshEntry,self.srcdesConnection) + if not self.noPositionInfo: + self.autocoordinates = True + #self.xmin,self.xmax,self.ymin,self.ymax,self.autoCordinatepos = autoCoordinates(self.meshEntry,self.srcdesConnection) + #print " after ",self.xmin,self.xmax, self.ymin, self.ymax,self.autoCordinatepos autoCoordinates(self.meshEntry,self.srcdesConnection) - + + self.size = QtCore.QSize(1000 ,550) + if self.xmax-self.xmin != 0: + self.xratio = (self.size.width()-10)/(self.xmax-self.xmin) + else: self.xratio = self.size.width()-10 + + if self.ymax-self.ymin: + self.yratio = (self.size.height()-10)/(self.ymax-self.ymin) + else: self.yratio = (self.size.height()-10) + + self.xratio = int(self.xratio) + self.yratio = int(self.yratio) + if self.xratio == 0: + self.xratio = 1 + if self.yratio == 0: + self.yratio = 1 + def sizeHint(self): return QtCore.QSize(800,400) @@ -460,7 +488,7 @@ class KineticsWidget(EditorWidgetBase): item = self.mooseId_GObj[mooseObject] if (isinstance(item,PoolItem) or isinstance(item,EnzItem) or isinstance(item,MMEnzItem) ): item.updateColor(color) - + ''' def mooseObjOntoscene(self): # All the compartments are put first on to the scene \ # Need to do: Check With upi if empty compartments exist @@ -535,15 +563,116 @@ class KineticsWidget(EditorWidgetBase): self.setupDisplay(cplxinfo,cplxItem,"cplx") # compartment's rectangle size is calculated depending on children - self.comptChilrenBoundingRect() + self.comptChildrenBoundingRect() + ''' + def mooseObjOntoscene(self): + # All the compartments are put first on to the scene \ + # Need to do: Check With upi if empty compartments exist + self.qGraCompt = {} + self.qGraGrp = {} + self.mooseId_GObj = {} + if self.qGraCompt: + self.qGraCompt.clear() + else: + self.qGraCompt = {} - def comptChilrenBoundingRect(self): + if self.qGraGrp: + self.qGraGrp.clear() + else: + self.qGraGrp = {} + + if self.qGraGrp: + self.qGraGrp.clear() + else: + self.qGraGrp = {} + + if self.mooseId_GObj: + self.mooseId_GObj.clear() + else: + self.mooseId_GObj = {} + for k,v in self.objPar.items(): + if isinstance(moose.element(k),moose.ChemCompt): + self.createCompt(k) + self.qGraCompt[k] + + elif isinstance(moose.element(k),Neutral): + if len(self.meshEntry[k]): + if isinstance(moose.element(v), moose.ChemCompt): + group_parent = self.qGraCompt[v] + elif isinstance(moose.element(v), moose.Neutral): + group_parent = self.qGraGrp[v] + self.createGroup(k,group_parent) + for cmpt_grp,memb in self.meshEntry.items(): + if len(memb): + if isinstance(moose.element(cmpt_grp),moose.ChemCompt): + qtGrpparent = self.qGraCompt[cmpt_grp] + elif isinstance(moose.element(cmpt_grp), moose.Neutral): + qtGrpparent = self.qGraGrp[cmpt_grp] + for mclass in ["enzyme","pool","reaction","cplx","function","stimTab"]: + self.mObjontoscene(memb,mclass,qtGrpparent) + + self.groupChildrenBoundingRect() + # compartment's rectangle size is calculated depending on children + self.comptChildrenBoundingRect() + def mObjontoscene(self,memb,mclass,qtGrpparent): + try: + value = memb[mclass] + except KeyError: + pass + else: + for mObj in memb[mclass]: + minfo = mObj.path+'/info' + + if mObj.className in['Enz',"ZombieEnz"]: + mItem = EnzItem(mObj,qtGrpparent) + + elif mObj.className in['MMenz',"ZombieMMenz"]: + mItem = MMEnzItem(mObj,qtGrpparent) + + elif isinstance (moose.element(mObj),moose.PoolBase) and mclass != "cplx": + #depending on Editor Widget or Run widget pool will be created a PoolItem or PoolItemCircle + mItem = self.makePoolItem(mObj,qtGrpparent) + + elif isinstance (moose.element(mObj),moose.ReacBase): + mItem = ReacItem(mObj,qtGrpparent) + + elif mclass == "cplx": + minfo = (mObj.parent).path+'/info' + mItem = CplxItem(mObj,self.mooseId_GObj[element(mObj).parent]) + self.mooseId_GObj[element(mObj.getId())] = mItem + elif mclass == "function": + if isinstance(moose.element(mObj.parent),moose.PoolBase): + minfo = moose.element(mObj).path+'/info' + Af = Annotator(minfo) + qtGrpparent = self.mooseId_GObj[element(mObj.parent)] + mItem = FuncItem(mObj,qtGrpparent) + elif mclass == "stimTab": + minfo = mObj.path+'/info' + mItem = TableItem(mObj,qtGrpparent) + self.mooseId_GObj[element(mObj.getId())] = mItem + self.setupDisplay(minfo,mItem,mclass) + + def createGroup(self,key,parent): + self.new_GRP = GRPItem(parent,0,0,0,0,key) + self.qGraGrp[key] = self.new_GRP + self.new_GRP.setRect(20,20,20,20) + + def groupChildrenBoundingRect(self): + for k, v in self.qGraGrp.items(): + grpcolor = moose.Annotator(moose.element(k.path+'/info')).color + #Todo: One may need to calculate explicitly the boundary for Group also if there is a cross-group connection, then + # childrenBoundrect() will take the QPolygonItem position + rectcompt = v.childrenBoundingRect() + v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20)) + v.setPen(QtGui.QPen(Qt.QColor(grpcolor), self.comptPen, Qt.Qt.SolidLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin)) + + def comptChildrenBoundingRect(self): for k, v in self.qGraCompt.items(): # compartment's rectangle size is calculated depending on children rectcompt = calculateChildBoundingRect(v) v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20)) v.setPen(QtGui.QPen(Qt.QColor(66,66,66,100), self.comptPen, Qt.Qt.SolidLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin)) - + def createCompt(self,key): self.new_Compt = ComptItem(self,0,0,0,0,key) self.qGraCompt[key] = self.new_Compt @@ -598,8 +727,14 @@ class KineticsWidget(EditorWidgetBase): '''By this time, model loaded from kkit,cspace,SBML would have info field created and co-ordinates are added either by autocoordinates (for cspace,SBML(unless it is not saved from moose)) or from kkit ''' - x = self.defaultScenewidth * float(element(iteminfo).getField('x')) - y = self.defaultSceneheight *float(element(iteminfo).getField('y')) + if moose.Annotator(self.plugin.modelRoot+'/info').modeltype == 'kkit': + x = self.defaultScenewidth * float(element(iteminfo).getField('x')) + y = self.defaultSceneheight * float(element(iteminfo).getField('y')) + #x = x /self.defaultScenewidth + #y = y /self.defaultSceneheight + else: + x = float(element(iteminfo).getField('x')) + y = float(element(iteminfo).getField('y')) return(x,y) def drawLine_arrow(self, itemignoreZooming=False): @@ -613,13 +748,13 @@ class KineticsWidget(EditorWidgetBase): if isinstance(out,tuple): src = self.mooseId_GObj[inn] if len(out[0])== 0: - print inn.className + ' : ' +inn.name+ " doesn't output message" + print (inn.className + ' : ' +inn.name+ " doesn't output message") else: for items in (items for items in out[0] ): des = self.mooseId_GObj[element(items[0])] self.lineCord(src,des,items,itemignoreZooming) if len(out[1]) == 0: - print inn.className + ' : ' +inn.name+ " doesn't output message" + print (inn.className + ' : ' +inn.name+ " doesn't output message") else: for items in (items for items in out[1] ): des = self.mooseId_GObj[element(items[0])] @@ -627,9 +762,9 @@ class KineticsWidget(EditorWidgetBase): elif isinstance(out,list): if len(out) == 0: if inn.className == "StimulusTable": - print inn.name +" doesn't have output" + print (inn.name +" doesn't have output") elif inn.className == "ZombieFunction" or inn.className == "Function": - print inn.name + " doesn't have sumtotal " + print (inn.name + " doesn't have sumtotal ") else: src = self.mooseId_GObj[inn] for items in (items for items in out ): @@ -640,7 +775,7 @@ class KineticsWidget(EditorWidgetBase): endtype = type_no[1] line = 0 if (src == "") and (des == ""): - print "Source or destination is missing or incorrect" + print ("Source or destination is missing or incorrect") return srcdes_list = [src,des,endtype,line] arrow = calcArrow(srcdes_list,itemignoreZooming,self.iconScale) @@ -653,7 +788,7 @@ class KineticsWidget(EditorWidgetBase): line = line +1 if type_no[2] > 5: - print "Higher order reaction will not be displayed" + print ("Higher order reaction will not be displayed") def drawLine(self,srcdes_list,arrow): src = srcdes_list[0] @@ -698,7 +833,7 @@ class KineticsWidget(EditorWidgetBase): #If the item position changes, the corresponding arrow's are calculated if isinstance(element(mooseObject),ChemCompt): for k, v in self.qGraCompt.items(): - mesh = mooseObject + mesh = moose.element(mooseObject).path if k.path == mesh: for rectChilditem in v.childItems(): if isinstance(rectChilditem, KineticsDisplayItem): @@ -712,6 +847,40 @@ class KineticsWidget(EditorWidgetBase): j = self.mooseId_GObj[moose.element(i)] self.updateArrow(j) self.updateArrow(rectChilditem) + elif element(mooseObject).className == 'Neutral': + for k,v in self.qGraGrp.items(): + if k.path == element(mooseObject).path: + for grpChilditem in v.childItems(): + if isinstance(grpChilditem, KineticsDisplayItem): + if moose.exists(grpChilditem.mobj.path): + iInfo = grpChilditem.mobj.path+'/info' + anno = moose.Annotator(iInfo) + if moose.Annotator(self.plugin.modelRoot+'/info').modeltype == 'kkit': + x = grpChilditem.scenePos().x()/self.defaultScenewidth + y = grpChilditem.scenePos().y()/self.defaultSceneheight + else: + #print "Check for other models at grp level ",grpChilditem.scenePos() + x = grpChilditem.scenePos().x() + y = grpChilditem.scenePos().y() + #print " x and y at 863 ",grpChilditem.scenePos() + anno.x = x + anno.y = y + #print " anno ",anno, anno.x, anno.y + if isinstance(moose.element(grpChilditem.mobj.path),PoolBase): + t = moose.element(grpChilditem.mobj.path) + moose.element(t).children + for items in moose.element(t).children: + if isinstance(moose.element(items),Function): + test = moose.element(items.path+'/x') + for i in moose.element(test).neighbors['input']: + j = self.mooseId_GObj[moose.element(i)] + self.updateArrow(j) + self.updateArrow(grpChilditem) + # grpcompt = self.qGraCompt[self.objPar[k]] + # rectcompt = calculateChildBoundingRect(grpcompt) + rectgrp = calculateChildBoundingRect(v) + v.setRect(rectgrp.x()-10,rectgrp.y()-10,(rectgrp.width()+20),(rectgrp.height()+20)) + else: mobj = self.mooseId_GObj[element(mooseObject)] self.updateArrow(mobj) @@ -719,31 +888,50 @@ class KineticsWidget(EditorWidgetBase): pos = elePath.find('/',1) l = elePath[0:pos] linfo = moose.Annotator(l+'/info') + if moose.exists(l): + #anno = moose.Annotator(linfo) + if moose.Annotator(self.plugin.modelRoot+'/info').modeltype == 'kkit': + x = mobj.scenePos().x()/self.defaultScenewidth + y = mobj.scenePos().y()/self.defaultSceneheight + else: + #print "Check for other models ",mobj.scenePos() + x = mobj.scenePos().x() + y = mobj.scenePos().y() + #print " x and y at 863 ",mobj.scenePos() + # for gk,gv in self.qGraGrp.items(): + # rectgrp = calculateChildBoundingRect(gv) + # grpBoundingRect = gv.boundingRect() + # if not grpBoundingRect.contains(rectgrp): + # self.updateCompartmentSize(v) + # else: + # gv.setRect(rectgrp.x()-10,rectgrp.y()-10,(rectgrp.width()+20),(rectgrp.height()+20)) for k, v in self.qGraCompt.items(): #rectcompt = v.childrenBoundingRect() rectcompt = calculateChildBoundingRect(v) comptBoundingRect = v.boundingRect() if not comptBoundingRect.contains(rectcompt): self.updateCompartmentSize(v) - ''' - if linfo.modeltype == "new_kkit": - #if newly built model then compartment is size is fixed for some size. - comptBoundingRect = v.boundingRect() - if not comptBoundingRect.contains(rectcompt): - self.updateCompartmentSize(v) else: - #if already built model then compartment size depends on max and min objects rectcompt = calculateChildBoundingRect(v) v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20)) - ''' + pass + + def updateGrpSize(self,compartment): + compartmentBoundary = compartment.rect() + + childrenBoundary = calculateChildBoundingRect(compartment) + x = childrenBoundary.x() + y = childrenBoundary.y() + height = childrenBoundary.height() + width = childrenBoundary.width() + compartment.setRect( x-10 + , y-10 + , width + 20 + , height + 20 + ) def updateCompartmentSize(self, compartment): compartmentBoundary = compartment.rect() - #print " compartmentBoundary ",compartmentBoundary, " ",compartment.childrenBoundingRect() - #compartmentBoundary =compartment.childrenBoundingRect() - #childrenBoundary = compartment.childrenBoundingRect() - #print " 758 ",compartment.childrenBoundaryRect() childrenBoundary = calculateChildBoundingRect(compartment) - #print " ch ",childrenBoundary x = min(compartmentBoundary.x(), childrenBoundary.x()) y = min(compartmentBoundary.y(), childrenBoundary.y()) width = max(compartmentBoundary.width(), childrenBoundary.width()) @@ -780,23 +968,6 @@ class KineticsWidget(EditorWidgetBase): if isinstance(item,CplxItem): self.updateArrow(item) - # def deleteSolver(self): - # print " delete Solver" - # print "### ",moose.wildcardFind(self.modelRoot+'/data/graph#/#') - # if moose.wildcardFind(self.modelRoot+'/##[ISA=ChemCompt]'): - # compt = moose.wildcardFind(self.modelRoot+'/##[ISA=ChemCompt]') - # print " deletSolver ", - # # print moose.exists(compt[0].path+'/stoich'), " ksolve ", moose.exists(compt[0].path+'/ksolve') - # # print "gsolve ", moose.delete( compt[0].path+'/gsolve' ) - # if ( moose.exists( compt[0].path+'/stoich' ) ): - # #print "delete" - # moose.delete( compt[0].path+'/stoich' ) - # if ( moose.exists( compt[0].path+'/ksolve' ) ): - # moose.delete( compt[0].path+'/ksolve' ) - # if ( moose.exists( compt[0].path+'/gsolve' ) ): - # moose.delete( compt[0].path+'/gsolve' ) - # for x in moose.wildcardFind( self.modelRoot+'/data/graph#/#' ): - # x.tick = -1 def positionChange1(self,mooseObject): #If the item position changes, the corresponding arrow's are calculated if ( (isinstance(element(mooseObject),CubeMesh)) or (isinstance(element(mooseObject),CylMesh))): @@ -923,58 +1094,6 @@ class kineticRunWidget(KineticsWidget): for item in self.sceneContainer.items(): if isinstance(item,PoolItemCircle): item.returnEllispeSize() - - # def addSolver(self,solver): - # print "\t addSolver--------" - # compt = moose.wildcardFind(self.modelRoot+'/##[ISA=ChemCompt]') - # comptinfo = moose.Annotator(moose.element(compt[0]).path+'/info') - # print " $$$$$$$$$$$$$$ ",moose.element(compt[0].path) - # previousSolver = comptinfo.solver - - # print "pre solver from kkit ",previousSolver, solver - # currentSolver = previousSolver - # if solver == "Gillespie": - # currentSolver = "Gillespie" - # elif solver == "Runge Kutta": - # currentSolver = "Runge Kutta" - # elif solver == " Exponential Euler": - # currentSolver == "Exponential Euler" - - # if previousSolver != currentSolver: - # if ( moose.exists( compt[0].path+'/stoich' ) ): - # print "1" - # self.deleteSolver() - # self.setCompartmentSolver(compt,currentSolver) - # elif ( moose.exists( compt[0].path+'/stoich' ) ): - # print "2" - # self.setCompartmentSolver(compt, currentSolver) - # comptinfo.solver = currentSolver - # else: - # print "3", moose.exists(compt[0].path+'/stoich') - # if not ( moose.exists( compt[0].path+'/stoich' ) ): - # self.setCompartmentSolver(compt,currentSolver) - # for x in moose.wildcardFind( self.modelRoot+'/data/graph#/#' ): - # x.tick = 18 - # #self.solverStatus() - # def setCompartmentSolver(self,compt,solver): - # if solver == 'GSL' or solver == "Runge Kutta": - # solver = 'gsl' - # elif solver == 'Gillespie': - # solver = 'gssa' - # elif solver == "Exponential Euler": - # solver = 'ee' - # print "setCompartmentSolver ",solver - # if ( solver == 'gsl' ): - # ksolve = moose.Ksolve( compt[0].path+'/ksolve' ) - # if ( solver == 'gssa' ): - # ksolve = moose.Gsolve( compt[0].path+'/gsolve' ) - # if (solver!= 'ee'): - # stoich = moose.Stoich( compt[0].path+'/stoich' ) - # stoich.compartment = compt[0] - # stoich.ksolve = ksolve - # stoich.path = compt[0].path+'/##' - # moose.reinit() - if __name__ == "__main__": app = QtGui.QApplication(sys.argv) size = QtCore.QSize(1024 ,768) @@ -988,7 +1107,7 @@ if __name__ == "__main__": try: filepath = '../../Demos/Genesis_files/'+modelPath+'.g' filepath = '/home/harsha/genesis_files/gfile/'+modelPath+'.g' - print filepath + print( "%s" %(filepath)) f = open(filepath, "r") loadModel(filepath,'/'+modelPath) @@ -1004,6 +1123,6 @@ if __name__ == "__main__": except IOError, what: (errno, strerror) = what - print "Error number",errno,"(%s)" %strerror + print ("Error number",errno,"(%s)" %(strerror)) sys.exit(0) sys.exit(app.exec_()) diff --git a/plugins/kkitCalcArrow.py b/plugins/kkitCalcArrow.py index e11ebe3ff29d3110751239f00782dd1f260143ed..4a3128f22159958d6fc6eeb5114a3c4c7c17c2bc 100644 --- a/plugins/kkitCalcArrow.py +++ b/plugins/kkitCalcArrow.py @@ -1,6 +1,15 @@ +__author__ = "HarshaRani" +__credits__ = ["Upi Lab"] +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "HarshaRani" +__email__ = "hrani@ncbs.res.in" +__status__ = "Development" +__updated__ = "Jul 27 2017" + from PyQt4.QtGui import QPolygonF from PyQt4.QtCore import QLineF,QPointF -import math +from math import sin,cos,atan2,radians from kkitQGraphics import PoolItem #, ReacItem,EnzItem,CplxItem,ComptItem ''' One to need to pass the source, destination,endtype and order for drawing the arrow between 2 object \ @@ -46,9 +55,9 @@ def calcArrow(srcdes_list,itemignoreZooming,iconScale): dy = desRect.center().y()- srcRect.center().y() dx0 = dy dy0 = -dx - tetha1 = (math.atan2(dy0,dx0)) - a0 = 4 *(math.cos(tetha1)) - b0 = 4 *(math.sin(tetha1)) + tetha1 = (atan2(dy0,dx0)) + a0 = 4 *(cos(tetha1)) + b0 = 4 *(sin(tetha1)) ''' Higher order ( > 4) connectivity will not be done''' if ((order == 3) or (order == 4)): a0 = a0*2 @@ -154,9 +163,9 @@ def calcLineRectIntersection(rect, centerLine): def arrowHead(srcAngle,degree,lineSpoint,iconScale): ''' arrow head is calculated ''' r = 8*iconScale - delta = math.radians(srcAngle) + math.radians(degree) - width = math.sin(delta)*r - height = math.cos(delta)*r + delta = radians(srcAngle) + radians(degree) + width = sin(delta)*r + height = cos(delta)*r srcXArr = (lineSpoint.x() + width) srcYArr = (lineSpoint.y() + height) return srcXArr,srcYArr diff --git a/plugins/kkitOrdinateUtil.py b/plugins/kkitOrdinateUtil.py index cdd23bc7d1af6539e7bd077620f78488e023eed3..dd3b967d4b17c4fa94a9ad0e8130b724ed876c6c 100644 --- a/plugins/kkitOrdinateUtil.py +++ b/plugins/kkitOrdinateUtil.py @@ -1,5 +1,143 @@ +__author__ = "HarshaRani" +__credits__ = ["Upi Lab"] +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "HarshaRani" +__email__ = "hrani@ncbs.res.in" +__status__ = "Development" +__updated__ = "Oct 18 2017" + +''' +Oct 18: moved some function to kkitUtil +getxyCord, etc function are added +''' +import collections from moose import * import numpy as np +from moose import wildcardFind,element,PoolBase,CplxEnzBase,Annotator,exists +from networkx.drawing.nx_agraph import graphviz_layout +import numpy as np +import networkx as nx +from kkitUtil import getRandColor,colorCheck,findCompartment, findGroup, findGroup_compt, mooseIsInstance +from PyQt4.QtGui import QColor + +def getxyCord(xcord,ycord,list1): + for item in list1: + # if isinstance(item,Function): + # objInfo = element(item.parent).path+'/info' + # else: + # objInfo = item.path+'/info' + if not isinstance(item,Function): + objInfo = item.path+'/info' + xcord.append(xyPosition(objInfo,'x')) + ycord.append(xyPosition(objInfo,'y')) + +def xyPosition(objInfo,xory): + try: + return(float(element(objInfo).getField(xory))) + except ValueError: + return (float(0)) +''' +def mooseIsInstance(melement, classNames): + return element(melement).__class__.__name__ in classNames + + +def findCompartment(melement): + while not mooseIsInstance(melement, ["CubeMesh", "CyclMesh"]): + melement = melement.parent + return melement + +def findGroup(melement): + while not mooseIsInstance(melement, ["Neutral"]): + melement = melement.parent + return melement + +def findGroup_compt(melement): + while not (mooseIsInstance(melement, ["Neutral","CubeMesh", "CyclMesh"])): + melement = melement.parent + return melement +''' +def populateMeshEntry(meshEntry,parent,types,obj): + #print " parent ",parent, "types ",types, " obj ",obj + try: + value = meshEntry[element(parent.path)][types] + except KeyError: + # Key is not present + meshEntry[element(parent.path)].update({types :[element(obj)]}) + else: + mlist = meshEntry[element(parent.path)][types] + mlist.append(element(obj)) +def updateMeshObj(modelRoot): + print " updateMeshObj " + meshEntry = {} + if meshEntry: + meshEntry.clear() + else: + meshEntry = {} + + objPar = collections.OrderedDict() + for compt in wildcardFind(modelRoot+'/##[ISA=ChemCompt]'): + groupColor = [] + try: + value = meshEntry[element(compt)] + except KeyError: + # Compt is not present + meshEntry[element(compt)] = {} + objPar[element(compt)] = element('/') + + for grp in wildcardFind(compt.path+'/##[TYPE=Neutral]'): + test = [x for x in wildcardFind(element(grp).path+'/#') if x.className in ["Pool","Reac","Enz"]] + grp_cmpt = findGroup_compt(grp.parent) + + try: + value = meshEntry[element(grp)] + except KeyError: + # Grp is not present + meshEntry[element(grp)] = {} + objPar[element(grp)] = element(grp_cmpt) + + for compt in wildcardFind(modelRoot+'/##[ISA=ChemCompt]'): + for m in wildcardFind(compt.path+'/##[ISA=PoolBase]'): + grp_cmpt = findGroup_compt(m) + if isinstance(element(grp_cmpt),Neutral): + if isinstance(element(m.parent),EnzBase): + populateMeshEntry(meshEntry,grp_cmpt,"cplx",m) + else: + populateMeshEntry(meshEntry,grp_cmpt,"pool",m) + else: + if isinstance(element(m.parent),EnzBase): + populateMeshEntry(meshEntry,compt,"cplx",m) + else: + populateMeshEntry(meshEntry,compt,"pool",m) + + for r in wildcardFind(compt.path+'/##[ISA=ReacBase]'): + rgrp_cmpt = findGroup_compt(r) + if isinstance(element(rgrp_cmpt),Neutral): + populateMeshEntry(meshEntry,rgrp_cmpt,"reaction",r) + else: + populateMeshEntry(meshEntry,compt,"reaction",r) + + for e in wildcardFind(compt.path+'/##[ISA=EnzBase]'): + egrp_cmpt = findGroup_compt(e) + if isinstance(element(egrp_cmpt),Neutral): + populateMeshEntry(meshEntry,egrp_cmpt,"enzyme",e) + else: + populateMeshEntry(meshEntry,compt,"enzyme",e) + + for f in wildcardFind(compt.path+'/##[ISA=Function]'): + fgrp_cmpt = findGroup_compt(f) + if isinstance(element(fgrp_cmpt),Neutral): + populateMeshEntry(meshEntry,fgrp_cmpt,"function",f) + else: + populateMeshEntry(meshEntry,compt,"function",f) + + for t in wildcardFind(compt.path+'/##[ISA=StimulusTable]'): + tgrp_cmpt = findGroup_compt(t) + if isinstance(element(tgrp_cmpt),Neutral): + populateMeshEntry(meshEntry,tgrp_cmpt,"stimTab",t) + else: + populateMeshEntry(meshEntry,compt,"stimTab",t) + return(objPar,meshEntry) def setupMeshObj(modelRoot): ''' Setup compartment and its members pool,reaction,enz cplx under self.meshEntry dictionaries \ @@ -7,6 +145,122 @@ def setupMeshObj(modelRoot): value is key2:list where key2 represents moose object type,list of objects of a perticular type e.g self.meshEntry[meshEnt] = { 'reaction': reaction_list,'enzyme':enzyme_list,'pool':poollist,'cplx': cplxlist } ''' + xmin = 0.0 + xmax = 1.0 + ymin = 0.0 + ymax = 1.0 + positionInfoExist = True + meshEntry = {} + if meshEntry: + meshEntry.clear() + else: + meshEntry = {} + xcord = [] + ycord = [] + n = 1 + objPar = collections.OrderedDict() + + for compt in wildcardFind(modelRoot+'/##[ISA=ChemCompt]'): + groupColor = [] + try: + value = meshEntry[element(compt)] + except KeyError: + # Compt is not present + meshEntry[element(compt)] = {} + objPar[element(compt)] = element('/') + + for grp in wildcardFind(compt.path+'/##[TYPE=Neutral]'): + test = [x for x in wildcardFind(element(grp).path+'/#') if x.className in ["Pool","Reac","Enz"]] + #if len(test) >1: + grpinfo = Annotator(element(grp).path+'/info') + validatecolor = colorCheck(grpinfo.color,"bg") + validatedgrpcolor = str(QColor(validatecolor).name()) + + groupColor.append(validatedgrpcolor) + grp_cmpt = findGroup_compt(grp.parent) + + try: + value = meshEntry[element(grp)] + except KeyError: + # Grp is not present + meshEntry[element(grp)] = {} + objPar[element(grp)] = element(grp_cmpt) + # if n > 1: + # validatecolor = colorCheck(grpinfo.color,"bg") + # validatedgrpcolor = str(QColor(validatecolor).name()) + # if validatedgrpcolor in groupColor: + # print " inside " + # c = getRandColor() + # print " c ",c, c.name() + # grpinfo.color = str(c.name()) + # groupColor.append(str(c.name())) + # print " groupColor ",grpinfo,grpinfo.color, groupColor + # n =n +1 + for compt in wildcardFind(modelRoot+'/##[ISA=ChemCompt]'): + for m in wildcardFind(compt.path+'/##[ISA=PoolBase]'): + grp_cmpt = findGroup_compt(m) + + xcord.append(xyPosition(m.path+'/info','x')) + ycord.append(xyPosition(m.path+'/info','y')) + if isinstance(element(grp_cmpt),Neutral): + if isinstance(element(m.parent),EnzBase): + populateMeshEntry(meshEntry,grp_cmpt,"cplx",m) + else: + populateMeshEntry(meshEntry,grp_cmpt,"pool",m) + else: + if isinstance(element(m.parent),EnzBase): + populateMeshEntry(meshEntry,compt,"cplx",m) + else: + populateMeshEntry(meshEntry,compt,"pool",m) + + for r in wildcardFind(compt.path+'/##[ISA=ReacBase]'): + rgrp_cmpt = findGroup_compt(r) + xcord.append(xyPosition(r.path+'/info','x')) + ycord.append(xyPosition(r.path+'/info','y')) + if isinstance(element(rgrp_cmpt),Neutral): + populateMeshEntry(meshEntry,rgrp_cmpt,"reaction",r) + else: + populateMeshEntry(meshEntry,compt,"reaction",r) + + for e in wildcardFind(compt.path+'/##[ISA=EnzBase]'): + egrp_cmpt = findGroup_compt(e) + xcord.append(xyPosition(e.path+'/info','x')) + ycord.append(xyPosition(e.path+'/info','y')) + + if isinstance(element(egrp_cmpt),Neutral): + populateMeshEntry(meshEntry,egrp_cmpt,"enzyme",e) + else: + populateMeshEntry(meshEntry,compt,"enzyme",e) + + for f in wildcardFind(compt.path+'/##[ISA=Function]'): + fgrp_cmpt = findGroup_compt(f) + if isinstance(element(fgrp_cmpt),Neutral): + populateMeshEntry(meshEntry,fgrp_cmpt,"function",f) + else: + populateMeshEntry(meshEntry,compt,"function",f) + + for t in wildcardFind(compt.path+'/##[ISA=StimulusTable]'): + tgrp_cmpt = findGroup_compt(t) + xcord.append(xyPosition(t.path+'/info','x')) + ycord.append(xyPosition(t.path+'/info','y')) + if isinstance(element(tgrp_cmpt),Neutral): + populateMeshEntry(meshEntry,tgrp_cmpt,"stimTab",t) + else: + populateMeshEntry(meshEntry,compt,"stimTab",t) + + xmin = min(xcord) + xmax = max(xcord) + ymin = min(ycord) + ymax = max(ycord) + positionInfoExist = not(len(np.nonzero(xcord)[0]) == 0 and len(np.nonzero(ycord)[0]) == 0) + return(objPar,meshEntry,xmin,xmax,ymin,ymax,positionInfoExist) +''' +def setupMeshObj(modelRoot): + # Setup compartment and its members pool,reaction,enz cplx under self.meshEntry dictionaries \ + # self.meshEntry with "key" as compartment, + # value is key2:list where key2 represents moose object type,list of objects of a perticular type + # e.g self.meshEntry[meshEnt] = { 'reaction': reaction_list,'enzyme':enzyme_list,'pool':poollist,'cplx': cplxlist } + meshEntry = {} if meshEntry: meshEntry.clear() @@ -55,11 +309,11 @@ def setupMeshObj(modelRoot): def sizeHint(self): return QtCore.QSize(800,400) - +''' def setupItem(modelPath,cntDict): - '''This function collects information of what is connected to what. \ - eg. substrate and product connectivity to reaction's and enzyme's \ - sumtotal connectivity to its pool are collected ''' + # This function collects information of what is connected to what. \ + # eg. substrate and product connectivity to reaction's and enzyme's \ + # sumtotal connectivity to its pool are collected #print " setupItem" sublist = [] prdlist = [] @@ -80,7 +334,7 @@ def setupItem(modelPath,cntDict): uniqItem,countuniqItem = countitems(items,'prd') prdNo = uniqItem if (len(subNo) == 0 or len(prdNo) == 0): - print "Substrate Product is empty ",path, " ",items + print ("Substrate Product is empty ",path, " ",items) for prd in uniqItem: prdlist.append((element(prd),'p',countuniqItem[prd])) @@ -156,24 +410,26 @@ def xyPosition(objInfo,xory): def autoCoordinates(meshEntry,srcdesConnection): - print " kkit Ordinatesutil autoCoordinates " - + G = nx.Graph() for cmpt,memb in meshEntry.items(): - for enzObj in find_index(memb,'enzyme'): - #G.add_node(enzObj.path) - G.add_node(enzObj.path,label='',shape='ellipse',color='',style='filled',fontname='Helvetica',fontsize=12,fontcolor='blue') + if memb in ["enzyme"]: + for enzObj in find_index(memb,'enzyme'): + #G.add_node(enzObj.path) + G.add_node(enzObj.path,label='',shape='ellipse',color='',style='filled',fontname='Helvetica',fontsize=12,fontcolor='blue') for cmpt,memb in meshEntry.items(): - for poolObj in find_index(memb,'pool'): - #G.add_node(poolObj.path) - G.add_node(poolObj.path,label = poolObj.name,shape = 'box',color = '',style = 'filled',fontname = 'Helvetica',fontsize = 12,fontcolor = 'blue') - for cplxObj in find_index(memb,'cplx'): - G.add_node(cplxObj.path) - G.add_node(cplxObj.path,label = cplxObj.name,shape = 'box',color = '',style = 'filled',fontname = 'Helvetica',fontsize = 12,fontcolor = 'blue') - #G.add_edge((cplxObj.parent).path,cplxObj.path) - for reaObj in find_index(memb,'reaction'): - #G.add_node(reaObj.path) - G.add_node(reaObj.path,label='',shape='circle',color='') + #if memb.has_key + if memb in ["pool","cplx","reaction"]: + for poolObj in find_index(memb,'pool'): + #G.add_node(poolObj.path) + G.add_node(poolObj.path,label = poolObj.name,shape = 'box',color = '',style = 'filled',fontname = 'Helvetica',fontsize = 9,fontcolor = 'blue') + for cplxObj in find_index(memb,'cplx'): + G.add_node(cplxObj.path) + G.add_node(cplxObj.path,label = cplxObj.name,shape = 'box',color = '',style = 'filled',fontname = 'Helvetica',fontsize = 12,fontcolor = 'blue') + #G.add_edge((cplxObj.parent).path,cplxObj.path) + for reaObj in find_index(memb,'reaction'): + #G.add_node(reaObj.path) + G.add_node(reaObj.path,label='',shape='circle',color='') for inn,out in srcdesConnection.items(): if (inn.className =='ZombieReac'): arrowcolor = 'green' @@ -181,22 +437,21 @@ def autoCoordinates(meshEntry,srcdesConnection): else: arrowcolor = 'blue' if isinstance(out,tuple): if len(out[0])== 0: - print inn.className + ':' +inn.name + " doesn't have input message" + print (inn.className + ':' +inn.name + " doesn't have input message") else: for items in (items for items in out[0] ): G.add_edge(element(items[0]).path,inn.path) if len(out[1]) == 0: - print inn.className + ':' + inn.name + "doesn't have output mssg" + print (inn.className + ':' + inn.name + "doesn't have output mssg") else: for items in (items for items in out[1] ): G.add_edge(inn.path,element(items[0]).path) elif isinstance(out,list): if len(out) == 0: - print "Func pool doesn't have sumtotal" + print ("Func pool doesn't have sumtotal") else: for items in (items for items in out ): G.add_edge(element(items[0]).path,inn.path) - position = graphviz_layout(G) xcord, ycord = [],[] for item in position.items(): @@ -215,9 +470,11 @@ def autoCoordinates(meshEntry,srcdesConnection): anno = Annotator(item[0]+'/info') Ax = (xy[0]-xmin)/(xmax-xmin) Ay = (xy[1]-ymin)/(ymax-ymin) - anno.x = round(Ax,1) - anno.y = round(Ay,1) - + #anno.x = round(Ax,1) + #anno.y = round(Ay,1) + #not roundingoff to max and min the co-ordinates for bigger model would overlay the co-ordinates + anno.x = xy[0] + anno.y = xy[1] def find_index(value, key): """ Value.get(key) to avoid expection which would raise if empty value in dictionary for a given key """ if value.get(key) != None: diff --git a/plugins/kkitQGraphics.py b/plugins/kkitQGraphics.py index b0bb4338871e106d8cee4094dc8c187d1ac22454..1f180190a8f133ac5c761c8892121fa10b650a92 100644 --- a/plugins/kkitQGraphics.py +++ b/plugins/kkitQGraphics.py @@ -1,3 +1,16 @@ + +__author__ = "HarshaRani" +__credits__ = ["Upi Lab"] +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "HarshaRani" +__email__ = "hrani@ncbs.res.in" +__status__ = "Development" +__updated__ = "Sep 19 2017" + +''' +sep 19: add GroupItem class +''' #import sys #sys.path.insert(0, '/home/harsha/trunk/gui') import config @@ -5,6 +18,7 @@ from PyQt4 import QtGui, QtCore, Qt from moose import * from PyQt4.QtGui import QPixmap, QImage, QGraphicsPixmapItem from constants import * +from os import path class KineticsDisplayItem(QtGui.QGraphicsWidget): """Base class for display elemenets in kinetics layout""" @@ -60,7 +74,8 @@ class FuncItem(KineticsDisplayItem): def __init__(self, mobj, parent): super(FuncItem, self).__init__(mobj, parent) self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True) - self.funcImage = QImage('icons/classIcon/Function.png').scaled(15,33) + iconmap_file = (path.join(config.settings[config.KEY_ICON_DIR], 'classIcon/Function.png')) + self.funcImage = QImage(iconmap_file).scaled(15,33) self.bg = QtGui.QGraphicsRectItem(self) self.bg.setAcceptHoverEvents(True) self.gobj = QtGui.QGraphicsPixmapItem(QtGui.QPixmap.fromImage(self.funcImage),self.bg) @@ -78,7 +93,8 @@ class FuncItem(KineticsDisplayItem): #else if droped from the GUI then placed wrt position #self.setGeometry(0, 30,self.gobj.boundingRect().width(),self.gobj.boundingRect().height()) #self.setGeometry(x,y) - if self.gobj.mobj.parent.className == "ZombieBufPool" or self.gobj.mobj.parent.className == "BufPool": + poolt = ["ZombieBufPool","BufPool","ZombiePool","Pool"] + if self.gobj.mobj.parent.className in poolt: self.setGeometry(0, 30,self.gobj.boundingRect().width(),self.gobj.boundingRect().height()) else: self.setGeometry(x,y,self.gobj.boundingRect().width(),self.gobj.boundingRect().height()) @@ -183,7 +199,9 @@ class PoolItem(KineticsDisplayItem): #This func will adjust the background color with respect to text size self.gobj.setText(self.mobj.name) self.bg.setRect(0, 0, self.gobj.boundingRect().width()+PoolItem.fontMetrics.width(' '), self.gobj.boundingRect().height()) - + self.setGeometry(self.pos().x(),self.pos().y(),self.gobj.boundingRect().width() + +PoolItem.fontMetrics.width(''), + self.gobj.boundingRect().height()) def updateColor(self,bgcolor): self.bg.setBrush(QtGui.QBrush(QtGui.QColor(bgcolor))) #pass @@ -451,6 +469,50 @@ class CplxItem(KineticsDisplayItem): defaultHeight = CplxItem.defaultHeight*scale self.gobj.setRect(0,0,defaultWidth,defaultHeight) +class GRPItem(QtGui.QGraphicsRectItem): + #This is used for displaying Grp Item + name = GROUP + def __init__(self,parent,x,y,w,h,item): + self.grpEmitter = QtCore.QObject() + QtGui.QGraphicsRectItem.__init__(self,x,y,w,h,parent) + self.mobj = item + self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True); + self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable) + self.setAcceptHoverEvents(True) + self.setToolTip(self.mobj.name) + QT_VERSION = str(QtCore.QT_VERSION_STR).split('.') + QT_MINOR_VERSION = int(QT_VERSION[1]) + if config.QT_MINOR_VERSION >= 6: + self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges, 1) + + # def paint(self, painter=None, option=None, widget = None): + # print " self .hasFocus ",self.hasFocus(), " ## ",self.isSelected() + + # if self.isSelected(): + # drawFocus(painter) + # #painter.setPen(QtGui.QPen(QtGui.QPen(QtCore.Qt.black, 1.8,Qt.Qt.DashLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin))) + # #painter.drawRect(self.boundingRect()) + + # def drawFocusRect(self, painter): + # self.focusbrush = QtGui.QBrush() + # self.focuspen = QtGui.QPen(QtCore.Qt.DotLine) + # self.focuspen.setColor(QtCore.Qt.black) + # self.focuspen.setWidthF(1.5) + # painter.setBrush(self.focusbrush) + # painter.setPen(self.focuspen) + # painter.drawRect(self.focusrect) + + def itemChange(self,change,value): + #print " itemchange at GRPItem ",change,value + if change == QtGui.QGraphicsItem.ItemPositionChange: + self.grpEmitter.emit(QtCore.SIGNAL("qgtextPositionChange(PyQt_PyObject)"),self.mobj) + #if change == QtGui.QGraphicsItem. + if change == QtGui.QGraphicsItem.ItemSelectedChange and value == True: + #self.setPen(QtGui.QPen(QtGui.QPen(QtCore.Qt.black, 1.8,Qt.Qt.DashLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin))) + #self.drawRect(self.boundingRect()) + self.grpEmitter.emit(QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),self.mobj) + + return QtGui.QGraphicsItem.itemChange(self,change,value) class ComptItem(QtGui.QGraphicsRectItem): name = COMPARTMENT @@ -479,8 +541,13 @@ class ComptItem(QtGui.QGraphicsRectItem): self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True); self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable) #self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges, 1) - if config.QT_MINOR_VERSION >= 6: - self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges, 1) + QT_VERSION = str(QtCore.QT_VERSION_STR).split('.') + QT_MINOR_VERSION = int(QT_VERSION[1]) + if QT_MINOR_VERSION >= 6: + #if config.QT_MINOR_VERSION >= 6: + self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges, 1) + self.setAcceptHoverEvents(True) + self.setToolTip(iParent.name) ''' def hoverEnterEvent(self, event): self.updateResizeHandles() diff --git a/plugins/kkitUtil.py b/plugins/kkitUtil.py index a83a496c320e9e9ddb578e8e4665ad60036c5e73..7185988005fc7c1c15e2795e878870bd1fd9b73f 100644 --- a/plugins/kkitUtil.py +++ b/plugins/kkitUtil.py @@ -1,5 +1,17 @@ -from moose import Annotator -from kkitQGraphics import PoolItem, ReacItem,EnzItem,CplxItem,ComptItem +__author__ = "HarshaRani" +__credits__ = ["Upi Lab"] +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "HarshaRani" +__email__ = "hrani@ncbs.res.in" +__status__ = "Development" +__updated__ = "Oct 18 2017" + +''' +Oct 18 some of the function moved to this file from kkitOrdinateUtils +''' +from moose import Annotator,element +from kkitQGraphics import PoolItem, ReacItem,EnzItem,CplxItem,GRPItem,ComptItem from PyQt4 import QtCore,QtGui,QtSvg from PyQt4.QtGui import QColor import numpy as np @@ -119,7 +131,7 @@ def handleCollisions(compartments, moveCallback, layoutPt,margin = 5.0): if len(compartments) is 0 : return compartments = sorted(compartments, key = lambda c: c.sceneBoundingRect().center().x()) reference = compartments.pop(0); - print reference.name + print (reference.name) referenceRect = reference.sceneBoundingRect() colliders = filter( lambda compartment : referenceRect.intersects(compartment.sceneBoundingRect()) , compartments @@ -141,10 +153,16 @@ def calculateChildBoundingRect(compt): ''' All the children including pool,reac,enz,polygon(arrow),table ''' if not isinstance(l,QtSvg.QGraphicsSvgItem): if (not isinstance(l,QtGui.QGraphicsPolygonItem)): - xpos.append((l.pos().x())+(l.boundingRect().bottomRight().x())) - xpos.append(l.pos().x()) - ypos.append(l.pos().y()+l.boundingRect().bottomRight().y()) - ypos.append(l.pos().y()) + if (not isinstance(l,GRPItem)): + xpos.append((l.pos().x())+(l.boundingRect().bottomRight().x())) + xpos.append(l.pos().x()) + ypos.append(l.pos().y()+l.boundingRect().bottomRight().y()) + ypos.append(l.pos().y()) + else: + xpos.append(l.rect().x()) + xpos.append(l.boundingRect().bottomRight().x()) + ypos.append(l.rect().y()) + ypos.append(l.boundingRect().bottomRight().y()) if (isinstance(l,PoolItem) or isinstance(l,EnzItem)): ''' For Enz cplx height and for pool function height needs to be taken''' for ll in l.childItems(): @@ -162,3 +180,21 @@ def calculateChildBoundingRect(compt): calculateRectcompt = compt.rect() return calculateRectcompt + +def mooseIsInstance(melement, classNames): + return element(melement).__class__.__name__ in classNames + +def findCompartment(melement): + while not mooseIsInstance(melement, ["CubeMesh", "CyclMesh"]): + melement = melement.parent + return melement + +def findGroup(melement): + while not mooseIsInstance(melement, ["Neutral"]): + melement = melement.parent + return melement + +def findGroup_compt(melement): + while not (mooseIsInstance(melement, ["Neutral","CubeMesh", "CyclMesh"])): + melement = melement.parent + return melement \ No newline at end of file diff --git a/plugins/kkitViewcontrol.py b/plugins/kkitViewcontrol.py index c9541743f847dcd8b049ab5aed3440b8845d2210..7d63950455985364a05fb8963a5e521809a71786 100644 --- a/plugins/kkitViewcontrol.py +++ b/plugins/kkitViewcontrol.py @@ -1,3 +1,25 @@ +__author__ = "HarshaRani" +__credits__ = ["Upi Lab"] +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "HarshaRani" +__email__ = "hrani@ncbs.res.in" +__status__ = "Development" +__updated__ = "Oct 17 2017" + +''' +Oct 17: If object is moved from one group or compartment to another group or with in same Compartment, + then both at moose level (group or compartment path is updated ) and qt level the setParentItem is set + -If object is moved to Empty place or not allowed place in the GUI its moved back to origin position + -also some clean up when object is just clicked in QsvgItem and v/s clicked and some action done + -with Rubber selection if object are moved then group size is updated +Oct 3 : At mousePressEvent, a clean way of checking on what object mouse press Event happened is checked. + This is after group is added where Group Interior and Boundary is checked, with in groupInterior if click in + on COMPARTMENT BOUNDARY is clicked then COMPARTMENT_BOUNDARY is return, else top most group object is returned. +Sep 20: Group related function added + -resolveGroupInteriorAndBoundary, findGraphic_groupcompt, graphicsIsInstance + -@resolveItem,editorMousePressEvent,editorMouseMoveEvent,editorMouseReleaseEvent checks made for group +''' import sys from modelBuild import * from constants import * @@ -66,11 +88,16 @@ class GraphicalView(QtGui.QGraphicsView): bound = item.rect().adjusted(3,3,-3,-3) return COMPARTMENT_INTERIOR if bound.contains(item.mapFromScene(position)) else COMPARTMENT_BOUNDARY + def resolveGroupInteriorAndBoundary(self, item, position): + bound = item.rect().adjusted(3,3,-3,-3) + return GROUP_INTERIOR if bound.contains(item.mapFromScene(position)) else GROUP_BOUNDARY + def resetState(self): self.state = { "press" : { "mode" : INVALID , "item" : None , "sign" : None - , "pos" : None + , "pos" : None + , "scenepos" : None } , "move" : { "happened": False } @@ -82,129 +109,133 @@ class GraphicalView(QtGui.QGraphicsView): def resolveItem(self, items, position): - solution = None + csolution = None + gsolution = None + groupInteriorfound = False + groupList = [] + comptInteriorfound = False + comptBoundary = [] + + # If clicked , moved and dropped then drop object should not take polygonItem it shd take Goup or compartment + #(this is checked is self.state["move"]), else qpolygonItem then deleting the connection b/w 2 objects + #move is True the for item in items: - # if isinstance(item, QtGui.QGraphicsPixmapItem): - # return (item, CONNECTOR) if isinstance(item, QtSvg.QGraphicsSvgItem): return (item, CONNECTOR) - - if isinstance(item, QtGui.QGraphicsPolygonItem): - return (item, CONNECTION) + + if not self.state["move"]["happened"]: + for item in items: + if isinstance(item, QtGui.QGraphicsPolygonItem): + return (item, CONNECTION) for item in items: if hasattr(item, "name"): - #print(item.name) if item.name == ITEM: return (item, ITEM) + if item.name == GROUP: + gsolution = (item, self.resolveGroupInteriorAndBoundary(item, position)) + if gsolution[1] == GROUP_BOUNDARY: + return gsolution + elif gsolution[1] == GROUP_INTERIOR: + groupInteriorfound = True + groupList.append(gsolution) + if item.name == COMPARTMENT: - solution = (item, self.resolveCompartmentInteriorAndBoundary(item, position)) - if solution is None: - return (None, EMPTY) - return solution + csolution = (item, self.resolveCompartmentInteriorAndBoundary(item, position)) + if csolution[1] == COMPARTMENT_BOUNDARY: + comptInteriorfound = True + comptBoundary.append(csolution) + + if groupInteriorfound: + if comptInteriorfound: + return comptBoundary[0] + else: + return groupList[0] + else: + if csolution is None: + return (None, EMPTY) + return csolution + + def findGraphic_groupcompt(self,gelement): + while not (self.graphicsIsInstance(gelement, ["GRPItem","ComptItem"])): + gelement = gelement.parentItem() + return gelement + + def graphicsIsInstance(self, gelement, classNames): + return gelement.__class__.__name__ in classNames def editorMousePressEvent(self, event): - # self.deselectSelections() - # if self.state["press"]["item"] is not None: - # self.state["press"]["item"].setSelected(False) - # self.resetState() + self.clickPosition = self.mapToScene(event.pos()) + (item, itemType) = self.resolveItem(self.items(event.pos()), self.clickPosition) if event.buttons() == QtCore.Qt.LeftButton: - self.clickPosition = self.mapToScene(event.pos()) - (item, itemType) = self.resolveItem(self.items(event.pos()), self.clickPosition) self.state["press"]["mode"] = VALID self.state["press"]["item"] = item self.state["press"]["type"] = itemType self.state["press"]["pos"] = event.pos() - #If connector exist and if mousePress on Compartment interior, - # then removing any connect if exist - if itemType == COMPARTMENT_INTERIOR: + if isinstance(item, QtSvg.QGraphicsSvgItem): + ##This is kept for reference, so that if object (P,R,E,Tab,Fun) is moved outside the compartment, + #then it need to be pull back to original position + self.state["press"]["scenepos"] = item.parent().scenePos() + + if itemType == COMPARTMENT_INTERIOR or itemType == GROUP_BOUNDARY or itemType == GROUP_INTERIOR: self.removeConnector() + elif itemType == ITEM: if not self.move: self.showConnector(self.state["press"]["item"]) - # self.layoutPt.plugin.mainWindow.objectEditSlot(self.state["press"]["item"].mobj, False) else: + #If right button clicked self.resetState() - comptList = [] - for k, v in self.layoutPt.qGraCompt.items(): - comptList.append(v) - if len(comptList) > 1: + if itemType == GROUP_BOUNDARY: popupmenu = QtGui.QMenu('PopupMenu', self) - popupmenu.addAction("LinearLayout", lambda : handleCollisions(comptList, moveX, self.layoutPt)) - popupmenu.addAction("VerticalLayout" ,lambda : handleCollisions(comptList, moveMin, self.layoutPt )) + popupmenu.addAction("DeleteGroup", lambda : self.deleteGroup(item,self.layoutPt)) + popupmenu.addAction("CloneGroup" ,lambda : handleCollisions(comptList, moveMin, self.layoutPt )) popupmenu.exec_(self.mapToGlobal(event.pos())) + + elif itemType == COMPARTMENT_BOUNDARY: + if len(list(self.layoutPt.qGraCompt.values())) > 1: + popupmenu = QtGui.QMenu('PopupMenu', self) + popupmenu.addAction("LinearLayout", lambda : handleCollisions(list(self.layoutPt.qGraCompt.values()), moveX, self.layoutPt)) + popupmenu.addAction("VerticalLayout" ,lambda : handleCollisions(list(self.layoutPt.qGraCompt.values()), moveMin, self.layoutPt )) + popupmenu.exec_(self.mapToGlobal(event.pos())) - - def editorMouseMoveEvent(self, event): + + def editorMouseMoveEvent(self,event): if self.state["press"]["mode"] == INVALID: self.state["move"]["happened"] = False return - if self.move: + #This part of the code is when rubberband selection is done and move option is selected initial = self.mapToScene(self.state["press"]["pos"]) final = self.mapToScene(event.pos()) displacement = final - initial for item in self.selectedItems: if isinstance(item, KineticsDisplayItem) and not isinstance(item,ComptItem) and not isinstance(item,CplxItem): item.moveBy(displacement.x(), displacement.y()) - self.layoutPt.positionChange(item.mobj.path) + self.layoutPt.positionChange(item.mobj.path) self.state["press"]["pos"] = event.pos() return - + self.state["move"]["happened"] = True itemType = self.state["press"]["type"] item = self.state["press"]["item"] - if itemType == CONNECTOR: - ''' connecting 2 object is removed and movement is impled''' actionType = str(item.data(0).toString()) if actionType == "move": QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor)) initial = self.mapToScene(self.state["press"]["pos"]) - #initial = item.parent().pos() final = self.mapToScene(event.pos()) displacement = final-initial - if isinstance(item.parent(),KineticsDisplayItem): - itemPath = item.parent().mobj.path - if moose.exists(itemPath): - iInfo = itemPath+'/info' - anno = moose.Annotator(iInfo) - modelAnno = moose.Annotator(self.modelRoot+'/info') - x = item.parent().scenePos().x()/self.layoutPt.defaultScenewidth - y = item.parent().scenePos().y()/self.layoutPt.defaultSceneheight - anno.x = x - anno.y = y - ''' - if modelAnno.modeltype == "kkit": - # x = ((self.mapToScene(event.pos()).x())+(self.minmaxratioDict['xmin']*self.minmaxratioDict['xratio']))/self.minmaxratioDict['xratio'] - # y = (1.0 - self.mapToScene(event.pos()).y()+(self.minmaxratioDict['ymin']*self.minmaxratioDict['yratio']))/self.minmaxratioDict['yratio'] - # anno.x = x - # anno.y = y - print " kvc CONNECTOR ",item.parent().mobj, displacement.x(), " y ",displacement.y() - print "scenePos CONNECTOR",item.parent().scenePos().x(),item.parent().scenePos().y(), - print "dive x ",item.parent().scenePos().x()/1000, " y ",item.parent().scenePos().y()/500 - #item.parent().update() - #self.updateScale(1) - x = item.parent().scenePos().x()/1000 - y = item.parent().scenePos().y()/500 - anno.x = x - anno.y = y - elif(modelAnno.modeltype == "new_kkit" or modelAnno.modeltype == "sbml" or modelAnno.modeltype == "cspace"): - anno.x = self.mapToScene(event.pos()).x() - anno.y = self.mapToScene(event.pos()).y() - ''' - #if not isinstance(item.parent(),FuncItem) and not isinstance(item.parent(),CplxItem): - if not isinstance(item.parent(),CplxItem): - self.removeConnector() - item.parent().moveBy(displacement.x(), displacement.y()) - if isinstance(item.parent(),PoolItem): - for funcItem in item.parent().childItems(): - if isinstance(funcItem,FuncItem): - self.layoutPt.updateArrow(funcItem) - + self.removeConnector() + item.parent().moveBy(displacement.x(), displacement.y()) + #self.layoutPt.updateArrow(item.parent()) + if isinstance(item.parent(),PoolItem): + for funcItem in item.parent().childItems(): + if isinstance(funcItem,FuncItem): + self.layoutPt.updateArrow(funcItem) self.state["press"]["pos"] = event.pos() self.layoutPt.positionChange(item.parent().mobj) - if actionType == "clone": + elif actionType == "clone": pixmap = QtGui.QPixmap(24, 24) pixmap.fill(QtCore.Qt.transparent) painter = QtGui.QPainter() @@ -216,13 +247,12 @@ class GraphicalView(QtGui.QGraphicsView): painter.drawLine(12,7,12,17) painter.drawLine(7,12,17,12) painter.end() - #self.setCursor(QtGui.QCursor(pixmap)) QtGui.QApplication.setOverrideCursor(QtGui.QCursor(pixmap)) if itemType == ITEM: self.drawExpectedConnection(event) - if itemType == COMPARTMENT_BOUNDARY: + if itemType == COMPARTMENT_BOUNDARY or itemType == GROUP_BOUNDARY: initial = self.mapToScene(self.state["press"]["pos"]) final = self.mapToScene(event.pos()) displacement = final - initial @@ -230,7 +260,7 @@ class GraphicalView(QtGui.QGraphicsView): self.layoutPt.positionChange(item.mobj.path) self.state["press"]["pos"] = event.pos() - if itemType == COMPARTMENT_INTERIOR: + if itemType == COMPARTMENT_INTERIOR or itemType == GROUP_INTERIOR: if self.customrubberBand == None: self.customrubberBand = QtGui.QRubberBand(QtGui.QRubberBand.Rectangle,self) self.customrubberBand.show() @@ -252,20 +282,11 @@ class GraphicalView(QtGui.QGraphicsView): self.customrubberBand.setGeometry(QtCore.QRect(QtCore.QPoint(x0, y0), QtCore.QSize(abs(displacement.x()), abs(displacement.y())))) - - # if itemType == COMPARTMENT: - # rubberband selection - - # if itemType == COMPARTMENT_BOUNDARY: - - # if itemType == ITEM: - # dragging the item - - def editorMouseReleaseEvent(self, event): + def editorMouseReleaseEvent(self,event): if self.move: self.move = False self.setCursor(Qt.Qt.ArrowCursor) - + if self.state["press"]["mode"] == INVALID: self.state["release"]["mode"] = INVALID self.resetState() @@ -287,8 +308,10 @@ class GraphicalView(QtGui.QGraphicsView): l = self.modelRoot if self.modelRoot.find('/',1) > 0: l = self.modelRoot[0:self.modelRoot.find('/',1)] - - linfo = moose.Annotator(l+'/model/info') + linfo = moose.Annotator(l+'/info') + for k,v in self.layoutPt.qGraGrp.items(): + rectgrp = calculateChildBoundingRect(v) + v.setRect(rectgrp.x()-10,rectgrp.y()-10,(rectgrp.width()+20),(rectgrp.height()+20)) for k, v in self.layoutPt.qGraCompt.items(): rectcompt = v.childrenBoundingRect() if linfo.modeltype == "new_kkit": @@ -302,6 +325,7 @@ class GraphicalView(QtGui.QGraphicsView): v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20)) else: + #When group is moved then compartment need to be update which is done here if isinstance(self.state["release"]["item"], KineticsDisplayItem): if not moose.element(self.state["press"]["item"].mobj) == moose.element(self.state["release"]["item"].mobj): self.populate_srcdes( self.state["press"]["item"].mobj @@ -311,13 +335,69 @@ class GraphicalView(QtGui.QGraphicsView): pass self.removeExpectedConnection() self.removeConnector() - self.move = False - if clickedItemType == CONNECTOR: + self.move = False + elif clickedItemType == CONNECTOR: actionType = str(self.state["press"]["item"].data(0).toString()) - - + pressItem = self.state["press"]["item"] + if actionType == "move": QtGui.QApplication.setOverrideCursor(QtGui.QCursor(Qt.Qt.ArrowCursor)) + #If any case, move is not valide need to move back the object to original position is store and calculation + initscenepos = self.state["press"]["scenepos"] + finialscenepos = pressItem.parent().scenePos() + xx = finialscenepos.x()-initscenepos.x() + yy = finialscenepos.y()-initscenepos.y() + + if itemType == EMPTY: + pressItem.parent().moveBy(-xx,-yy) + self.layoutPt.updateArrow(pressItem.parent()) + QtGui.QMessageBox.warning(None,'Could not move the object', "The object can't be moved to empty space") + else: + if isinstance(self.state["press"]["item"], Qt.QGraphicsSvgItem): + pressedItem = self.state["press"]["item"] + releaseItem = self.state["release"]["item"] + sgrp = findGroup(pressItem.parent().mobj) + scmpt = findCompartment(pressItem.parent().mobj) + dgrp = findGroup(releaseItem.mobj) + dcmpt = findCompartment(releaseItem.mobj) + if isinstance(dgrp,Neutral): + # This is obj moved from group to + # - another group + # - into compartment + if sgrp.path != dgrp.path: + if scmpt.volume == dcmpt.volume: + #With in same compartment but different group + moose.move(pressItem.parent().mobj,dgrp) + lKey = self.layoutPt.qGraGrp[dgrp] + pressItem.parent().setParentItem(lKey) + self.layoutPt.positionChange(sgrp) + self.layoutPt.positionChange(dgrp) + else: + #If object is tried to move to diff compartment, + # then object will be pulled back to origin position which it was moved from + pressItem.parent().moveBy(-xx,-yy) + self.layoutPt.updateArrow(pressItem.parent()) + QtGui.QMessageBox.warning(None,'Could not move the object', "The object can't be moved to empty space") + elif isinstance(dcmpt,CubeMesh): + # This is obj moved from group into compartment + if scmpt.path != dcmpt.path: + if scmpt.volume == dcmpt.volume: + moose.move(pressItem.parent().mobj,dcmpt) + lKey = self.layoutPt.qGraCompt[dcmpt] + pressItem.parent().setParentItem(lKey) + self.layoutPt.positionChange(sgrp) + self.layoutPt.positionChange(dgrp) + else: + #If object is tried to move to diff compartment, + # then object will be pulled back to origin position which it was moved from + pressItem.parent().moveBy(-xx,-yy) + self.layoutPt.updateArrow(pressItem.parent()) + QtGui.QMessageBox.warning(None,'Could not move the object', "The object can't be moved to empty space") + else: + print " Check what moved when! does it reaches this condition" + + self.layoutPt.positionChange(item.mobj) + self.updateScale(self.iconScale) if actionType == "delete": self.removeConnector() @@ -346,7 +426,12 @@ class GraphicalView(QtGui.QGraphicsView): elif actionType == "plot": element = moose.element(item.parent().mobj.path) if isinstance (element,moose.PoolBase): - self.graph = moose.element(self.modelRoot+'/data/graph_0') + if moose.exists(self.modelRoot+'/data/graph_0'): + self.graph = moose.element(self.modelRoot+'/data/graph_0') + else: + moose.Neutral(self.modelRoot+'/data') + moose.Neutral(self.modelRoot+'/data/graph_0') + self.graph = moose.element(self.modelRoot+'/data/graph_0') tablePath = utils.create_table_path(moose.element(self.modelRoot), self.graph, element, "Conc") table = utils.create_table(tablePath, element, "Conc","Table2") self.layoutPt.plugin.view.getCentralWidget().plotWidgetContainer.plotAllData() @@ -360,12 +445,16 @@ class GraphicalView(QtGui.QGraphicsView): posWrtComp = self.mapToScene(event.pos()) itemAtView = self.sceneContainerPt.itemAt(self.mapToScene(event.pos())) self.removeConnector() - if isinstance(itemAtView,ComptItem): + if isinstance(itemAtView,ComptItem) or isinstance(itemAtView, GRPItem): #Solver should be deleted ## if there is change in 'Topology' of the model ## or if copy has to made then oject should be in unZombify mode deleteSolver(self.modelRoot) - lKey = [key for key, value in self.layoutPt.qGraCompt.iteritems() if value == itemAtView][0] + #As name is suggesting, if item is Compartment, then search in qGraCompt and if group then qGraGrp + if isinstance(itemAtView,ComptItem): + lKey = [key for key, value in self.layoutPt.qGraCompt.iteritems() if value == itemAtView][0] + if isinstance (itemAtView, GRPItem): + lKey = [key for key, value in self.layoutPt.qGraGrp.iteritems() if value == itemAtView][0] iR = 0 iP = 0 t = moose.element(cloneObj.parent().mobj) @@ -374,9 +463,7 @@ class GraphicalView(QtGui.QGraphicsView): retValue = self.objExist(lKey.path,name,iP) if retValue != None: name += retValue - pmooseCp = moose.copy(t,lKey.path,name,1) - #if moose.copy failed then check for path != '/' if pmooseCp.path != '/': ct = moose.element(pmooseCp) concInit = pmooseCp.concInit[0] @@ -401,7 +488,6 @@ class GraphicalView(QtGui.QGraphicsView): rmooseCp = moose.copy(t,lKey.path,name,1) if rmooseCp.path != '/': ct = moose.element(rmooseCp) - #itemAtView = self.state["release"]["item"] reacObj = moose.element(ct) reacinfo = moose.Annotator(reacObj.path+'/info') qGItem = ReacItem(reacObj,itemAtView) @@ -409,26 +495,27 @@ class GraphicalView(QtGui.QGraphicsView): posWrtComp = self.mapToScene(event.pos()) qGItem.setDisplayProperties(posWrtComp.x(),posWrtComp.y(),"white", "white") self.emit(QtCore.SIGNAL("dropped"),reacObj) - self.updateScale(self.iconScale) - else: if itemAtView == None: QtGui.QMessageBox.information(None,'Dropping Not possible ','Dropping not allowed outside the compartment',QtGui.QMessageBox.Ok) else: srcdesString = ((self.state["release"]["item"]).mobj).className QtGui.QMessageBox.information(None,'Dropping Not possible','Dropping on \'{srcdesString}\' not allowed'.format(srcdesString = srcdesString),QtGui.QMessageBox.Ok) + if clickedItemType == CONNECTION: popupmenu = QtGui.QMenu('PopupMenu', self) popupmenu.addAction("Delete", lambda : self.deleteConnection(item)) popupmenu.exec_(self.mapToGlobal(event.pos())) - if clickedItemType == COMPARTMENT_BOUNDARY: - if not self.state["move"]["happened"]: - self.layoutPt.plugin.mainWindow.objectEditSlot(self.state["press"]["item"].mobj, True) - self.resetState() + if clickedItemType == COMPARTMENT_BOUNDARY or clickedItemType == GROUP_BOUNDARY: + if item != None: + item.setSelected(True) + if not self.state["move"]["happened"]: + self.layoutPt.plugin.mainWindow.objectEditSlot(self.state["press"]["item"].mobj, True) + self.resetState() - if clickedItemType == COMPARTMENT_INTERIOR: + if clickedItemType == COMPARTMENT_INTERIOR or clickedItemType == GROUP_INTERIOR: if self.state["move"]["happened"]: startingPosition = self.state["press"]["pos"] endingPosition = event.pos() @@ -444,36 +531,30 @@ class GraphicalView(QtGui.QGraphicsView): if displacement.y() < 0 : y0,y1= y1,y0 - #print "kkitview COMPARTMENT_INTERIOR",x0,y0 self.selectedItems = selectedItems = self.items(x0,y0,abs(displacement.x()), abs(displacement.y())) - # print("Rect => ", self.customrubberBand.rect()) - # selectedItems = self.items(self.mapToScene(self.customrubberBand.rect()).boundingRect()) self.selectSelections(selectedItems) for item in selectedItems: if isinstance(item, KineticsDisplayItem) and not isinstance(item,ComptItem): item.setSelected(True) - #print("Rubberband Selections => ", self.selections) - self.customrubberBand.hide() - self.customrubberBand = None + if self.customrubberBand != None: + self.customrubberBand.hide() + self.customrubberBand = None popupmenu = QtGui.QMenu('PopupMenu', self) popupmenu.addAction("Delete", lambda: self.deleteSelections(x0,y0,x1,y1)) popupmenu.addAction("Zoom", lambda: self.zoomSelections(x0,y0,x1,y1)) popupmenu.addAction("Move", lambda: self.moveSelections()) - popupmenu.exec_(self.mapToGlobal(event.pos())) - # self.delete = QtGui.QAction(self.tr('delete'), self) - # self.connect(self.delete, QtCore.SIGNAL('triggered()'), self.deleteItems) - # self.zoom = QtGui.QAction(self.tr('zoom'), self) - # self.connect(self.zoom, QtCore.SIGNAL('triggered()'), self.zoomItem) - # self.move = QtGui.QAction(self.tr('move'), self) - # self.connect(self.move, QtCore.SIGNAL('triggered()'), self.moveItem) - - - - - # else: - # self.layoutPt.plugin.mainWindow.objectEditSlot(self.state["press"]["item"].mobj, True) + popupmenu.exec_(self.mapToGlobal(event.pos())) self.resetState() + + def deleteGroup(self,item,layoutPt): + key = [k for k,v in self.layoutPt.qGraGrp.items() if v == item] + if key[0] in self.layoutPt.qGraGrp: + self.layoutPt.qGraGrp.pop(key[0]) + self.groupItemlist1 = item.childItems() + self.groupItemlist = [ i for i in self.groupItemlist1 if not isinstance(i,QtGui.QGraphicsPolygonItem)] + self.deleteObj(self.groupItemlist) + self.deleteItem(item) def drawExpectedConnection(self, event): self.connectionSource = self.state["press"]["item"] @@ -497,30 +578,7 @@ class GraphicalView(QtGui.QGraphicsView): , destinationPoint.y() ) - ''' - print " drawExpectedConnection ()() ",self.state["item"]["press"].mobj - sourcePoint = self.connectionSource.mapToScene( - self.connectionSource.boundingRect().center() - ) - destinationPoint = self.mapToScene(event.pos()) - if self.expectedConnection is None: - self.expectedConnection = QGraphicsLineItem( sourcePoint.x() - , sourcePoint.y() - , destinationPoint.x() - , destinationPoint.y() - ) - self.expectedConnection.setPen(QPen(Qt.Qt.DashLine)) - - self.sceneContainerPt.addItem(self.expectedConnection) - else: - self.expectedConnection.setLine( sourcePoint.x() - , sourcePoint.y() - , destinationPoint.x() - , destinationPoint.y() - ) - ''' def removeExpectedConnection(self): - #print("removeExpectedConnection") self.sceneContainerPt.removeItem(self.expectedConnection) self.expectedConnection = None self.connectionSource = None @@ -531,18 +589,9 @@ class GraphicalView(QtGui.QGraphicsView): if k is not None: self.sceneContainerPt.removeItem(k) self.connectorlist[l] = None - ''' - if self.connectionSign is not None: - # self.sceneContainerPt.removeItem(self.connectionSign) - # self.connectionSign = None - ''' except: #print("Exception received!") pass - # if self.connectionSign is not None: - # print "self.connectionSign ",self.connectionSign - # self.sceneContainerPt.removeItem(self.connectionSign) - # self.connectionSign = None def showConnector(self, item): self.removeConnector() @@ -700,39 +749,9 @@ class GraphicalView(QtGui.QGraphicsView): des = [j for j in destination if isinstance(j,KineticsDisplayItem)] if len(des): self.populate_srcdes(src.mobj,des[0].mobj) - #print " pop", self.layoutPt.srcdesConnection() self.setCursor(Qt.Qt.ArrowCursor) QtGui.QGraphicsView.mouseReleaseEvent(self, event) - '''if(self.customrubberBand): - self.customrubberBand.hide() - self.customrubberBand = 0 - if event.button() == QtCore.Qt.LeftButton and self.itemSelected == False : - self.endingPos = event.pos() - self.endScenepos = self.mapToScene(self.endingPos) - self.rubberbandWidth = (self.endScenepos.x()-self.startScenepos.x()) - self.rubberbandHeight = (self.endScenepos.y()-self.startScenepos.y()) - selecteditems = self.sceneContainerPt.selectedItems() - #print "selecteditems ",selecteditems - if self.rubberbandWidth != 0 and self.rubberbandHeight != 0 and len(selecteditems) != 0 : - self.showpopupmenu = True - ''' - #self.itemSelected = False - ''' - if self.showpopupmenu: - popupmenu = QtGui.QMenu('PopupMenu', self) - self.delete = QtGui.QAction(self.tr('delete'), self) - self.connect(self.delete, QtCore.SIGNAL('triggered()'), self.deleteItems) - self.zoom = QtGui.QAction(self.tr('zoom'), self) - self.connect(self.zoom, QtCore.SIGNAL('triggered()'), self.zoomItem) - self.move = QtGui.QAction(self.tr('move'), self) - self.connect(self.move, QtCore.SIGNAL('triggered()'), self.moveItem) - popupmenu.addAction(self.delete) - popupmenu.addAction(self.zoom) - popupmenu.addAction(self.move) - popupmenu.exec_(event.globalPos()) - self.showpopupmenu = False - ''' - + def updateItemTransformationMode(self, on): for v in self.sceneContainerPt.items(): #v.setFlag(QtGui.QGraphicsItem.ItemIgnoresTransformations,on) @@ -746,7 +765,7 @@ class GraphicalView(QtGui.QGraphicsView): if (key == Qt.Qt.Key_A and (event.modifiers() & Qt.Qt.ShiftModifier)): # 'A' fits the view to iconScale factor itemignoreZooming = False self.updateItemTransformationMode(itemignoreZooming) - self.fitInView(self.sceneContainerPt.itemsBoundingRect().x()-10,self.sceneContainerPt.itemsBoundingRect().y()-10,self.sceneContainerPt.itemsBoundingRect().width()+20,self.sceneContainerPt.itemsBoundingRect().height()+20,Qt.Qt.IgnoreAspectRatio) + #self.fitInView(self.sceneContainerPt.itemsBoundingRect().x()-10,self.sceneContainerPt.itemsBoundingRect().y()-10,self.sceneContainerPt.itemsBoundingRect().width()+20,self.sceneContainerPt.itemsBoundingRect().height()+20,Qt.Qt.IgnoreAspectRatio) self.layoutPt.drawLine_arrow(itemignoreZooming=False) elif (key == Qt.Qt.Key_Less or key == Qt.Qt.Key_Minus):# and (event.modifiers() & Qt.Qt.ShiftModifier)): # '<' key. zooms-in to iconScale factor @@ -764,6 +783,7 @@ class GraphicalView(QtGui.QGraphicsView): self.scale(1/1.1,1/1.1) elif (key == Qt.Qt.Key_A): # 'a' fits the view to initial value where iconscale=1 + self.iconscale = 1 self.updateScale( 1 ) self.fitInView(self.sceneContainerPt.itemsBoundingRect().x()-10,self.sceneContainerPt.itemsBoundingRect().y()-10,self.sceneContainerPt.itemsBoundingRect().width()+20,self.sceneContainerPt.itemsBoundingRect().height()+20,Qt.Qt.IgnoreAspectRatio) @@ -771,10 +791,8 @@ class GraphicalView(QtGui.QGraphicsView): for item in self.sceneContainerPt.items(): if isinstance(item,KineticsDisplayItem): item.refresh(scale) - #iteminfo = item.mobj.path+'/info' - #xpos,ypos = self.positioninfo(iteminfo) - xpos = item.scenePos().x() - ypos = item.scenePos().y() + xpos = item.pos().x() + ypos = item.pos().y() if isinstance(item,ReacItem) or isinstance(item,EnzItem) or isinstance(item,MMEnzItem): item.setGeometry(xpos,ypos, item.gobj.boundingRect().width(), @@ -790,23 +808,14 @@ class GraphicalView(QtGui.QGraphicsView): item.bg.setRect(0, 0, item.gobj.boundingRect().width()+PoolItem.fontMetrics.width(' '), item.gobj.boundingRect().height()) self.layoutPt.drawLine_arrow(itemignoreZooming=False) - self.layoutPt.comptChilrenBoundingRect() - #compartment width is resize according apart from calculating boundingRect - # for k, v in self.layoutPt.qGraCompt.items(): - # rectcompt = v.childrenBoundingRect() - # comptPen = v.pen() - # comptWidth = self.defaultComptsize*self.iconScale - # comptPen.setWidth(comptWidth) - # v.setPen(comptPen) - # v.setRect(rectcompt.x()-comptWidth,rectcompt.y()-comptWidth,(rectcompt.width()+2*comptWidth),(rectcompt.height()+2*comptWidth)) - + self.layoutPt.comptChildrenBoundingRect() + def moveSelections(self): self.setCursor(Qt.Qt.CrossCursor) self.move = True return def GrVfitinView(self): - #print " here in GrVfitinView" itemignoreZooming = False self.layoutPt.updateItemTransformationMode(itemignoreZooming) self.fitInView(self.sceneContainerPt.itemsBoundingRect().x()-10,self.sceneContainerPt.itemsBoundingRect().y()-10,self.sceneContainerPt.itemsBoundingRect().width()+20,self.sceneContainerPt.itemsBoundingRect().height()+20,Qt.Qt.IgnoreAspectRatio) @@ -814,51 +823,40 @@ class GraphicalView(QtGui.QGraphicsView): def deleteSelections(self,x0,y0,x1,y1): if( x1-x0 > 0 and y1-y0 >0): - self.rubberbandlist = self.sceneContainerPt.items(self.mapToScene(QtCore.QRect(x0, y0, x1 - x0, y1 - y0)).boundingRect(), Qt.Qt.IntersectsItemShape) - for unselectitem in self.rubberbandlist: + # self.rubberbandlist = self.sceneContainerPt.items(self.mapToScene(QtCore.QRect(x0, y0, x1 - x0, y1 - y0)).boundingRect(), Qt.Qt.IntersectsItemShape) + # for unselectitem in self.rubberbandlist: + self.rubberbandlist_qpolygon = [] + for unselectitem in self.rubberbandlist_qpolygon: if unselectitem.isSelected() == True: unselectitem.setSelected(0) + self.rubberbandlist_qpolygon = self.sceneContainerPt.items(self.mapToScene(QtCore.QRect(x0, y0, x1 - x0, y1 - y0)).boundingRect(), Qt.Qt.IntersectsItemShape) self.deleteObj(self.rubberbandlist) - # deleteSolver(self.layoutPt.modelRoot) - # for item in (qgraphicsitem for qgraphicsitem in self.rubberbandlist): - # #First Loop to remove all the enz b'cos if parent (which is a Pool) is removed, - # #then it will created problem at qgraphicalitem not having parent. - # #So first delete enz and then delete pool - # if isinstance(item,MMEnzItem) or isinstance(item,EnzItem) or isinstance(item,CplxItem): - # self.deleteItem(item) - # for item in (qgraphicsitem for qgraphicsitem in self.rubberbandlist): - # if not (isinstance(item,MMEnzItem) or isinstance(item,EnzItem) or isinstance(item,CplxItem)): - # if isinstance(item,PoolItem): - # plot = moose.wildcardFind(self.layoutPt.modelRoot+'/data/graph#/#') - # for p in plot: - # if len(p.neighbors['requestOut']): - # if item.mobj.path == moose.element(p.neighbors['requestOut'][0]).path: - # p.tick = -1 - # moose.delete(p) - # self.layoutPt.plugin.view.getCentralWidget().plotWidgetContainer.plotAllData() - # self.deleteItem(item) self.selections = [] + def deleteObj(self,item): self.rubberbandlist = item deleteSolver(self.layoutPt.modelRoot) - for item in (qgraphicsitem for qgraphicsitem in self.rubberbandlist): + self.Enz_cplxlist = [ i for i in self.rubberbandlist if (isinstance(i,MMEnzItem) or isinstance(i,EnzItem) or isinstance(i,CplxItem) )] + self.PFRSlist = [ i for i in self.rubberbandlist if (isinstance(i,PoolItem) or isinstance(i,TableItem) or isinstance(i,ReacItem) or isinstance(i,FuncItem) )] + self.grp = [ i for i in self.rubberbandlist if isinstance(i,GRPItem)] + for item in self.Enz_cplxlist: #First Loop to remove all the enz b'cos if parent (which is a Pool) is removed, #then it will created problem at qgraphicalitem not having parent. #So first delete enz and then delete pool - if isinstance(item,MMEnzItem) or isinstance(item,EnzItem) or isinstance(item,CplxItem): - self.deleteItem(item) - for item in (qgraphicsitem for qgraphicsitem in self.rubberbandlist): - if not (isinstance(item,MMEnzItem) or isinstance(item,EnzItem) or isinstance(item,CplxItem)): - if isinstance(item,PoolItem): - plot = moose.wildcardFind(self.layoutPt.modelRoot+'/data/graph#/#') - for p in plot: - if len(p.neighbors['requestOut']): - if item.mobj.path == moose.element(p.neighbors['requestOut'][0]).path: - p.tick = -1 - moose.delete(p) - self.layoutPt.plugin.view.getCentralWidget().plotWidgetContainer.plotAllData() - self.deleteItem(item) - + self.deleteItem(item) + for item in self.PFRSlist: + if isinstance(item,PoolItem) or isinstance(item,BufPool): + plot = moose.wildcardFind(self.layoutPt.modelRoot+'/data/graph#/#') + for p in plot: + if len(p.neighbors['requestOut']): + if item.mobj.path == moose.element(p.neighbors['requestOut'][0]).path: + p.tick = -1 + moose.delete(p) + self.layoutPt.plugin.view.getCentralWidget().plotWidgetContainer.plotAllData() + self.deleteItem(item) + for item in self.grp: + self.deleteItem(item) + def deleteObject2line(self,qpolygonline,src,des,endt): object2lineInfo = self.layoutPt.object2line[des] if len(object2lineInfo) == 1: @@ -866,7 +864,7 @@ class GraphicalView(QtGui.QGraphicsView): if polygon == qpolygonline and objdes == src and endtype == endt: del(self.layoutPt.object2line[des]) else: - print " check this condition when is len is single and else condition",qpolygonline, objdes,endtype + print( " check this condition when is len is single and else condition",qpolygonline, objdes,endtype) else: n = 0 for polygon,objdes,endtype,numL in object2lineInfo: @@ -1003,26 +1001,13 @@ class GraphicalView(QtGui.QGraphicsView): #delete Items self.layoutPt.plugin.mainWindow.objectEditSlot('/', False) - if isinstance(item,KineticsDisplayItem): + if isinstance(item,KineticsDisplayItem) or isinstance(item,GRPItem): if moose.exists(item.mobj.path): - # if isinstance(item.mobj,Function): - # print " inside the function" - # for items in moose.element(item.mobj.path).children: - # print items if isinstance(item,PoolItem) or isinstance(item,BufPool): # pool is item is removed, then check is made if its a parent to any # enz if 'yes', then enz and its connection are removed before # removing Pool for items in moose.element(item.mobj.path).children: - # if isinstance(moose.element(items), Function): - # gItem = self.layoutPt.mooseId_GObj[moose.element(items)] - # for l in self.layoutPt.object2line[gItem]: - # sceneItems = self.sceneContainerPt.items() - # if l[0] in sceneItems: - # #deleting the connection which is connected to Enz - # self.sceneContainerPt.removeItem(l[0]) - # moose.delete(items) - # self.sceneContainerPt.removeItem(gItem) if isinstance(moose.element(items), EnzBase): gItem = self.layoutPt.mooseId_GObj[moose.element(items)] for l in self.layoutPt.object2line[gItem]: @@ -1059,7 +1044,6 @@ class GraphicalView(QtGui.QGraphicsView): def zoomSelections(self, x0, y0, x1, y1): p0 = self.mapToScene(x0, y0) p1 = self.mapToScene(x1, y1) - #print QtCore.QRectF(p0, p1) self.fitInView(QtCore.QRectF(p0, p1), Qt.Qt.KeepAspectRatio) self.deselectSelections() return @@ -1119,7 +1103,6 @@ class GraphicalView(QtGui.QGraphicsView): founds, foundp = False,False if isinstance(moose.element(des),EnzBase): - print moose.element(des).neighbors["subOut"] if len(moose.element(des).neighbors["subOut"]) > 0: founds = True @@ -1195,10 +1178,6 @@ class GraphicalView(QtGui.QGraphicsView): elif founds: srcdesString = desClass+' is already connected as '+'\'Substrate\''+' to '+srcClass +' \n \nIf you wish to connect this object then first delete the exist connection' QtGui.QMessageBox.information(None,'Connection Not possible','{srcdesString}'.format(srcdesString = srcdesString),QtGui.QMessageBox.Ok) - # elif( isinstance(moose.element(src),ReacBase) and (isinstance(moose.element(des),PoolBase) ) ): - # moose.connect(src, 'prd', des, 'reac', 'OneToOne') - # elif( isinstance(moose.element(src),EnzBase) and (isinstance(moose.element(des),PoolBase) ) ): - # moose.connect(src, 'prd', des, 'reac', 'OneToOne') elif( isinstance(moose.element(src),StimulusTable) and (isinstance(moose.element(des),PoolBase) ) ): moose.connect(src, 'output', des, 'setConcInit', 'OneToOne') else: diff --git a/plugins/modelBuild.py b/plugins/modelBuild.py index 406e0d2a4360a08c0489f25c2f9a782839a3bb2d..25579bfd3d113a03b0dbf29b348d4f800f4079d9 100644 --- a/plugins/modelBuild.py +++ b/plugins/modelBuild.py @@ -1,3 +1,12 @@ +__author__ = "HarshaRani" +__credits__ = ["Upi Lab"] +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "HarshaRani" +__email__ = "hrani@ncbs.res.in" +__status__ = "Development" +__updated__ = "Jul 27 2017" + import moose from kkitQGraphics import * from kkitOrdinateUtil import * @@ -25,7 +34,6 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout # modelRoot = modelpath[0:modelpath.find('/',1)] # else: # modelRoot = modelpath - print "28 ",modelpath if moose.exists(modelpath+'/info'): mType = moose.Annotator((moose.element(modelpath+'/info'))).modeltype itemAtView = view.sceneContainerPt.itemAt(view.mapToScene(event_pos))