Exemplo n.º 1
0
 def createCompt(self, key):
     self.new_Compt = ComptItem(self, 0, 0, 0, 0, key)
     self.qGraCompt[key] = self.new_Compt
     self.new_Compt.setRect(10, 10, 10, 10)
     self.sceneContainer.addItem(self.new_Compt)
Exemplo n.º 2
0
class KineticsWidget(EditorWidgetBase):
    def __init__(self, plugin, *args):
        EditorWidgetBase.__init__(self, *args)
        self.plugin = plugin
        self.border = 5
        self.comptPen = 6
        self.iconScale = 1
        self.arrowsize = 2
        self.defaultComptsize = 5
        self.noPositionInfo = True
        self.xyCord = {}
        self.reset()
        self.qGraCompt = {}
        self.mooseId_GObj = {}
        self.srcdesConnection = {}
        self.editor = None

    def reset(self):
        # print "reset "
        self.createdItem = {}
        # This are created at drawLine
        self.lineItem_dict = {}
        self.object2line = defaultdict(list)
        self.itemignoreZooming = False

        if hasattr(self, "sceneContainer"):
            self.sceneContainer.clear()
        self.sceneContainer = QtGui.QGraphicsScene(self)
        sceneDim = self.sceneContainer.itemsBoundingRect()
        # if (sceneDim.width() == 0 and sceneDim.height() == 0):
        #     self.sceneContainer.setSceneRect(0,0,30,30)
        # else:
        # elf.sceneContainer.setSceneRect(self.sceneContainer.itemsBoundingRect())
        self.sceneContainer.setBackgroundBrush(QColor(230, 220, 219, 120))

    def updateModelView(self):
        self.getMooseObj()
        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)
            if isinstance(self, kineticEditorWidget):
                self.view.setRefWidget("editorView")
                self.view.setAcceptDrops(True)
            elif isinstance(self, kineticRunWidget):
                self.view.setRefWidget("runView")
            self.connect(self.view, QtCore.SIGNAL("dropped"), self.objectEditSlot)
            hLayout = QtGui.QGridLayout(self)
            self.setLayout(hLayout)
            hLayout.addWidget(self.view, 0, 0)
        else:
            # Already created Model
            # maxmium and minimum coordinates of the objects specified in kkit file.
            # self.mooseObjOntoscene()
            # 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)
            if isinstance(self, kineticEditorWidget):
                # self.getMooseObj()
                self.mooseObjOntoscene()
                self.drawLine_arrow()
                self.view.setRefWidget("editorView")
                self.view.setAcceptDrops(True)
                self.connect(self.view, QtCore.SIGNAL("dropped"), self.objectEditSlot)
                hLayout = QtGui.QGridLayout(self)
                self.setLayout(hLayout)
                hLayout.addWidget(self.view)
            elif isinstance(self, kineticRunWidget):
                self.view.setRefWidget("runView")
                hLayout = QtGui.QGridLayout(self)
                self.setLayout(hLayout)
                hLayout.addWidget(self.view)
                self.view.fitInView(
                    self.sceneContainer.itemsBoundingRect().x() - 10,
                    self.sceneContainer.itemsBoundingRect().y() - 10,
                    self.sceneContainer.itemsBoundingRect().width() + 20,
                    self.sceneContainer.itemsBoundingRect().height() + 20,
                    Qt.Qt.IgnoreAspectRatio,
                )

    def getMooseObj(self):
        # This fun call 2 more function
        # -- setupMeshObj(self.modelRoot),
        #    ----self.meshEntry has [meshEnt] = function: {}, Pool: {} etc
        # 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
            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)

    def sizeHint(self):
        return QtCore.QSize(800, 400)

    def updateItemSlot(self, mooseObject):
        # This is overridden by derived classes to connect appropriate
        # slot for updating the display item.
        # In this case if the name is updated from the keyboard both in mooseobj and gui gets updation
        changedItem = ""

        for item in self.sceneContainer.items():
            if isinstance(item, PoolItem):
                if mooseObject.getId() == element(item.mobj).getId():
                    item.updateSlot()
                    # once the text is edited in editor, laydisplay gets updated in turn resize the length, positionChanged signal shd be emitted
                    self.positionChange(mooseObject)

    def updateColorSlot(self, mooseObject, color):
        # Color slot for changing background color for PoolItem from objecteditor
        anninfo = moose.Annotator(mooseObject.path + "/info")
        textcolor, bgcolor = getColor(anninfo)
        anninfo.color = str(color.name())
        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
        self.qGraCompt = {}
        self.mooseId_GObj = {}
        if self.qGraCompt:
            self.qGraCompt.clear()
        else:
            self.qGraCompt = {}
        if self.mooseId_GObj:
            self.mooseId_GObj.clear()
        else:
            self.mooseId_GObj = {}

        for cmpt in sorted(self.meshEntry.iterkeys()):
            self.createCompt(cmpt)
            self.qGraCompt[cmpt]
            # comptRef = self.qGraCompt[cmpt]

        # Enzymes of all the compartments are placed first, \
        #     so that when cplx (which is pool object) queries for its parent, it gets its \
        #     parent enz co-ordinates with respect to QGraphicsscene """

        for cmpt, memb in self.meshEntry.items():
            for enzObj in find_index(memb, "enzyme"):
                enzinfo = enzObj.path + "/info"
                if enzObj.className == "Enz":
                    enzItem = EnzItem(enzObj, self.qGraCompt[cmpt])
                else:
                    enzItem = MMEnzItem(enzObj, self.qGraCompt[cmpt])
                self.mooseId_GObj[element(enzObj.getId())] = enzItem
                self.setupDisplay(enzinfo, enzItem, "enzyme")

                # self.setupSlot(enzObj,enzItem)
        for cmpt, memb in self.meshEntry.items():
            for poolObj in find_index(memb, "pool"):
                poolinfo = poolObj.path + "/info"
                # depending on Editor Widget or Run widget pool will be created a PoolItem or PoolItemCircle
                poolItem = self.makePoolItem(poolObj, self.qGraCompt[cmpt])
                self.mooseId_GObj[element(poolObj.getId())] = poolItem
                self.setupDisplay(poolinfo, poolItem, "pool")

            for reaObj in find_index(memb, "reaction"):
                reainfo = reaObj.path + "/info"
                reaItem = ReacItem(reaObj, self.qGraCompt[cmpt])
                self.setupDisplay(reainfo, reaItem, "reaction")
                self.mooseId_GObj[element(reaObj.getId())] = reaItem

            for tabObj in find_index(memb, "table"):
                tabinfo = tabObj.path + "/info"
                tabItem = TableItem(tabObj, self.qGraCompt[cmpt])
                self.setupDisplay(tabinfo, tabItem, "tab")
                self.mooseId_GObj[element(tabObj.getId())] = tabItem

            for funcObj in find_index(memb, "function"):
                funcinfo = moose.element(funcObj.parent).path + "/info"
                funcParent = self.mooseId_GObj[element(funcObj.parent)]
                funcItem = FuncItem(funcObj, funcParent)
                self.mooseId_GObj[element(funcObj.getId())] = funcItem
                self.setupDisplay(funcinfo, funcItem, "Function")

            for cplxObj in find_index(memb, "cplx"):
                cplxinfo = (cplxObj.parent).path + "/info"
                p = element(cplxObj).parent
                cplxItem = CplxItem(cplxObj, self.mooseId_GObj[element(cplxObj).parent])
                self.mooseId_GObj[element(cplxObj.getId())] = cplxItem
                self.setupDisplay(cplxinfo, cplxItem, "cplx")

        # compartment's rectangle size is calculated depending on children
        self.comptChilrenBoundingRect()

    def comptChilrenBoundingRect(self):
        for k, v in self.qGraCompt.items():
            # compartment's rectangle size is calculated depending on children
            rectcompt = v.childrenBoundingRect()
            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
        self.new_Compt.setRect(10, 10, 10, 10)
        self.sceneContainer.addItem(self.new_Compt)

    def setupDisplay(self, info, graphicalObj, objClass):
        Annoinfo = Annotator(info)
        # For Reaction and Complex object I have skipped the process to get the facecolor and background color as \
        #    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 = "white", "white"
        else:
            textcolor, bgcolor = getColor(info)
            if bgcolor.name() == "#ffffff" or bgcolor == "white":
                bgcolor = getRandColor()
                Annoinfo.color = str(bgcolor.name())
        if isinstance(self, kineticEditorWidget):
            xpos, ypos = self.positioninfo(info)
            self.xylist = [xpos, ypos]
            self.xyCord[moose.element(info).parent] = [xpos, ypos]
        elif isinstance(self, kineticRunWidget):
            self.editormooseId_GObj = self.editor.getCentralWidget().mooseId_GObj
            editorItem = self.editormooseId_GObj[moose.element(info).parent]
            # print "editorItem ",info,editorItem
            xpos = editorItem.scenePos().x()
            ypos = editorItem.scenePos().y()
            Annoinfo.x = xpos
            Annoinfo.y = -ypos
        graphicalObj.setDisplayProperties(xpos, ypos, textcolor, bgcolor)

    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
        xpos = (x - self.xmin) * self.xratio

        return (xpos, ypos)

    def drawLine_arrow(self, itemignoreZooming=False):
        for inn, out in self.srcdesConnection.items():
            # print "inn ",inn, " out ",out
            # self.srcdesConnection is dictionary which contains key,value \
            #    key is Enzyme or Reaction  and value [[list of substrate],[list of product]] (tuple)
            #    key is Function and value is [list of pool] (list)

            # src = self.mooseId_GObj[inn]
            if isinstance(out, tuple):
                src = self.mooseId_GObj[inn]
                if len(out[0]) == 0:
                    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"
                else:
                    for items in (items for items in out[1]):
                        des = self.mooseId_GObj[element(items[0])]
                        self.lineCord(src, des, items, itemignoreZooming)
            elif isinstance(out, list):
                if len(out) == 0:
                    print "Func pool doesn't have sumtotal"
                else:
                    src = self.mooseId_GObj[inn]
                    for items in (items for items in out):
                        des = self.mooseId_GObj[element(items[0])]
                        self.lineCord(src, des, items, itemignoreZooming)

    def lineCord(self, src, des, type_no, itemignoreZooming):
        srcdes_list = []
        endtype = type_no[1]
        line = 0
        if (src == "") and (des == ""):
            print "Source or destination is missing or incorrect"
            return
        srcdes_list = [src, des, endtype, line]
        arrow = calcArrow(srcdes_list, itemignoreZooming, self.iconScale)
        self.drawLine(srcdes_list, arrow)

        while type_no[2] > 1 and line <= (type_no[2] - 1):
            srcdes_list = [src, des, endtype, line]
            arrow = calcArrow(srcdes_list, itemignoreZooming, self.iconScale)
            self.drawLine(srcdes_list, arrow)
            line = line + 1

        if type_no[2] > 5:
            print "Higher order reaction will not be displayed"

    def drawLine(self, srcdes_list, arrow):
        src = srcdes_list[0]
        des = srcdes_list[1]
        endtype = srcdes_list[2]
        line = srcdes_list[3]
        source = element(next((k for k, v in self.mooseId_GObj.items() if v == src), None))
        for l, v, et, o in self.object2line[src]:
            if v == des and o == line:
                l.setPolygon(arrow)
                arrowPen = l.pen()
                arrowPenWidth = self.arrowsize * self.iconScale
                arrowPen.setColor(l.pen().color())
                arrowPen.setWidth(arrowPenWidth)
                l.setPen(arrowPen)
                return
        qgLineitem = self.sceneContainer.addPolygon(arrow)
        qgLineitem.setParentItem(src.parentItem())
        pen = QtGui.QPen(QtCore.Qt.green, 0, Qt.Qt.SolidLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin)
        pen.setWidth(self.arrowsize)
        # Green is default color moose.ReacBase and derivatives - already set above
        if isinstance(source, EnzBase):
            if (endtype == "s") or (endtype == "p"):
                pen.setColor(QtCore.Qt.red)
            elif endtype != "cplx":
                p1 = next((k for k, v in self.mooseId_GObj.items() if v == src), None)
                pinfo = p1.path + "/info"
                color, bgcolor = getColor(pinfo)
                # color = QColor(color[0],color[1],color[2])
                pen.setColor(color)
        elif isinstance(source, moose.PoolBase) or isinstance(source, moose.Function):
            pen.setColor(QtCore.Qt.blue)
        elif isinstance(source, moose.StimulusTable):
            pen.setColor(QtCore.Qt.yellow)
        self.lineItem_dict[qgLineitem] = srcdes_list
        self.object2line[src].append((qgLineitem, des, endtype, line))
        self.object2line[des].append((qgLineitem, src, endtype, line))
        qgLineitem.setPen(pen)

    def positionChange(self, mooseObject):
        # 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
                if k.path == mesh:
                    for rectChilditem in v.childItems():
                        if isinstance(rectChilditem, KineticsDisplayItem):
                            if isinstance(moose.element(rectChilditem.mobj.path), PoolBase):
                                t = moose.element(rectChilditem.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(rectChilditem)
        else:
            mobj = self.mooseId_GObj[element(mooseObject)]
            self.updateArrow(mobj)
            elePath = moose.element(mooseObject).path
            pos = elePath.find("/", 1)
            l = elePath[0:pos]
            linfo = moose.Annotator(l + "/info")
            for k, v in self.qGraCompt.items():
                rectcompt = v.childrenBoundingRect()
                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
                    v.setRect(
                        rectcompt.x() - 10, rectcompt.y() - 10, (rectcompt.width() + 20), (rectcompt.height() + 20)
                    )

    def updateCompartmentSize(self, compartment):
        compartmentBoundary = compartment.rect()
        childrenBoundary = compartment.childrenBoundingRect()
        x = min(compartmentBoundary.x(), childrenBoundary.x())
        y = min(compartmentBoundary.y(), childrenBoundary.y())
        width = max(compartmentBoundary.width(), childrenBoundary.width())
        height = max(compartmentBoundary.height(), childrenBoundary.height())
        compartment.setRect(x - 10, y - 10, width + 20, height + 20)

    def updateArrow(self, qGTextitem):
        # if there is no arrow to update then return
        if qGTextitem not in self.object2line:
            return
        listItem = self.object2line[qGTextitem]
        for ql, va, endtype, order in self.object2line[qGTextitem]:
            srcdes = []
            srcdes = self.lineItem_dict[ql]
            # Checking if src (srcdes[0]) or des (srcdes[1]) is ZombieEnz,
            # if yes then need to check if cplx is connected to any mooseObject,
            # so that when Enzyme is moved, cplx connected arrow to other mooseObject(poolItem) should also be updated
            if type(srcdes[0]) == EnzItem:
                self.cplxUpdatearrow(srcdes[0])
            elif type(srcdes[1]) == EnzItem:
                self.cplxUpdatearrow(srcdes[1])
            # For calcArrow(src,des,endtype,itemignoreZooming) is to be provided
            arrow = calcArrow(srcdes, self.itemignoreZooming, self.iconScale)
            ql.setPolygon(arrow)

    def cplxUpdatearrow(self, srcdes):
        # srcdes which is 'EnzItem' from this,get ChildItems are retrived (b'cos cplx is child of zombieEnz)
        # And cplxItem is passed for updatearrow
        for item in srcdes.childItems():
            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)):
            v = self.qGraCompt[mooseObject]
            for rectChilditem in v.childItems():
                self.updateArrow(rectChilditem)
        else:
            mobj = self.mooseId_GObj[mooseObject.getId()]
            self.updateArrow(mobj)
            mooseObjcompt = self.findparent(mooseObject)
            v = self.qGraCompt[mooseObjcompt]
            childBoundingRect = v.childrenBoundingRect()
            comptBoundingRect = v.boundingRect()
            rectcompt = comptBoundingRect.united(childBoundingRect)
            comptPen = v.pen()
            comptWidth = 5
            comptPen.setWidth(comptWidth)
            v.setPen(comptPen)
            if not comptBoundingRect.contains(childBoundingRect):
                v.setRect(
                    rectcompt.x() - comptWidth,
                    rectcompt.y() - comptWidth,
                    rectcompt.width() + (comptWidth * 2),
                    rectcompt.height() + (comptWidth * 2),
                )
