Skip to content

Instantly share code, notes, and snippets.

@fbergmann
Last active January 12, 2024 09:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fbergmann/d3a42558d9d7816b623b154d8d1049c0 to your computer and use it in GitHub Desktop.
Save fbergmann/d3a42558d9d7816b623b154d8d1049c0 to your computer and use it in GitHub Desktop.
While generally not recommended to remove multiplications with compartment sizes from kinetics, here is how it could be done. All it needs to work is the python libsbml package installed.
from libsbml import *
def replace_compartment_multiplication(node, compartents):
"""Removes all multiplications with compartment sizes from the given ASTNode.
:param node: The ASTNode to process.
:type node: ASTNode
:param compartents: A list of compartment ids.
:type compartents: list[str]
:return: The new ASTNode.
"""
# convert the ASTNode to an infix string
infix = formulaToL3String(node)
# add spaces around infix operators
infix = ' ' + infix + ' '
infix = infix.replace(')', ' ) ')
infix = infix.replace('(', ' ( ')
# remove compartment multiplications
for c in compartents:
infix = infix.replace('* ' + c + ' ', '')
infix = infix.replace(' ' + c + ' *', '')
# parse the infix string to an ASTNode
return parseL3Formula(infix)
def drop_compartment_multiplication(input_file, output_file):
"""Drops all multiplications with compartment sizes from the given SBML file.
:param input_file: The input SBML file.
:type input_file: str
:param output_file: The output SBML file.
:type output_file: str
"""
# read the SBML file
doc = readSBMLFromFile(input_file)
if doc.getNumErrors(LIBSBML_SEV_ERROR) > 0:
print("Read Error(s):")
doc.printErrors()
return
model = doc.getModel()
if model == None:
print("Model not found!")
return
# only replace compartments that have an id and
# are of size 1 (otherwise the result would differ later)
compartments = [ c.getId() for c in model.getListOfCompartments() if c.getId() and c.getVolume() == 1 ]
# replace kinetics
for reaction in model.getListOfReactions():
if not reaction.isSetKineticLaw():
continue
kl = reaction.getKineticLaw()
if not kl.isSetMath():
continue
math = kl.getMath()
# create a new ASTNode to replace the old one
new_math = replace_compartment_multiplication(math, compartments)
kl.setMath(new_math)
# write the new SBML file
writeSBMLToFile(doc, output_file)
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: drop_compartment_multiplication input-file output-file")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
drop_compartment_multiplication(input_file, output_file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment