Skip to content

Commit 417a4b8

Browse files
committed
add vcml_to_sbml and sbml_to_vcml to Java only
1 parent 71303eb commit 417a4b8

File tree

4 files changed

+144
-2
lines changed

4 files changed

+144
-2
lines changed

build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def main() -> None:
3333
"src/test/resources/TinySpatialProject_Application0.xml "
3434
"src/test/resources/TinySpatialProject_Application0.vcml "
3535
"Simulation0 "
36+
"unnamed_spatialGeom "
3637
"target/sbml-input",
3738
cwd=vcell_native_dir,
3839
)

vcell-native/src/main/java/org/vcell/libvcell/MainRecorder.java

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,23 @@
99

1010
import static org.vcell.libvcell.SolverUtils.sbmlToFiniteVolumeInput;
1111
import static org.vcell.libvcell.SolverUtils.vcmlToFiniteVolumeInput;
12-
12+
import static org.vcell.libvcell.ModelUtils.sbml_to_vcml;
13+
import static org.vcell.libvcell.ModelUtils.vcml_to_sbml;
1314

1415
public class MainRecorder {
1516
private static final Logger logger = LogManager.getLogger(MainRecorder.class);
1617

1718
public static void main(String[] args) {
1819
try {
20+
if (args.length != 5) {
21+
System.out.println("Usage: java -cp <classpath> org.vcell.libvcell.MainRecorder <sbml_file> <vcml_file> <vcml_sim_name> <vcml_app_name> <output_dir>");
22+
return;
23+
}
1924
File sbml_file = new File(args[0]);
2025
File vcml_file = new File(args[1]);
2126
String vcml_sim_name = args[2];
22-
File output_dir = new File(args[3]);
27+
String vcml_app_name = args[3];
28+
File output_dir = new File(args[4]);
2329
File parent_dir = output_dir.getParentFile();
2430
logger.info("Logger logging");
2531
PropertyLoader.setProperty(PropertyLoader.vcellServerIDProperty, "none");
@@ -39,6 +45,43 @@ public static void main(String[] args) {
3945
vcmlToFiniteVolumeInput(vcml_str, vcml_sim_name, parent_dir, output_dir);
4046
}
4147

48+
// exercise the sbml_to_vcml and vcml_to_sbml methods
49+
try (FileInputStream f_sbml = new FileInputStream(sbml_file)) {
50+
byte[] data = f_sbml.readAllBytes();
51+
logger.info("Read " + data.length + " bytes from " + sbml_file.getAbsolutePath());
52+
String sbml_str = new String(data);
53+
54+
// create a temporary file for the VCML output
55+
File temp_vcml_file = new File(output_dir, "temp.vcml");
56+
boolean validateSBML = true;
57+
sbml_to_vcml(sbml_str, temp_vcml_file.toPath(), validateSBML);
58+
// remove temporary file
59+
if (temp_vcml_file.exists()) {
60+
boolean deleted = temp_vcml_file.delete();
61+
if (!deleted) {
62+
logger.warn("Failed to delete temporary VCML file: " + temp_vcml_file.getAbsolutePath());
63+
}
64+
}
65+
}
66+
try (FileInputStream f_vcml = new FileInputStream(vcml_file)) {
67+
byte[] data = f_vcml.readAllBytes();
68+
logger.info("Read " + data.length + " bytes from " + vcml_file.getAbsolutePath());
69+
String vcml_str = new String(data);
70+
71+
// create a temporary file for the SBML output
72+
File temp_sbml_file = new File(output_dir, "temp.vcml");
73+
boolean validateSBML = true;
74+
vcml_to_sbml(vcml_str, vcml_app_name, temp_sbml_file.toPath(), validateSBML);
75+
// remove temporary file
76+
if (temp_sbml_file.exists()) {
77+
boolean deleted = temp_sbml_file.delete();
78+
if (!deleted) {
79+
logger.warn("Failed to delete temporary SBML file: " + temp_sbml_file.getAbsolutePath());
80+
}
81+
}
82+
83+
}
84+
4285
// use reflection to load jsbml classes and call their default constructors
4386
Class.forName("org.sbml.jsbml.AlgebraicRule").getDeclaredConstructor().newInstance();
4487
Class.forName("org.sbml.jsbml.Annotation").getDeclaredConstructor().newInstance();
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.vcell.libvcell;
2+
3+
import cbit.util.xml.VCLogger;
4+
import cbit.util.xml.VCLoggerException;
5+
import cbit.util.xml.XmlUtil;
6+
import cbit.vcell.biomodel.BioModel;
7+
import cbit.vcell.mapping.MappingException;
8+
import cbit.vcell.mapping.SimulationContext;
9+
import cbit.vcell.xml.XMLSource;
10+
import cbit.vcell.xml.XmlHelper;
11+
import cbit.vcell.xml.XmlParseException;
12+
import org.vcell.sbml.SbmlException;
13+
import org.vcell.sbml.vcell.SBMLExporter;
14+
import org.vcell.sbml.vcell.SBMLImporter;
15+
16+
import javax.xml.stream.XMLStreamException;
17+
import java.io.ByteArrayInputStream;
18+
import java.io.IOException;
19+
import java.io.InputStream;
20+
import java.nio.file.Path;
21+
import java.util.ArrayList;
22+
23+
public class ModelUtils {
24+
25+
public static void sbml_to_vcml(String sbml_content, Path vcmlPath, boolean validateSBML)
26+
throws VCLoggerException, XmlParseException, IOException, MappingException {
27+
28+
record LoggerMessage(VCLogger.Priority priority, VCLogger.ErrorType errorType, String message) {};
29+
final ArrayList<LoggerMessage> messages = new ArrayList<>();
30+
31+
VCLogger vclogger = new VCLogger() {
32+
@Override public boolean hasMessages() { return false; }
33+
@Override public void sendAllMessages() { }
34+
@Override public void sendMessage(Priority p, ErrorType et, String message) {
35+
messages.add(new LoggerMessage(p,et,message));
36+
}
37+
};
38+
39+
// parse the SBML content
40+
final BioModel bioModel;
41+
try (InputStream inputStream = new ByteArrayInputStream(sbml_content.getBytes())) {
42+
// create a SBMLImporter from the XMLSource
43+
SBMLImporter sbmlImporter = new SBMLImporter(inputStream, vclogger, validateSBML);
44+
bioModel = sbmlImporter.getBioModel();
45+
}
46+
bioModel.updateAll(false);
47+
48+
// check for errors and warnings
49+
for (LoggerMessage message : messages) {
50+
if (message.priority == VCLogger.Priority.HighPriority) {
51+
throw new RuntimeException("Error: " + message.message);
52+
} else if (message.priority == VCLogger.Priority.MediumPriority) {
53+
System.err.println("Warning: " + message.message);
54+
}
55+
}
56+
57+
// write the BioModel to a VCML file
58+
String vcml_str = XmlHelper.bioModelToXML(bioModel);
59+
XmlUtil.writeXMLStringToFile(vcml_str, vcmlPath.toFile().getAbsolutePath(), true);
60+
}
61+
62+
63+
public static void vcml_to_sbml(String vcml_content, String applicationName, Path sbmlPath, boolean validateSBML)
64+
throws XmlParseException, IOException, XMLStreamException, SbmlException, MappingException {
65+
66+
BioModel bioModel = XmlHelper.XMLToBioModel(new XMLSource(vcml_content));
67+
bioModel.updateAll(false);
68+
SimulationContext simContext = bioModel.getSimulationContext(applicationName);
69+
SBMLExporter sbmlExporter = new SBMLExporter(simContext, 3, 1, validateSBML);
70+
String sbml_string = sbmlExporter.getSBMLString();
71+
XmlUtil.writeXMLStringToFile(sbml_string, sbmlPath.toFile().getAbsolutePath(), true);
72+
}
73+
}

vcell-native/src/test/java/org/vcell/libvcell/EntrypointsTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
1010
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
1111
import org.junit.jupiter.api.Test;
12+
import org.vcell.sbml.SbmlException;
1213

14+
import javax.xml.stream.XMLStreamException;
1315
import java.beans.PropertyVetoException;
1416
import java.io.*;
1517
import java.nio.charset.StandardCharsets;
@@ -23,6 +25,8 @@
2325
import static org.junit.jupiter.api.Assertions.*;
2426
import static org.vcell.libvcell.SolverUtils.sbmlToFiniteVolumeInput;
2527
import static org.vcell.libvcell.SolverUtils.vcmlToFiniteVolumeInput;
28+
import static org.vcell.libvcell.ModelUtils.sbml_to_vcml;
29+
import static org.vcell.libvcell.ModelUtils.vcml_to_sbml;
2630

2731
public class EntrypointsTest {
2832

@@ -107,6 +111,27 @@ public void testVcmlToFiniteVolumeInput() throws SolverException, ExpressionExce
107111
assertEquals(4, countFiles(output_dir));
108112
}
109113

114+
@Test
115+
public void test_sbml_to_vcml() throws MappingException, IOException, XmlParseException, VCLoggerException {
116+
String sbmlContent = getFileContentsAsString("/TinySpatialProject_Application0.xml");
117+
File parent_dir = Files.createTempDirectory("sbmlToVcml").toFile();
118+
File vcml_temp_file = new File(parent_dir, "temp.vcml");
119+
boolean validate = true;
120+
sbml_to_vcml(sbmlContent, vcml_temp_file.toPath(), validate);
121+
assert(vcml_temp_file.exists());
122+
}
123+
124+
@Test
125+
public void test_vcml_to_sbml() throws MappingException, IOException, XmlParseException, XMLStreamException, SbmlException {
126+
String vcmlContent = getFileContentsAsString("/TinySpatialProject_Application0.vcml");
127+
File parent_dir = Files.createTempDirectory("vcmlToSbml").toFile();
128+
File sbml_temp_file = new File(parent_dir, "temp.sbml");
129+
String applicationName = "unnamed_spatialGeom";
130+
boolean validate = true;
131+
vcml_to_sbml(vcmlContent, applicationName, sbml_temp_file.toPath(), validate);
132+
assert(sbml_temp_file.exists());
133+
}
134+
110135
@Test
111136
public void testVcmlToFiniteVolumeInput_bad_simname() throws IOException {
112137
String vcmlContent = getFileContentsAsString("/TinySpatialProject_Application0.vcml");

0 commit comments

Comments
 (0)