Exemplo n.º 3
0
class  KineticsWidget(EditorWidgetBase):
    def __init__(self, *args):
        EditorWidgetBase.__init__(self, *args)
        self.setAcceptDrops(True)
        self.border = 10        
        self.sceneContainer = QtGui.QGraphicsScene(self)
        self.sceneContainer.setSceneRect(self.sceneContainer.itemsBoundingRect())
        self.sceneContainer.setBackgroundBrush(QtGui.QColor(230,220,219,120))
        #self.insertMenu = QtGui.QMenu('&Insert')
        #self._menus.append(self.insertMenu)
        #self.insertMapper = QtCore.QSignalMapper(self)
        classlist = ['CubeMesh','CylMesh','Pool','FuncPool','SumFunc','Reac','Enz','MMenz','StimulusTable','Table']
        #insertMapper, actions = self.getInsertActions(classlist)

        #for action in actions:
        #    self.insertMenu.addAction(action)
        #print "viewType",self.viewType
        # pickled the color map file """
        colormap_file = open(os.path.join(config.settings[config.KEY_COLORMAP_DIR], 'rainbow2.pkl'),'rb')
        self.colorMap = pickle.load(colormap_file)
        colormap_file.close()   
        
        if self.modelRoot == '/':
            self.m = wildcardFind('/##[ISA=ChemCompt]')
        else:
            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 = {}
            
            # Compartment and its members are setup
            self.meshEntry,self.xmin,self.xmax,self.ymin,self.ymax,self.noPositionInfo = setupMeshObj(self.modelRoot)
            self.autocoordinates = False
            # srcdesConnection dictonary will have connection information between src and des """
            self.srcdesConnection = {}
            setupItem(self.modelRoot,self.srcdesConnection)

            if self.noPositionInfo:
                self.autocoordinates = True
                QtGui.QMessageBox.warning(self, 
                                          'No coordinates found for the model', 
                                          '\n Automatic layouting will be done')
            #raise Exception('Unsupported kkit version')
                self.xmin,self.xmax,self.ymin,self.ymax,self.autoCordinatepos = autoCoordinates(self.meshEntry,self.srcdesConnection)
            # TODO: size will be dummy at this point, but I need the availiable size from the Gui
            self.size = QtCore.QSize(1024 ,768)
            #self.size = QtCore.QSize(300,400)
            
            # Scale factor to translate the x -y position to fit the Qt graphicalScene, scene width. """
            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)

        #A map b/w moose compartment key with QGraphicsObject
            self.qGraCompt = {}
        
        #A map between mooseId of all the mooseObject (except compartment) with QGraphicsObject
            self.mooseId_GObj = {}
        
            self.border = 5
            self.arrowsize = 2
            self.iconScale = 1
            self.defaultComptsize = 5
            self.itemignoreZooming = False
            self.lineItem_dict = {}
            self.object2line = defaultdict(list)

    def makePoolItem(self, poolObj, qGraCompt):
        raise NotImplementedError('method must be reimplemented in subclass')

    def mooseObjOntoscene(self):
        #  All the compartments are put first on to the scene \
        #  Need to do: Check With upi if empty compartments exist 
        for cmpt in sorted(self.meshEntry.iterkeys()):
            self.createCompt(cmpt)
            self.qGraCompt[cmpt]
            #comptRef = self.qGraCompt[cmpt]
        
        #Enzymes of all the compartments are placed first, \
        #     so that when cplx (which is pool object) queries for its parent, it gets its \
        #     parent enz co-ordinates with respect to QGraphicsscene """
        
        for cmpt,memb in self.meshEntry.items():
            for enzObj in find_index(memb,'enzyme'):
                enzinfo = enzObj.path+'/info'
                if enzObj.className == 'Enz':
                    enzItem = EnzItem(enzObj,self.qGraCompt[cmpt])
                else:
                    enzItem = MMEnzItem(enzObj,self.qGraCompt[cmpt])
                self.setupDisplay(enzinfo,enzItem,"enzyme")
                self.setupSlot(enzObj,enzItem)
        
        for cmpt,memb in self.meshEntry.items():
            for poolObj in find_index(memb,'pool'):
                poolinfo = poolObj.path+'/info'
                ''' depending on Editor Widget or Run widget pool will be created a PoolItem or PoolItemCircle '''
                poolItem = self.makePoolItem(poolObj,self.qGraCompt[cmpt])
                self.setupDisplay(poolinfo,poolItem,"pool")
                self.setupSlot(poolObj,poolItem)
            
            for cplxObj in find_index(memb,'cplx'):
                cplxinfo = (cplxObj.parent).path+'/info'
                cplxItem = CplxItem(cplxObj,self.mooseId_GObj[element(cplxObj).parent.getId()])
                self.setupDisplay(cplxinfo,cplxItem,"cplx")
                self.setupSlot(cplxObj,cplxItem)
            
            for reaObj in find_index(memb,'reaction'):
                reainfo = reaObj.path+'/info'
                reaItem = ReacItem(reaObj,self.qGraCompt[cmpt])
                self.setupDisplay(reainfo,reaItem,"reaction")
                self.setupSlot(reaObj,reaItem)
                
            for tabObj in find_index(memb,'table'):
                tabinfo = tabObj.path+'/info'
                tabItem = TableItem(tabObj,self.qGraCompt[cmpt])
                self.setupDisplay(tabinfo,tabItem,"tab")
                self.setupSlot(tabObj,tabItem)
        
        # compartment's rectangle size is calculated depending on children 
        for k, v in self.qGraCompt.items():
            rectcompt = v.childrenBoundingRect()
            v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20))
            v.setPen(QtGui.QPen(Qt.QColor(66,66,66,100), 5, Qt.Qt.SolidLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin))
            v.cmptEmitter.connect(v.cmptEmitter,QtCore.SIGNAL("qgtextPositionChange(PyQt_PyObject)"),self.positionChange)
            v.cmptEmitter.connect(v.cmptEmitter,QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),self.objectEditSlot)
        
    def createCompt(self,key):
        self.new_Compt = ComptItem(self,0,0,0,0,key)
        self.qGraCompt[key] = self.new_Compt
        self.new_Compt.setRect(10,10,10,10)
        self.sceneContainer.addItem(self.new_Compt)
        
    def setupDisplay(self,info,graphicalObj,objClass):
        xpos,ypos = self.positioninfo(info)
        # For Reaction and Complex object I have skipped the process to get the facecolor and background color as \
        #    we are not using these colors for displaying the object so just passing dummy color white 

        if( (objClass == "reaction" ) or (objClass == "cplx")):
            textcolor,bgcolor = "white","white"
        elif objClass == "tab":
            textcolor,bgcolor = getColor(info,self.colorMap)
        else:
            textcolor,bgcolor = getColor(info,self.colorMap)
        graphicalObj.setDisplayProperties(xpos,ypos,textcolor,bgcolor)
    
    def positioninfo(self,iteminfo):
        if 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 
            ypos = -(y-self.ymin)*self.yratio
        xpos = (x-self.xmin)*self.xratio
        
        return(xpos,ypos)

    def setupSlot(self,mooseObj,qgraphicItem):
        self.mooseId_GObj[element(mooseObj).getId()] = qgraphicItem
        qgraphicItem.connect(qgraphicItem,QtCore.SIGNAL("qgtextPositionChange(PyQt_PyObject)"),self.positionChange)
        qgraphicItem.connect(qgraphicItem,QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),self.objectEditSlot)

    def updateItemSlot(self, mooseObject):
        #This is overridden by derived classes to connect appropriate
        #slot for updating the display item.
        #In this case if the name is updated from the keyboard both in mooseobj and gui gets updation
        changedItem = ''

        for item in self.sceneContainer.items():
            #print "updateItemSlot",item
            if isinstance(item,PoolItem):
                if mooseObject.getId() == element(item.mobj).getId():
                    print "##",mooseObject.getId(),element(item.mobj).getId()
                    item.updateSlot()
                    #once the text is edited in editor, laydisplay gets updated in turn resize the length, positionChanged signal shd be emitted
                    self.positionChange(mooseObject)        
    def getToolBars(self):
        raise NotImplementedError('method must be reimplemented in subclass')
        '''if not hasattr(self, '_insertToolBar'):
            self._insertToolBar = QtGui.QToolBar('Insert')
            self._toolBars.append(self._insertToolBar)
            for action in self.insertMenu.actions():
                button = MToolButton()
                button.setDefaultAction(action)
                self._insertToolBar.addWidget(button)
        return self._toolBars
        '''
    def sizeHint(self):
        return QtCore.QSize(800,400)

    def updateModelView(self):
        # if self.modelRoot == '/':
        #     m = wildcardFind('/##[ISA=ChemCompt]')
        # else:
        #     m = wildcardFind(self.modelRoot+'/##[ISA=ChemCompt]')
        if not self.m:
            # 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)
            createdItem = {}
            self.sceneContainer.setSceneRect(-self.width()/2,-self.height()/2,self.width(),self.height())
            self.view = GraphicalView(self, self.modelRoot,self.sceneContainer,self.border,self,createdItem)
            self.connect(self.view, QtCore.SIGNAL("dropped"), self.objectEditSlot)
            hLayout = QtGui.QGridLayout(self)
            self.setLayout(hLayout)
            hLayout.addWidget(self.view)
        else:
            # maxmium and minimum coordinates of the objects specified in kkit file. 
            self.sceneContainer.clear()
            
            
            # Compartment and its members are put on the qgraphicsscene
            self.mooseObjOntoscene()
            
            # All the moose Object are connected for visualization 
            self.drawLine_arrow(itemignoreZooming=False)

            createdItem = {}
            if hasattr(self, 'view') and isinstance(self.view, QtGui.QWidget):
                self.layout().removeWidget(self.view)
            self.view = GraphicalView(self,self.modelRoot,self.sceneContainer,self.border,self,createdItem)
            hLayout = QtGui.QGridLayout(self)
            self.setLayout(hLayout)
            hLayout.addWidget(self.view)
            #self.layout().addWidget(self.view)
    
    '''
    def resetColor(self):
        for item in self.sceneContainer.items():
            if isinstance(item,PoolItem):
                pinfo = moose.element(item.mobj).path+'/info'
                color,bg = getColor(pinfo,self.colorMap)
                item.updateColor(bg)
    def changeBgSize(self):
        for item in self.sceneContainer.items():
            if isinstance(item,PoolItem):
                initialConc = moose.element(item.mobj).concInit
                presentConc = moose.element(item.mobj).conc
                if initialConc != 0:
                    ratio = presentConc/initialConc
                else:
                    # multipying by 1000 b'cos moose concentration is in milli in moose
                    ratio = presentConc*1000
                item.updateRect(math.sqrt(ratio))
        
    def colorChange(self):
        #While simulation is running pool color are increased or decreased as per concentration level 
        for item in self.sceneContainer.items():
            if isinstance(item,PoolItem):
                bg = item.returnColor()
                initialConc = moose.element(item.mobj[0]).concInit
                presentConc = moose.element(item.mobj[0]).conc
                if initialConc != 0:
                    ratio = presentConc/initialConc
                else:
                    # multipying by 1000 b'cos moose concentration is in milli in moose
                    ratio = presentConc*1000
                #alpha between0-255
                alpha = 128*ratio
                # Limiting alpha values
                if int(math.floor(alpha)) > 255:
                    alpha = 255
                elif int(math.floor(alpha))< 40:
                    alpha = 40
                #only alpha value is changed
                bg =QtGui.QColor(bg.red(),bg.green(),bg.blue(),alpha)
                item.updateColor(bg)
     '''   
    def positionChange(self,mooseObject):
        #If the item position changes, the corresponding arrow's are calculated
        if isinstance(element(mooseObject),CubeMesh):
            for k, v in self.qGraCompt.items():
                #mesh = mooseObject.path+'/mesh[0]'
                #print " mesh ",mesh,k.path
                #if k.path == mesh:
                for rectChilditem in v.childItems():
                    self.updateArrow(rectChilditem)
        else:
            mobj = self.mooseId_GObj[mooseObject.getId()]
            self.updateArrow(mobj)
            for k, v in self.qGraCompt.items():
                rectcompt = v.childrenBoundingRect()
                v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20))

    def emitItemtoEditor(self,mooseObject):
        #self.emit(QtCore.SIGNAL("itemPressed(PyQt_PyObject)"),mooseObject)
        self.editObject.emit(mooseObject.path)

    def drawLine_arrow(self, itemignoreZooming=False):
        for inn,out in self.srcdesConnection.items():
            # self.srcdesConnection is dictionary which contains key,value \
            #    key is Enzyme or Reaction  and value [[list of substrate],[list of product]] (tuple)
            #    key is FuncBase and value is [list of pool] (list)

            #src = self.mooseId_GObj[inn]
            if isinstance(out,tuple):
                if len(out[0])== 0:
                    print inn.className + ':' +inn.name+ " doesn't output message"
                else:
                    src = self.mooseId_GObj[inn.getId()]
                    for items in (items for items in out[0] ):
                        des = self.mooseId_GObj[element(items[0]).getId()]
                        self.lineCord(src,des,items,itemignoreZooming)
                if len(out[1]) == 0:
                    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]).getId()]
                        self.lineCord(src,des,items,itemignoreZooming)
            elif isinstance(out,list):
                if len(out) == 0:
                    print "Func pool doesn't have sumtotal"
                else:
                    src = self.mooseId_GObj[element(inn).getId()]
                    for items in (items for items in out ):
                        des = self.mooseId_GObj[element(items[0]).getId()]
                        self.lineCord(src,des,items,itemignoreZooming)
    
    def lineCord(self,src,des,type_no,itemignoreZooming):
        endtype = type_no[1]
        line = 0
        if (src == "") and (des == ""):
            print "Source or destination is missing or incorrect"
            return 
        srcdes_list = [src,des,endtype,line]
        arrow = calcArrow(srcdes_list,itemignoreZooming,self.iconScale)
        self.drawLine(srcdes_list,arrow)

        while(type_no[2] > 1 and line <= (type_no[2]-1)):
            srcdes_list =[src,des,endtype,line]
            arrow = calcArrow(srcdes_list,itemignoreZooming,self.iconScale)
            self.drawLine(srcdes_list,arrow)
            line = line +1

        if type_no[2] > 5:
            print "Higher order reaction will not be displayed"

    def drawLine(self,srcdes_list,arrow):
        src = srcdes_list[0]
        des = srcdes_list[1]
        endtype = srcdes_list[2]
        line = srcdes_list[3]
        source = element(next((k for k,v in self.mooseId_GObj.items() if v == src), None))
        for l,v,o in self.object2line[src]:
            if v == des and o ==line:
                l.setPolygon(arrow)
                arrowPen = l.pen()
                arrowPenWidth = self.arrowsize*self.iconScale
                arrowPen.setColor(l.pen().color())
                arrowPen.setWidth(arrowPenWidth)
                l.setPen(arrowPen)
                return
        qgLineitem = self.sceneContainer.addPolygon(arrow)
        pen = QtGui.QPen(QtCore.Qt.green, 0, Qt.Qt.SolidLine, Qt.Qt.RoundCap, Qt.Qt.RoundJoin)
        pen.setWidth(self.arrowsize)
        #pen.setCosmetic(True)
        # Green is default color moose.ReacBase and derivatives - already set above
        if  isinstance(source, EnzBase):
            if ( (endtype == 's') or (endtype == 'p')):
                pen.setColor(QtCore.Qt.red)
            elif(endtype != 'cplx'):
                p1 = (next((k for k,v in self.mooseId_GObj.items() if v == src), None))
                pinfo = p1.path+'/info'
                color,bgcolor = getColor(pinfo,self.colorMap)
                pen.setColor(color)
        elif isinstance(source, moose.PoolBase):
            pen.setColor(QtCore.Qt.blue)
        elif isinstance(source,moose.StimulusTable):
            pen.setColor(QtCore.Qt.yellow)
        self.lineItem_dict[qgLineitem] = srcdes_list
        self.object2line[ src ].append( ( qgLineitem, des,line) )
        self.object2line[ des ].append( ( qgLineitem, src,line ) )
        qgLineitem.setPen(pen)

    def updateArrow(self,qGTextitem):
        #if there is no arrow to update then return
        if qGTextitem not in self.object2line:
            return
        listItem = self.object2line[qGTextitem]
        for ql, va,order in self.object2line[qGTextitem]:
            srcdes = []
            srcdes = self.lineItem_dict[ql]
            # Checking if src (srcdes[0]) or des (srcdes[1]) is ZombieEnz,
            # if yes then need to check if cplx is connected to any mooseObject, 
            # so that when Enzyme is moved, cplx connected arrow to other mooseObject(poolItem) should also be updated
            if( type(srcdes[0]) == EnzItem):
                self.cplxUpdatearrow(srcdes[0])
            elif( type(srcdes[1]) == EnzItem):
                self.cplxUpdatearrow(srcdes[1])
            
            # For calcArrow(src,des,endtype,itemignoreZooming) is to be provided
            arrow = calcArrow(srcdes,self.itemignoreZooming,self.iconScale)
            ql.setPolygon(arrow)
    
    def cplxUpdatearrow(self,srcdes):
        # srcdes which is 'EnzItem' from this,get ChildItems are retrived (b'cos cplx is child of zombieEnz)
        #And cplxItem is passed for updatearrow

        #Note: Here at this point enzItem has just one child which is cplxItem and childItems returns, PyQt4.QtGui.QGraphicsEllipseItem,CplxItem
        #Assuming CplxItem is always[1], but still check if not[0], if something changes in structure one need to keep an eye.
        if (srcdes.childItems()[1],CplxItem):
            self.updateArrow(srcdes.childItems()[1])
        else:
            self.updateArrow(srcdes.childItems()[0])
    
    def keyPressEvent(self,event):
        # key1 = event.key() # key event does not distinguish between capital and non-capital letters
        key = event.text().toAscii().toHex()
        if key ==  '41': # 'A' fits the view to iconScale factor
            itemignoreZooming = False
            self.updateItemTransformationMode(itemignoreZooming)
            self.view.fitInView(self.sceneContainer.itemsBoundingRect().x()-10,self.sceneContainer.itemsBoundingRect().y()-10,self.sceneContainer.itemsBoundingRect().width()+20,self.sceneContainer.itemsBoundingRect().height()+20,Qt.Qt.IgnoreAspectRatio)
            self.drawLine_arrow(itemignoreZooming=False)
            
        elif (key == '2e'): # '.' key, lower case for '>' zooms in 
            self.view.scale(1.1,1.1)

        elif (key == '2c'): # ',' key, lower case for '<' zooms in
            self.view.scale(1/1.1,1/1.1)

        elif (key == '3c'): # '<' key. zooms-in to iconScale factor
            self.iconScale *= 0.8
            self.updateScale( self.iconScale )

        elif (key == '3e'): # '>' key. zooms-out to iconScale factor
            self.iconScale *= 1.25
            self.updateScale( self.iconScale )
            
        elif (key == '61'):  # 'a' fits the view to initial value where iconscale=1
            self.iconScale = 1
            self.updateScale( self.iconScale )
            self.view.fitInView(self.sceneContainer.itemsBoundingRect().x()-10,self.sceneContainer.itemsBoundingRect().y()-10,self.sceneContainer.itemsBoundingRect().width()+20,self.sceneContainer.itemsBoundingRect().height()+20,Qt.Qt.IgnoreAspectRatio)
                   
    def updateItemTransformationMode(self, on):
        for v in self.sceneContainer.items():
            if( not isinstance(v,ComptItem)):
                #if ( isinstance(v, PoolItem) or isinstance(v, ReacItem) or isinstance(v, EnzItem) or isinstance(v, CplxItem) ):
                if isinstance(v,KineticsDisplayItem):
                    v.setFlag(QtGui.QGraphicsItem.ItemIgnoresTransformations, on)

    def updateScale( self, scale ):
        for item in self.sceneContainer.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()

                if isinstance(item,ReacItem) or isinstance(item,EnzItem) or isinstance(item,MMEnzItem):
                     item.setGeometry(xpos,ypos, 
                                     item.gobj.boundingRect().width(), 
                                     item.gobj.boundingRect().height())
                elif isinstance(item,CplxItem):
                    item.setGeometry(item.gobj.boundingRect().width()/2,item.gobj.boundingRect().height(), 
                                     item.gobj.boundingRect().width(), 
                                     item.gobj.boundingRect().height())
                elif isinstance(item,PoolItem):
                     item.setGeometry(xpos, ypos,item.gobj.boundingRect().width()
                                     +PoolItem.fontMetrics.width('  '), 
                                     item.gobj.boundingRect().height())
                     item.bg.setRect(0, 0, item.gobj.boundingRect().width()+PoolItem.fontMetrics.width('  '), item.gobj.boundingRect().height())

        self.drawLine_arrow(itemignoreZooming=False)
        for k, v in self.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))
