From 320e525a5a34fbd3f1cb572b6de38eca0c0876f0 Mon Sep 17 00:00:00 2001
From: Dilawar Singh <dilawars@ncbs.res.in>
Date: Wed, 21 Jun 2017 12:23:51 +0530
Subject: [PATCH] Squashed 'moose-gui/' changes from d282884250..49779ba730

49779ba730 As per Upi suggestion, co-ordinates are reprocessed for genesis file (yaxis is negated) at loading time so that, at the interface level co-ordinate are played around independently and while saving scene co-ordinates are save.
1f32b418d2 Kd is calculated for second order reaction only and value is displayed in object editor,Notes header is added, and unit for Kd is added in default.py
254d1f077a Enzyme can't be connected for second order reaction
3038c31d1a missing import math
355d721e4f added libsbml and moogli is removed
0343ce3e11 Added a Model information, like number of compartment,group,pool,function,reaction etc when model is loaded for the first time

git-subtree-dir: moose-gui
git-subtree-split: 49779ba730bbbb214728c86d3550fc2b27d8ef24
---
 .travis.yml                 |   7 +-
 defaults.py                 |   1 +
 mgui.py                     |  19 +++-
 mload.py                    |  24 ++++-
 objectedit.py               |  33 +++++--
 plugins/kkit.py             | 169 +++++++++++++-----------------------
 plugins/kkitOrdinateUtil.py | 153 ++++++++++++--------------------
 plugins/kkitQGraphics.py    |   1 -
 plugins/kkitViewcontrol.py  |  63 ++++++++++----
 plugins/modelBuild.py       |  69 ++++++++++-----
 10 files changed, 278 insertions(+), 261 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 111481f0..e5a702f3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,12 +13,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 -y --force-yes install python3
-    - sudo apt-get  -y --force-yes 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/defaults.py b/defaults.py
index 4ab8008f..ac591c81 100644
--- a/defaults.py
+++ b/defaults.py
@@ -10,6 +10,7 @@ PLOT_FIELDS={
     }
 FIELD_UNITS={
     'volume':'m3',
+    'Kd' : 'mM',
     'Km':'mM',
     'kcat':'s-1',
     'k1' :'1/# s',
diff --git a/mgui.py b/mgui.py
index 0226db50..b8574648 100644
--- a/mgui.py
+++ b/mgui.py
@@ -1186,7 +1186,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/mload.py b/mload.py
index cf0aeccd..8ee50546 100644
--- a/mload.py
+++ b/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(" ", "")
@@ -148,7 +149,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"
@@ -158,6 +178,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')
@@ -186,7 +207,7 @@ def loadFile(filename, target, solver="gsl", merge=True):
 
             # moose.move("cells/", cell.path)
         elif subtype == 'sbml':
-            foundLibSBML_ = False
+            foundLibtaSBML_ = False
             try:
                 import libsbml
                 foundLibSBML_ = True
@@ -214,6 +235,5 @@ def loadFile(filename, target, solver="gsl", merge=True):
             'foundlib' :libsfound}
 
 
-
 #
 # mload.py ends here
diff --git a/objectedit.py b/objectedit.py
index 8e59eb07..b76257ef 100644
--- a/objectedit.py
+++ b/objectedit.py
@@ -6,7 +6,7 @@
 # Maintainer:
 # Created: Wed Jun 30 11:18:34 2010 (+0530)
 # Version:
-# Last-Updated: Tue Mar 7 12:45:59 2017 (+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)
 
@@ -330,7 +335,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"):
@@ -477,7 +493,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/plugins/kkit.py b/plugins/kkit.py
index 83cd224f..9c8f96ec 100644
--- a/plugins/kkit.py
+++ b/plugins/kkit.py
@@ -7,7 +7,7 @@ __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 *
@@ -31,6 +31,7 @@ import RunWidget
 from os.path import expanduser
 from setsolver import *
 
+
 class KkitPlugin(MoosePlugin):
     """Default plugin for MOOSE GUI"""
     #objectSolverChanged = pyqtSignal()
@@ -100,37 +101,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
 
@@ -179,13 +168,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):
@@ -347,22 +329,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
@@ -383,16 +368,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)
@@ -409,7 +394,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()
@@ -434,44 +420,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)
 
@@ -576,7 +541,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():
@@ -597,6 +561,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":
@@ -634,31 +603,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/plugins/kkitOrdinateUtil.py b/plugins/kkitOrdinateUtil.py
index dcfeb8ac..cb2c1f86 100644
--- a/plugins/kkitOrdinateUtil.py
+++ b/plugins/kkitOrdinateUtil.py
@@ -9,15 +9,11 @@ __updated__     =   "Feb 14 2017"
 
 from moose import *
 import numpy as np
-from collections import Counter
+from moose import wildcardFind,element,PoolBase,CplxEnzBase,Annotator,exists
+import numpy as np
 import networkx as nx
 from networkx.drawing.nx_agraph import graphviz_layout
-#import pygraphviz as pgv
-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 \ 
@@ -25,11 +21,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()
@@ -57,17 +48,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,
@@ -76,28 +58,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 \
@@ -155,20 +127,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 = []
@@ -179,17 +137,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()
     #G = pgv.AGraph()
     positionInfo = {}
@@ -230,52 +212,27 @@ def autoCoordinates(meshEntry,srcdesConnection):
             else:
                 for items in (items for items in out ):
                     G.add_edge(element(items[0]).path,inn.path)
-    xcord = []
-    ycord = []
     
     position = graphviz_layout(G)
+    xcord, ycord = [],[]
     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)
     
-    '''
-    if int( nx.__version__.split( '.' )[-1] ) >= 11:
-     	position = nx.spring_layout( G )
-    else:
-     	position = nx.graphviz_layout(G, prog = 'dot')
+    xmin = min(xcord)
+    xmax = max(xcord)
+    ymin = min(ycord)
+    ymax = max(ycord)
     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])
-    '''
-    '''
-    #pygraphviz
-    G.layout()
-    for n in G.nodes():
-        print "inside 250 "
-        value = str(n.attr['pos'])
-        valuelist = (value.split(','))
-        positionInfo[(moose.element(n)).path] ={'x':float(valuelist[0]),'y':float(valuelist[1])}
-        ann = moose.Annotator(moose.element(n).path+'/info')
-        ann.x = float(valuelist[0])
-        ann.y = float(valuelist[1])
-        
-        xcord.append(float(valuelist[0]))
-        xcord.append(float(valuelist[1]))
-    '''
-    if xcord and ycord:
-        xmin = min(xcord)
-        xmax = max(xcord)
-        ymin = min(ycord)
-        ymax = max(ycord)    	    
-    return(xmin,xmax,ymin,ymax,position)
+        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)
 
 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/plugins/kkitQGraphics.py b/plugins/kkitQGraphics.py
index 1a804b0d..bbab5983 100644
--- a/plugins/kkitQGraphics.py
+++ b/plugins/kkitQGraphics.py
@@ -59,7 +59,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/plugins/kkitViewcontrol.py b/plugins/kkitViewcontrol.py
index c5c74b54..c9541743 100644
--- a/plugins/kkitViewcontrol.py
+++ b/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/plugins/modelBuild.py b/plugins/modelBuild.py
index 27e57a12..2fc00342 100644
--- a/plugins/modelBuild.py
+++ b/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))
+        return findCompartment(moose.element(mooseObj.parent))
\ No newline at end of file
-- 
GitLab