|
|
|
@ -44,19 +44,21 @@ public class SBML2Prism implements EntityResolver |
|
|
|
private ArrayList<Species> speciesList; |
|
|
|
private ArrayList<Parameter> parameterList; |
|
|
|
private ArrayList<Reaction> 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 <sbml_file> [scale_factor]"); |
|
|
|
System.err.println("Usage: java -cp classes prism.SBML2Prism <sbml_file> [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<Parameter>(); |
|
|
|
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<String> modulesNames; |
|
|
|
HashSet<String> 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<String>(); |
|
|
|
@ -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<String> reactants; |
|
|
|
public ArrayList<String> products; |
|
|
|
public ArrayList<Integer> productStoichs; |
|
|
|
public Element kineticLaw; |
|
|
|
public ArrayList<Parameter> parameters; |
|
|
|
public Reaction(String id, String name) |
|
|
|
@ -519,13 +544,28 @@ public class SBML2Prism implements EntityResolver |
|
|
|
this.name = name; |
|
|
|
reactants = new ArrayList<String>(); |
|
|
|
products = new ArrayList<String>(); |
|
|
|
productStoichs = new ArrayList<Integer>(); |
|
|
|
kineticLaw = null; |
|
|
|
parameters = new ArrayList<Parameter>(); |
|
|
|
} |
|
|
|
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; |
|
|
|
|