Exemplo n.º 4
0
 def createCompt(self, key):
     self.new_Compt = ComptItem(self, 0, 0, 0, 0, key)
     self.qGraCompt[key] = self.new_Compt
     self.new_Compt.setRect(10, 10, 10, 10)
     self.sceneContainer.addItem(self.new_Compt)
Exemplo n.º 5
0
class KineticsWidget(EditorWidgetBase):
    def __init__(self, plugin, *args):
        EditorWidgetBase.__init__(self, *args)
        self.plugin = plugin
        self.border = 5
        self.comptPen = 6
        self.iconScale = 1
        self.arrowsize = 2
        self.defaultComptsize = 5
        self.noPositionInfo = True
        self.xyCord = {}
        self.reset()
        self.qGraCompt = {}
        self.mooseId_GObj = {}
        self.srcdesConnection = {}
        self.editor = None

    def reset(self):
        #print "reset "
        self.createdItem = {}
        #This are created at drawLine
        self.lineItem_dict = {}
        self.object2line = defaultdict(list)
        self.itemignoreZooming = False

        if hasattr(self, 'sceneContainer'):
            self.sceneContainer.clear()
        self.sceneContainer = QtGui.QGraphicsScene(self)
        sceneDim = self.sceneContainer.itemsBoundingRect()
        # if (sceneDim.width() == 0 and sceneDim.height() == 0):
        #     self.sceneContainer.setSceneRect(0,0,30,30)
        # else:
        #elf.sceneContainer.setSceneRect(self.sceneContainer.itemsBoundingRect())
        self.sceneContainer.setBackgroundBrush(QColor(230, 220, 219, 120))

    def updateModelView(self):
        self.getMooseObj()
        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)
            if isinstance(self, kineticEditorWidget):
                self.view.setRefWidget("editorView")
                self.view.setAcceptDrops(True)
            elif isinstance(self, kineticRunWidget):
                self.view.setRefWidget("runView")
            self.connect(self.view, QtCore.SIGNAL("dropped"),
                         self.objectEditSlot)
            hLayout = QtGui.QGridLayout(self)
            self.setLayout(hLayout)
            hLayout.addWidget(self.view, 0, 0)
        else:
            # Already created Model
            # maxmium and minimum coordinates of the objects specified in kkit file.
            #self.mooseObjOntoscene()
            #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)
            if isinstance(self, kineticEditorWidget):
                #self.getMooseObj()
                self.mooseObjOntoscene()
                self.drawLine_arrow()
                self.view.setRefWidget("editorView")
                self.view.setAcceptDrops(True)
                self.connect(self.view, QtCore.SIGNAL("dropped"),
                             self.objectEditSlot)
                hLayout = QtGui.QGridLayout(self)
                self.setLayout(hLayout)
                hLayout.addWidget(self.view)
            elif isinstance(self, kineticRunWidget):
                self.view.setRefWidget("runView")
                hLayout = QtGui.QGridLayout(self)
                self.setLayout(hLayout)
                hLayout.addWidget(self.view)
                self.view.fitInView(
                    self.sceneContainer.itemsBoundingRect().x() - 10,
                    self.sceneContainer.itemsBoundingRect().y() - 10,
                    self.sceneContainer.itemsBoundingRect().width() + 20,
                    self.sceneContainer.itemsBoundingRect().height() + 20,
                    Qt.Qt.IgnoreAspectRatio)

    def getMooseObj(self):
        #This fun call 2 more function
        # -- setupMeshObj(self.modelRoot),
        #    ----self.meshEntry has [meshEnt] = function: {}, Pool: {} etc
        # 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
            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)

    def sizeHint(self):
        return QtCore.QSize(800, 400)

    def updateItemSlot(self, mooseObject):
        #This is overridden by derived classes to connect appropriate
        #slot for updating the display item.
        #In this case if the name is updated from the keyboard both in mooseobj and gui gets updation
        changedItem = ''

        for item in self.sceneContainer.items():
            if isinstance(item, PoolItem):
                if mooseObject.getId() == element(item.mobj).getId():
                    item.updateSlot()
                    #once the text is edited in editor, laydisplay gets updated in turn resize the length, positionChanged signal shd be emitted
                    self.positionChange(mooseObject)

    def updateColorSlot(self, mooseObject, color):
        #Color slot for changing background color for PoolItem from objecteditor
        anninfo = moose.Annotator(mooseObject.path + '/info')
        textcolor, bgcolor = getColor(anninfo)
        anninfo.color = str(color.name())
        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
        self.qGraCompt = {}
        self.mooseId_GObj = {}
        if self.qGraCompt:
            self.qGraCompt.clear()
        else:
            self.qGraCompt = {}
        if self.mooseId_GObj:
            self.mooseId_GObj.clear()
        else:
            self.mooseId_GObj = {}

        for cmpt in sorted(self.meshEntry.iterkeys()):
            self.createCompt(cmpt)
            self.qGraCompt[cmpt]
            #comptRef = self.qGraCompt[cmpt]

        #Enzymes of all the compartments are placed first, \
        #     so that when cplx (which is pool object) queries for its parent, it gets its \
        #     parent enz co-ordinates with respect to QGraphicsscene """

        for cmpt, memb in self.meshEntry.items():
            for enzObj in find_index(memb, 'enzyme'):
                enzinfo = enzObj.path + '/info'
                if enzObj.className == 'Enz':
                    enzItem = EnzItem(enzObj, self.qGraCompt[cmpt])
                else:
                    enzItem = MMEnzItem(enzObj, self.qGraCompt[cmpt])
                self.mooseId_GObj[element(enzObj.getId())] = enzItem
                self.setupDisplay(enzinfo, enzItem, "enzyme")

                #self.setupSlot(enzObj,enzItem)
        for cmpt, memb in self.meshEntry.items():
            for poolObj in find_index(memb, 'pool'):
                poolinfo = poolObj.path + '/info'
                #depending on Editor Widget or Run widget pool will be created a PoolItem or PoolItemCircle
                poolItem = self.makePoolItem(poolObj, self.qGraCompt[cmpt])
                self.mooseId_GObj[element(poolObj.getId())] = poolItem
                self.setupDisplay(poolinfo, poolItem, "pool")

            for reaObj in find_index(memb, 'reaction'):
                reainfo = reaObj.path + '/info'
                reaItem = ReacItem(reaObj, self.qGraCompt[cmpt])
                self.setupDisplay(reainfo, reaItem, "reaction")
                self.mooseId_GObj[element(reaObj.getId())] = reaItem

            for tabObj in find_index(memb, 'table'):
                tabinfo = tabObj.path + '/info'
                tabItem = TableItem(tabObj, self.qGraCompt[cmpt])
                self.setupDisplay(tabinfo, tabItem, "tab")
                self.mooseId_GObj[element(tabObj.getId())] = tabItem

            for funcObj in find_index(memb, 'function'):
                funcinfo = moose.element(funcObj.parent).path + '/info'
                funcParent = self.mooseId_GObj[element(funcObj.parent)]
                funcItem = FuncItem(funcObj, funcParent)
                self.mooseId_GObj[element(funcObj.getId())] = funcItem
                self.setupDisplay(funcinfo, funcItem, "Function")

            for cplxObj in find_index(memb, 'cplx'):
                cplxinfo = (cplxObj.parent).path + '/info'
                p = element(cplxObj).parent
                cplxItem = CplxItem(cplxObj,
                                    self.mooseId_GObj[element(cplxObj).parent])
                self.mooseId_GObj[element(cplxObj.getId())] = cplxItem
                self.setupDisplay(cplxinfo, cplxItem, "cplx")

        # compartment's rectangle size is calculated depending on children
        self.comptChilrenBoundingRect()

    def comptChilrenBoundingRect(self):
        for k, v in self.qGraCompt.items():
            # compartment's rectangle size is calculated depending on children
            rectcompt = v.childrenBoundingRect()
            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
        self.new_Compt.setRect(10, 10, 10, 10)
        self.sceneContainer.addItem(self.new_Compt)

    def setupDisplay(self, info, graphicalObj, objClass):
        Annoinfo = Annotator(info)
        # For Reaction and Complex object I have skipped the process to get the facecolor and background color as \
        #    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 = "white", "white"
        else:
            textcolor, bgcolor = getColor(info)
            if bgcolor.name() == "#ffffff" or bgcolor == "white":
                bgcolor = getRandColor()
                Annoinfo.color = str(bgcolor.name())
        if isinstance(self, kineticEditorWidget):
            xpos, ypos = self.positioninfo(info)
            self.xylist = [xpos, ypos]
            self.xyCord[moose.element(info).parent] = [xpos, ypos]
        elif isinstance(self, kineticRunWidget):
            self.editormooseId_GObj = self.editor.getCentralWidget(
            ).mooseId_GObj
            editorItem = self.editormooseId_GObj[moose.element(info).parent]
            #print "editorItem ",info,editorItem
            xpos = editorItem.scenePos().x()
            ypos = editorItem.scenePos().y()
            Annoinfo.x = xpos
            Annoinfo.y = -ypos
        graphicalObj.setDisplayProperties(xpos, ypos, textcolor, bgcolor)

    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
        xpos = (x - self.xmin) * self.xratio

        return (xpos, ypos)

    def drawLine_arrow(self, itemignoreZooming=False):
        for inn, out in self.srcdesConnection.items():
            #print "inn ",inn, " out ",out
            # self.srcdesConnection is dictionary which contains key,value \
            #    key is Enzyme or Reaction  and value [[list of substrate],[list of product]] (tuple)
            #    key is Function and value is [list of pool] (list)

            #src = self.mooseId_GObj[inn]
            if isinstance(out, tuple):
                src = self.mooseId_GObj[inn]
                if len(out[0]) == 0:
                    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"
                else:
                    for items in (items for items in out[1]):
                        des = self.mooseId_GObj[element(items[0])]
                        self.lineCord(src, des, items, itemignoreZooming)
            elif isinstance(out, list):
                if len(out) == 0:
                    print "Func pool doesn't have sumtotal"
                else:
                    src = self.mooseId_GObj[inn]
                    for items in (items for items in out):
                        des = self.mooseId_GObj[element(items[0])]
                        self.lineCord(src, des, items, itemignoreZooming)

    def lineCord(self, src, des, type_no, itemignoreZooming):
        srcdes_list = []
        endtype = type_no[1]
        line = 0
        if (src == "") and (des == ""):
            print "Source or destination is missing or incorrect"
            return
        srcdes_list = [src, des, endtype, line]
        arrow = calcArrow(srcdes_list, itemignoreZooming, self.iconScale)
        self.drawLine(srcdes_list, arrow)

        while (type_no[2] > 1 and line <= (type_no[2] - 1)):
            srcdes_list = [src, des, endtype, line]
            arrow = calcArrow(srcdes_list, itemignoreZooming, self.iconScale)
            self.drawLine(srcdes_list, arrow)
            line = line + 1

        if type_no[2] > 5:
            print "Higher order reaction will not be displayed"

    def drawLine(self, srcdes_list, arrow):
        src = srcdes_list[0]
        des = srcdes_list[1]
        endtype = srcdes_list[2]
        line = srcdes_list[3]
        source = element(
            next((k for k, v in self.mooseId_GObj.items() if v == src), None))
        for l, v, et, o in self.object2line[src]:
            if v == des and o == line:
                l.setPolygon(arrow)
                arrowPen = l.pen()
                arrowPenWidth = self.arrowsize * self.iconScale
                arrowPen.setColor(l.pen().color())
                arrowPen.setWidth(arrowPenWidth)
                l.setPen(arrowPen)
                return
        qgLineitem = self.sceneContainer.addPolygon(arrow)
        qgLineitem.setParentItem(src.parentItem())
        pen = QtGui.QPen(QtCore.Qt.green, 0, Qt.Qt.SolidLine, Qt.Qt.RoundCap,
                         Qt.Qt.RoundJoin)
        pen.setWidth(self.arrowsize)
        # Green is default color moose.ReacBase and derivatives - already set above
        if isinstance(source, EnzBase):
            if ((endtype == 's') or (endtype == 'p')):
                pen.setColor(QtCore.Qt.red)
            elif (endtype != 'cplx'):
                p1 = (next(
                    (k for k, v in self.mooseId_GObj.items() if v == src),
                    None))
                pinfo = p1.path + '/info'
                color, bgcolor = getColor(pinfo)
                #color = QColor(color[0],color[1],color[2])
                pen.setColor(color)
        elif isinstance(source, moose.PoolBase) or isinstance(
                source, moose.Function):
            pen.setColor(QtCore.Qt.blue)
        elif isinstance(source, moose.StimulusTable):
            pen.setColor(QtCore.Qt.yellow)
        self.lineItem_dict[qgLineitem] = srcdes_list
        self.object2line[src].append((qgLineitem, des, endtype, line))
        self.object2line[des].append((qgLineitem, src, endtype, line))
        qgLineitem.setPen(pen)

    def positionChange(self, mooseObject):
        #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
                if k.path == mesh:
                    for rectChilditem in v.childItems():
                        if isinstance(rectChilditem, KineticsDisplayItem):
                            if isinstance(
                                    moose.element(rectChilditem.mobj.path),
                                    PoolBase):
                                t = moose.element(rectChilditem.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(rectChilditem)
        else:
            mobj = self.mooseId_GObj[element(mooseObject)]
            self.updateArrow(mobj)
            elePath = moose.element(mooseObject).path
            pos = elePath.find('/', 1)
            l = elePath[0:pos]
            linfo = moose.Annotator(l + '/info')
            for k, v in self.qGraCompt.items():
                rectcompt = v.childrenBoundingRect()
                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
                    v.setRect(rectcompt.x() - 10,
                              rectcompt.y() - 10, (rectcompt.width() + 20),
                              (rectcompt.height() + 20))

    def updateCompartmentSize(self, compartment):
        compartmentBoundary = compartment.rect()
        childrenBoundary = compartment.childrenBoundingRect()
        x = min(compartmentBoundary.x(), childrenBoundary.x())
        y = min(compartmentBoundary.y(), childrenBoundary.y())
        width = max(compartmentBoundary.width(), childrenBoundary.width())
        height = max(compartmentBoundary.height(), childrenBoundary.height())
        compartment.setRect(x - 10, y - 10, width + 20, height + 20)

    def updateArrow(self, qGTextitem):
        #if there is no arrow to update then return
        if qGTextitem not in self.object2line:
            return
        listItem = self.object2line[qGTextitem]
        for ql, va, endtype, order in self.object2line[qGTextitem]:
            srcdes = []
            srcdes = self.lineItem_dict[ql]
            # Checking if src (srcdes[0]) or des (srcdes[1]) is ZombieEnz,
            # if yes then need to check if cplx is connected to any mooseObject,
            # so that when Enzyme is moved, cplx connected arrow to other mooseObject(poolItem) should also be updated
            if (type(srcdes[0]) == EnzItem):
                self.cplxUpdatearrow(srcdes[0])
            elif (type(srcdes[1]) == EnzItem):
                self.cplxUpdatearrow(srcdes[1])
            # For calcArrow(src,des,endtype,itemignoreZooming) is to be provided
            arrow = calcArrow(srcdes, self.itemignoreZooming, self.iconScale)
            ql.setPolygon(arrow)

    def cplxUpdatearrow(self, srcdes):
        # srcdes which is 'EnzItem' from this,get ChildItems are retrived (b'cos cplx is child of zombieEnz)
        #And cplxItem is passed for updatearrow
        for item in srcdes.childItems():
            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))):
            v = self.qGraCompt[mooseObject]
            for rectChilditem in v.childItems():
                self.updateArrow(rectChilditem)
        else:
            mobj = self.mooseId_GObj[mooseObject.getId()]
            self.updateArrow(mobj)
            mooseObjcompt = self.findparent(mooseObject)
            v = self.qGraCompt[mooseObjcompt]
            childBoundingRect = v.childrenBoundingRect()
            comptBoundingRect = v.boundingRect()
            rectcompt = comptBoundingRect.united(childBoundingRect)
            comptPen = v.pen()
            comptWidth = 5
            comptPen.setWidth(comptWidth)
            v.setPen(comptPen)
            if not comptBoundingRect.contains(childBoundingRect):
                v.setRect(rectcompt.x() - comptWidth,
                          rectcompt.y() - comptWidth,
                          rectcompt.width() + (comptWidth * 2),
                          rectcompt.height() + (comptWidth * 2))
