Last active
January 12, 2024 09:27
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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