package circdesignagui.TripleSim; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Map; import processing.core.PApplet; import processing.xml.XMLElement; import processing.xml.XMLWriter; import circdesigna.TripleSim.ReactionGraph3X.BimolecularNode; import circdesigna.TripleSim.ReactionGraph3X.Graph; import circdesigna.TripleSim.ReactionGraph3X.GraphEdge; import circdesigna.TripleSim.ReactionGraph3X.GraphNode; public class TripleSimSBML { private XMLElement xml; public TripleSimSBML(String source, Graph add){ PApplet got = new PApplet(); got.init(); xml = new XMLElement(got, source); //System.out.println(xml.toString(true)); { XMLElement model = xml.getChild(0); //Leave units alone //Leave compartments alone Map<String, String> speciesLUT = new HashMap<String, String>(); addSpecies(add, model.getChild("listOfSpecies"), speciesLUT); addReactions(add, model.getChild("listOfParameters"), model.getChild("listOfReactions"), speciesLUT); } } private void addSpecies(Graph g, XMLElement listOfSpecies, Map<String, String> speciesLUT) { String namespace = "http://www.sbml.org/sbml/level2/version4"; int id = 1; for(GraphNode q : g.allSingles.values()){ XMLElement species = new XMLElement(); species.setName("species"); String spid = "species_"+id++; speciesLUT.put(q.toString(),spid); species.setAttribute("id", spid); species.setAttribute("name", q.toString()); species.setAttribute("compartment", "compartment_1"); species.setAttribute("initialConcentration", String.format("%.3e",q.initialConc)); listOfSpecies.addChild(species); } } private void addReactions(Graph g, XMLElement listOfParameters, XMLElement listOfReactions, Map<String, String> speciesLUT) { Map<String, String> ratesLUT = new HashMap(); int pid = 1; int rid = 1; String baseKinetic = listOfReactions.getChild(0).getChild("kineticLaw").toString(false); while(listOfReactions.getChildCount()>0){ listOfReactions.removeChildAtIndex(0); } while(listOfParameters.getChildCount()>0){ listOfParameters.removeChildAtIndex(0); } for(GraphEdge edge : g.edges){ addParameter(listOfParameters,edge.k, pid++, ratesLUT); addParameter(listOfParameters,edge.reverse.k, pid++, ratesLUT); XMLElement reaction = new XMLElement(); String rname = "reaction_"+rid++; reaction.setName("reaction"); reaction.setAttribute("id",rname); reaction.setAttribute("name",edge.type); XMLElement listOfReactants = new XMLElement(); listOfReactants.setName("listOfReactants"); addSpeciesReferences(edge.reverse.towards, listOfReactants, speciesLUT); XMLElement listOfProducts = new XMLElement(); listOfProducts.setName("listOfProducts"); addSpeciesReferences(edge.towards, listOfProducts, speciesLUT); XMLElement kineticLaw = new XMLElement(baseKinetic); XMLElement[] reactProd = kineticLaw.getChild("math").getChild("apply").getChild("apply").getChildren("apply"); addOneWayKinetic(reactProd[0],edge, ratesLUT, speciesLUT); addOneWayKinetic(reactProd[1],edge.reverse, ratesLUT, speciesLUT); reaction.addChild(listOfReactants); reaction.addChild(listOfProducts); reaction.addChild(kineticLaw); listOfReactions.addChild(reaction); } } private void addOneWayKinetic(XMLElement element, GraphEdge edge, Map<String, String> ratesLUT, Map<String, String> speciesLUT) { //Clear the element while(element.getChildCount()>0){ element.removeChildAtIndex(0); } element.addChild(new XMLElement("<times/>")); element.addChild(new XMLElement("<ci> "+ratesLUT.get(rf(edge.k))+" </ci>")); for(GraphNode s : getSpecies(edge.reverse.towards)){ element.addChild(new XMLElement("<ci> "+speciesLUT.get(s.toString())+" </ci>")); } } private GraphNode[] getSpecies(GraphNode v){ if (v instanceof BimolecularNode){ return ((BimolecularNode) v).associate; } return new GraphNode[]{v}; } private void addSpeciesReferences(GraphNode v, XMLElement listOfReactants, Map<String, String> speciesLUT) { for(GraphNode s : getSpecies(v)){ XMLElement ref = new XMLElement(); ref.setName("speciesReference"); ref.setAttribute("species", speciesLUT.get(s.toString())); listOfReactants.addChild(ref); } } private void addParameter(XMLElement listOfParameters, double k, int id, Map<String, String> ratesLUT) { XMLElement par = new XMLElement(); par.setName("parameter"); String kon = rf(k); String kon_ = "parameter_"+id; par.setAttribute("id", kon_); par.setAttribute("name", kon); par.setAttribute("value", kon); ratesLUT.put(kon, kon_); listOfParameters.addChild(par); } private String rf(double k) { return String.format("%e",k); } public void write(String out2) { try { FileWriter out = new FileWriter(new File(out2)); //System.out.println(xml.toString(true)); out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"); XMLWriter write = new XMLWriter(out); write.write(xml, true); out.close(); } catch (IOException e) { e.printStackTrace(); } } }