diff --git a/moose-gui/.travis.yml b/moose-gui/.travis.yml index 5e29a4846ea26d48637ce99e46e52b124fc4abb7..15779bf198d587255777bc0c0afe4c636ee06f89 100644 --- a/moose-gui/.travis.yml +++ b/moose-gui/.travis.yml @@ -11,12 +11,13 @@ install: - sudo apt-key add - < Release.key - sudo sh -c "echo 'deb http://download.opensuse.org/repositories/home:/moose/xUbuntu_12.04/ /' >> /etc/apt/sources.list.d/moose.list" - sudo apt-get -y update - - sudo apt-get install python3 - - sudo apt-get -y install moose + - sudo apt-get -y --force-yes install python3 python-pip + - sudo apt-get -y --force-yes install moose + - sudo pip install python-libsbml script: - # Making sure no python incompatible file is added. - python -m compileall -q . - python -c 'import moose' - - python -c 'import moogli' + - #python -c 'import moogli' - # More tests here for gui. diff --git a/moose-gui/defaults.py b/moose-gui/defaults.py index 6551d2d9eb2cc5ba6d79bf396de8b1d5c81bebfc..458f7b389e3f566a83ce0e2fc6c98cfaa3e1ac74 100644 --- a/moose-gui/defaults.py +++ b/moose-gui/defaults.py @@ -10,6 +10,7 @@ PLOT_FIELDS={ } FIELD_UNITS={ 'volume':'m3', + 'Kd' : 'mM', 'Km':'mM', 'kcat':'s-1', 'Vm':'V', diff --git a/moose-gui/mgui.py b/moose-gui/mgui.py index ede1ba954889a588d8ef37f41645daa6d0f0ec13..9f201303e2db36f325e27661637b37fbcfb7504a 100644 --- a/moose-gui/mgui.py +++ b/moose-gui/mgui.py @@ -1130,7 +1130,24 @@ class MWindow(QtGui.QMainWindow): self.setPlugin(pluginName, ret['model'].path) if pluginName == 'kkit': QtCore.QCoreApplication.sendEvent(self.plugin.getEditorView().getCentralWidget().view, QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Qt.Key_A, Qt.Qt.NoModifier)) - + + noOfCompt = len(moose.wildcardFind(ret['model'].path+'/##[ISA=ChemCompt]')) + grp = 0 + for c in moose.wildcardFind(ret['model'].path+'/##[ISA=ChemCompt]'): + noOfGrp = moose.wildcardFind(moose.element(c).path+'/#[TYPE=Neutral]') + grp = grp+len(noOfGrp) + + noOfPool = len(moose.wildcardFind(ret['model'].path+'/##[ISA=PoolBase]')) + noOfFunc = len(moose.wildcardFind(ret['model'].path+'/##[ISA=Function]')) + noOfReac = len(moose.wildcardFind(ret['model'].path+'/##[ISA=ReacBase]')) + noOfEnz = len(moose.wildcardFind(ret['model'].path+'/##[ISA=EnzBase]')) + noOfStimtab = len(moose.wildcardFind(ret['model'].path+'/##[ISA=StimulusTable]')) + + reply = QtGui.QMessageBox.information(self,"Model Info","Model has : \n %s Compartment \t \n %s Group \t \n %s Pool \t \n %s Function \t \n %s reaction \t \n %s Enzyme \t \n %s StimulusTable" %(noOfCompt, grp, noOfPool, noOfFunc, noOfReac, noOfEnz, noOfStimtab)) + if reply == QtGui.QMessageBox.Ok: + QtGui.QApplication.restoreOverrideCursor() + return + def checkPlugin(self,dialog): fileNames = dialog.selectedFiles() for fileName in fileNames: diff --git a/moose-gui/mload.py b/moose-gui/mload.py index b91e2888592a75138554a28521cb0f1fea98c218..257daa9410909a3fb8eb877afdf8ef7ff7d125b5 100644 --- a/moose-gui/mload.py +++ b/moose-gui/mload.py @@ -55,6 +55,7 @@ from os.path import splitext from PyQt4 import QtGui, QtCore, Qt from plugins.setsolver import * from moose.SBML import * +from plugins.kkitOrdinateUtil import * def loadGenCsp(target,filename,solver="gsl"): target = target.replace(" ", "") @@ -146,7 +147,26 @@ def loadFile(filename, target, solver="gsl", merge=True): if modeltype == 'genesis': if subtype == 'kkit' or subtype == 'prototype': 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" @@ -156,6 +176,7 @@ def loadFile(filename, target, solver="gsl", merge=True): elif modeltype == 'cspace': model,modelpath = loadGenCsp(target,filename) + if moose.exists(modelpath): moose.Annotator((moose.element(modelpath).path+'/info')).modeltype = "cspace" addSolver(modelpath,'gsl') @@ -184,13 +205,21 @@ def loadFile(filename, target, solver="gsl", merge=True): # moose.move("cells/", cell.path) elif subtype == 'sbml': - if target != '/': - if moose.exists(target): - moose.delete(target) - model = mooseReadSBML(filename,target) - if moose.exists(moose.element(model).path): - moose.Annotator(moose.element(model).path+'/info').modeltype = "sbml" - addSolver(target,'gsl') + foundLibtaSBML_ = False + try: + import libsbml + foundLibSBML_ = True + except ImportError: + pass + if foundLibSBML_: + if target != '/': + if moose.exists(target): + moose.delete(target) + model = mooseReadSBML(filename,target) + if moose.exists(moose.element(model).path): + moose.Annotator(moose.element(model).path+'/info').modeltype = "sbml" + addSolver(target,'gsl') + libsfound = foundLibSBML_ else: raise FileLoadError('Do not know how to handle this filetype: %s' % (filename)) moose.setCwe(pwe) # The MOOSE loadModel changes the current working element to newly loaded model. We revert that behaviour @@ -203,6 +232,5 @@ def loadFile(filename, target, solver="gsl", merge=True): 'model': model} - # # mload.py ends here diff --git a/moose-gui/objectedit.py b/moose-gui/objectedit.py index 2545a1e2a562c60ab88cc3cb2a3197ab933d2594..a98294cc3f3fa619651e8ccf70f011bba1122810 100644 --- a/moose-gui/objectedit.py +++ b/moose-gui/objectedit.py @@ -6,7 +6,7 @@ # Maintainer: # Created: Wed Jun 30 11:18:34 2010 (+0530) # Version: -# Last-Updated: Wed Aug 3 15:55:59 2016 (+0530) +# Last-Updated: Friday May 17 23:45:59 2017 (+0530) # By: Harsha # Update #: # URL: @@ -38,8 +38,10 @@ # # Fri Apr 19 15:05:53 IST 2013 - Subhasis added undo redo # feature. Create ObjectEditModel as part of ObjectEditView. -# - +# Tue Mar 7 16:10:54 IST 2017 - Harsha now Pool or BufPool can be interchangable +# by setting/unsetting isbuffered field +# Fri May 17 23:45:59 2017 (+0530) - Harsha added, notes header, +# Kd is calculated for the second order reaction and value is displayed # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -172,13 +174,16 @@ class ObjectEditModel(QtCore.QAbstractTableModel): #harsha: For signalling models will be pulling out notes field from Annotator # can updates if exist for other types also if ( isinstance(self.mooseObject, moose.PoolBase) - #or isinstance(self.mooseObject,moose.ReacBase) or isinstance(self.mooseObject,moose.EnzBase) ) : self.fields.append("Color") - # self.fields.append("Notes") flag = QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable self.fieldFlags[fieldName] = flag + if ( isinstance(self.mooseObject, moose.ReacBase) ) : + self.fields.append("Kd") + flag = QtCore.Qt.ItemIsEnabled + self.fieldFlags[fieldName] = flag + def rowCount(self, parent): return len(self.fields) @@ -320,7 +325,18 @@ class ObjectEditModel(QtCore.QAbstractTableModel): try: if (str(field) =="Color" ): return QtGui.QPushButton("Press Me!") - if ( (str(field) != "Notes") and (str(field) != "className")): + if (str(field) =="Kd" ): + #ret = self.mooseObject.getField(str(field)) + Kd = 0 + + if self.mooseObject.className == "ZombieReac" or self.mooseObject.className == "Reac": + if self.mooseObject.numSubstrates > 1 or self.mooseObject.numProducts > 1: + if self.mooseObject.Kf != 0: + Kd = self.mooseObject.Kb/self.mooseObject.Kf + + #Kd = QtCore.QVariant(QtCore.QString(str(ret))) + ret = QtCore.QVariant(QtCore.QString(str(Kd))) + if ( (str(field) != "Notes") and (str(field) != "className") and (str(field) != "Kd")): ret = self.mooseObject.getField(str(field)) ret = QtCore.QVariant(QtCore.QString(str(ret))) elif(str(field) == "className"): @@ -465,7 +481,10 @@ class ObjectEditDockWidget(QtGui.QDockWidget): base.setOrientation(PyQt4.QtCore.Qt.Vertical) layout = QVBoxLayout() layout.addWidget(view)#, 0, 0) - + lineedit = QtGui.QLineEdit("Notes:") + lineedit.setReadOnly(True) + layout.addWidget(lineedit) + if ( isinstance(mobj, moose.PoolBase) or isinstance(mobj,moose.ReacBase) or isinstance(mobj,moose.EnzBase) diff --git a/moose-gui/plugins/kkit.py b/moose-gui/plugins/kkit.py index 5b79ea6fa2514f7fa9968b412d210f904cfdf03f..68bfd85ee77dcfb1a38c00ffea00e794363bc74a 100644 --- a/moose-gui/plugins/kkit.py +++ b/moose-gui/plugins/kkit.py @@ -1,3 +1,13 @@ + +__author__ = "HarshaRani" +__credits__ = ["Upi Lab"] +__license__ = "GPL3" +__version__ = "1.0.0" +__maintainer__ = "HarshaRani" +__email__ = "hrani@ncbs.res.in" +__status__ = "Development" +__updated__ = "Mar 7 2017" +import math import sys from PyQt4 import QtGui, QtCore, Qt from default import * @@ -21,6 +31,7 @@ import RunWidget from os.path import expanduser from setsolver import * + class KkitPlugin(MoosePlugin): """Default plugin for MOOSE GUI""" def __init__(self, *args): @@ -89,37 +100,25 @@ class KkitPlugin(MoosePlugin): elif filters[str(filter_)] == 'Genesis': mdtype = moose.Annotator(self.modelRoot+'/info') self.coOrdinates = {} - xycord = [] - self.sceneObj = KkitEditorView(self).getCentralWidget().mooseId_GObj - #Here get x,y coordinates from the Annotation, to save layout position - # into genesis - for k,v in self.sceneObj.items(): + ss = KkitEditorView(self).getCentralWidget().mooseId_GObj + for k,v in ss.items(): if moose.exists(moose.element(k).path+'/info'): annoInfo = Annotator(k.path+'/info') - self.coOrdinates[k] = {'x':annoInfo.x, 'y':annoInfo.y} - if mdtype.modeltype != "kkit": - #If coordinates come from kkit then directly transfering the co-ordinates - # else zoomed in factor is applied before saving it to genesis form - for k,v in self.coOrdinates.items(): - xycord.append(v['x']) - xycord.append(v['y']) - cmin = min(xycord) - cmax = max(xycord) - for k,v in self.coOrdinates.items(): - x = v['x'] - xprime = int((20*(float(v['x']-cmin)/float(cmax-cmin)))-10) - v['x'] = xprime - y = v['y'] - yprime = int((20*(float(v['y']-cmin)/float(cmax-cmin)))-10) - v['y'] = -yprime - - filename = filename - writeerror = mooseWriteKkit(self.modelRoot,str(filename),self.coOrdinates) - if writeerror == False: + #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 + self.coOrdinates[k] = {'x':x, 'y':y} + + error,writen = mooseWriteKkit(self.modelRoot,str(filename),self.coOrdinates) + if writen == False: QtGui.QMessageBox.information(None,'Could not save the Model','\nCheck the file') else: - QtGui.QMessageBox.information(None,'Saved the Model','\n File saved to \'{filename}\''.format(filename =filename+'.g'),QtGui.QMessageBox.Ok) - + if error == "": + QtGui.QMessageBox.information(None,'Saved the Model','\n File saved to \'{filename}\''.format(filename =filename+'.g'),QtGui.QMessageBox.Ok) + else: + status = QtCore.QString("File saved but %2").arg(error); + QtGui.QMessageBox.information(None,'Saved the Model but ...','{error}'.format(error=error),QtGui.QMessageBox.Ok) + def getPreviousPlugin(self): return None @@ -168,13 +167,6 @@ class KkitPlugin(MoosePlugin): graphView.layout().addWidget(self.currentRunView,0,0,2,1) return self.view -# class AnotherKkitRunViewsCentralWidget(QWidget): - -# def __init__(): -# QWidget.__init__() - -# def - class AnotherKkitRunView(RunView): def __init__(self, modelRoot, plugin,*args): @@ -335,22 +327,25 @@ class KineticsWidget(EditorWidgetBase): self.comptPen = 5 self.iconScale = 1 self.arrowsize = 2 - self.defaultComptsize = 5 - self.noPositionInfo = True - self.xyCord = {} self.reset() - self.qGraCompt = {} - self.mooseId_GObj = {} + + self.defaultSceneheight = 500 + self.defaultScenewidth = 1000 + self.positionInfoExist = True + self.defaultComptsize = 5 self.srcdesConnection = {} + + 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 - - + # 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 = {} #This are created at drawLine @@ -371,16 +366,16 @@ class KineticsWidget(EditorWidgetBase): def updateModelView(self): self.getMooseObj() - minmaxratiodict = {'xmin':self.xmin,'xmax':self.xmax,'ymin':self.ymin,'ymax':self.ymax,'xratio':self.xratio,'yratio':self.yratio} + #minmaxratiodict = {'xmin':self.xmin,'xmax':self.xmax,'ymin':self.ymin,'ymax':self.ymax,'xratio':self.xratio,'yratio':self.yratio} if not self.m: #At the time of model building # when we want an empty GraphicView while creating new model, # then remove all the view and add an empty view if hasattr(self, 'view') and isinstance(self.view, QtGui.QWidget): self.layout().removeWidget(self.view) - #self.sceneContainer.setSceneRect(-self.width()/2,-self.height()/2,self.width(),self.height()) - self.view = GraphicalView(self.modelRoot,self.sceneContainer,self.border,self,self.createdItem,minmaxratiodict) - + #self.sceneContainer.setSceneRect(-self.width()/2,-self.height()/2,self.width(),self.height()) + #self.view = GraphicalView(self.modelRoot,self.sceneContainer,self.border,self,self.createdItem,minmaxratiodict) + self.view = GraphicalView(self.modelRoot,self.sceneContainer,self.border,self,self.createdItem) if isinstance(self,kineticEditorWidget): self.view.setRefWidget("editorView") self.view.setAcceptDrops(True) @@ -397,7 +392,8 @@ class KineticsWidget(EditorWidgetBase): #self.drawLine_arrow() if hasattr(self, 'view') and isinstance(self.view, QtGui.QWidget): self.layout().removeWidget(self.view) - self.view = GraphicalView(self.modelRoot,self.sceneContainer,self.border,self,self.createdItem,minmaxratiodict) + # self.view = GraphicalView(self.modelRoot,self.sceneContainer,self.border,self,self.createdItem,minmaxratiodict) + self.view = GraphicalView(self.modelRoot,self.sceneContainer,self.border,self,self.createdItem) if isinstance(self,kineticEditorWidget): #self.getMooseObj() self.mooseObjOntoscene() @@ -422,44 +418,23 @@ class KineticsWidget(EditorWidgetBase): # setupItem self.m = wildcardFind(self.modelRoot+'/##[ISA=ChemCompt]') if self.m: - # self.xmin = 0.0 - # self.xmax = 1.0 - # self.ymin = 0.0 - # self.ymax = 1.0 - self.autoCordinatepos = {} self.srcdesConnection = {} - #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.autocoordinates = False + #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) + if self.srcdesConnection: self.srcdesConnection.clear() else: self.srcdesConnection = {} setupItem(self.modelRoot,self.srcdesConnection) - if not self.noPositionInfo: - self.autocoordinates = True - - self.xmin,self.xmax,self.ymin,self.ymax,self.autoCordinatepos = autoCoordinates(self.meshEntry,self.srcdesConnection) - # TODO: size will be dummy at this point, but size I need the availiable size from the Gui - 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 - + if not self.positionInfoExist: + autoCoordinates(self.meshEntry,self.srcdesConnection) + def sizeHint(self): return QtCore.QSize(800,400) @@ -561,7 +536,6 @@ class KineticsWidget(EditorWidgetBase): # compartment's rectangle size is calculated depending on children self.comptChilrenBoundingRect() - def comptChilrenBoundingRect(self): for k, v in self.qGraCompt.items(): @@ -582,6 +556,11 @@ class KineticsWidget(EditorWidgetBase): # we are not using these colors for displaying the object so just passing dummy color white if( objClass == "reaction" or objClass == "cplx" or objClass == "Function" or objClass == "StimulusTable"): textcolor,bgcolor = QColor("white"),QColor("white") + elif(objClass == "enzyme"): + textcolor,bgcolor = getColor(info) + if bgcolor.name() == "#ffffff" or bgcolor == "white": + bgcolor = getRandColor() + Annoinfo.color = str(bgcolor.name()) else: textcolor,bgcolor = getColor(info) if bgcolor.name() == "#ffffff" or bgcolor == "white": @@ -616,31 +595,13 @@ class KineticsWidget(EditorWidgetBase): #Annoinfo.y = ypos def positioninfo(self,iteminfo): - Anno = moose.Annotator(self.modelRoot+'/info') - if not self.noPositionInfo: - try: - # kkit does exist item's/info which up querying for parent.path gives the information of item's parent - x,y = self.autoCordinatepos[(element(iteminfo).parent).path] - except: - # But in Cspace reader doesn't create item's/info, up on querying gives me the error which need to change\ - # in ReadCspace.cpp, at present i am taking care b'cos i don't want to pass just the item where I need to check\ - # type of the object (rea,pool,enz,cplx,tab) which I have already done. - parent, child = posixpath.split(iteminfo) - x,y = self.autoCordinatepos[parent] - ypos = (y-self.ymin)*self.yratio - else: - x = float(element(iteminfo).getField('x')) - y = float(element(iteminfo).getField('y')) - #Qt origin is at the top-left corner. The x values increase to the right and the y values increase downwards \ - #as compared to Genesis codinates where origin is center and y value is upwards, that is why ypos is negated - # if Anno.modeltype == "kkit": - # ypos = 1.0-(y-self.ymin)*self.yratio - # else: - # ypos = (y-self.ymin)*self.yratio - ypos = 1.0 - (y-self.ymin)*self.yratio - xpos = (x-self.xmin)*self.xratio - return(xpos,ypos) - + '''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')) + return(x,y) + def drawLine_arrow(self, itemignoreZooming=False): for inn,out in self.srcdesConnection.items(): #print "inn ",inn, " out ",out diff --git a/moose-gui/plugins/kkitOrdinateUtil.py b/moose-gui/plugins/kkitOrdinateUtil.py index 03484f19ca5e61d3e56921e89e99ab8edd06c037..27ac35d62e5ad383816001e12b5adeb4b590d961 100644 --- a/moose-gui/plugins/kkitOrdinateUtil.py +++ b/moose-gui/plugins/kkitOrdinateUtil.py @@ -1,13 +1,5 @@ from moose import * import numpy as np -import networkx as nx -from collections import Counter - -def xyPosition(objInfo,xory): - try: - return(float(element(objInfo).getField(xory))) - except ValueError: - return (float(0)) def setupMeshObj(modelRoot): ''' Setup compartment and its members pool,reaction,enz cplx under self.meshEntry dictionaries \ @@ -15,11 +7,6 @@ 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() @@ -47,17 +34,8 @@ def setupMeshObj(modelRoot): for m in mol_cpl: if isinstance(element(m.parent),CplxEnzBase): cplxlist.append(m) - objInfo = m.parent.path+'/info' elif isinstance(element(m),moose.PoolBase): mollist.append(m) - objInfo =m.path+'/info' - xcord.append(xyPosition(objInfo,'x')) - ycord.append(xyPosition(objInfo,'y')) - - getxyCord(xcord,ycord,funclist) - getxyCord(xcord,ycord,enzlist) - getxyCord(xcord,ycord,realist) - getxyCord(xcord,ycord,tablist) meshEntry[meshEnt] = {'enzyme':enzlist, 'reaction':realist, @@ -66,28 +44,18 @@ def setupMeshObj(modelRoot): 'table':tablist, 'function':funclist } - 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(meshEntry,xmin,xmax,ymin,ymax,positionInfoExist) + + for mert in [mollist,enzlist,realist,tablist]: + for merts in mert: + objInfo = merts.path+'/info' + if exists(objInfo): + xcord.append(element(objInfo).x) + ycord.append(element(objInfo).y) + return(meshEntry,xcord,ycord) def sizeHint(self): return QtCore.QSize(800,400) -def getxyCord(xcord,ycord,list1): - for item in list1: - # if isinstance(item,Function): - # objInfo = moose.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 setupItem(modelPath,cntDict): '''This function collects information of what is connected to what. \ eg. substrate and product connectivity to reaction's and enzyme's \ @@ -145,20 +113,6 @@ def setupItem(modelPath,cntDict): prdlist.append((element(funcpar),'stp',countuniqItem[funcpar])) cntDict[items] = sublist,prdlist - # elif baseObj == 'Function': - # #ZombieSumFunc adding inputs - # inputlist = [] - # outputlist = [] - # funplist = [] - # nfunplist = [] - # for items in wildcardFind(path): - # for funplist in moose.element(items).neighbors['valueOut']: - # for func in funplist: - # funcx = moose.element(items.path+'/x[0]') - # uniqItem,countuniqItem = countitems(funcx,'input') - # for inPut in uniqItem: - # inputlist.append((inPut,'st',countuniqItem[inPut])) - # cntDict[func] = inputlist else: for tab in wildcardFind(path): tablist = [] @@ -169,17 +123,41 @@ def setupItem(modelPath,cntDict): def countitems(mitems,objtype): items = [] - #print "mitems in countitems ",mitems,objtype items = element(mitems).neighbors[objtype] uniqItems = set(items) - countuniqItems = Counter(items) + #countuniqItemsauto = Counter(items) + countuniqItems = dict((i, items.count(i)) for i in items) return(uniqItems,countuniqItems) +def recalculatecoordinatesforKkit(mObjlist,xcord,ycord): + + positionInfoExist = not(len(np.nonzero(xcord)[0]) == 0 \ + and len(np.nonzero(ycord)[0]) == 0) + + if positionInfoExist: + #Here all the object has been taken now recalculate and reassign back x and y co-ordinates + xmin = min(xcord) + xmax = max(xcord) + ymin = min(ycord) + ymax = max(ycord) + for merts in mObjlist: + objInfo = merts.path+'/info' + if moose.exists(objInfo): + Ix = (xyPosition(objInfo,'x')-xmin)/(xmax-xmin) + Iy = (ymin-xyPosition(objInfo,'y'))/(ymax-ymin) + element(objInfo).x = Ix + element(objInfo).y = Iy + +def xyPosition(objInfo,xory): + try: + return(float(element(objInfo).getField(xory))) + except ValueError: + return (float(0)) + + def autoCoordinates(meshEntry,srcdesConnection): - xmin = 0.0 - xmax = 1.0 - ymin = 0.0 - ymax = 1.0 + print " kkit Ordinatesutil autoCoordinates " + G = nx.Graph() for cmpt,memb in meshEntry.items(): for enzObj in find_index(memb,'enzyme'): @@ -218,6 +196,7 @@ def autoCoordinates(meshEntry,srcdesConnection): else: for items in (items for items in out ): G.add_edge(element(items[0]).path,inn.path) +<<<<<<< HEAD position = nx.spring_layout(G) #nx.draw(G,pos=nx.spring_layout(G)) #position = nx.spring_layout(G) @@ -231,20 +210,38 @@ def autoCoordinates(meshEntry,srcdesConnection): xcord = [] ycord = [] +======= + + position = graphviz_layout(G) + xcord, ycord = [],[] +>>>>>>> 320e525a5a34fbd3f1cb572b6de38eca0c0876f0 for item in position.items(): xy = item[1] - ann = moose.Annotator(item[0]+'/info') - ann.x = xy[0] - xcord.append(xy[0]) - ann.y = xy[1] - ycord.append(xy[1]) + xroundoff = round(xy[0],0) + yroundoff = round(xy[1],0) + xcord.append(xroundoff) + ycord.append(yroundoff) +<<<<<<< HEAD if xcord and ycord: xmin = min(xcord) xmax = max(xcord) ymin = min(ycord) ymax = max(ycord) return(xmin,xmax,ymin,ymax,position) +======= + xmin = min(xcord) + xmax = max(xcord) + ymin = min(ycord) + ymax = max(ycord) + for item in position.items(): + xy = item[1] + 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) +>>>>>>> 320e525a5a34fbd3f1cb572b6de38eca0c0876f0 def find_index(value, key): """ Value.get(key) to avoid expection which would raise if empty value in dictionary for a given key """ diff --git a/moose-gui/plugins/kkitQGraphics.py b/moose-gui/plugins/kkitQGraphics.py index 27ddbe3555d0bff5f9672ba9db5dd2b15b3dc7c6..b0bb4338871e106d8cee4094dc8c187d1ac22454 100644 --- a/moose-gui/plugins/kkitQGraphics.py +++ b/moose-gui/plugins/kkitQGraphics.py @@ -48,7 +48,6 @@ class KineticsDisplayItem(QtGui.QGraphicsWidget): # self.emit(QtCore.SIGNAL("qgtextPositionChange(PyQt_PyObject)"),self.mobj) if change == QtGui.QGraphicsItem.ItemSelectedChange and value == True: self.emit(QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),element(self.mobj)) - #print " itemChange ",self.mobj,change,value return QtGui.QGraphicsItem.itemChange(self,change,value) class FuncItem(KineticsDisplayItem): diff --git a/moose-gui/plugins/kkitViewcontrol.py b/moose-gui/plugins/kkitViewcontrol.py index c5c74b54c770e7d01ce640f4796a6821f633fa51..c9541743f847dcd8b049ab5aed3440b8845d2210 100644 --- a/moose-gui/plugins/kkitViewcontrol.py +++ b/moose-gui/plugins/kkitViewcontrol.py @@ -10,9 +10,9 @@ from moose import utils class GraphicalView(QtGui.QGraphicsView): - def __init__(self, modelRoot,parent,border,layoutPt,createdItem,minmaxratio): + def __init__(self, modelRoot,parent,border,layoutPt,createdItem): QtGui.QGraphicsView.__init__(self,parent) - self.minmaxratioDict = minmaxratio + self.state = None self.move = False self.resetState() @@ -99,7 +99,6 @@ class GraphicalView(QtGui.QGraphicsView): return (item, ITEM) if item.name == COMPARTMENT: solution = (item, self.resolveCompartmentInteriorAndBoundary(item, position)) - if solution is None: return (None, EMPTY) return solution @@ -171,15 +170,29 @@ class GraphicalView(QtGui.QGraphicsView): 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'] + # 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() @@ -1102,17 +1115,28 @@ class GraphicalView(QtGui.QGraphicsView): if ( isinstance(moose.element(src),PoolBase) and ( (isinstance(moose.element(des),ReacBase) ) or isinstance(moose.element(des),EnzBase) )): #If one to tries to connect pool to Reac/Enz (substrate to Reac/Enz), check if already (product to Reac/Enz) exist. #If exist then connection not allowed one need to delete the msg and try connecting back. - found = False + #And in moose Enzyme can't have 2nd order reaction. + 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 + for msg in des.msgOut: if moose.element(msg.e2.path) == src: if msg.srcFieldsOnE1[0] == "prdOut": - found = True - if found == False: + foundp = True + + if foundp == False and founds == False: # moose.connect(src, 'reac', des, 'sub', 'OneToOne') moose.connect(des, 'sub', src, 'reac', 'OneToOne') - else: + elif foundp: srcdesString = srcClass+' is already connected as '+ '\'Product\''+' to '+desClass +' \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 founds: + srcdesString = desClass+' has already connected to a'+ '\'Substrate\''+' \n \nIn moose Enzyme\'s can not have second order reaction. If 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),PoolBase) and (isinstance(moose.element(des),Function))): numVariables = des.numVars @@ -1153,15 +1177,22 @@ class GraphicalView(QtGui.QGraphicsView): ): moose.connect(src, 'valueOut', des, 'setNumKf', 'OneToOne') elif (((isinstance(moose.element(src),ReacBase))or (isinstance(moose.element(src),EnzBase))) and (isinstance(moose.element(des),PoolBase))): - found = False + founds,foundp = False,False + if isinstance(moose.element(src),EnzBase): + if len(moose.element(src).neighbors["prdOut"]) > 0: + foundp = True + for msg in src.msgOut: if moose.element(msg.e2.path) == des: if msg.srcFieldsOnE1[0] == "subOut": - found = True - if found == False: + founds = True + if founds == False and foundp == False: #moose.connect(src, 'prd', des, 'reac', 'OneToOne') - moose.connect(src, 'prd', des, 'reac', 'OneToOne') - else: + moose.connect(src, 'prd', des, 'reac', 'OneToOne') + elif foundp: + srcdesString = srcClass+' is already connected as '+ '\'Product\''+' to '+desClass +' \n \nIn moose Enzyme\'s can not have second order reaction. If 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 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) ) ): @@ -1180,4 +1211,4 @@ class GraphicalView(QtGui.QGraphicsView): if callsetupItem: self.layoutPt.getMooseObj() setupItem(self.modelRoot,self.layoutPt.srcdesConnection) - self.layoutPt.drawLine_arrow(False) \ No newline at end of file + self.layoutPt.drawLine_arrow(False) diff --git a/moose-gui/plugins/modelBuild.py b/moose-gui/plugins/modelBuild.py index 471d8e9eaf63953343cb3a7e968e5e2135e27860..406e0d2a4360a08c0489f25c2f9a782839a3bb2d 100644 --- a/moose-gui/plugins/modelBuild.py +++ b/moose-gui/plugins/modelBuild.py @@ -28,13 +28,9 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout print "28 ",modelpath if moose.exists(modelpath+'/info'): mType = moose.Annotator((moose.element(modelpath+'/info'))).modeltype - print " 1 event_pos ",event_pos itemAtView = view.sceneContainerPt.itemAt(view.mapToScene(event_pos)) - print "2 ",itemAtView pos = view.mapToScene(event_pos) - print " 3 ",pos modelpath = moose.element(modelpath) - print " model path @34 ",modelpath if num: string_num = ret_string+str(num) else: @@ -73,15 +69,12 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout bgcolor = getRandColor() qGItem.setDisplayProperties(posWrtComp.x(),posWrtComp.y(),QtGui.QColor('green'),bgcolor) poolinfo.color = str(bgcolor.getRgb()) - #if mType == "new_kkit": - poolinfo.x = posWrtComp.x() - poolinfo.y = posWrtComp.y() view.emit(QtCore.SIGNAL("dropped"),poolObj) setupItem(modelpath.path,layoutPt.srcdesConnection) layoutPt.drawLine_arrow(False) - poolinfo.x = posWrtComp.x() - poolinfo.y = posWrtComp.y() - + x,y = roundoff(qGItem.scenePos(),layoutPt) + poolinfo.x = x + poolinfo.y = y #Dropping is on compartment then update Compart size if isinstance(mobj,moose.ChemCompt): compt = layoutPt.qGraCompt[moose.element(mobj)] @@ -94,8 +87,8 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout qGItem = ReacItem(reacObj,itemAtView) qGItem.setDisplayProperties(posWrtComp.x(),posWrtComp.y(),"white", "white") #if mType == "new_kkit": - reacinfo.x = posWrtComp.x() - reacinfo.y = posWrtComp.y() + # reacinfo.x = posWrtComp.x() + # reacinfo.y = posWrtComp.y() layoutPt.mooseId_GObj[reacObj] = qGItem view.emit(QtCore.SIGNAL("dropped"),reacObj) setupItem(modelpath.path,layoutPt.srcdesConnection) @@ -104,6 +97,9 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout if isinstance(mobj,moose.ChemCompt): compt = layoutPt.qGraCompt[moose.element(mobj)] updateCompartmentSize(compt) + x,y = roundoff(qGItem.scenePos(),layoutPt) + reacinfo.x = x + reacinfo.y = y elif string == "StimulusTable": posWrtComp = (itemAtView.mapFromScene(pos)).toPoint() @@ -112,8 +108,8 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout qGItem = TableItem(tabObj,itemAtView) qGItem.setDisplayProperties(posWrtComp.x(),posWrtComp.y(),QtGui.QColor('white'),QtGui.QColor('white')) #if mType == "new_kkit": - tabinfo.x = posWrtComp.x() - tabinfo.y = posWrtComp.y() + #tabinfo.x = posWrtComp.x() + #tabinfo.y = posWrtComp.y() layoutPt.mooseId_GObj[tabObj] = qGItem view.emit(QtCore.SIGNAL("dropped"),tabObj) setupItem(modelpath.path,layoutPt.srcdesConnection) @@ -122,6 +118,10 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout if isinstance(mobj,moose.ChemCompt): compt = layoutPt.qGraCompt[moose.element(mobj)] updateCompartmentSize(compt) + x,y = roundoff(qGItem.scenePos(),layoutPt) + tabinfo.x = x + tabinfo.y = y + elif string == "Function": posWrtComp = (itemAtView.mapFromScene(pos)).toPoint() funcObj = moose.Function(mobj.path+'/'+string_num) @@ -140,8 +140,8 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout qGItem.setDisplayProperties(posWrtComp.x(),posWrtComp.y(),QtGui.QColor('red'),QtGui.QColor('green')) layoutPt.mooseId_GObj[funcObj] = qGItem #if mType == "new_kkit": - funcinfo.x = posWrtComp.x() - funcinfo.y = posWrtComp.y() + #funcinfo.x = posWrtComp.x() + #funcinfo.y = posWrtComp.y() view.emit(QtCore.SIGNAL("dropped"),funcObj) setupItem(modelpath.path,layoutPt.srcdesConnection) layoutPt.drawLine_arrow(False) @@ -150,6 +150,9 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout if isinstance(mooseCmpt,moose.ChemCompt): compt = layoutPt.qGraCompt[moose.element(mooseCmpt)] updateCompartmentSize(compt) + x,y = roundoff(qGItem.scenePos(),layoutPt) + funcinfo.x = x + funcinfo.y = y elif string == "Enz" or string == "MMenz": #If 2 enz has same pool parent, then pos of the 2nd enz shd be displaced by some position, need to check how to deal with it @@ -170,11 +173,16 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout posWrtComp = pos bgcolor = getRandColor() qGItem.setDisplayProperties(posWrtComp.x(),posWrtComp.y()-40,QtGui.QColor('green'),bgcolor) + x,y = roundoff(qGItem.scenePos(),layoutPt) + enzinfo.x = x + enzinfo.y = y + enzinfo.color = str(bgcolor.name()) + enzinfo.textColor = str(QtGui.QColor('green').name()) #if mType == "new_kkit": - enzinfo.x = posWrtComp.x() - enzinfo.y = posWrtComp.y() + #enzinfo.x = posWrtComp.x() + #enzinfo.y = posWrtComp.y() - enzinfo.color = str(bgcolor.name()) + #enzinfo.color = str(bgcolor.name()) e = moose.Annotator(enzinfo) #e.x = posWrtComp.x() #e.y = posWrtComp.y() @@ -187,8 +195,8 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout enzboundingRect = qGEnz.boundingRect() moose.connect( enzObj, 'cplx', cplxItem, 'reac' ) qGItem.setDisplayProperties(enzboundingRect.height()/2,enzboundingRect.height()-40,QtGui.QColor('white'),QtGui.QColor('white')) - cplxinfo.x = enzboundingRect.height()/2 - cplxinfo.y = enzboundingRect.height()-60 + #cplxinfo.x = enzboundingRect.height()/2 + #cplxinfo.y = enzboundingRect.height()-60 view.emit(QtCore.SIGNAL("dropped"),enzObj) else: @@ -199,13 +207,17 @@ def checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layout posWrtComp = pos bgcolor = getRandColor() qGItem.setDisplayProperties(posWrtComp.x(),posWrtComp.y()-30,QtGui.QColor('green'),bgcolor) - enzinfo.x = posWrtComp.x() - enzinfo.y = posWrtComp.y() + #enzinfo.x = posWrtComp.x() + #enzinfo.y = posWrtComp.y() enzinfo.color = str(bgcolor.name()) layoutPt.mooseId_GObj[enzObj] = qGItem view.emit(QtCore.SIGNAL("dropped"),enzObj) + x,y = roundoff(qGItem.scenePos(),layoutPt) + enzinfo.x = x + enzinfo.y = y setupItem(modelpath.path,layoutPt.srcdesConnection) layoutPt.drawLine_arrow(False) + #Dropping is on compartment then update Compart size if isinstance(enzparent,moose.ChemCompt): updateCompartmentSize(parentcompt) @@ -280,6 +292,15 @@ def createObj(scene,view,modelpath,string,pos,layoutPt): if ret_string != " ": checkCreate(scene,view,modelpath,mobj,string,ret_string,num,event_pos,layoutPt) +def roundoff(scenePos,layoutPt): + xtest = scenePos.x()/layoutPt.defaultScenewidth + xroundoff = round(xtest,1) + + ytest = scenePos.y()/layoutPt.defaultSceneheight + yroundoff = round(ytest,1) + + return(xroundoff,yroundoff) + def findUniqId(mobj,string,num): if num == 0: path = mobj.path+'/'+string; @@ -297,4 +318,4 @@ def findCompartment(mooseObj): elif isinstance(mooseObj,ChemCompt): return (mooseObj) else: - return findCompartment(moose.element(mooseObj.parent)) \ No newline at end of file + return findCompartment(moose.element(mooseObj.parent))