Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions core/src/org/sbml/jsbml/util/AntimonySerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import org.sbml.jsbml.AlgebraicRule;
import org.sbml.jsbml.Event;
import org.sbml.jsbml.EventAssignment;
import org.sbml.jsbml.Parameter;
import org.sbml.jsbml.FunctionDefinition;

/**
* Utility class to serialize SBML models and components into the Antimony scripting language.
Expand Down Expand Up @@ -46,6 +48,10 @@ public static String toAntimony(SBase element) {
return toAntimony((Rule) element);
} else if (element instanceof Event) {
return toAntimony((Event) element);
} else if (element instanceof Parameter) {
return toAntimony((Parameter) element);
} else if (element instanceof FunctionDefinition) {
return toAntimony((FunctionDefinition) element);
}

return "// Unsupported SBML component for Antimony serialization.";
Expand Down Expand Up @@ -94,6 +100,18 @@ public static String toAntimony(Model model) {
}
ant.append("\n");

ant.append(" // Parameters\n");
for (Parameter p : model.getListOfParameters()) {
ant.append(" ").append(toAntimony(p)).append("\n");
}
ant.append("\n");

ant.append(" // Function Definitions\n");
for (FunctionDefinition fd : model.getListOfFunctionDefinitions()) {
ant.append(" ").append(toAntimony(fd)).append("\n");
}
ant.append("\n");

ant.append(END).append("\n");

return ant.toString();
Expand Down Expand Up @@ -298,4 +316,53 @@ public static String toAntimony(Event e) {
ant.append(";");
return ant.toString();
}

/**
* Converts an individual SBML Parameter into an Antimony string.
*/
public static String toAntimony(Parameter p) {
if (p == null) return "";
StringBuilder ant = new StringBuilder();

ant.append(p.getId());
if (p.isSetValue()) {
ant.append(" = ").append(p.getValue());
}
ant.append(";");
return ant.toString();
}

/**
* Converts an individual SBML FunctionDefinition into an Antimony string.
*/
public static String toAntimony(FunctionDefinition fd) {
if (fd == null || !fd.isSetMath()) return "";
StringBuilder ant = new StringBuilder();

ant.append("function ").append(fd.getId()).append("(");

ASTNode math = fd.getMath();
if (math.isLambda()) {
// In JSBML, all children except the last one are the bound variables (bvars)
int numBvars = math.getChildCount() - 1;

for (int i = 0; i < numBvars; i++) {
// Fetch the child node directly
ant.append(math.getChild(i).getName());
if (i < numBvars - 1) {
ant.append(", ");
}
}
ant.append(")\n ");

// The last child is the actual math body of the function
if (math.getChildCount() > 0) {
ASTNode body = math.getChild(math.getChildCount() - 1);
ant.append(ASTNode.formulaToString(body));
}
}

ant.append("\n").append(END).append("\n");
return ant.toString();
}
}
35 changes: 34 additions & 1 deletion core/test/org/sbml/jsbml/util/AntimonySerializerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
import org.sbml.jsbml.Trigger;
import org.sbml.jsbml.Delay;
import org.sbml.jsbml.Priority;

import org.sbml.jsbml.Parameter;
import org.sbml.jsbml.FunctionDefinition;
/**
* Tests for the {@link AntimonySerializer} Phase 1 LLM utility.
*
Expand Down Expand Up @@ -288,4 +289,36 @@ public void testAdvancedEventOptions() {
String expected = "E2: at 5 after x, priority = 1, t0 = false, persistent = false: S1 = 0;";
assertEquals("Should serialize advanced event options", expected, AntimonySerializer.toAntimony(e));
}
@Test
public void testToAntimonyParameter() {
// Test a parameter with a value
Parameter p1 = new Parameter();
p1.setId("k1");
p1.setValue(0.5);
String result1 = AntimonySerializer.toAntimony(p1);
assertEquals("k1 = 0.5;", result1);

// Test a parameter without a value
Parameter p2 = new Parameter();
p2.setId("k2");
String result2 = AntimonySerializer.toAntimony(p2);
assertEquals("k2;", result2);
}

@Test
public void testToAntimonyFunctionDefinition() throws Exception {
FunctionDefinition fd = new FunctionDefinition();
fd.setId("multiply");

// In JSBML, parseFormula converts the string into a proper ASTNode tree
ASTNode math = ASTNode.parseFormula("lambda(x, y, x * y)");
fd.setMath(math);

String result = AntimonySerializer.toAntimony(fd);

// The expected Antimony output (removed spaces around the asterisk)
String expected = "function multiply(x, y)\n x*y\n" + AntimonyConstants.END + "\n";

assertEquals(expected, result);
}
}