Skip to content

Commit 8df4045

Browse files
authored
Merge pull request #7 from virtualcell/existing-image-fieldata
support image-based field data from pyvcell
2 parents 3ae5e81 + 3a42ff0 commit 8df4045

File tree

9 files changed

+235
-129
lines changed

9 files changed

+235
-129
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "libvcell"
7-
version = "0.0.9"
7+
version = "0.0.10"
88
description = "This is a python package which wraps a subset of VCell Java code as a native python package."
99
authors = ["Jim Schaff <[email protected]>", "Ezequiel Valencia <[email protected]>"]
1010
repository = "https://github.com/virtualcell/libvcell"

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

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import cbit.vcell.messaging.server.SimulationTask;
1313
import cbit.vcell.mongodb.VCMongoMessage;
1414
import cbit.vcell.parser.ExpressionException;
15+
import cbit.vcell.simdata.SimulationData;
1516
import cbit.vcell.solver.*;
1617
import cbit.vcell.xml.XMLSource;
1718
import cbit.vcell.xml.XmlHelper;
@@ -30,6 +31,7 @@
3031
import java.io.ByteArrayInputStream;
3132
import java.io.File;
3233
import java.io.InputStream;
34+
import java.math.BigDecimal;
3335
import java.util.ArrayList;
3436
import java.util.List;
3537

@@ -49,24 +51,57 @@ public static void vcmlToFiniteVolumeInput(String vcml_content, String simulatio
4951
if (sim == null) {
5052
throw new IllegalArgumentException("Simulation not found: " + simulation_name);
5153
}
52-
FieldDataIdentifierSpec[] fdiSpecs = getFieldDataIdentifierSpecs(sim, parentDir);
54+
FieldDataIdentifierSpec[] fdiSpecs = getFieldDataIdentifierSpecs(sim, outputDir, parentDir);
5355

5456
TempSimulation tempSimulation = new TempSimulation(sim, false);
5557
tempSimulation.setSimulationOwner(sim.getSimulationOwner());
5658
SimulationJob tempSimulationJob = new SimulationJob(tempSimulation, 0, fdiSpecs);
59+
60+
renameExistingFieldDataFiles(tempSimulation.getKey(), tempSimulationJob.getJobIndex(), outputDir);
61+
5762
SimulationTask simTask = new SimulationTask(tempSimulationJob, 0);
5863
LocalFVSolverStandalone solver = new LocalFVSolverStandalone(simTask, outputDir);
5964
solver.initialize();
6065
}
6166