Exemplo n.º 6
0
class KineticsWidget(EditorWidgetBase):
    def __init__(self, *args):
        EditorWidgetBase.__init__(self, *args)
        self.setAcceptDrops(True)
        self.border = 10
        self.sceneContainer = QtGui.QGraphicsScene(self)
        self.sceneContainer.setSceneRect(
            self.sceneContainer.itemsBoundingRect())
        self.sceneContainer.setBackgroundBrush(QtGui.QColor(
            230, 220, 219, 120))

        self.insertMenu = QtGui.QMenu('&Insert')
        self._menus.append(self.insertMenu)
        self.insertMapper = QtCore.QSignalMapper(self)

        classlist = [
            'CubeMesh', 'CylMesh', 'Pool', 'FuncPool', 'SumFunc', 'Reac',
            'Enz', 'MMenz', 'StimulusTable', 'Table'
        ]
        insertMapper, actions = self.getInsertActions(classlist)

        for action in actions:
            self.insertMenu.addAction(action)

    def getToolBars(self):
        if not hasattr(self, '_insertToolBar'):
            self._insertToolBar = QtGui.QToolBar('Insert')
            self._toolBars.append(self._insertToolBar)
            for action in self.insertMenu.actions():
                button = MToolButton()
                button.setDefaultAction(action)
                self._insertToolBar.addWidget(button)
        return self._toolBars

    def sizeHint(self):
        return QtCore.QSize(800, 400)

    def updateModelView(self):
        #print "update model view",self.modelRoot
        if self.modelRoot == '/':
            m = wildcardFind('/##[ISA=ChemCompt]')
        else:
            m = wildcardFind(self.modelRoot + '/##[ISA=ChemCompt]')
        #print "111",self.modelRoot,m
        if not m:
            # 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.view = GraphicalView(self.sceneContainer, self.border, self)
            self.layout().addWidget(self.view)
        else:
            # maxmium and minimum coordinates of the objects specified in kkit file.
            self.xmin = 0.0
            self.xmax = 1.0
            self.ymin = 0.0
            self.ymax = 1.0
            self.autoCordinatepos = {}
            self.sceneContainer.clear()
            # TODO: size will be dummy at this point, but I need the availiable size from the Gui
            self.size = QtCore.QSize(1024, 768)
            #self.size = QtCore.QSize(300,400)
            self.autocoordinates = False

            # pickled the color map file """
            colormap_file = open(
                os.path.join(config.settings[config.KEY_COLORMAP_DIR],
                             'rainbow2.pkl'), 'rb')
            self.colorMap = pickle.load(colormap_file)
            colormap_file.close()

            # Compartment and its members are setup """
            self.meshEntry, self.xmin, self.xmax, self.ymin, self.ymax, self.noPositionInfo = setupMeshObj(
                self.modelRoot)
            # srcdesConnection dictonary will have connection information between src and des """

            self.srcdesConnection = {}
            setupItem(self.modelRoot, self.srcdesConnection)
            if self.noPositionInfo:
                self.autocoordinates = True
                QtGui.QMessageBox.warning(
                    self, 'No coordinates found for the model',
                    '\n Automatic layouting will be done')
                #raise Exception('Unsupported kkit version')

                self.xmin, self.xmax, self.ymin, self.ymax, self.autoCordinatepos = autoCoordinates(
                    self.meshEntry, self.srcdesConnection)

            # Scale factor to translate the x -y position to fit the Qt graphicalScene, scene width. """
            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)

            #A map b/w moose compartment key with QGraphicsObject
            self.qGraCompt = {}

            #A map between mooseId of all the mooseObject (except compartment) with QGraphicsObject
            self.mooseId_GObj = {}

            self.border = 5
            self.arrowsize = 2
            self.iconScale = 1
            self.defaultComptsize = 5
            self.itemignoreZooming = False
            self.lineItem_dict = {}
            self.object2line = defaultdict(list)

            # Compartment and its members are put on the qgraphicsscene
            self.mooseObjOntoscene()

            # All the moose Object are connected for visualization
            self.drawLine_arrow(itemignoreZooming=False)
            if hasattr(self, 'view') and isinstance(self.view, QtGui.QWidget):
                self.layout().removeWidget(self.view)
            self.view = GraphicalView(self.sceneContainer, self.border, self)
            hLayout = QtGui.QGridLayout(self)
            self.setLayout(hLayout)
            hLayout.addWidget(self.view)
            #self.layout().addWidget(self.view)

    def mooseObjOntoscene(self):
        #  All the compartments are put first on to the scene \
        #  Need to do: Check With upi if empty compartments exist
        for cmpt in sorted(self.meshEntry.iterkeys()):
            self.createCompt(cmpt)
            self.qGraCompt[cmpt]
            #comptRef = self.qGraCompt[cmpt]

        #Enzymes of all the compartments are placed first, \
        #     so that when cplx (which is pool object) queries for its parent, it gets its \
        #     parent enz co-ordinates with respect to QGraphicsscene """

        for cmpt, memb in self.meshEntry.items():
            for enzObj in find_index(memb, 'enzyme'):
                enzinfo = enzObj.path + '/info'
                if enzObj.className == 'ZEnz':
                    enzItem = EnzItem(enzObj, self.qGraCompt[cmpt])
                else:
                    enzItem = MMEnzItem(enzObj, self.qGraCompt[cmpt])
                self.setupDisplay(enzinfo, enzItem, "enzyme")
                self.setupSlot(enzObj, enzItem)

        for cmpt, memb in self.meshEntry.items():
            for poolObj in find_index(memb, 'pool'):
                poolinfo = poolObj.path + '/info'
                poolItem = PoolItem(poolObj, self.qGraCompt[cmpt])
                self.setupDisplay(poolinfo, poolItem, "pool")
                self.setupSlot(poolObj, poolItem)

            for cplxObj in find_index(memb, 'cplx'):
                cplxinfo = (cplxObj[0].parent).path + '/info'
                cplxItem = CplxItem(
                    cplxObj,
                    self.mooseId_GObj[element(cplxObj[0]).parent.getId()])
                self.setupDisplay(cplxinfo, cplxItem, "cplx")
                self.setupSlot(cplxObj, cplxItem)

            for reaObj in find_index(memb, 'reaction'):
                reainfo = reaObj.path + '/info'
                reaItem = ReacItem(reaObj, self.qGraCompt[cmpt])
                self.setupDisplay(reainfo, reaItem, "reaction")
                self.setupSlot(reaObj, reaItem)

            for tabObj in find_index(memb, 'table'):
                tabinfo = tabObj.path + '/info'
                tabItem = PoolItem(tabObj, self.qGraCompt[cmpt])
                self.setupDisplay(tabinfo, tabItem, "tab")
                self.setupSlot(tabObj, tabItem)
        # compartment's rectangle size is calculated depending on children
        for k, v in self.qGraCompt.items():
            rectcompt = v.childrenBoundingRect()
            v.setRect(rectcompt.x() - 10,
                      rectcompt.y() - 10, (rectcompt.width() + 20),
                      (rectcompt.height() + 20))
            v.setPen(
                QtGui.QPen(Qt.QColor(66, 66, 66, 100), 5, Qt.Qt.SolidLine,
                           Qt.Qt.RoundCap, Qt.Qt.RoundJoin))
            v.cmptEmitter.connect(
                v.cmptEmitter,
                QtCore.SIGNAL("qgtextPositionChange(PyQt_PyObject)"),
                self.positionChange)
            v.cmptEmitter.connect(
                v.cmptEmitter,
                QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),
                self.objectEditSlot)

    def createCompt(self, key):
        self.new_Compt = ComptItem(self, 0, 0, 0, 0, key)
        self.qGraCompt[key] = self.new_Compt
        self.new_Compt.setRect(10, 10, 10, 10)
        self.sceneContainer.addItem(self.new_Compt)

    def setupDisplay(self, info, graphicalObj, objClass):
        xpos, ypos = self.positioninfo(info)

        # For Reaction and Complex object I have skipped the process to get the facecolor and background color as \
        #    we are not using these colors for displaying the object so just passing dummy color white

        if ((objClass == "reaction") or (objClass == "cplx")):
            textcolor, bgcolor = "white", "white"
        elif objClass == "tab":
            textcolor, bgcolor = getColor(info, self.colorMap)
        else:
            textcolor, bgcolor = getColor(info, self.colorMap)

        graphicalObj.setDisplayProperties(xpos, ypos, textcolor, bgcolor)

    def positioninfo(self, iteminfo):
        if 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
            ypos = -(y - self.ymin) * self.yratio
        xpos = (x - self.xmin) * self.xratio

        return (xpos, ypos)

    def setupSlot(self, mooseObj, qgraphicItem):
        self.mooseId_GObj[element(mooseObj).getId()] = qgraphicItem
        qgraphicItem.connect(
            qgraphicItem, QtCore.SIGNAL("qgtextPositionChange(PyQt_PyObject)"),
            self.positionChange)
        qgraphicItem.connect(
            qgraphicItem,
            QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),
            self.objectEditSlot)

    def updateItemSlot(self, mooseObject):
        #This is overridden by derived classes to connect appropriate
        #slot for updating the display item.
        #In this case if the name is updated from the keyboard both in mooseobj and gui gets updation
        changedItem = ''
        for item in self.sceneContainer.items():
            if isinstance(item, PoolItem):
                if mooseObject.getId() == element(item.mobj).getId():
                    item.updateSlot()
                    #once the text is edited in editor, laydisplay gets updated in turn resize the length, positionChanged signal shd be emitted
                    self.positionChange(mooseObject)

    def positionChange(self, mooseObject):
        #If the item position changes, the corresponding arrow's are calculated
        if isinstance(element(mooseObject), CubeMesh):
            for k, v in self.qGraCompt.items():
                mesh = mooseObject.path + '/mesh[0]'
                if k.path == mesh:
                    for rectChilditem in v.childItems():
                        self.updateArrow(rectChilditem)
        else:
            mobj = self.mooseId_GObj[mooseObject.getId()]
            self.updateArrow(mobj)
            for k, v in self.qGraCompt.items():
                rectcompt = v.childrenBoundingRect()
                v.setRect(rectcompt.x() - 10,
                          rectcompt.y() - 10, (rectcompt.width() + 20),
                          (rectcompt.height() + 20))

    def emitItemtoEditor(self, mooseObject):
        #self.emit(QtCore.SIGNAL("itemPressed(PyQt_PyObject)"),mooseObject)
        self.editObject.emit(mooseObject.path)

    def drawLine_arrow(self, itemignoreZooming=False):
        for inn, out in self.srcdesConnection.items():
            # self.srcdesConnection is dictionary which contains key,value \
            #    key is Enzyme or Reaction  and value [[list of substrate],[list of product]] (tuple)
            #    key is FuncBase and value is [list of pool] (list)

            #src = self.mooseId_GObj[inn]
            if isinstance(out, tuple):
                if len(out[0]) == 0:
                    print inn.className + ':' + inn[
                        0].name + " doesn't output message"
                else:
                    src = self.mooseId_GObj[inn]
                    for items in (items for items in out[0]):
                        des = self.mooseId_GObj[element(items[0]).getId()]

                        self.lineCord(src, des, items, itemignoreZooming)
                if len(out[1]) == 0:
                    print inn.className + ':' + inn[
                        0].name + " doesn't output message"
                else:
                    for items in (items for items in out[1]):
                        des = self.mooseId_GObj[element(items[0]).getId()]
                        self.lineCord(src, des, items, itemignoreZooming)

            elif isinstance(out, list):
                if len(out) == 0:
                    print "Func pool doesn't have sumtotal"
                else:
                    src = self.mooseId_GObj[element(inn).getId()]
                    for items in (items for items in out):
                        des = self.mooseId_GObj[element(items[0]).getId()]
                        self.lineCord(src, des, items, itemignoreZooming)

    def lineCord(self, src, des, type_no, itemignoreZooming):
        endtype = type_no[1]
        line = 0
        if (src == "") and (des == ""):
            print "Source or destination is missing or incorrect"
            return
        srcdes_list = [src, des, endtype, line]
        arrow = calcArrow(srcdes_list, itemignoreZooming, self.iconScale)
        self.drawLine(srcdes_list, arrow)

        while (type_no[2] > 1 and line <= (type_no[2] - 1)):
            srcdes_list = [src, des, endtype, line]
            arrow = calcArrow(srcdes_list, itemignoreZooming, self.iconScale)
            self.drawLine(srcdes_list, arrow)
            line = line + 1

        if type_no[2] > 5:
            print "Higher order reaction will not be displayed"

    def drawLine(self, srcdes_list, arrow):
        src = srcdes_list[0]
        des = srcdes_list[1]
        endtype = srcdes_list[2]
        line = srcdes_list[3]
        source = element(
            next((k for k, v in self.mooseId_GObj.items() if v == src), None))
        for l, v, o in self.object2line[src]:
            if v == des and o == line:
                l.setPolygon(arrow)
                arrowPen = l.pen()
                arrowPenWidth = self.arrowsize * self.iconScale
                arrowPen.setColor(l.pen().color())
                arrowPen.setWidth(arrowPenWidth)
                l.setPen(arrowPen)
                return

        qgLineitem = self.sceneContainer.addPolygon(arrow)
        pen = QtGui.QPen(QtCore.Qt.green, 0, Qt.Qt.SolidLine, Qt.Qt.RoundCap,
                         Qt.Qt.RoundJoin)
        pen.setWidth(self.arrowsize)
        #pen.setCosmetic(True)
        # Green is default color moose.ReacBase and derivatives - already set above
        if isinstance(source, EnzBase):
            if ((endtype == 's') or (endtype == 'p')):
                pen.setColor(QtCore.Qt.red)
            elif (endtype != 'cplx'):
                p1 = (next(
                    (k for k, v in self.mooseId_GObj.items() if v == src),
                    None))
                pinfo = p1.path + '/info'
                color, bgcolor = getColor(pinfo, self.colorMap)
                pen.setColor(color)
        elif isinstance(source, moose.PoolBase):
            pen.setColor(QtCore.Qt.blue)
        elif isinstance(source, moose.StimulusTable):
            pen.setColor(QtCore.Qt.yellow)
        self.lineItem_dict[qgLineitem] = srcdes_list
        self.object2line[src].append((qgLineitem, des, line))
        self.object2line[des].append((qgLineitem, src, line))
        qgLineitem.setPen(pen)

    def updateArrow(self, qGTextitem):
        #if there is no arrow to update then return
        if qGTextitem not in self.object2line:
            return
        listItem = self.object2line[qGTextitem]
        for ql, va, order in self.object2line[qGTextitem]:
            srcdes = []
            srcdes = self.lineItem_dict[ql]
            # Checking if src (srcdes[0]) or des (srcdes[1]) is ZombieEnz,
            # if yes then need to check if cplx is connected to any mooseObject,
            # so that when Enzyme is moved, cplx connected arrow to other mooseObject(poolItem) should also be updated
            if (type(srcdes[0]) == EnzItem):
                self.cplxUpdatearrow(srcdes[0])
            elif (type(srcdes[1]) == EnzItem):
                self.cplxUpdatearrow(srcdes[1])

            # For calcArrow(src,des,endtype,itemignoreZooming) is to be provided
            arrow = calcArrow(srcdes, self.itemignoreZooming, self.iconScale)
            ql.setPolygon(arrow)

    def cplxUpdatearrow(self, srcdes):
        # srcdes which is 'EnzItem' from this,get ChildItems are retrived (b'cos cplx is child of zombieEnz)
        #And cplxItem is passed for updatearrow

        #Note: Here at this point enzItem has just one child which is cplxItem and childItems returns, PyQt5.QtGui.QGraphicsEllipseItem,CplxItem
        #Assuming CplxItem is always[1], but still check if not[0], if something changes in structure one need to keep an eye.
        if (srcdes.childItems()[1], CplxItem):
            self.updateArrow(srcdes.childItems()[1])
        else:
            self.updateArrow(srcdes.childItems()[0])

    def keyPressEvent(self, event):
        # key1 = event.key() # key event does not distinguish between capital and non-capital letters
        key = event.text().toAscii().toHex()
        if key == '41':  # 'A' fits the view to iconScale factor
            itemignoreZooming = False
            self.updateItemTransformationMode(itemignoreZooming)
            self.view.fitInView(
                self.sceneContainer.itemsBoundingRect().x() - 10,
                self.sceneContainer.itemsBoundingRect().y() - 10,
                self.sceneContainer.itemsBoundingRect().width() + 20,
                self.sceneContainer.itemsBoundingRect().height() + 20,
                Qt.Qt.IgnoreAspectRatio)
            self.drawLine_arrow(itemignoreZooming=False)

        elif (key == '2e'):  # '.' key, lower case for '>' zooms in
            self.view.scale(1.1, 1.1)

        elif (key == '2c'):  # ',' key, lower case for '<' zooms in
            self.view.scale(1 / 1.1, 1 / 1.1)

        elif (key == '3c'):  # '<' key. zooms-in to iconScale factor
            self.iconScale *= 0.8
            self.updateScale(self.iconScale)

        elif (key == '3e'):  # '>' key. zooms-out to iconScale factor
            self.iconScale *= 1.25
            self.updateScale(self.iconScale)

        elif (key == '61'
              ):  # 'a' fits the view to initial value where iconscale=1
            self.iconScale = 1
            self.updateScale(self.iconScale)
            self.view.fitInView(
                self.sceneContainer.itemsBoundingRect().x() - 10,
                self.sceneContainer.itemsBoundingRect().y() - 10,
                self.sceneContainer.itemsBoundingRect().width() + 20,
                self.sceneContainer.itemsBoundingRect().height() + 20,
                Qt.Qt.IgnoreAspectRatio)

    def updateItemTransformationMode(self, on):
        for v in self.sceneContainer.items():
            if (not isinstance(v, ComptItem)):
                #if ( isinstance(v, PoolItem) or isinstance(v, ReacItem) or isinstance(v, EnzItem) or isinstance(v, CplxItem) ):
                if isinstance(v, KineticsDisplayItem):
                    v.setFlag(QtGui.QGraphicsItem.ItemIgnoresTransformations,
                              on)

    def updateScale(self, scale):
        for item in self.sceneContainer.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()

                if isinstance(item, ReacItem) or isinstance(
                        item, EnzItem) or isinstance(item, MMEnzItem):
                    item.setGeometry(xpos, ypos,
                                     item.gobj.boundingRect().width(),
                                     item.gobj.boundingRect().height())
                elif isinstance(item, CplxItem):
                    item.setGeometry(item.gobj.boundingRect().width() / 2,
                                     item.gobj.boundingRect().height(),
                                     item.gobj.boundingRect().width(),
                                     item.gobj.boundingRect().height())
                elif isinstance(item, PoolItem):
                    item.setGeometry(
                        xpos, ypos,
                        item.gobj.boundingRect().width() +
                        PoolItem.fontMetrics.width('  '),
                        item.gobj.boundingRect().height())
                    item.bg.setRect(
                        0, 0,
                        item.gobj.boundingRect().width() +
                        PoolItem.fontMetrics.width('  '),
                        item.gobj.boundingRect().height())

        self.drawLine_arrow(itemignoreZooming=False)
        for k, v in self.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))