diff --git a/AUTHROS b/AUTHROS new file mode 100644 index 0000000000000000000000000000000000000000..f568c742ebe5fc90330f250c3c5e035224fed581 --- /dev/null +++ b/AUTHROS @@ -0,0 +1,9 @@ +Upinder S. Bhalla Primary Architect +Niraj Dudani Neuronal solver +Subhasis Ray Python interface +Aditya Gilra NeuroML support +Aviral Goel Moogli +HarshaRani. G.V Designing of Website,read and write SBML and + Graphical User Interface for moose +Dilawar Singh Packaging, BOOST solvers +Dharma Teja GPU parallelization using CUDA diff --git a/CMakeLists.txt b/CMakeLists.txt index 390904c58e1e4ebd1f8a9c4e1337014f7676d173..916c01176ab45eb8065bdd9a9aab2fd63dad81be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ set(CMAKE_LEGACY_CYGWIN_WIN32 0) -cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR) +cmake_minimum_required(VERSION 2.8 FATAL_ERROR) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) @@ -11,9 +11,11 @@ endif(COMMAND cmake_policy) project(MOOSE) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") include(CheckCXXCompiler.cmake) include(CheckIncludeFileCXX) include(FindPkgConfig) +include(GetRevision) # If from command line, version info is not passed, use the git to generate a # version file. If GIT fails, use the previous known version. @@ -27,14 +29,14 @@ if( (NOT MOOSE_VERSION) AND GIT_EXEC) OUTPUT_VARIABLE MOOSE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) - message(STATUS "+ Writing ${MOOSE_VERSION} to ${VERSION_FILE}" ) - file(WRITE ${VERSION_FILE} ${MOOSE_VERSION}) -elseif( (NOT MOOSE_VERSION) AND (NOT GIT_EXEC) ) - message(STATUS "+ Reading ${VERSION_FILE}" ) - file(READ ${VERSION_FILE} GIT_VERSION_OUTPUT ) +endif( ) + +# Default to current date. +if( (NOT MOOSE_VERSION) ) + NOW(TIMESTAMP) + set(MOOSE_VERSION "nightly-${TIMESTAMP}" ) elseif(MOOSE_VERSION) message(STATUS "+ Using user specified VERSION = ${MOOSE_VERSION}" ) - file(WRITE ${VERSION_FILE} ${MOOSE_VERSION}) else() message(FATAL_ERROR "Could not determine MOOSE_VERSION" ) endif( ) @@ -42,6 +44,10 @@ endif( ) add_definitions( -DMOOSE_VERSION="${MOOSE_VERSION}") message( STATUS "MOOSE Version ${MOOSE_VERSION}" ) +# Write VERSION to a file VERSION so that setup.py can use it. +message(STATUS "+ Writing ${MOOSE_VERSION} to ${VERSION_FILE}" ) +file(WRITE ${VERSION_FILE} ${MOOSE_VERSION} ) + # This snippet is from LLVM project. # Sanity check our source directory to make sure that we are not trying to # generate an in-tree build (unless on MSVC_IDE, where it is ok), and to make @@ -98,9 +104,6 @@ option(WITH_MPI "Enable Openmpi support" OFF) option(WITH_BOOST "Use boost library instead of GSL" OFF) option(WITH_GSL "Use gsl-library. Alternative is WITH_BOOST" ON) -################################# CMKAE MACROS ################################# - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") ############################ BUILD CONFIGURATION ################################# diff --git a/basecode/global.h b/basecode/global.h index 9b06b2820245f1ef4d8fd0639be1b3e6f42a5a13..692bb71cbd15adfc81d6470f830cba0600a50c11 100644 --- a/basecode/global.h +++ b/basecode/global.h @@ -48,9 +48,6 @@ extern unsigned int totalTests; #define TEST_END totalTests++; \ cout << std::right << setw(20) << "test of " << SIMPLE_CURRENT_FUNCTION << " finished."; -/*----------------------------------------------------------------------------- - * Global functions in namespace moose - *-----------------------------------------------------------------------------*/ #define MISSING_BRACKET_AT_END -1 #define EMPTY_PATH -2 #define SPACES_AT_THE_BEGINING -3 @@ -59,6 +56,9 @@ extern unsigned int totalTests; #define BAD_CHARACTER_IN_PATH -6 +/*----------------------------------------------------------------------------- + * Global functions in namespace moose + *-----------------------------------------------------------------------------*/ namespace moose { diff --git a/cmake_modules/GetRevision.cmake b/cmake_modules/GetRevision.cmake new file mode 100644 index 0000000000000000000000000000000000000000..41c991cb8a6e06d71b82eb08b0705ab085b37366 --- /dev/null +++ b/cmake_modules/GetRevision.cmake @@ -0,0 +1,20 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3) + +MACRO(NOW RESULT) + IF(CMAKE_VERSION VERSION_GREATER "2.8.10") + STRING(TIMESTAMP ${RESULT} "%Y%m%d") + ELSE() + IF(WIN32) + EXECUTE_PROCESS(COMMAND "wmic" "os" "get" "localdatetime" OUTPUT_VARIABLE DATETIME) + IF(NOT DATETIME MATCHES "ERROR") + STRING(REGEX REPLACE ".*\n([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9]).*" "\\1-\\2-\\3 \\4:\\5:\\6" ${RESULT} "${DATETIME}") + ENDIF() + ELSEIF(UNIX) + EXECUTE_PROCESS(COMMAND "date" "+%Y%m%d" OUTPUT_VARIABLE DATETIME) + STRING(REGEX REPLACE "([0-9: -]+).*" "\\1" ${RESULT} "${DATETIME}") + ELSE() + MESSAGE(SEND_ERROR "date not implemented") + SET(${RESULT} "00000000") + ENDIF() + ENDIF() +ENDMACRO() diff --git a/python/moose/SBML/readSBML.py b/python/moose/SBML/readSBML.py index 2765c5e045a4d600aea8a23c0398e422c8bd5c96..6a627054181e6d06e26ed7a4e2db2317cd962b25 100644 --- a/python/moose/SBML/readSBML.py +++ b/python/moose/SBML/readSBML.py @@ -10,10 +10,10 @@ ** This program is part of 'MOOSE', the ** Messaging Object Oriented Simulation Environment, ** also known as GENESIS 3 base code. -** copyright (C) 2003-2016 Upinder S. Bhalla. and NCBS +** copyright (C) 2003-2017 Upinder S. Bhalla. and NCBS Created : Thu May 12 10:19:00 2016(+0530) Version -Last-Updated: Wed Sep 28 +Last-Updated: Tue Feb 10 2017 By: **********************************************************************/ @@ -23,8 +23,8 @@ import sys import os.path import collections import moose - - +from validation import validateModel +import re ''' TODO in -Compartment @@ -57,13 +57,13 @@ try: except ImportError: pass - def mooseReadSBML(filepath, loadpath, solver="ee"): global foundLibSBML_ if not foundLibSBML_: print('No python-libsbml found.' '\nThis module can be installed by following command in terminal:' - '\n\t easy_install python-libsbl' + '\n\t easy_install python-libsbml' + '\n\t apt-get install python-libsbml' ) return None @@ -74,12 +74,9 @@ def mooseReadSBML(filepath, loadpath, solver="ee"): with open(filepath, "r") as filep: filep = open(filepath, "r") document = libsbml.readSBML(filepath) - num_errors = document.getNumErrors() - if (num_errors > 0): - print("Encountered the following SBML errors:") - document.printErrors() - return moose.element('/') - else: + tobecontinue = False + tobecontinue = validateModel(document) + if tobecontinue: level = document.getLevel() version = document.getVersion() print(("\n" + "File: " + filepath + " (Level " + @@ -120,17 +117,19 @@ def mooseReadSBML(filepath, loadpath, solver="ee"): return moose.element('/') else: baseId = moose.Neutral(loadpath) + basePath = baseId # All the model will be created under model as # a thumbrule - basePath = moose.Neutral( - baseId.path + '/model') + basePath = moose.Neutral(baseId.path + '/model') # Map Compartment's SBML id as key and value is # list of[ Moose ID and SpatialDimensions ] global comptSbmlidMooseIdMap global warning warning = " " + global msg + msg = " " comptSbmlidMooseIdMap = {} - print(("modelPath:" + basePath.path)) + #print(("modelPath:" + basePath.path)) globparameterIdValue = {} modelAnnotaInfo = {} mapParameter(model, globparameterIdValue) @@ -138,8 +137,10 @@ def mooseReadSBML(filepath, loadpath, solver="ee"): basePath, model, comptSbmlidMooseIdMap) if errorFlag: specInfoMap = {} - errorFlag = createSpecies( + errorFlag,warning = createSpecies( basePath, model, comptSbmlidMooseIdMap, specInfoMap, modelAnnotaInfo) + #print(errorFlag,warning) + if errorFlag: errorFlag = createRules( model, specInfoMap, globparameterIdValue) @@ -148,7 +149,7 @@ def mooseReadSBML(filepath, loadpath, solver="ee"): model, specInfoMap, modelAnnotaInfo, globparameterIdValue) getModelAnnotation( model, baseId, basePath) - + if not errorFlag: print(msg) # Any time in the middle if SBML does not read then I @@ -157,7 +158,11 @@ def mooseReadSBML(filepath, loadpath, solver="ee"): # built which is not correct print "Deleted rest of the # model" moose.delete(basePath) - return baseId + basePath = moose.Shell('/') + return basePath + else: + print("Validation failed while reading the model.") + return moose.element('/') def setupEnzymaticReaction(enz, groupName, enzName, @@ -168,7 +173,6 @@ def setupEnzymaticReaction(enz, groupName, enzName, cplx = (modelAnnotaInfo[groupName]["complex"]) cplx = str(idBeginWith(cplx)) complx = moose.element(specInfoMap[cplx]["Mpath"].path) - enzyme_ = moose.Enz(enzParent.path + '/' + enzName) moose.move(complx, enzyme_) moose.connect(enzyme_, "cplx", complx, "reac") @@ -284,7 +288,7 @@ def getModelAnnotation(obj, baseId, basepath): for plots in plotlist: plots = plots.replace(" ", "") plotorg = plots - if moose.exists(basepath.path + plotorg): + if( moose.exists(basepath.path + plotorg) and isinstance(moose.element(basepath.path+plotorg),moose.PoolBase)) : plotSId = moose.element( basepath.path + plotorg) # plotorg = convertSpecialChar(plotorg) @@ -299,8 +303,7 @@ def getModelAnnotation(obj, baseId, basepath): if not fullPath in tablelistname: tab = moose.Table2(fullPath) tablelistname.append(fullPath) - moose.connect( - tab, "requestOut", plotSId, "getConc") + moose.connect(tab, "requestOut", plotSId, "getConc") def getObjAnnotation(obj, modelAnnotationInfo): @@ -333,6 +336,8 @@ def getObjAnnotation(obj, modelAnnotationInfo): annotateMap[nodeName] = nodeValue if nodeName == "textColor": annotateMap[nodeName] = nodeValue + if nodeName == "Group": + annotateMap[nodeName] = nodeValue return annotateMap @@ -457,7 +462,14 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue): for ritem in range(0, model.getNumReactions()): reactionCreated = False groupName = "" + reac = model.getReaction(ritem) + group = "" + reacAnnoInfo = {} + reacAnnoInfo = getObjAnnotation(reac, modelAnnotaInfo) + if "Group" in reacAnnoInfo: + group = reacAnnoInfo["Group"] + if (reac.isSetId()): rId = reac.getId() if (reac.isSetName()): @@ -509,9 +521,7 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue): nummodifiers = reac.getNumModifiers() if not (numRcts and numPdts): - print( - rName, - " : Substrate and Product is missing, we will be skiping creating this reaction in MOOSE") + print("Warning: %s" %(rName)," : Substrate or Product is missing, we will be skiping creating this reaction in MOOSE") reactionCreated = False elif (reac.getNumModifiers() > 0): reactionCreated, reaction_ = setupMMEnzymeReaction( @@ -529,6 +539,11 @@ def createReaction(model, specInfoMap, modelAnnotaInfo, globparameterIdValue): sp = react.getSpecies() sp = str(idBeginWith(sp)) speCompt = specInfoMap[sp]["comptId"].path + if group: + if moose.exists(speCompt+'/'+group): + speCompt = speCompt+'/'+group + else: + speCompt = (moose.Neutral(speCompt+'/'+group)).path reaction_ = moose.Reac(speCompt + '/' + rName) reactionCreated = True reactSBMLIdMooseId[rName] = { @@ -758,10 +773,12 @@ def createRules(model, specInfoMap, globparameterIdValue): exp = rule.getFormula() for mem in ruleMemlist: if (mem in specInfoMap): - exp1 = exp.replace(mem, str(speFunXterm[mem])) + #exp1 = exp.replace(mem, str(speFunXterm[mem])) + exp1 = re.sub(r'\b%s\b'% (mem), speFunXterm[mem], exp) exp = exp1 elif(mem in globparameterIdValue): - exp1 = exp.replace(mem, str(globparameterIdValue[mem])) + #exp1 = exp.replace(mem, str(globparameterIdValue[mem])) + exp1 = re.sub(r'\b%s\b'% (mem), globparameterIdValue[mem], exp) exp = exp1 else: print("Math expression need to be checked") @@ -805,12 +822,17 @@ def createSpecies(basePath, model, comptSbmlidMooseIdMap, # - Need to add group name if exist in pool # - Notes # print "species " - if not (model.getNumSpecies()): - return False + return (False,"number of species is zero") else: for sindex in range(0, model.getNumSpecies()): spe = model.getSpecies(sindex) + group = "" + specAnnoInfo = {} + specAnnoInfo = getObjAnnotation(spe, modelAnnotaInfo) + if "Group" in specAnnoInfo: + group = specAnnoInfo["Group"] + sName = None sId = spe.getId() if spe.isSetName(): @@ -829,7 +851,11 @@ def createSpecies(basePath, model, comptSbmlidMooseIdMap, hasonlySubUnit = spe.getHasOnlySubstanceUnits() # "false": is {unit of amount}/{unit of size} (i.e., concentration or density). # "true": then the value is interpreted as having a unit of amount only. - + if group: + if moose.exists(comptEl+'/'+group): + comptEl = comptEl+'/'+group + else: + comptEl = (moose.Neutral(comptEl+'/'+group)).path if (boundaryCondition): poolId = moose.BufPool(comptEl + '/' + sName) else: @@ -837,13 +863,13 @@ def createSpecies(basePath, model, comptSbmlidMooseIdMap, if (spe.isSetNotes): pullnotes(spe, poolId) - specAnnoInfo = {} - specAnnoInfo = getObjAnnotation(spe, modelAnnotaInfo) + if specAnnoInfo: if not moose.exists(poolId.path + '/info'): poolInfo = moose.Annotator(poolId.path + '/info') else: poolInfo = moose.element(poolId.path + '/info') + for k, v in list(specAnnoInfo.items()): if k == 'xCord': poolInfo.x = float(v) @@ -876,8 +902,7 @@ def createSpecies(basePath, model, comptSbmlidMooseIdMap, initvalue = initvalue * unitfactor elif spe.isSetInitialConcentration(): initvalue = spe.getInitialConcentration() - print( - " Since hasonlySubUnit is true and concentration is set units are not checked") + print(" Since hasonlySubUnit is true and concentration is set units are not checked") poolId.nInit = initvalue elif hasonlySubUnit == False: @@ -885,8 +910,7 @@ def createSpecies(basePath, model, comptSbmlidMooseIdMap, if spe.isSetInitialAmount(): initvalue = spe.getInitialAmount() # initAmount is set we need to convert to concentration - initvalue = initvalue / \ - comptSbmlidMooseIdMap[comptId]["size"] + initvalue = initvalue / comptSbmlidMooseIdMap[comptId]["size"] elif spe.isSetInitialConcentration(): initvalue = spe.getInitialConcentration() @@ -907,13 +931,14 @@ def createSpecies(basePath, model, comptSbmlidMooseIdMap, if (rule_variable == sId): found = True break + if not (found): print( "Invalid SBML: Either initialConcentration or initialAmount must be set or it should be found in assignmentRule but non happening for ", sName) - return False + return (False,"Invalid SBML: Either initialConcentration or initialAmount must be set or it should be found in assignmentRule but non happening for ",sName) - return True + return (True," ") def transformUnit(unitForObject, hasonlySubUnit=False): @@ -995,7 +1020,7 @@ def createCompartment(basePath, model, comptSbmlidMooseIdMap): # ToDoList : Check what should be done for the spaitialdimension is 2 or # 1, area or length if not(model.getNumCompartments()): - return False + return False, else: for c in range(0, model.getNumCompartments()): compt = model.getCompartment(c) @@ -1115,19 +1140,25 @@ def findCompartment(element): return element if __name__ == "__main__": - - filepath = sys.argv[1] - path = sys.argv[2] - - f = open(filepath, 'r') - - if path == '': - loadpath = filepath[filepath.rfind('/'):filepath.find('.')] - else: - loadpath = path - - read = mooseReadSBML(filepath, loadpath) - if read: - print(" Read to path", loadpath) + try: + sys.argv[1] + except IndexError: + print("Filename or path not given") + exit(0) else: - print(" could not read SBML to MOOSE") + filepath = sys.argv[1] + if not os.path.exists(filepath): + print("Filename or path does not exist",filepath) + + else: + try: + sys.argv[2] + except : + modelpath = filepath[filepath.rfind('/'):filepath.find('.')] + else: + modelpath = sys.argv[2] + read = mooseReadSBML(filepath, modelpath) + if read: + print(" Model read to moose path "+ modelpath) + else: + print(" could not read SBML to MOOSE") \ No newline at end of file diff --git a/python/moose/SBML/validation.py b/python/moose/SBML/validation.py new file mode 100644 index 0000000000000000000000000000000000000000..41ab4140b6a1a1ae659d2738fd0471e793756fcb --- /dev/null +++ b/python/moose/SBML/validation.py @@ -0,0 +1,95 @@ +foundLibSBML_ = False +try: + from libsbml import * + foundLibSBML_ = True +except Exception as e: + pass + +def validateModel(sbmlDoc): + if sbmlDoc.getNumErrors() > 0: + tobecontinued = False + for i in range(0,sbmlDoc.getNumErrors()): + print (sbmlDoc.getError(i).getMessage()) + return False + + if (not sbmlDoc): + print("validateModel: given a null SBML Document") + return False + + consistencyMessages = "" + validationMessages = "" + noProblems = True + numCheckFailures = 0 + numConsistencyErrors = 0 + numConsistencyWarnings = 0 + numValidationErrors = 0 + numValidationWarnings = 0 + # Once the whole model is done and before it gets written out, + # it's important to check that the whole model is in fact complete, + # consistent and valid. + numCheckFailures = sbmlDoc.checkInternalConsistency() + if (numCheckFailures > 0): + for i in range(0, numCheckFailures): + sbmlErr = sbmlDoc.getError(i) + if (sbmlErr.isFatal() or sbmlErr.isError()): + noProblems = False + numConsistencyErrors += 1 + else: + numConsistencyWarnings += 1 + constStr = sbmlDoc.printErrors() + if sbmlDoc.printErrors(): + consistencyMessages = constStr + + # If the internal checks fail, it makes little sense to attempt + # further validation, because the model may be too compromised to + # be properly interpreted. + + if (numConsistencyErrors > 0): + consistencyMessages += "Further validation aborted." + else: + numCheckFailures = sbmlDoc.checkConsistency() + validationMessages; + #numCheckFailures = sbmlDoc.checkL3v1Compatibility() + if (numCheckFailures > 0): + for i in range(0, (numCheckFailures)): + consistencyMessages = sbmlDoc.getErrorLog().toString() + sbmlErr = sbmlDoc.getError(i) + if (sbmlErr.isFatal() or sbmlErr.isError()): + noProblems = False + numValidationErrors += 1 + else: + numValidationWarnings += 1 + + warning = sbmlDoc.getErrorLog().toString() + oss = sbmlDoc.printErrors() + validationMessages = oss + + if (noProblems): + return True + else: + if consistencyMessages is None: + consistencyMessages = "" + if consistencyMessages != "": + print("consistency Warning: " + consistencyMessages) + + if (numConsistencyErrors > 0): + print("ERROR: encountered " +str(numConsistencyErrors) +" consistency error in model " +sbmlDoc.getModel().getId() +"'.") + + if (numConsistencyWarnings > 0): + print("Notice: encountered " +str(numConsistencyWarnings) +" consistency warning in model " +sbmlDoc.getModel().getId() +"'.") + + if (numValidationErrors > 0): + print("ERROR: encountered " + str(numValidationErrors) + " validation error in model " +sbmlDoc.getModel().getId() + "'.") + if (numValidationWarnings > 0): + print("Notice: encountered " +str(numValidationWarnings) +" validation warning in model " +sbmlDoc.getModel().getId() +"'.") + + if validationMessages: + print(validationMessages) + + return False + # return ( numConsistencyErrors == 0 and numValidationErrors == 0, + # consistencyMessages) + +if __name__ == '__main__': + sbmlDoc = libsbml.readSBML('00001-sbml-l3v1.xml') + validateModel(sbmlDoc) diff --git a/python/moose/SBML/writeSBML.py b/python/moose/SBML/writeSBML.py index 3057f1002b3d356114f579a195a97c0804f568b1..90400306877ebe14cb5fccc4e7c42211d648ae20 100644 --- a/python/moose/SBML/writeSBML.py +++ b/python/moose/SBML/writeSBML.py @@ -9,26 +9,28 @@ ** This program is part of 'MOOSE', the ** Messaging Object Oriented Simulation Environment, ** also known as GENESIS 3 base code. -** copyright (C) 2003-2016 Upinder S. Bhalla. and NCBS +** copyright (C) 2003-2017 Upinder S. Bhalla. and NCBS Created : Friday May 27 12:19:00 2016(+0530) Version -Last-Updated: Thursday Oct 27 11:20:00 2016(+0530) - By: +Last-Updated: Wed Jan 11 15:20:00 2017(+0530) + By: **********************************************************************/ /**************************** ''' - -import moose +import sys import re from collections import Counter -import networkx as nx -import matplotlib.pyplot as plt -import sys + +import moose +from validation import validateModel +from moose.chemUtil.chemConnectUtil import * +from moose.chemUtil.graphUtils import * + # ToDo: -# Table should be written -# Group's should be added +# Table should be written +# Group's should be added # boundary condition for buffer pool having assignment statment constant # shd be false @@ -41,12 +43,14 @@ except Exception as e: def mooseWriteSBML(modelpath, filename, sceneitems={}): global foundLibSBML_ + msg = " " if not foundLibSBML_: print('No python-libsbml found.' '\nThis module can be installed by following command in terminal:' - '\n\t easy_install python-libsbl' + '\n\t easy_install python-libsbml or' + '\n\t apt-get install python-libsbml' ) - return -1, msg + return -2, "Could not save the model in to SBML file. \nThis module can be installed by following command in terminal: \n\t easy_install python-libsbml or \n\t apt-get install python-libsbml",'' sbmlDoc = SBMLDocument(3, 1) filepath, filenameExt = os.path.split(filename) @@ -57,12 +61,11 @@ def mooseWriteSBML(modelpath, filename, sceneitems={}): # validatemodel sbmlOk = False - global spe_constTrue, cmin, cmax + global spe_constTrue spe_constTrue = [] global nameList_ nameList_ = [] - - autoCoordinateslayout = False + positionInfoexist = False xmlns = XMLNamespaces() xmlns.add("http://www.sbml.org/sbml/level3/version1") xmlns.add("http://www.moose.ncbs.res.in", "moose") @@ -74,55 +77,57 @@ def mooseWriteSBML(modelpath, filename, sceneitems={}): cremodel_.setExtentUnits("substance") cremodel_.setSubstanceUnits("substance") neutralNotes = "" + specieslist = moose.wildcardFind(modelpath + '/##[ISA=PoolBase]') - neutralPath = getGroupinfo(specieslist[0]) - if moose.exists(neutralPath.path + '/info'): - neutralInfo = moose.element(neutralPath.path + '/info') - neutralNotes = neutralInfo.notes - if neutralNotes != "": - cleanNotes = convertNotesSpecialChar(neutralNotes) - notesString = "<body xmlns=\"http://www.w3.org/1999/xhtml\">\n \t \t" + \ - neutralNotes + "\n\t </body>" - cremodel_.setNotes(notesString) - srcdesConnection = {} - cmin, cmax = 0, 1 + if specieslist: + neutralPath = getGroupinfo(specieslist[0]) + if moose.exists(neutralPath.path + '/info'): + neutralInfo = moose.element(neutralPath.path + '/info') + neutralNotes = neutralInfo.notes + if neutralNotes != "": + cleanNotes = convertNotesSpecialChar(neutralNotes) + notesString = "<body xmlns=\"http://www.w3.org/1999/xhtml\">\n \t \t" + \ + neutralNotes + "\n\t </body>" + cremodel_.setNotes(notesString) + srcdesConnection = {} if not bool(sceneitems): - autoCoordinateslayout = True - srcdesConnection = setupItem(modelpath) - meshEntry = setupMeshObj(modelpath) - cmin, cmax, sceneitems = autoCoordinates( - meshEntry, srcdesConnection) - + meshEntry,xmin,xmax,ymin,ymax,positionInfoexist,sitem = setupMeshObj(modelpath) + #moose.coordinateUtil.setupItem(modelpath,srcdesConnection) + setupItem(modelpath,srcdesConnection) + if not positionInfoexist: + autoCoordinates(meshEntry,srcdesConnection) + writeUnits(cremodel_) modelAnno = writeSimulationAnnotation(modelpath) if modelAnno: cremodel_.setAnnotation(modelAnno) + compartexist = writeCompt(modelpath, cremodel_) - species = writeSpecies( - modelpath, - cremodel_, - sbmlDoc, - sceneitems, - autoCoordinateslayout) - if species: - writeFunc(modelpath, cremodel_) - writeReac(modelpath, cremodel_, sceneitems, autoCoordinateslayout) - writeEnz(modelpath, cremodel_, sceneitems, autoCoordinateslayout) - - consistencyMessages = "" - SBMLok = validateModel(sbmlDoc) - if (SBMLok): - writeTofile = filepath + "/" + filename + '.xml' - writeSBMLToFile(sbmlDoc, writeTofile) - return True, consistencyMessages, writeTofile - - if (not SBMLok): - cerr << "Errors encountered " << endl - return -1, consistencyMessages - - -def writeEnz(modelpath, cremodel_, sceneitems, autoCoordinateslayout): + if compartexist == True: + species = writeSpecies( modelpath,cremodel_,sbmlDoc,sceneitems) + if species: + writeFunc(modelpath, cremodel_) + writeReac(modelpath, cremodel_, sceneitems) + writeEnz(modelpath, cremodel_, sceneitems) + consistencyMessages = "" + SBMLok = validateModel(sbmlDoc) + if (SBMLok): + writeTofile = filepath + "/" + filename + '.xml' + writeSBMLToFile(sbmlDoc, writeTofile) + return True, consistencyMessages, writeTofile + + if (not SBMLok): + cerr << "Errors encountered " << endl + return -1, consistencyMessages + else: + return False, "Atleast one compartment should exist to write SBML" + +def calPrime(x): + prime = int((20 * (float(x - cmin) / float(cmax - cmin))) - 10) + return prime + +def writeEnz(modelpath, cremodel_, sceneitems): for enz in moose.wildcardFind(modelpath + '/##[ISA=EnzBase]'): enzannoexist = False enzGpnCorCol = " " @@ -135,25 +140,26 @@ def writeEnz(modelpath, cremodel_, sceneitems, autoCoordinateslayout): notesE = Anno.notes element = moose.element(enz) ele = getGroupinfo(element) - if ele.className == "Neutral" or sceneitems[ - element] or Anno.color or Anno.textColor: - enzannoexist = True - + if element.className == "Neutral" or sceneitems or Anno.x or Anno.y: + enzannoexist = True if enzannoexist: + enzAnno = "<moose:ModelAnnotation>\n" if ele.className == "Neutral": - enzGpnCorCol = "<moose:Group> " + ele.name + " </moose:Group>\n" - if sceneitems[element]: - v = sceneitems[element] - if autoCoordinateslayout == False: - enzGpnCorCol = enzGpnCorCol + "<moose:xCord>" + \ - str(v['x']) + "</moose:xCord>\n" + \ - "<moose:yCord>" + str(v['y']) + "</moose:yCord>\n" - elif autoCoordinateslayout == True: - x = calPrime(v['x']) - y = calPrime(v['y']) - enzGpnCorCol = enzGpnCorCol + "<moose:xCord>" + \ - str(x) + "</moose:xCord>\n" + \ - "<moose:yCord>" + str(y) + "</moose:yCord>\n" + enzGpnCorCol = "<moose:Group>" + ele.name + "</moose:Group>\n" + if sceneitems: + #Saved from GUI, then scene co-ordinates are passed + enzGpnCorCol = enzGpnCorCol + "<moose:xCord>" + \ + str(sceneitems[enz]['x']) + "</moose:xCord>\n" + \ + "<moose:yCord>" + \ + str(sceneitems[enz]['y'])+ "</moose:yCord>\n" + else: + #Saved from cmdline,genesis coordinates are kept as its + # SBML, cspace, python, then auto-coordinates are done + #and coordinates are updated in moose Annotation field + enzGpnCorCol = enzGpnCorCol + "<moose:xCord>" + \ + str(Anno.x) + "</moose:xCord>\n" + \ + "<moose:yCord>" + \ + str(Anno.y)+ "</moose:yCord>\n" if Anno.color: enzGpnCorCol = enzGpnCorCol + "<moose:bgColor>" + Anno.color + "</moose:bgColor>\n" if Anno.textColor: @@ -501,7 +507,7 @@ def listofname(reacSub, mobjEnz): nameList_.append(clean_name) -def writeReac(modelpath, cremodel_, sceneitems, autoCoordinateslayout): +def writeReac(modelpath, cremodel_, sceneitems): for reac in moose.wildcardFind(modelpath + '/##[ISA=ReacBase]'): reacSub = reac.neighbors["sub"] reacPrd = reac.neighbors["prd"] @@ -537,34 +543,34 @@ def writeReac(modelpath, cremodel_, sceneitems, autoCoordinateslayout): reaction.setNotes(notesStringR) element = moose.element(reac) ele = getGroupinfo(element) - if ele.className == "Neutral" or sceneitems[ - element] or Anno.color or Anno.textColor: + if element.className == "Neutral" or sceneitems or Anno.x or Anno.y: reacannoexist = True if reacannoexist: reacAnno = "<moose:ModelAnnotation>\n" if ele.className == "Neutral": reacAnno = reacAnno + "<moose:Group>" + ele.name + "</moose:Group>\n" - if sceneitems[element]: - v = sceneitems[element] - if autoCoordinateslayout == False: - reacAnno = reacAnno + "<moose:xCord>" + \ - str(v['x']) + "</moose:xCord>\n" + \ + if sceneitems: + #Saved from GUI, then scene co-ordinates are passed + reacAnno = reacAnno + "<moose:xCord>" + \ + str(sceneitems[reac]['x']) + "</moose:xCord>\n" + \ + "<moose:yCord>" + \ + str(sceneitems[reac]['y'])+ "</moose:yCord>\n" + else: + #Saved from cmdline,genesis coordinates are kept as its + # SBML, cspace, python, then auto-coordinates are done + #and coordinates are updated in moose Annotation field + reacAnno = reacAnno + "<moose:xCord>" + \ + str(Anno.x) + "</moose:xCord>\n" + \ "<moose:yCord>" + \ - str(v['y']) + "</moose:yCord>\n" - elif autoCoordinateslayout == True: - x = calPrime(v['x']) - y = calPrime(v['y']) - reacAnno = reacAnno + "<moose:xCord>" + \ - str(x) + "</moose:xCord>\n" + \ - "<moose:yCord>" + str(y) + "</moose:yCord>\n" + str(Anno.y)+ "</moose:yCord>\n" if Anno.color: reacAnno = reacAnno + "<moose:bgColor>" + Anno.color + "</moose:bgColor>\n" if Anno.textColor: reacAnno = reacAnno + "<moose:textColor>" + \ Anno.textColor + "</moose:textColor>\n" reacAnno = reacAnno + "</moose:ModelAnnotation>" - # s1.appendAnnotation(XMLNode.convertStringToXMLNode(speciAnno)) reaction.setAnnotation(reacAnno) + kl_s, sRL, pRL, compt = "", "", "", "" if not reacSub and not reacPrd: @@ -712,8 +718,7 @@ def convertSpecialChar(str1): return str1 -def writeSpecies(modelpath, cremodel_, sbmlDoc, - sceneitems, autoCoordinateslayout): +def writeSpecies(modelpath, cremodel_, sbmlDoc, sceneitems): # getting all the species for spe in moose.wildcardFind(modelpath + '/##[ISA=PoolBase]'): sName = convertSpecialChar(spe.name) @@ -785,28 +790,29 @@ def writeSpecies(modelpath, cremodel_, sbmlDoc, cleanNotesS + "\n\t </body>" s1.setNotes(notesStringS) + element = moose.element(spe) ele = getGroupinfo(element) - if ele.className == "Neutral" or sceneitems[ - element] or Anno.color or Anno.textColor: + if element.className == "Neutral" or Anno.color or Anno.textColor or sceneitems or Anno.x or Anno.y: speciannoexist = True if speciannoexist: speciAnno = "<moose:ModelAnnotation>\n" if ele.className == "Neutral": speciAnno = speciAnno + "<moose:Group>" + ele.name + "</moose:Group>\n" - if sceneitems[element]: - v = sceneitems[element] - if autoCoordinateslayout == False: - speciAnno = speciAnno + "<moose:xCord>" + \ - str(v['x']) + "</moose:xCord>\n" + \ + if sceneitems: + #Saved from GUI, then scene co-ordinates are passed + speciAnno = speciAnno + "<moose:xCord>" + \ + str(sceneitems[spe]['x']) + "</moose:xCord>\n" + \ + "<moose:yCord>" + \ + str(sceneitems[spe]['y'])+ "</moose:yCord>\n" + else: + #Saved from cmdline,genesis coordinates are kept as its + # SBML, cspace, python, then auto-coordinates are done + #and coordinates are updated in moose Annotation field + speciAnno = speciAnno + "<moose:xCord>" + \ + str(Anno.x) + "</moose:xCord>\n" + \ "<moose:yCord>" + \ - str(v['y']) + "</moose:yCord>\n" - elif autoCoordinateslayout == True: - x = calPrime(v['x']) - y = calPrime(v['y']) - speciAnno = speciAnno + "<moose:xCord>" + \ - str(x) + "</moose:xCord>\n" + \ - "<moose:yCord>" + str(y) + "</moose:yCord>\n" + str(Anno.y)+ "</moose:yCord>\n" if Anno.color: speciAnno = speciAnno + "<moose:bgColor>" + Anno.color + "</moose:bgColor>\n" if Anno.textColor: @@ -819,7 +825,8 @@ def writeSpecies(modelpath, cremodel_, sbmlDoc, def writeCompt(modelpath, cremodel_): # getting all the compartments - for compt in moose.wildcardFind(modelpath + '/##[ISA=ChemCompt]'): + compts = moose.wildcardFind(modelpath + '/##[ISA=ChemCompt]') + for compt in compts: comptName = convertSpecialChar(compt.name) # converting m3 to litre size = compt.volume * pow(10, 3) @@ -836,7 +843,10 @@ def writeCompt(modelpath, cremodel_): c1.setSize(size) c1.setSpatialDimensions(ndim) c1.setUnits('volume') - + if compts: + return True + else: + return False # write Simulation runtime,simdt,plotdt def writeSimulationAnnotation(modelpath): modelAnno = "" @@ -867,18 +877,17 @@ def writeSimulationAnnotation(modelpath): graphSpefound = True if graphSpefound: if not plots: - #plots = ori[ori.find(q.name)-1:len(ori)] - plots = '/' + q.name + '/' + name + plots = ori[ori.find(q.name)-1:len(ori)] + #plots = '/' + q.name + '/' + name else: - #plots = plots + "; "+ori[ori.find(q.name)-1:len(ori)] - plots = plots + "; /" + q.name + '/' + name + plots = plots + "; "+ori[ori.find(q.name)-1:len(ori)] + #plots = plots + "; /" + q.name + '/' + name if plots != " ": modelAnno = modelAnno + "<moose:plots> " + plots + "</moose:plots>\n" modelAnno = modelAnno + "</moose:ModelAnnotation>" return modelAnno - def writeUnits(cremodel_): unitVol = cremodel_.createUnitDefinition() unitVol.setId("volume") @@ -896,357 +905,28 @@ def writeUnits(cremodel_): unit.setExponent(1.0) unit.setScale(-3) - -def validateModel(sbmlDoc): - # print " sbmlDoc ",sbmlDoc.toSBML() - if (not sbmlDoc): - print("validateModel: given a null SBML Document") - return False - consistencyMessages = "" - validationMessages = "" - noProblems = True - numCheckFailures = 0 - numConsistencyErrors = 0 - numConsistencyWarnings = 0 - numValidationErrors = 0 - numValidationWarnings = 0 - # Once the whole model is done and before it gets written out, - # it's important to check that the whole model is in fact complete, - # consistent and valid. - numCheckFailures = sbmlDoc.checkInternalConsistency() - if (numCheckFailures > 0): - noProblems = False - for i in range(0, numCheckFailures): - sbmlErr = sbmlDoc.getError(i) - if (sbmlErr.isFatal() or sbmlErr.isError()): - numConsistencyErrors += 1 - else: - numConsistencyWarnings += 1 - constStr = sbmlDoc.printErrors() - consistencyMessages = constStr - - # If the internal checks fail, it makes little sense to attempt - # further validation, because the model may be too compromised to - # be properly interpreted. - if (numConsistencyErrors > 0): - consistencyMessages += "Further validation aborted." - else: - numCheckFailures = sbmlDoc.checkConsistency() - #numCheckFailures = sbmlDoc.checkL3v1Compatibility() - if (numCheckFailures > 0): - noProblems = False - for i in range(0, (numCheckFailures)): - consistencyMessages = sbmlDoc.getErrorLog().toString() - sbmlErr = sbmlDoc.getError(i) - if (sbmlErr.isFatal() or sbmlErr.isError()): - numValidationErrors += 1 - else: - numValidationWarnings += 1 - warning = sbmlDoc.getErrorLog().toString() - oss = sbmlDoc.printErrors() - validationMessages = oss - if (noProblems): - return True - else: - if consistencyMessages is None: - consistencyMessages = "" - if consistencyMessages != "": - print(" consistency Warning: " + consistencyMessages) - - if (numConsistencyErrors > 0): - if numConsistencyErrors == 1: - t = "" - else: - t = "s" - print( - "ERROR: encountered " + - numConsistencyErrors + - " consistency error" + - t + - " in model '" + - sbmlDoc.getModel().getId() + - "'.") - if (numConsistencyWarnings > 0): - if numConsistencyWarnings == 1: - t1 = "" - else: - t1 = "s" - print( - "Notice: encountered " + - numConsistencyWarnings + - " consistency warning" + - t + - " in model '" + - sbmlDoc.getModel().getId() + - "'.") - - if (numValidationErrors > 0): - if numValidationErrors == 1: - t2 = "" - else: - t2 = "s" - print( - "ERROR: encountered " + - numValidationErrors + - " validation error" + - t2 + - " in model '" + - sbmlDoc.getModel().getId() + - "'.") - if (numValidationWarnings > 0): - if numValidationWarnings == 1: - t3 = "" - else: - t3 = "s" - - print( - "Notice: encountered " + - numValidationWarnings + - " validation warning" + - t3 + - " in model '" + - sbmlDoc.getModel().getId() + - "'.") - - print(validationMessages) - return (numConsistencyErrors == 0 and numValidationErrors == 0) - # return ( numConsistencyErrors == 0 and numValidationErrors == 0, - # consistencyMessages) - - -def setupItem(modelPath): - '''This function collects information of what is connected to what. \ - eg. substrate and product connectivity to reaction's and enzyme's \ - sumtotal connectivity to its pool are collected ''' - # print " setupItem" - sublist = [] - prdlist = [] - cntDict = {} - zombieType = ['ReacBase', 'EnzBase', 'Function', 'StimulusTable'] - for baseObj in zombieType: - path = '/##[ISA=' + baseObj + ']' - if modelPath != '/': - path = modelPath + path - if ((baseObj == 'ReacBase') or (baseObj == 'EnzBase')): - for items in moose.wildcardFind(path): - sublist = [] - prdlist = [] - uniqItem, countuniqItem = countitems(items, 'subOut') - subNo = uniqItem - for sub in uniqItem: - sublist.append((moose.element(sub), 's', countuniqItem[sub])) - - uniqItem, countuniqItem = countitems(items, 'prd') - prdNo = uniqItem - if (len(subNo) == 0 or len(prdNo) == 0): - print("Substrate Product is empty ", " ", items) - for prd in uniqItem: - prdlist.append((moose.element(prd), 'p', countuniqItem[prd])) - - if (baseObj == 'CplxEnzBase'): - uniqItem, countuniqItem = countitems(items, 'toEnz') - for enzpar in uniqItem: - sublist.append( - (moose.element(enzpar), 't', countuniqItem[enzpar])) - - uniqItem, countuniqItem = countitems(items, 'cplxDest') - for cplx in uniqItem: - prdlist.append( - (moose.element(cplx), 'cplx', countuniqItem[cplx])) - - if (baseObj == 'EnzBase'): - uniqItem, countuniqItem = countitems(items, 'enzDest') - for enzpar in uniqItem: - sublist.append( - (moose.element(enzpar), 't', countuniqItem[enzpar])) - cntDict[items] = sublist, prdlist - elif baseObj == 'Function': - for items in moose.wildcardFind(path): - sublist = [] - prdlist = [] - item = items.path + '/x[0]' - uniqItem, countuniqItem = countitems(item, 'input') - for funcpar in uniqItem: - sublist.append( - (moose.element(funcpar), 'sts', countuniqItem[funcpar])) - - uniqItem, countuniqItem = countitems(items, 'valueOut') - for funcpar in uniqItem: - prdlist.append( - (moose.element(funcpar), 'stp', countuniqItem[funcpar])) - cntDict[items] = sublist, prdlist - else: - for tab in moose.wildcardFind(path): - tablist = [] - uniqItem, countuniqItem = countitems(tab, 'output') - for tabconnect in uniqItem: - tablist.append( - (moose.element(tabconnect), 'tab', countuniqItem[tabconnect])) - cntDict[tab] = tablist - return cntDict - - -def countitems(mitems, objtype): - items = [] - # print "mitems in countitems ",mitems,objtype - items = moose.element(mitems).neighbors[objtype] - uniqItems = set(items) - countuniqItems = Counter(items) - return(uniqItems, countuniqItems) - - -def setupMeshObj(modelRoot): - ''' Setup compartment and its members pool,reaction,enz cplx under self.meshEntry dictionaries \ - self.meshEntry with "key" as compartment, - value is key2:list where key2 represents moose object type,list of objects of a perticular type - e.g self.meshEntry[meshEnt] = { 'reaction': reaction_list,'enzyme':enzyme_list,'pool':poollist,'cplx': cplxlist } - ''' - meshEntry = {} - if meshEntry: - meshEntry.clear() +if __name__ == "__main__": + try: + sys.argv[1] + except IndexError: + print("Filename or path not given") + exit(0) else: - meshEntry = {} - meshEntryWildcard = '/##[ISA=ChemCompt]' - if modelRoot != '/': - meshEntryWildcard = modelRoot + meshEntryWildcard - for meshEnt in moose.wildcardFind(meshEntryWildcard): - mollist = [] - cplxlist = [] - mol_cpl = moose.wildcardFind(meshEnt.path + '/##[ISA=PoolBase]') - funclist = moose.wildcardFind(meshEnt.path + '/##[ISA=Function]') - enzlist = moose.wildcardFind(meshEnt.path + '/##[ISA=EnzBase]') - realist = moose.wildcardFind(meshEnt.path + '/##[ISA=ReacBase]') - tablist = moose.wildcardFind(meshEnt.path + '/##[ISA=StimulusTable]') - if mol_cpl or funclist or enzlist or realist or tablist: - for m in mol_cpl: - if isinstance(moose.element(m.parent), moose.CplxEnzBase): - cplxlist.append(m) - elif isinstance(moose.element(m), moose.PoolBase): - mollist.append(m) - - meshEntry[meshEnt] = {'enzyme': enzlist, - 'reaction': realist, - 'pool': mollist, - 'cplx': cplxlist, - 'table': tablist, - 'function': funclist - } - return(meshEntry) - - -def autoCoordinates(meshEntry, srcdesConnection): - G = nx.Graph() - for cmpt, memb in list(meshEntry.items()): - for enzObj in find_index(memb, 'enzyme'): - G.add_node( - enzObj.path, - label='', - shape='ellipse', - color='', - style='filled', - fontname='Helvetica', - fontsize=12, - fontcolor='blue') - for cmpt, memb in list(meshEntry.items()): - for poolObj in find_index(memb, 'pool'): - #poolinfo = moose.element(poolObj.path+'/info') - G.add_node( - poolObj.path, - label=poolObj.name, - shape='box', - color='', - style='filled', - fontname='Helvetica', - fontsize=12, - fontcolor='blue') - for cplxObj in find_index(memb, 'cplx'): - pass - for reaObj in find_index(memb, 'reaction'): - G.add_node(reaObj.path, label='', shape='record', color='') - - for inn, out in list(srcdesConnection.items()): - if (inn.className == 'ZombieReac'): - arrowcolor = 'green' - elif(inn.className == 'ZombieEnz'): - arrowcolor = 'red' + filepath = sys.argv[1] + if not os.path.exists(filepath): + print("Filename or path does not exist",filepath) else: - arrowcolor = 'blue' - if isinstance(out, tuple): - if len(out[0]) == 0: - print( - inn.className + - ':' + - inn.name + - " doesn't have input message") + try: + sys.argv[2] + except : + modelpath = filepath[filepath.rfind('/'):filepath.find('.')] else: - for items in (items for items in out[0]): - G.add_edge(moose.element(items[0]).path, inn.path) - - if len(out[1]) == 0: - print( - inn.className + - ':' + - inn.name + - "doesn't have output mssg") - else: - for items in (items for items in out[1]): - G.add_edge(inn.path, moose.element(items[0]).path) + modelpath = sys.argv[2] + + moose.loadModel(filepath, modelpath, "gsl") - elif isinstance(out, list): - if len(out) == 0: - print("Func pool doesn't have sumtotal") + written, c, writtentofile = mooseWriteSBML(modelpath, filepath) + if written: + print(" File written to ", writtentofile) else: - for items in (items for items in out): - G.add_edge(moose.element(items[0]).path, inn.path) - #from networkx.drawing.nx_agraph import graphviz_layout - #position = graphviz_layout(G,prog='dot') - - position = nx.pygraphviz_layout(G, prog='dot') - position = nx.spring_layout(G) - #agraph = nx.to_agraph(G) - #agraph.draw("~/out.png", format = 'png', prog = 'dot') - - sceneitems = {} - xycord = [] - cmin = 0 - cmax = 0 - for key, value in list(position.items()): - xycord.append(value[0]) - xycord.append(value[1]) - sceneitems[moose.element(key)] = {'x': value[0], 'y': value[1]} - if len(xycord) > 0: - cmin = min(xycord) - cmax = max(xycord) - return cmin, cmax, sceneitems - - -def calPrime(x): - prime = int((20 * (float(x - cmin) / float(cmax - cmin))) - 10) - return prime - - -def find_index(value, key): - """ Value.get(key) to avoid expection which would raise if empty value in dictionary for a given key """ - if value.get(key) is not None: - return value.get(key) - else: - raise ValueError('no dict with the key found') -if __name__ == "__main__": - - filepath = sys.argv[1] - path = sys.argv[2] - - f = open(filepath, 'r') - - if path == '': - loadpath = filepath[filepath.rfind('/'):filepath.find('.')] - else: - loadpath = path - - moose.loadModel(filepath, loadpath, "gsl") - - written, c, writtentofile = mooseWriteSBML(loadpath, filepath) - if written: - print(" File written to ", writtentofile) - else: - print(" could not write model to SBML file") + print(" could not write model to SBML file") diff --git a/python/moose/chemUtil/__init__.py b/python/moose/chemUtil/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..dce7080f0a0f57a421c2428821689fe824ff50a5 --- /dev/null +++ b/python/moose/chemUtil/__init__.py @@ -0,0 +1,3 @@ +from .add_Delete_ChemicalSolver import * +from .chemConnectUtil import * +from .graphUtils import autoCoordinates diff --git a/python/moose/add_Delete_ChemicalSolver.py b/python/moose/chemUtil/add_Delete_ChemicalSolver.py similarity index 94% rename from python/moose/add_Delete_ChemicalSolver.py rename to python/moose/chemUtil/add_Delete_ChemicalSolver.py index f788118b7d20ad116c0a3323330ed20a598a712f..af9437b92dd886e39e4644a60f15579f3f76d525 100644 --- a/python/moose/add_Delete_ChemicalSolver.py +++ b/python/moose/chemUtil/add_Delete_ChemicalSolver.py @@ -1,5 +1,4 @@ -from . import _moose as moose - +import moose def moosedeleteChemSolver(modelRoot): """Delete solvers from Chemical Compartment @@ -25,11 +24,11 @@ def mooseaddChemSolver(modelRoot, solver): comptinfo = moose.Annotator(moose.element(compt[0]).path + '/info') previousSolver = comptinfo.solver currentSolver = previousSolver - if solver == "Gillespie": + if solver == "Gillespie" or solver == "gssa": currentSolver = "gssa" - elif solver == "Runge Kutta": + elif solver == "Runge Kutta" or solver == "gsl": currentSolver = "gsl" - elif solver == "Exponential Euler": + elif solver == "Exponential Euler" or solver == "ee": currentSolver = "ee" if previousSolver != currentSolver: diff --git a/python/moose/chemUtil/chemConnectUtil.py b/python/moose/chemUtil/chemConnectUtil.py new file mode 100644 index 0000000000000000000000000000000000000000..93d8be9d1442970c5ac748184f6743ba6810fc6b --- /dev/null +++ b/python/moose/chemUtil/chemConnectUtil.py @@ -0,0 +1,181 @@ +import moose +import numpy as np +from collections import Counter + +def xyPosition(objInfo,xory): + try: + return(float(moose.element(objInfo).getField(xory))) + except ValueError: + return (float(0)) + +def setupMeshObj(modelRoot): + ''' Setup compartment and its members pool,reaction,enz cplx under self.meshEntry dictionaries \ + self.meshEntry with "key" as compartment, + value is key2:list where key2 represents moose object type,list of objects of a perticular type + e.g self.meshEntry[meshEnt] = { 'reaction': reaction_list,'enzyme':enzyme_list,'pool':poollist,'cplx': cplxlist } + ''' + xmin = 0.0 + xmax = 1.0 + ymin = 0.0 + ymax = 1.0 + listOfitems = {} + positionInfoExist = True + meshEntry = {} + if meshEntry: + meshEntry.clear() + else: + meshEntry = {} + xcord = [] + ycord = [] + meshEntryWildcard = '/##[ISA=ChemCompt]' + if modelRoot != '/': + meshEntryWildcard = modelRoot+meshEntryWildcard + for meshEnt in moose.wildcardFind(meshEntryWildcard): + mollist = [] + realist = [] + enzlist = [] + cplxlist = [] + tablist = [] + funclist = [] + + mol_cpl = moose.wildcardFind(meshEnt.path+'/##[ISA=PoolBase]') + funclist = moose.wildcardFind(meshEnt.path+'/##[ISA=Function]') + enzlist = moose.wildcardFind(meshEnt.path+'/##[ISA=EnzBase]') + realist = moose.wildcardFind(meshEnt.path+'/##[ISA=ReacBase]') + tablist = moose.wildcardFind(meshEnt.path+'/##[ISA=StimulusTable]') + if mol_cpl or funclist or enzlist or realist or tablist: + for m in mol_cpl: + if isinstance(moose.element(m.parent),moose.CplxEnzBase): + cplxlist.append(m) + objInfo = m.parent.path+'/info' + elif isinstance(moose.element(m),moose.PoolBase): + mollist.append(m) + objInfo =m.path+'/info' + if moose.exists(objInfo): + listOfitems[moose.element(moose.element(objInfo).parent)]={'x':xyPosition(objInfo,'x'),'y':xyPosition(objInfo,'y')} + + xcord.append(xyPosition(objInfo,'x')) + ycord.append(xyPosition(objInfo,'y')) + + getxyCord(xcord,ycord,funclist,listOfitems) + getxyCord(xcord,ycord,enzlist,listOfitems) + getxyCord(xcord,ycord,realist,listOfitems) + getxyCord(xcord,ycord,tablist,listOfitems) + + meshEntry[meshEnt] = {'enzyme':enzlist, + 'reaction':realist, + 'pool':mollist, + 'cplx':cplxlist, + 'table':tablist, + 'function':funclist + } + positionInfoExist = not(len(np.nonzero(xcord)[0]) == 0 \ + and len(np.nonzero(ycord)[0]) == 0) + if positionInfoExist: + xmin = min(xcord) + xmax = max(xcord) + ymin = min(ycord) + ymax = max(ycord) + return meshEntry,xmin,xmax,ymin,ymax,positionInfoExist,listOfitems + +def sizeHint(self): + return QtCore.QSize(800,400) + +def getxyCord(xcord,ycord,list1,listOfitems): + for item in list1: + # if isinstance(item,Function): + # objInfo = moose.element(item.parent).path+'/info' + # else: + # objInfo = item.path+'/info' + if not isinstance(item,moose.Function): + objInfo = item.path+'/info' + xcord.append(xyPosition(objInfo,'x')) + ycord.append(xyPosition(objInfo,'y')) + if moose.exists(objInfo): + listOfitems[moose.element(moose.element(objInfo).parent)]={'x':xyPosition(objInfo,'x'),'y':xyPosition(objInfo,'y')} + +def setupItem(modelPath,cntDict): + '''This function collects information of what is connected to what. \ + eg. substrate and product connectivity to reaction's and enzyme's \ + sumtotal connectivity to its pool are collected ''' + #print " setupItem" + sublist = [] + prdlist = [] + zombieType = ['ReacBase','EnzBase','Function','StimulusTable'] + for baseObj in zombieType: + path = '/##[ISA='+baseObj+']' + if modelPath != '/': + path = modelPath+path + if ( (baseObj == 'ReacBase') or (baseObj == 'EnzBase')): + for items in moose.wildcardFind(path): + sublist = [] + prdlist = [] + uniqItem,countuniqItem = countitems(items,'subOut') + subNo = uniqItem + for sub in uniqItem: + sublist.append((moose.element(sub),'s',countuniqItem[sub])) + + uniqItem,countuniqItem = countitems(items,'prd') + prdNo = uniqItem + if (len(subNo) == 0 or len(prdNo) == 0): + print ("Substrate Product is empty ",path, " ",items) + + for prd in uniqItem: + prdlist.append((moose.element(prd),'p',countuniqItem[prd])) + + if (baseObj == 'CplxEnzBase') : + uniqItem,countuniqItem = countitems(items,'toEnz') + for enzpar in uniqItem: + sublist.append((moose.element(enzpar),'t',countuniqItem[enzpar])) + + uniqItem,countuniqItem = countitems(items,'cplxDest') + for cplx in uniqItem: + prdlist.append((moose.element(cplx),'cplx',countuniqItem[cplx])) + + if (baseObj == 'EnzBase'): + uniqItem,countuniqItem = countitems(items,'enzDest') + for enzpar in uniqItem: + sublist.append((moose.element(enzpar),'t',countuniqItem[enzpar])) + cntDict[items] = sublist,prdlist + elif baseObj == 'Function': + for items in moose.wildcardFind(path): + sublist = [] + prdlist = [] + item = items.path+'/x[0]' + uniqItem,countuniqItem = countitems(item,'input') + for funcpar in uniqItem: + sublist.append((moose.element(funcpar),'sts',countuniqItem[funcpar])) + + uniqItem,countuniqItem = countitems(items,'valueOut') + for funcpar in uniqItem: + prdlist.append((moose.element(funcpar),'stp',countuniqItem[funcpar])) + cntDict[items] = sublist,prdlist + + # elif baseObj == 'Function': + # #ZombieSumFunc adding inputs + # inputlist = [] + # outputlist = [] + # funplist = [] + # nfunplist = [] + # for items in moose.wildcardFind(path): + # for funplist in moose.element(items).neighbors['valueOut']: + # for func in funplist: + # funcx = moose.element(items.path+'/x[0]') + # uniqItem,countuniqItem = countitems(funcx,'input') + # for inPut in uniqItem: + # inputlist.append((inPut,'st',countuniqItem[inPut])) + # cntDict[func] = inputlist + else: + for tab in moose.wildcardFind(path): + tablist = [] + uniqItem,countuniqItem = countitems(tab,'output') + for tabconnect in uniqItem: + tablist.append((moose.element(tabconnect),'tab',countuniqItem[tabconnect])) + cntDict[tab] = tablist + +def countitems(mitems,objtype): + items = [] + items = moose.element(mitems).neighbors[objtype] + uniqItems = set(items) + countuniqItems = Counter(items) + return(uniqItems,countuniqItems) \ No newline at end of file diff --git a/python/moose/chemUtil/graphUtils.py b/python/moose/chemUtil/graphUtils.py new file mode 100644 index 0000000000000000000000000000000000000000..5bf05f54ace749c62ded010dc3c05f11efda52c9 --- /dev/null +++ b/python/moose/chemUtil/graphUtils.py @@ -0,0 +1,87 @@ +import moose + +pygraphvizFound_ = True +try: + import pygraphviz as pgv +except Exception as e: + pygraphvizFound_ = False + +def autoCoordinates(meshEntry,srcdesConnection): + global pygraphvizFound_ + positionInfo = {} + + if not pygraphvizFound_: + print( '[warn] python-pygraphviz could not be found.' ) + print( '\tMOOSE Install pygraphviz to use this feature' ) + return positionInfo + + if meshEntry: + #G = nx.Graph() + G = pgv.AGraph() + + for cmpt,memb in list(meshEntry.items()): + for enzObj in find_index(memb,'enzyme'): + #G.add_node(enzObj.path) + G.add_node(enzObj.path,label='',shape='ellipse',color='',style='filled',fontname='Helvetica',fontsize=12,fontcolor='blue') + for cmpt,memb in list(meshEntry.items()): + for poolObj in find_index(memb,'pool'): + #G.add_node(poolObj.path) + G.add_node(poolObj.path,label = poolObj.name,shape = 'box',color = '',style = 'filled',fontname = 'Helvetica',fontsize = 12,fontcolor = 'blue') + for cplxObj in find_index(memb,'cplx'): + G.add_node(cplxObj.path) + G.add_node(cplxObj.path,label = cplxObj.name,shape = 'box',color = '',style = 'filled',fontname = 'Helvetica',fontsize = 12,fontcolor = 'blue') + #G.add_edge((cplxObj.parent).path,cplxObj.path) + for reaObj in find_index(memb,'reaction'): + #G.add_node(reaObj.path) + G.add_node(reaObj.path,label='',shape='circle',color='') + + for inn,out in list(srcdesConnection.items()): + if (inn.className =='ZombieReac'): arrowcolor = 'green' + elif(inn.className =='ZombieEnz'): arrowcolor = 'red' + else: arrowcolor = 'blue' + if isinstance(out,tuple): + if len(out[0])== 0: + print( inn.className + ':' +inn.name + " doesn't have input message") + else: + for items in (items for items in out[0] ): + G.add_edge(moose.element(items[0]).path,inn.path) + if len(out[1]) == 0: + print(inn.className + ':' + inn.name + "doesn't have output mssg") + else: + for items in (items for items in out[1] ): + G.add_edge(inn.path,moose.element(items[0]).path) + elif isinstance(out,list): + if len(out) == 0: + print ("Func pool doesn't have sumtotal") + else: + for items in (items for items in out ): + G.add_edge(moose.element(items[0]).path,inn.path) + + # if int( nx.__version__.split( '.' )[-1] ) >= 11: + # position = nx.spring_layout( G ) + # else: + # position = nx.graphviz_layout(G, prog = 'dot') + # for item in position.items(): + # xy = item[1] + # ann = moose.Annotator(item[0]+'/info') + # ann.x = xy[0] + # ann.y = xy[1] + # positioninfo[(moose.element(item[0]))] ={'x':float(xy[0]),'y':float(xy[1])} + + G.layout() + for n in G.nodes(): + value = str(n.attr['pos']) + valuelist = (value.split(',')) + positionInfo[(moose.element(n))] ={'x':float(valuelist[0]),'y':float(valuelist[1])} + ann = moose.Annotator(moose.element(n).path+'/info') + ann.x = float(valuelist[0]) + ann.y = float(valuelist[1]) + + return positionInfo + +def find_index(value, key): + """ Value.get(key) to avoid expection which would raise if empty value in dictionary for a given key """ + if value.get(key) != None: + return value.get(key) + else: + raise ValueError('no dict with the key found') diff --git a/python/moose/genesis/writeKkit.py b/python/moose/genesis/writeKkit.py index 226fe2a319b000f199357f41a3fac3fdf0f85a73..2bd33e212590cad4216ca54e733b45bde7ad60b3 100644 --- a/python/moose/genesis/writeKkit.py +++ b/python/moose/genesis/writeKkit.py @@ -1,22 +1,27 @@ """ Chemical Signalling model loaded into moose can be save into Genesis-Kkit format """ __author__ = "Harsha Rani" -__copyright__ = "Copyright 2015, Harsha Rani and NCBS Bangalore" +__copyright__ = "Copyright 2017, Harsha Rani and NCBS Bangalore" __credits__ = ["NCBS Bangalore"] __license__ = "GNU GPL" __version__ = "1.0.0" __maintainer__ = "Harsha Rani" __email__ = "hrani@ncbs.res.in" __status__ = "Development" - +__updated__ = "Feb 13 2017" import sys import random -import moose -import numpy as np import re -from collections import Counter -import networkx as nx -import matplotlib +import moose +from moose.chemUtil.chemConnectUtil import * +from moose.chemUtil.graphUtils import * + +foundmatplotlib_ = False +try: + import matplotlib + foundmatplotlib_ = True +except Exception as e: + pass GENESIS_COLOR_SEQUENCE = ((248, 0, 255), (240, 0, 255), (232, 0, 255), (224, 0, 255), (216, 0, 255), (208, 0, 255), (200, 0, 255), (192, 0, 255), (184, 0, 255), (176, 0, 255), (168, 0, 255), (160, 0, 255), (152, 0, 255), (144, 0, 255), @@ -38,264 +43,117 @@ GENESIS_COLOR_SEQUENCE = ((248, 0, 255), (240, 0, 255), (232, 0, 255), (224, 0, #Todo : To be written # --StimulusTable -def mooseWriteKkit( modelpath, filename,sceneitems=None): - if filename.rfind('.') != -1: - filename = filename[:filename.rfind('.')] - else: - filename = filename[:len(filename)] - filename = filename+'.g' - global NA - NA = 6.0221415e23 - global cmin,cmax,xmin,xmax,ymin,ymax - cmin = 0 - cmax = 1 - xmin = 0 - xmax = 1 - ymin = 0 - ymax = 1 - - compt = moose.wildcardFind(modelpath+'/##[ISA=ChemCompt]') - maxVol = estimateDefaultVol(compt) - f = open(filename, 'w') - - if sceneitems == None: - srcdesConnection = {} - setupItem(modelpath,srcdesConnection) - meshEntry = setupMeshObj(modelpath) - cmin,cmax,sceneitems = autoCoordinates(meshEntry,srcdesConnection) - for k,v in list(sceneitems.items()): - v = sceneitems[k] - x1 = calPrime(v['x']) - y1 = calPrime(v['y']) - sceneitems[k]['x'] = x1 - sceneitems[k]['y'] = y1 - else: - cs, xcord, ycord = [], [] ,[] - for k,v in list(sceneitems.items()): - xcord.append(v['x']) - cs.append(v['x']) - ycord.append(v['y']) - cs.append(v['y']) - xmin = min(xcord) - xmax = max(xcord) - ymin = min(ycord) - ymax = max(ycord) - - cmin = min(cs) - cmax = max(cs) - writeHeader (f,maxVol) - - if (compt > 0): - gtId_vol = writeCompartment(modelpath,compt,f) - writePool(modelpath,f,gtId_vol,sceneitems) - reacList = writeReac(modelpath,f,sceneitems) - enzList = writeEnz(modelpath,f,sceneitems) - writeSumtotal(modelpath,f) - f.write("simundump xgraph /graphs/conc1 0 0 99 0.001 0.999 0\n" - "simundump xgraph /graphs/conc2 0 0 100 0 1 0\n") - tgraphs = moose.wildcardFind(modelpath+'/##[ISA=Table2]') - first, second = " ", " " - if tgraphs: - first,second = writeplot(tgraphs,f) - if first: - f.write(first) - f.write("simundump xgraph /moregraphs/conc3 0 0 100 0 1 0\n" - "simundump xgraph /moregraphs/conc4 0 0 100 0 1 0\n") - if second: - f.write(second) - f.write("simundump xcoredraw /edit/draw 0 -6 4 -2 6\n" - "simundump xtree /edit/draw/tree 0 \\\n" - " /kinetics/#[],/kinetics/#[]/#[],/kinetics/#[]/#[]/#[][TYPE!=proto],/kinetics/#[]/#[]/#[][TYPE!=linkinfo]/##[] \"edit_elm.D <v>; drag_from_edit.w <d> <S> <x> <y> <z>\" auto 0.6\n" - "simundump xtext /file/notes 0 1\n") - storeReacMsg(reacList,f) - storeEnzMsg(enzList,f) - if tgraphs: - storePlotMsgs(tgraphs,f) - writeFooter1(f) - writeNotes(modelpath,f) - writeFooter2(f) - return True - else: - print(("Warning: writeKkit:: No model found on " , modelpath)) +def mooseWriteKkit( modelpath, filename, sceneitems={}): + global foundmatplotlib_ + if not foundmatplotlib_: + print('No maplotlib found.' + '\nThis module can be installed by following command in terminal:' + '\n\t sudo apt install python-maplotlib', "") return False - -def calPrime(x): - prime = int((20*(float(x-cmin)/float(cmax-cmin)))-10) - return prime - -def setupItem(modelPath,cntDict): - '''This function collects information of what is connected to what. \ - eg. substrate and product connectivity to reaction's and enzyme's \ - sumtotal connectivity to its pool are collected ''' - #print " setupItem" - sublist = [] - prdlist = [] - zombieType = ['ReacBase','EnzBase','Function','StimulusTable'] - for baseObj in zombieType: - path = '/##[ISA='+baseObj+']' - if modelPath != '/': - path = modelPath+path - if ( (baseObj == 'ReacBase') or (baseObj == 'EnzBase')): - for items in moose.wildcardFind(path): - sublist = [] - prdlist = [] - uniqItem,countuniqItem = countitems(items,'subOut') - subNo = uniqItem - for sub in uniqItem: - sublist.append((moose.element(sub),'s',countuniqItem[sub])) - - uniqItem,countuniqItem = countitems(items,'prd') - prdNo = uniqItem - if (len(subNo) == 0 or len(prdNo) == 0): - print("Substrate Product is empty ",path, " ",items) - - for prd in uniqItem: - prdlist.append((moose.element(prd),'p',countuniqItem[prd])) - - if (baseObj == 'CplxEnzBase') : - uniqItem,countuniqItem = countitems(items,'toEnz') - for enzpar in uniqItem: - sublist.append((moose.element(enzpar),'t',countuniqItem[enzpar])) - - uniqItem,countuniqItem = countitems(items,'cplxDest') - for cplx in uniqItem: - prdlist.append((moose.element(cplx),'cplx',countuniqItem[cplx])) - - if (baseObj == 'EnzBase'): - uniqItem,countuniqItem = countitems(items,'enzDest') - for enzpar in uniqItem: - sublist.append((moose.element(enzpar),'t',countuniqItem[enzpar])) - cntDict[items] = sublist,prdlist - elif baseObj == 'Function': - for items in moose.wildcardFind(path): - sublist = [] - prdlist = [] - item = items.path+'/x[0]' - uniqItem,countuniqItem = countitems(item,'input') - for funcpar in uniqItem: - sublist.append((moose.element(funcpar),'sts',countuniqItem[funcpar])) - - uniqItem,countuniqItem = countitems(items,'valueOut') - for funcpar in uniqItem: - prdlist.append((moose.element(funcpar),'stp',countuniqItem[funcpar])) - cntDict[items] = sublist,prdlist - else: - for tab in moose.wildcardFind(path): - tablist = [] - uniqItem,countuniqItem = countitems(tab,'output') - for tabconnect in uniqItem: - tablist.append((moose.element(tabconnect),'tab',countuniqItem[tabconnect])) - cntDict[tab] = tablist -def countitems(mitems,objtype): - items = [] - items = moose.element(mitems).neighbors[objtype] - uniqItems = set(items) - countuniqItems = Counter(items) - return(uniqItems,countuniqItems) - -def setupMeshObj(modelRoot): - ''' Setup compartment and its members pool,reaction,enz cplx under self.meshEntry dictionaries \ - self.meshEntry with "key" as compartment, - value is key2:list where key2 represents moose object type,list of objects of a perticular type - e.g self.meshEntry[meshEnt] = { 'reaction': reaction_list,'enzyme':enzyme_list,'pool':poollist,'cplx': cplxlist } - ''' - meshEntry = {} - if meshEntry: - meshEntry.clear() else: - meshEntry = {} - meshEntryWildcard = '/##[ISA=ChemCompt]' - if modelRoot != '/': - meshEntryWildcard = modelRoot+meshEntryWildcard - for meshEnt in moose.wildcardFind(meshEntryWildcard): - mollist = [] - cplxlist = [] - mol_cpl = moose.wildcardFind(meshEnt.path+'/##[ISA=PoolBase]') - funclist = moose.wildcardFind(meshEnt.path+'/##[ISA=Function]') - enzlist = moose.wildcardFind(meshEnt.path+'/##[ISA=EnzBase]') - realist = moose.wildcardFind(meshEnt.path+'/##[ISA=ReacBase]') - tablist = moose.wildcardFind(meshEnt.path+'/##[ISA=StimulusTable]') - if mol_cpl or funclist or enzlist or realist or tablist: - for m in mol_cpl: - if isinstance(moose.element(m.parent),moose.CplxEnzBase): - cplxlist.append(m) - elif isinstance(moose.element(m),moose.PoolBase): - mollist.append(m) - - meshEntry[meshEnt] = {'enzyme':enzlist, - 'reaction':realist, - 'pool':mollist, - 'cplx':cplxlist, - 'table':tablist, - 'function':funclist - } - return(meshEntry) -def autoCoordinates(meshEntry,srcdesConnection): - G = nx.Graph() - for cmpt,memb in list(meshEntry.items()): - for enzObj in find_index(memb,'enzyme'): - #G.add_node(enzObj.path) - G.add_node(enzObj.path,label=enzObj.name,shape='ellipse',color='',style='filled',fontname='Helvetica',fontsize=12,fontcolor='blue') - for cmpt,memb in list(meshEntry.items()): - for poolObj in find_index(memb,'pool'): - #G.add_node(poolObj.path) - G.add_node(poolObj.path,label = poolObj.name,shape = 'box',color = '',style = 'filled',fontname = 'Helvetica',fontsize = 12,fontcolor = 'blue') - for cplxObj in find_index(memb,'cplx'): - pass - #G.add_node(cplxObj.path) - #G.add_edge((cplxObj.parent).path,cplxObj.path) - for reaObj in find_index(memb,'reaction'): - #G.add_node(reaObj.path) - G.add_node(reaObj.path,label=reaObj.name,shape='',color='') - for funcObj in find_index(memb,'function'): - G.add_node(poolObj.path,label = funcObj.name,shape = 'box',color = 'red',style = 'filled',fontname = 'Helvetica',fontsize = 12,fontcolor = 'blue') + + ignoreColor= ["mistyrose","antiquewhite","aliceblue","azure","bisque","black","blanchedalmond","blue","cornsilk","darkolivegreen","darkslategray","dimgray","floralwhite","gainsboro","ghostwhite","honeydew","ivory","lavender","lavenderblush","lemonchiffon","lightcyan","lightgoldenrodyellow","lightgray","lightyellow","linen","mediumblue","mintcream","navy","oldlace","papayawhip","saddlebrown","seashell","snow","wheat","white","whitesmoke","aquamarine","lightsalmon","moccasin","limegreen","snow","sienna","beige","dimgrey","lightsage"] + matplotcolor = {} + for name,hexno in matplotlib.colors.cnames.items(): + matplotcolor[name]=hexno + if filename.rfind('.') != -1: + filename = filename[:filename.rfind('.')] + else: + filename = filename[:len(filename)] + filename = filename+'.g' + global NA + NA = 6.0221415e23 + global cmin,cmax,xmin,xmax,ymin,ymax + cmin, xmin, ymin = 0, 0, 0 + cmax, xmax, ymax = 1, 1, 1 - for inn,out in list(srcdesConnection.items()): - if (inn.className =='ZombieReac'): arrowcolor = 'green' - elif(inn.className =='ZombieEnz'): arrowcolor = 'red' - else: arrowcolor = 'blue' - if isinstance(out,tuple): - if len(out[0])== 0: - print(inn.className + ':' +inn.name + " doesn't have input message") - else: - for items in (items for items in out[0] ): - G.add_edge(moose.element(items[0]).path,inn.path) - if len(out[1]) == 0: - print(inn.className + ':' + inn.name + "doesn't have output mssg") - else: - for items in (items for items in out[1] ): - G.add_edge(inn.path,moose.element(items[0]).path) - elif isinstance(out,list): - if len(out) == 0: - print("Func pool doesn't have sumtotal") - else: - for items in (items for items in out ): - G.add_edge(moose.element(items[0]).path,inn.path) - - position = nx.graphviz_layout(G, prog = 'dot') - if int( nx.__version__.split( '.' )[-1] ) >= 11: - position = nx.spring_layout( G ) + compt = moose.wildcardFind(modelpath+'/##[ISA=ChemCompt]') + maxVol = estimateDefaultVol(compt) + positionInfoExist = True + if compt: + if bool(sceneitems): + cmin,cmax,xmin1,xmax1,ymin1,ymax1 = findMinMax(sceneitems) + elif not bool(sceneitems): + srcdesConnection = {} + setupItem(modelpath,srcdesConnection) + meshEntry,xmin,xmax,ymin,ymax,positionInfoExist,sceneitems = setupMeshObj(modelpath) + if not positionInfoExist: + #cmin,cmax,sceneitems = autoCoordinates(meshEntry,srcdesConnection) + sceneitems = autoCoordinates(meshEntry,srcdesConnection) + + if not positionInfoExist: + # if position are not from kkit, then zoom factor is applied while + # writing to genesis. Like if position is from pyqtSceneItem or auto-coordinates + cmin,cmax,xmin1,xmax1,ymin1,ymax1 = findMinMax(sceneitems) + for k,v in list(sceneitems.items()): + anno = moose.element(k.path+'/info') + x1 = calPrime(v['x']) + y1 = calPrime(v['y']) + sceneitems[k]['x'] = x1 + sceneitems[k]['y'] = y1 + + f = open(filename, 'w') + writeHeader (f,maxVol) + + gtId_vol = writeCompartment(modelpath,compt,f) + writePool(modelpath,f,gtId_vol,sceneitems) + reacList = writeReac(modelpath,f,sceneitems) + enzList = writeEnz(modelpath,f,sceneitems) + writeSumtotal(modelpath,f) + f.write("simundump xgraph /graphs/conc1 0 0 99 0.001 0.999 0\n" + "simundump xgraph /graphs/conc2 0 0 100 0 1 0\n") + tgraphs = moose.wildcardFind(modelpath+'/##[ISA=Table2]') + first, second = " ", " " + if tgraphs: + first,second = writeplot(tgraphs,f) + if first: + f.write(first) + f.write("simundump xgraph /moregraphs/conc3 0 0 100 0 1 0\n" + "simundump xgraph /moregraphs/conc4 0 0 100 0 1 0\n") + if second: + f.write(second) + f.write("simundump xcoredraw /edit/draw 0 -6 4 -2 6\n" + "simundump xtree /edit/draw/tree 0 \\\n" + " /kinetics/#[],/kinetics/#[]/#[],/kinetics/#[]/#[]/#[][TYPE!=proto],/kinetics/#[]/#[]/#[][TYPE!=linkinfo]/##[] \"edit_elm.D <v>; drag_from_edit.w <d> <S> <x> <y> <z>\" auto 0.6\n" + "simundump xtext /file/notes 0 1\n") + storeReacMsg(reacList,f) + storeEnzMsg(enzList,f) + if tgraphs: + storePlotMsgs(tgraphs,f) + writeFooter1(f) + writeNotes(modelpath,f) + writeFooter2(f) + print('Written to file '+filename) + return True + else: + print(("Warning: writeKkit:: No model found on " , modelpath)) + return False - #agraph = nx.to_agraph(G) - #agraph.draw("writetogenesis.png", format = 'png', prog = 'dot') - sceneitems = {} +def findMinMax(sceneitems): + cmin = 0.0 + cmax = 1.0 + xmin,xymin = 0.0,0.0 + xmax,xymax = 1.0,1.0 xycord = [] - - for key,value in list(position.items()): - xycord.append(value[0]) - xycord.append(value[1]) - sceneitems[moose.element(key)] = {'x':value[0],'y':value[1]} + xcord = [] + ycord = [] + for k,v in list(sceneitems.items()): + xycord.append(v['x']) + xycord.append(v['y']) + xcord.append(v['x']) + ycord.append(v['y']) + xmin = min(xcord) + xmax = max(xcord) + ymin = min(ycord) + ymax = max(ycord) cmin = min(xycord) cmax = max(xycord) - return cmin,cmax,sceneitems + return cmin,cmax,xmin,xmax,ymin,ymax -def find_index(value, key): - """ Value.get(key) to avoid expection which would raise if empty value in dictionary for a given key """ - if value.get(key) != None: - return value.get(key) - else: - raise ValueError('no dict with the key found') +def calPrime(x): + prime = int((20*(float(x-cmin)/float(cmax-cmin)))-10) + return prime def storeCplxEnzMsgs( enz, f ): for sub in enz.neighbors["subOut"]: @@ -409,9 +267,7 @@ def nearestColorIndex(color, color_sequence): #Trying to find the index to closest color map from the rainbow pickle file for matching the Genesis color map distance = [ (color[0] - temp[0]) ** 2 + (color[1] - temp[1]) ** 2 + (color[2] - temp[2]) ** 2 for temp in color_sequence] - minindex = 0 - for i in range(1, len(distance)): if distance[minindex] > distance[i] : minindex = i @@ -500,11 +356,23 @@ def storePlotMsgs( tgraphs,f): for graph in tgraphs: slash = graph.path.find('graphs') if not slash > -1: - slash = graph.path.find('graph_0') + slash = graph.path.find('graph') if slash > -1: - conc = graph.path.find('conc') - if conc > -1 : - tabPath = graph.path[slash:len(graph.path)] + foundConc = True + if not ( (graph.path.find('conc1') > -1 ) or + (graph.path.find('conc2') > -1 ) or + (graph.path.find('conc3') > -1 ) or + (graph.path.find('conc4') > -1) ): + foundConc = False + + #conc = graph.path.find('conc') + # if conc > -1 : + # tabPath = graph.path[slash:len(graph.path)] + # else: + # slash1 = graph.path.find('/',slash) + # tabPath = "/graphs/conc1" +graph.path[slash1:len(graph.path)] + if foundConc == True: + tabPath = "/"+graph.path[slash:len(graph.path)] else: slash1 = graph.path.find('/',slash) tabPath = "/graphs/conc1" +graph.path[slash1:len(graph.path)] @@ -527,14 +395,21 @@ def writeplot( tgraphs,f ): for graphs in tgraphs: slash = graphs.path.find('graphs') if not slash > -1: - slash = graphs.path.find('graph_0') + slash = graphs.path.find('graph') if slash > -1: - conc = graphs.path.find('conc') - if conc > -1 : + foundConc = True + if not ( (graphs.path.find('conc1') > -1 ) or + (graphs.path.find('conc2') > -1 ) or + (graphs.path.find('conc3') > -1 ) or + (graphs.path.find('conc4') > -1) ): + foundConc = False + if foundConc == True: tabPath = "/"+graphs.path[slash:len(graphs.path)] else: slash1 = graphs.path.find('/',slash) tabPath = "/graphs/conc1" +graphs.path[slash1:len(graphs.path)] + + if len(moose.element(graphs).msgOut): poolPath = (moose.element(graphs).msgOut)[0].e2.path poolEle = moose.element(poolPath) @@ -586,7 +461,7 @@ def writePool(modelpath,f,volIndex,sceneitems): color = getRandColor() if textcolor == "" or textcolor == " ": textcolor = getRandColor() - #print " trimPath",trimPath(p) + #print " trimPath",trimPath(p) f.write("simundump kpool /kinetics/" + trimPath(p) + " 0 " + str(p.diffConst) + " " + str(0) + " " + @@ -628,11 +503,6 @@ def getColorCheck(color,GENESIS_COLOR_SEQUENCE): else: raise Exception("Invalid Color Value!") -ignoreColor= ["mistyrose","antiquewhite","aliceblue","azure","bisque","black","blanchedalmond","blue","cornsilk","darkolivegreen","darkslategray","dimgray","floralwhite","gainsboro","ghostwhite","honeydew","ivory","lavender","lavenderblush","lemonchiffon","lightcyan","lightgoldenrodyellow","lightgray","lightyellow","linen","mediumblue","mintcream","navy","oldlace","papayawhip","saddlebrown","seashell","snow","wheat","white","whitesmoke","aquamarine","lightsalmon","moccasin","limegreen","snow","sienna","beige","dimgrey","lightsage"] -matplotcolor = {} -for name,hexno in matplotlib.colors.cnames.items(): - matplotcolor[name]=hexno - def getRandColor(): k = random.choice(list(matplotcolor.keys())) if k in ignoreColor: @@ -761,13 +631,19 @@ def writeFooter2(f): if __name__ == "__main__": import sys - + import os filename = sys.argv[1] - modelpath = filename[0:filename.find('.')] + filepath, filenameWithext = os.path.split(filename) + if filenameWithext.find('.') != -1: + modelpath = filenameWithext[:filenameWithext.find('.')] + else: + modelpath = filenameWithext + moose.loadModel(filename,'/'+modelpath,"gsl") - output = modelpath+"_4mmoose.g" - written = write('/'+modelpath,output) + output = modelpath+"_.g" + written = mooseWriteKkit('/'+modelpath,output) + if written: print((" file written to ",output)) else: - print(" could be written to kkit format") + print(" could be written to kkit format") \ No newline at end of file diff --git a/python/moose/moose.py b/python/moose/moose.py index edc9954ede60f22beac919c43c91e22210dd60b6..1309c68fc838d4b225e75cad82c3347232c932fe 100644 --- a/python/moose/moose.py +++ b/python/moose/moose.py @@ -17,24 +17,9 @@ from collections import defaultdict from . import _moose from ._moose import * import __main__ as main - -sbmlSupport_, genesisSupport_ = True, True -try: - import SBML.readSBML - import SBML.writeSBML -except Exception as e: - print( 'MOOSE could not load SBML support due to %s' % e ) - sbmlSupport_ = False - -try: - import genesis.writeKkit -except Exception as e: - print('MOOSE could not load GENESIS support') - print('\tError was %s' % e) - genesisSupport_ = False - -from . import add_Delete_ChemicalSolver - +import genesis.writeKkit +import SBML.readSBML +import SBML.writeSBML sequence_types = ['vector<double>', 'vector<int>', 'vector<long>', @@ -71,17 +56,10 @@ def mooseReadSBML(filepath, loadpath, solver='ee'): solver -- Solver to use (default 'ee' ) \n """ - global sbmlSupport_ - if not sbmlSupport_: - print('SBML support was not loaded') - return None - if not os.path.isfile(filepath): - raise UserWarning('File %s not found' % filepath) - return SBML.readSBML.mooseReadSBML( filepath, loadpath, solver ) -def mooseWriteSBML(modelpath, filenpath, sceneitems={}): +def mooseWriteSBML(modelpath, filepath, sceneitems={}): """Writes loaded model under modelpath to a file in SBML format. keyword arguments:\n @@ -97,16 +75,10 @@ def mooseWriteSBML(modelpath, filenpath, sceneitems={}): --- else, auto-coordinates is used for layout position and passed """ - - global sbmlSupport_ - if not sbmlSupport_: - print('SBML support was not loaded') - return None - return SBML.writeSBML.mooseWriteSBML(modelpath, filepath, sceneitems) -def mooseWriteKkit(modelpath, filepath): +def mooseWriteKkit(modelpath, filepath,sceneitems={}): """Writes loded model under modelpath to a file in Kkit format. keyword arguments:\n @@ -114,12 +86,7 @@ def mooseWriteKkit(modelpath, filepath): modelpath -- model path in moose \n filepath -- Path of output file. """ - global genesisSupport_ - if not genesisSupport_: - print('GENESIS(kkit) support was not loaded') - return None - - return moose.genesis.writeKkit.mooseWiteKkit(modelpath, filepath) + return genesis.writeKkit.mooseWriteKkit(modelpath, filepath,sceneitems) def moosedeleteChemSolver(modelpath): @@ -128,7 +95,7 @@ def moosedeleteChemSolver(modelpath): this should be followed by mooseaddChemSolver for add solvers on to compartment to simulate else default is Exponential Euler (ee) """ - return add_Delete_ChemicalSolver.moosedeleteChemSolver(modelpath) + return chemUtil.add_Delete_ChemicalSolver.moosedeleteChemSolver(modelpath) def mooseaddChemSolver(modelpath, solver): @@ -142,7 +109,7 @@ def mooseaddChemSolver(modelpath, solver): "Runge Kutta" ("gsl") """ - return add_Delete_ChemicalSolver.mooseaddChemSolver(modelpath, solver) + return chemUtil.add_Delete_ChemicalSolver.mooseaddChemSolver(modelpath, solver) ################################################################ # Wrappers for global functions diff --git a/python/setup.py b/python/setup.py index 47b5f3aa0d06da2ac630645b00ce7e9cc005e5c5..94d51ca14a0addf41ecb64901281d868b92956dd 100644 --- a/python/setup.py +++ b/python/setup.py @@ -12,34 +12,19 @@ # You should have received a copy of the GNU General Public License # along with MOOSE. If not, see <http://www.gnu.org/licenses/>. - -"""setup.py: - - Script to install python targets. - -""" - __author__ = "Dilawar Singh" -__copyright__ = "Copyright 2013, Dilawar Singh and NCBS Bangalore" +__copyright__ = "Copyright 2013-17, Dilawar Singh" __credits__ = ["NCBS Bangalore"] -__license__ = "GNU GPL" -__version__ = "1.0.0" +__license__ = "GNU GPLv3" __maintainer__ = "Dilawar Singh" __email__ = "dilawars@ncbs.res.in" -__status__ = "Development" import os from distutils.core import setup script_dir = os.path.dirname( os.path.abspath( __file__ ) ) -version = '3.1' -try: - with open( os.path.join( script_dir, '..', 'VERSION'), 'r' ) as f: - version = f.read( ) -except Exception as e: - print( 'Failed to read VERSION %s' % e ) - print( 'Using default 3.1' ) +version = '3.1.2' try: import importlib.machinery @@ -51,7 +36,7 @@ setup( name='moose', version=version, description='MOOSE python scripting module.', - author='MOOSERes', + author='See AUTHORS file', author_email='bhalla@ncbs.res.in', maintainer='Dilawar Singh', maintainer_email='dilawars@ncbs.res.in', @@ -62,6 +47,7 @@ setup( , 'moose.SBML' , 'moose.neuroml' , 'moose.genesis' + , 'moose.chemUtil' ], package_dir = { 'moose' : 'moose'