Skip to content

Commit

Permalink
new BiosimulationsLog to read/write biosimulations JSON log files
Browse files Browse the repository at this point in the history
  • Loading branch information
jcschaff committed Nov 21, 2024
1 parent 5dd85a4 commit e775967
Show file tree
Hide file tree
Showing 2 changed files with 397 additions and 0 deletions.
98 changes: 98 additions & 0 deletions vcell-core/src/main/java/org/vcell/sedml/log/BiosimulationLog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package org.vcell.sedml.log;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

public class BiosimulationLog {

public enum Status {
QUEUED,
SUCCEEDED,
FAILED,
SKIPPED
}
public static class ExceptionLog {
public String type;
public String message;
}
public static class DataSetLog {
public String id;
public Status status;
}
public static class CurveLog {
public String id;
public Status status;
}
public static class SkipReason {
public String type;
public String message;
}
public static class OutputLog {
public String id;
public Status status;
public ExceptionLog exception;
public SkipReason skipReason;
public String output;
public BigDecimal duration;
@JsonInclude(JsonInclude.Include.NON_NULL) public List<DataSetLog> dataSets;
@JsonInclude(JsonInclude.Include.NON_NULL) public List<CurveLog> curves;
}
public static class TaskLog {
public String id;
public Status status;
public ExceptionLog exception;
public SkipReason skipReason;
public String output;
public BigDecimal duration;
public String algorithm;
public String simulatorDetails;
}
public static class SedDocumentLog {
public String location;
public Status status;
public ExceptionLog exception;
public SkipReason skipReason;
public String output;
public BigDecimal duration;
public List<TaskLog> tasks = new ArrayList<>();
public List<OutputLog> outputs = new ArrayList<>();
}
public static class ArchiveLog {
public Status status;
public ExceptionLog exception;
public SkipReason skipReason;
public String output;
public BigDecimal duration;
public List<SedDocumentLog> sedDocuments = new ArrayList<>();
}

public static ArchiveLog readArchiveLogFromJsonFile(Path path) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(path.toFile(), ArchiveLog.class);
}

public static ArchiveLog readArchiveLogFromJson(String json) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json.getBytes(StandardCharsets.UTF_8), ArchiveLog.class);
}

public static void writeArchiveLogToJsonFile(ArchiveLog archiveLog, Path path) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
objectMapper.writeValue(path.toFile(), archiveLog);
}

public static String writeArchiveLogToJson(ArchiveLog archiveLog) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
return objectMapper.writeValueAsString(archiveLog);
}
}
299 changes: 299 additions & 0 deletions vcell-core/src/test/java/org/vcell/sedml/log/BiosimulationLogTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
package org.vcell.sedml.log;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.util.Collection;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

@Tag("Fast")
public class BiosimulationLogTest {
static String json_element_beginning = """
{
"status": "QUEUED",
"exception": null,
"skipReason": null,
"output": null,
"duration": null,
"sedDocuments": [
{
"location": "doc_1.sedml",
"status": "QUEUED",
"exception": null,
"skipReason": null,
"output": null,
"duration": null,
"tasks": [
{
"id": "task_1_ss",
"status": "QUEUED",
"exception": null,
"skipReason": null,
"output": null,
"duration": null,
"algorithm": null,
"simulatorDetails": null
},
{
"id": "task_2_time_course",
"status": "QUEUED",
"exception": null,
"skipReason": null,
"output": null,
"duration": null,
"algorithm": null,
"simulatorDetails": null
}
],
"outputs": [
{
"id": "report_1",
"status": "QUEUED",
"exception": null,
"skipReason": null,
"output": null,
"duration": null,
"dataSets": [
{
"id": "dataset_1",
"status": "QUEUED"
},
{
"id": "dataset_2",
"status": "QUEUED"
}
]
},
{
"id": "plot_1",
"status": "QUEUED",
"exception": null,
"skipReason": null,
"output": null,
"duration": null,
"curves": [
{
"id": "curve_1",
"status": "QUEUED"
}
]
}
]
}
]
}
""";
static String json_element_success = """
{
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 6,
"sedDocuments": [
{
"location": "doc_1.sedml",
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 5,
"tasks": [
{
"id": "task_1_ss",
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n",
"duration": 2,
"algorithm": null,
"simulatorDetails": null
},
{
"id": "task_2_time_course",
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n",
"duration": 1,
"algorithm": null,
"simulatorDetails": null
}
],
"outputs": [
{
"id": "report_1",
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 0.1,
"dataSets": [
{
"id": "dataset_1",
"status": "SUCCEEDED"
},
{
"id": "dataset_2",
"status": "SUCCEEDED"
}
]
},
{
"id": "plot_1",
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 0.01,
"curves": [
{
"id": "curve_1",
"status": "SUCCEEDED"
}
]
}
]
}
]
}
""";
static String json_element_failure = """
{
"status": "FAILED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 6,
"sedDocuments": [
{
"location": "doc_1.sedml",
"status": "FAILED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 5,
"tasks": [
{
"id": "task_1_ss",
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n",
"duration": 2,
"algorithm": null,
"simulatorDetails": null
},
{
"id": "task_2_time_course",
"status": "FAILED",
"exception": {
"type": "FileNotFoundError",
"message": "Model `model2.xml` does not exist."
},
"skipReason": null,
"output": null,
"duration": 1,
"algorithm": null,
"simulatorDetails": null
}
],
"outputs": [
{
"id": "report_1",
"status": "SUCCEEDED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 0.1,
"dataSets": [
{
"id": "dataset_1",
"status": "SUCCEEDED"
},
{
"id": "dataset_2",
"status": "SUCCEEDED"
}
]
},
{
"id": "plot_1",
"status": "SKIPPED",
"exception": null,
"skipReason": {
"type": "2DPlotNotImplemented",
"message": "Output skipped because the simulator cannot generate plots."
},
"output": null,
"duration": 0.01,
"curves": [
{
"id": "curve_1",
"status": "SKIPPED"
}
]
}
]
}
]
}
""";
static String json_document_failed = """
{
"status": "FAILED",
"exception": null,
"skipReason": null,
"output": null,
"duration": 6,
"sedDocuments": [
{
"location": "doc_1.sedml",
"status": "FAILED",
"exception": {
"type": "FileNotFoundError",
"message": "Model `model2.xml` does not exist."
},
"skipReason": null,
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n",
"duration": 5,
"tasks": null,
"outputs": null
}
]
}
""";

public static Collection<String> testCases() {
return List.of(json_element_beginning, json_element_success, json_element_failure, json_document_failed);
}

@ParameterizedTest
@MethodSource("testCases")
public void testArchiveLogRead(String expectedJson) throws IOException {
// create ArchiveLog from given JSON
BiosimulationLog.ArchiveLog archiveLog = BiosimulationLog.readArchiveLogFromJson(expectedJson);

// generate new JSON string from ArchiveLog
String newJson = BiosimulationLog.writeArchiveLogToJson(archiveLog);

// compare the original JSON string with the new JSON string - normalize by pretty printing
assertEquals(prettyPrintJson(expectedJson), prettyPrintJson(newJson));
}


public static String prettyPrintJson(String jsonString) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(jsonString);
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
return objectMapper.writeValueAsString(jsonNode);
}

}

0 comments on commit e775967

Please sign in to comment.