From 21bfd39f10fceba48100f85f0577460c299f32d7 Mon Sep 17 00:00:00 2001 From: Dave Parker Date: Fri, 25 May 2007 09:00:20 +0000 Subject: [PATCH] SBML-to-PRISM updates: maxAmount tidy up, listOfParameters bugfix, support for product stoichiometries. git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@370 bbc10eb1-c90d-0410-af57-cb519fbb1720 --- prism/src/prism/SBML2Prism.java | 111 ++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 35 deletions(-) diff --git a/prism/src/prism/SBML2Prism.java b/prism/src/prism/SBML2Prism.java index 50ae8750..eb4d3132 100644 --- a/prism/src/prism/SBML2Prism.java +++ b/prism/src/prism/SBML2Prism.java @@ -44,19 +44,21 @@ public class SBML2Prism implements EntityResolver private ArrayList speciesList; private ArrayList parameterList; private ArrayList reactionList; - private int scaleFactor; + private int maxAmount; // Calling point: e.g. java -cp classes prism.SBML2Prism myfile.sbml 100 - // (100 denotes (integer) scale factor used to compute population sizes from (real-valued) concentrations, default is 10) + // + // (100 denotes (integer) maximum for species population sizes, default is 100) + // (also used to compute amounts from (real-valued) concentrations) public static void main(String args[]) { try { if (args.length < 1) { - System.err.println("Usage: java -cp classes prism.SBML2Prism [scale_factor]"); + System.err.println("Usage: java -cp classes prism.SBML2Prism [max_amount]"); System.exit(1); } - new SBML2Prism().load(new File(args[0]), (args.length>1)?args[1]:"10"); + new SBML2Prism().load(new File(args[0]), (args.length>1)?args[1]:"100"); } catch (PrismException e) { System.err.println("Error: "+e.getMessage()); @@ -66,7 +68,7 @@ public class SBML2Prism implements EntityResolver // Main method: load SBML file, process and sent resulting PRISM file to stdout - public void load(File f, String scaleFactor) throws PrismException + public void load(File f, String maxAmount) throws PrismException { try { // obtain exclusive acces to the prism parser @@ -75,8 +77,8 @@ public class SBML2Prism implements EntityResolver // translate try { - try { this.scaleFactor = Integer.parseInt(scaleFactor); } - catch (NumberFormatException e) { throw new PrismException("Invalid scale factor \""+scaleFactor+"\""); } + try { this.maxAmount = Integer.parseInt(maxAmount); } + catch (NumberFormatException e) { throw new PrismException("Invalid max amount \""+maxAmount+"\""); } Document doc = parseSBML(f); extractModelFromSBML(doc); //printModel(System.err); @@ -158,12 +160,14 @@ public class SBML2Prism implements EntityResolver { Element e, e_model, e_list, e_species, e_parameter, e_reaction, e_kinetics, e_mathml, e_params; NodeList nodes, nodes2; + Node node = null; Species species; Parameter parameter; Reaction reaction; - int i, j, n, m; + int i, j, k, n, m; double d; - String s; + String s, s2; + boolean found; // Get "model" element of SBML file nodes = doc.getDocumentElement().getElementsByTagName("model"); @@ -183,8 +187,16 @@ public class SBML2Prism implements EntityResolver // Process list of parameters (if present) parameterList = new ArrayList(); - e_list = (Element)e_model.getElementsByTagName("listOfParameters").item(0); - if (e_list != null) { + // Look at direct children only (there might be listOfParameters nodes lower in the tree) + nodes = e_model.getChildNodes(); + n = nodes.getLength(); + found = false; + for (i = 0; i < n; i++) { + node = nodes.item(i); + if ("listOfParameters".equals(node.getNodeName())) { found = true; break; } + } + if (found) { + e_list = (Element)node; nodes = e_list.getElementsByTagName("parameter"); n = nodes.getLength(); for (i = 0; i < n; i++) { @@ -224,8 +236,15 @@ public class SBML2Prism implements EntityResolver m = nodes2.getLength(); for (j = 0; j < m; j++) { e = (Element)nodes2.item(j); + // Get species name of product s = e.getAttribute("species"); - reaction.addProduct(s); + // Get stoichiometry if present + s2 = e.getAttribute("stoichiometry"); + k = 1; + if (s2.length() > 0) try { k = Integer.parseInt(s2); } + catch (NumberFormatException ex) { throw new PrismException("Invalid stoichiometry value \""+s2+"\""); } + // Add product to reaction + reaction.addProduct(s, k); } } @@ -276,6 +295,14 @@ public class SBML2Prism implements EntityResolver Parameter parameter; HashSet modulesNames; HashSet prismIdents; + + // Look at initial amounts for all species + // If any exceed MAX_AMOUNT, increase it accordingly + n = speciesList.size(); + for (i = 0; i < n; i++) { + species = speciesList.get(i); + if (species.init > maxAmount) maxAmount = (int)species.init; + } // Generate unique and valid PRISM identifier (module and variable name) for each species modulesNames = new HashSet(); @@ -337,7 +364,7 @@ public class SBML2Prism implements EntityResolver private void printPRISMModel(File f) throws PrismException { - int i, i2, n, n2; + int i, i2, n, n2, before, after; Species species; Reaction reaction; Parameter parameter; @@ -349,9 +376,7 @@ public class SBML2Prism implements EntityResolver s += "// File generated by automatic SBML-to-PRISM conversion\n"; s += "// Original SBML file: " + f.getPath() + "\n\n"; s += "ctmc\n"; - - // - s += "\nconst int SCALE_FACTOR = " + scaleFactor + ";\n"; + s += "\nconst int MAX_AMOUNT = " + maxAmount + ";\n"; // Generate constant definition for each (model and reaction) parameter n = parameterList.size(); @@ -380,35 +405,34 @@ public class SBML2Prism implements EntityResolver for (i = 0; i < n; i++) { species = speciesList.get(i); s += "\n// Species " + species + "\n"; + s += "const int "+species.prismName+"_MAX = MAX_AMOUNT;\n"; s += "module " + species.prismName + "\n"; // Generate variable representing the amount of this species - s += "\t\n\t" + species.prismName + " : [0.." + scaleFactor + "]"; - s += " init " + (int)Math.round(scaleFactor*species.init) + "; // Initial amount " + species.init + "\n\t\n"; + s += "\t\n\t" + species.prismName + " : [0.."+species.prismName+"_MAX]"; + s += " init " + (int)species.init + "; // Initial amount " + (int)species.init + "\n\t\n"; +// s += " init " + (int)Math.round(scaleFactor*species.init) + "; // Initial amount " + species.init + "\n\t\n"; - // Generate a command for each reaction that involves this species as a reactant + // Generate a command for each reaction that involves this species n2 = reactionList.size(); for (i2 = 0; i2 < n2; i2++) { reaction = reactionList.get(i2); - if (reaction.reactants.contains(species.id)) { + if (reaction.isSpeciesInvolved(species.id)) { s += "\t// " + reaction.id; if (reaction.name.length() > 0) s += " (" + reaction.name + ")"; s += "\n"; s += "\t[" + reaction.id + "] " ; - s += species.prismName + " > 0 -> (" + species.prismName + "'=" + species.prismName + "-1);\n"; - } - } - - // Generate a command for each reaction that involves this species as a product - n2 = reactionList.size(); - for (i2 = 0; i2 < n2; i2++) { - reaction = reactionList.get(i2); - if (reaction.products.contains(species.id)) { - s += "\t// " + reaction.id; - if (reaction.name.length() > 0) s += " (" + reaction.name + ")"; - s += "\n"; - s += "\t[" + reaction.id + "] " ; - s += species.prismName + " < " + scaleFactor + " -> (" + species.prismName + "'=" + species.prismName + "+1);\n"; + before = reaction.before(species.id); + after = reaction.after(species.id); + if (before > 0) s += species.prismName + " > "+(before-1); + if (after-before > 0) { + if (before > 0) s += " &"; + s += " " + species.prismName + " <= "+species.prismName + "_MAX-" + (after-before); + } + s += " -> (" + species.prismName + "'=" + species.prismName; + if (after-before > 0) s += "+" + (after-before); + if (after-before < 0) s += (after-before); + s += ");\n"; } } @@ -511,6 +535,7 @@ public class SBML2Prism implements EntityResolver public String name; public ArrayList reactants; public ArrayList products; + public ArrayList productStoichs; public Element kineticLaw; public ArrayList parameters; public Reaction(String id, String name) @@ -519,13 +544,28 @@ public class SBML2Prism implements EntityResolver this.name = name; reactants = new ArrayList(); products = new ArrayList(); + productStoichs = new ArrayList(); kineticLaw = null; parameters = new ArrayList(); } public void addReactant(String reactant) { reactants.add(reactant); } - public void addProduct(String product) { products.add(product); } + public void addProduct(String product) { addProduct(product, 1); } + public void addProduct(String product, int stoich) { products.add(product); productStoichs.add(stoich); } public void setKineticLaw(Element kineticLaw) { this.kineticLaw = kineticLaw; } public void addParameter(String name, String value) { parameters.add(new Parameter(name, value)); } + public boolean isSpeciesInvolved(String species) { return reactants.contains(species) || products.contains(species); } + public int before(String species) + { + int i = reactants.indexOf(species); + if (i == -1) return 0; + return 1; + } + public int after(String species) + { + int i = products.indexOf(species); + if (i == -1) return 0; + return productStoichs.get(i); + } public String toString() { String s = ""; @@ -534,6 +574,7 @@ public class SBML2Prism implements EntityResolver s += ":\n"; s += " Reactants: " + reactants+"\n"; s += " Products: " + products+"\n"; + s += " Products stoichiometry: " + productStoichs+"\n"; s += " Kinetic law: " + kineticLaw+"\n"; s += " Parameters: " + parameters+"\n"; return s;