62-
private static FieldDataIdentifierSpec[] getFieldDataIdentifierSpecs(Simulation sim, File parentDir) throws MathException, ExpressionException {
67+
private static void renameExistingFieldDataFiles(KeyValue tempSimKey, int jobId, File outputDir) {
68+
File[] files = outputDir.listFiles();
69+
if (files != null) {
70+
for (File file : files) {
71+
if (file.getName().startsWith("SimID_SIMULATIONKEY_JOBINDEX_")) {
72+
String newName = file.getName().replace("SIMULATIONKEY",tempSimKey.toString()).replace("JOBINDEX",String.valueOf(jobId));
73+
File newFile = new File(outputDir, newName);
74+
if (!file.renameTo(newFile)){
75+
throw new RuntimeException("Could not rename " + file.getName() + " to " + newFile.getAbsolutePath());
76+
}
77+
}
78+
}
79+
}
80+
}
81+
82+
private static FieldDataIdentifierSpec[] getFieldDataIdentifierSpecs(Simulation sim, File outputDir, File parentDir) throws MathException, ExpressionException {
6383
FieldDataIdentifierSpec[] fdiSpecs = null;
6484
FieldFunctionArguments[] fieldFuncArgs = FieldUtilities.getFieldFunctionArguments(sim.getMathDescription());
6585
if (fieldFuncArgs != null) {
6686
List<FieldDataIdentifierSpec> fdiSpecList = new ArrayList<>();
6787
for (FieldFunctionArguments fieldFuncArg : fieldFuncArgs) {
6888
if (fieldFuncArg != null) {
6989
String name = fieldFuncArg.getFieldName();
90+
//
91+
// First, check if the resampled field data files are already present (e.g. if pyvcell wrote the files directly from image data)
92+
//
93+
ExternalDataIdentifier fakeExtDataId = new ExternalDataIdentifier(sim.getKey(), User.tempUser, name);
94+
String fieldDataFileName = SimulationData.createCanonicalResampleFileName(fakeExtDataId, fieldFuncArg);
95+
fieldDataFileName = fieldDataFileName.replace("SimID_" + sim.getKey().toString() + "_0_", "SimID_SIMULATIONKEY_JOBINDEX_");
96+
File preexistingFieldDataFile = new File(outputDir, fieldDataFileName);
97+
if (preexistingFieldDataFile.exists()) {
98+
fdiSpecList.add(new FieldDataIdentifierSpec(fieldFuncArg, fakeExtDataId));
99+
continue;
100+
}
101+
102+
//
103+
// If not, check if the field data directory exists as a subdirectory of the parentDir - holding simulation results.
104+
//
70105
File fieldDataDir = new File(parentDir, name);
71106
if (!fieldDataDir.exists()) {
72107
throw new IllegalArgumentException("Field data directory does not exist: " + fieldDataDir.getAbsolutePath());

vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFVSolverStandalone.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ public void writeFieldFunctionData(OutputContext outputContext, FieldDataIdentif
167167
HashMap<FieldDataIdentifierSpec, Boolean> bFieldDataResample = new HashMap<>();
168168
int i=0;
169169
for (FieldDataIdentifierSpec fdiSpec: argFieldDataIDSpecs) {
170-
File ext_dataDir = new File(this.parentDir, fdiSpec.getFieldFuncArgs().getFieldName());
171170
if (!uniqueFieldDataIDSpecAndFileH.containsKey(fdiSpec)){
172171
File newResampledFieldDataFile = new File(dataDir, SimulationData.createCanonicalResampleFileName(getSimulationJob().getVCDataIdentifier(), fdiSpec.getFieldFuncArgs()));
173172
uniqueFieldDataIDSpecAndFileH.put(fdiSpec,newResampledFieldDataFile);
@@ -179,6 +178,9 @@ public void writeFieldFunctionData(OutputContext outputContext, FieldDataIdentif
179178
Set<Map.Entry<FieldDataIdentifierSpec, File>> resampleSet = uniqueFieldDataIDSpecAndFileH.entrySet();
180179
for (Map.Entry<FieldDataIdentifierSpec, File> resampleEntry : resampleSet) {
181180
if (resampleEntry.getValue().exists()) {
181+
// field data file has already been written
182+
// 1. in a previous loop iteration
183+
// 2. from pyvcell writing the field data file directly into this directory for an image-based field data
182184
continue;
183185
}
184186
FieldDataIdentifierSpec fieldDataIdSpec = resampleEntry.getKey();

vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFiniteVolumeFileWriter.java

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77
import cbit.vcell.math.Variable;
88
import cbit.vcell.math.VariableType;
99
import cbit.vcell.messaging.server.SimulationTask;
10+
import cbit.vcell.parser.DivideByZeroException;
1011
import cbit.vcell.parser.Expression;
1112
import cbit.vcell.parser.ExpressionException;
13+
import cbit.vcell.simdata.DataSet;
1214
import cbit.vcell.simdata.SimDataBlock;
1315
import cbit.vcell.simdata.SimulationData;
1416
import cbit.vcell.simdata.VCData;
1517
import cbit.vcell.solver.Simulation;
1618
import cbit.vcell.solvers.FiniteVolumeFileWriter;
1719
import org.vcell.util.DataAccessException;
20+
import org.vcell.util.document.ExternalDataIdentifier;
21+
import org.vcell.util.document.User;
1822

1923
import java.io.File;
2024
import java.io.IOException;
@@ -66,15 +70,7 @@ protected void writeFieldData() throws ExpressionException, DataAccessException
6670
);
6771
uniqueFieldDataIDSpecs.add(fieldDataIDSpec);
6872
VariableType varType = fieldDataIDSpec.getFieldFuncArgs().getVariableType();
69-
final VariableType dataVarType;
70-
try {
71-
File ext_data_dir = new File(workingDirectory.getParentFile(), ffa.getFieldName());
72-
VCData vcData = new SimulationData(fieldDataIDSpec.getExternalDataIdentifier(), ext_data_dir, ext_data_dir, null);
73-
SimDataBlock simDataBlock = vcData.getSimDataBlock(null, ffa.getVariableName(), ffa.getTime().evaluateConstant());
74-
dataVarType = simDataBlock.getVariableType();
75-
} catch (IOException e) {
76-
throw new DataAccessException("Error reading field data file: " + e.getMessage());
77-
}
73+
final VariableType dataVarType = getVariableTypeFromFieldDataFiles(fieldDataIDSpec, ffa);
7874
if (varType.equals(VariableType.UNKNOWN)) {
7975
varType = dataVarType;
8076
} else if (!varType.equals(dataVarType)) {
@@ -104,4 +100,35 @@ protected void writeFieldData() throws ExpressionException, DataAccessException
104100
printWriter.println();
105101
}
106102

103+
private VariableType getVariableTypeFromFieldDataFiles(FieldDataIdentifierSpec fieldDataIDSpec, FieldFunctionArguments ffa) throws DataAccessException {
104+
105+
try {
106+
final VariableType dataVarType;
107+
//
108+
// First, look to see if the processed field data file already exists, if so, use it to determine the variable type
109+
//
110+
DataSet dataSet = new DataSet();
111+
ExternalDataIdentifier existingFieldDataID = new ExternalDataIdentifier(this.simTask.getSimKey(), User.tempUser, ffa.getFieldName());
112+
File existingFieldDataFile = new File(workingDirectory, SimulationData.createCanonicalResampleFileName(existingFieldDataID, ffa));
113+
if (existingFieldDataFile.exists()) {
114+
// field data file may already exist
115+
// 1. from pyvcell writing the field data file directly into this directory for an image-based field data
116+
dataSet.read(existingFieldDataFile, null);
117+
int varTypeInteger = dataSet.getVariableTypeInteger(fieldDataIDSpec.getFieldFuncArgs().getVariableName());
118+
dataVarType = VariableType.getVariableTypeFromInteger(varTypeInteger);
119+
}else {
120+
//
121+
// Else, read the unprocessed simulation results referenced in the FieldDataIdentifierSpec and extract the VariableType
122+
//
123+
File ext_data_dir = new File(workingDirectory.getParentFile(), ffa.getFieldName());
124+
VCData vcData = new SimulationData(fieldDataIDSpec.getExternalDataIdentifier(), ext_data_dir, ext_data_dir, null);
125+
SimDataBlock simDataBlock = vcData.getSimDataBlock(null, ffa.getVariableName(), ffa.getTime().evaluateConstant());
126+
dataVarType = simDataBlock.getVariableType();
127+
}
128+
return dataVarType;
129+
} catch (IOException | ExpressionException | DataAccessException e) {
130+
throw new DataAccessException("Error reading field data file: " + e.getMessage());
131+
}
132+
}
133+
107134
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.vcell.libvcell;
2+
3+
import cbit.util.xml.VCLoggerException;
4+
import cbit.vcell.mapping.MappingException;
5+
import cbit.vcell.xml.XmlParseException;
6+
import org.junit.jupiter.api.Test;
7+
import org.vcell.sbml.SbmlException;
8+
9+
import javax.xml.stream.XMLStreamException;
10+
import java.io.File;
11+
import java.io.IOException;
12+
import java.nio.file.Files;
13+
14+
import static org.vcell.libvcell.ModelUtils.*;
15+
import static org.vcell.libvcell.TestUtils.getFileContentsAsString;
16+
17+
public class ModelEntrypointsTest {
18+
19+
@Test
20+
public void test_sbml_to_vcml() throws MappingException, IOException, XmlParseException, VCLoggerException {
21+
String sbmlContent = getFileContentsAsString("/TinySpatialProject_Application0.xml");
22+
File parent_dir = Files.createTempDirectory("sbmlToVcml").toFile();
23+
File vcml_temp_file = new File(parent_dir, "temp.vcml");
24+
sbml_to_vcml(sbmlContent, vcml_temp_file.toPath());
25+
assert(vcml_temp_file.exists());
26+
}
27+
28+
@Test
29+
public void test_vcml_to_sbml() throws MappingException, IOException, XmlParseException, XMLStreamException, SbmlException {
30+
String vcmlContent = getFileContentsAsString("/TinySpatialProject_Application0.vcml");
31+
File parent_dir = Files.createTempDirectory("vcmlToSbml").toFile();
32+
File sbml_temp_file = new File(parent_dir, "temp.sbml");
33+
String applicationName = "unnamed_spatialGeom";
34+
vcml_to_sbml(vcmlContent, applicationName, sbml_temp_file.toPath());
35+
assert(sbml_temp_file.exists());
36+
}
37+
38+
@Test
39+
public void test_vcml_to_vcml() throws MappingException, IOException, XmlParseException, XMLStreamException, SbmlException {
40+
String vcmlContent = getFileContentsAsString("/TinySpatialProject_Application0.vcml");
41+
File parent_dir = Files.createTempDirectory("vcmlToVcml").toFile();
42+
File vcml_temp_file = new File(parent_dir, "temp.vcml");
43+
vcml_to_vcml(vcmlContent, vcml_temp_file.toPath());
44+
assert(vcml_temp_file.exists());
45+
}
46+
47+
}

0 commit comments

Comments
 (0)