Skip to content
Merged
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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "libvcell"
version = "0.0.9"
version = "0.0.10"
description = "This is a python package which wraps a subset of VCell Java code as a native python package."
authors = ["Jim Schaff <[email protected]>", "Ezequiel Valencia <[email protected]>"]
repository = "https://github.com/virtualcell/libvcell"
Expand Down
39 changes: 37 additions & 2 deletions vcell-native/src/main/java/org/vcell/libvcell/SolverUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import cbit.vcell.messaging.server.SimulationTask;
import cbit.vcell.mongodb.VCMongoMessage;
import cbit.vcell.parser.ExpressionException;
import cbit.vcell.simdata.SimulationData;
import cbit.vcell.solver.*;
import cbit.vcell.xml.XMLSource;
import cbit.vcell.xml.XmlHelper;
Expand All @@ -30,6 +31,7 @@
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

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

TempSimulation tempSimulation = new TempSimulation(sim, false);
tempSimulation.setSimulationOwner(sim.getSimulationOwner());
SimulationJob tempSimulationJob = new SimulationJob(tempSimulation, 0, fdiSpecs);

renameExistingFieldDataFiles(tempSimulation.getKey(), tempSimulationJob.getJobIndex(), outputDir);

SimulationTask simTask = new SimulationTask(tempSimulationJob, 0);
LocalFVSolverStandalone solver = new LocalFVSolverStandalone(simTask, outputDir);
solver.initialize();
}

private static FieldDataIdentifierSpec[] getFieldDataIdentifierSpecs(Simulation sim, File parentDir) throws MathException, ExpressionException {
private static void renameExistingFieldDataFiles(KeyValue tempSimKey, int jobId, File outputDir) {
File[] files = outputDir.listFiles();
if (files != null) {
for (File file : files) {
if (file.getName().startsWith("SimID_SIMULATIONKEY_JOBINDEX_")) {
String newName = file.getName().replace("SIMULATIONKEY",tempSimKey.toString()).replace("JOBINDEX",String.valueOf(jobId));
File newFile = new File(outputDir, newName);
if (!file.renameTo(newFile)){
throw new RuntimeException("Could not rename " + file.getName() + " to " + newFile.getAbsolutePath());
}
}
}
}
}

private static FieldDataIdentifierSpec[] getFieldDataIdentifierSpecs(Simulation sim, File outputDir, File parentDir) throws MathException, ExpressionException {
FieldDataIdentifierSpec[] fdiSpecs = null;
FieldFunctionArguments[] fieldFuncArgs = FieldUtilities.getFieldFunctionArguments(sim.getMathDescription());
if (fieldFuncArgs != null) {
List<FieldDataIdentifierSpec> fdiSpecList = new ArrayList<>();
for (FieldFunctionArguments fieldFuncArg : fieldFuncArgs) {
if (fieldFuncArg != null) {
String name = fieldFuncArg.getFieldName();
//
// First, check if the resampled field data files are already present (e.g. if pyvcell wrote the files directly from image data)
//
ExternalDataIdentifier fakeExtDataId = new ExternalDataIdentifier(sim.getKey(), User.tempUser, name);
String fieldDataFileName = SimulationData.createCanonicalResampleFileName(fakeExtDataId, fieldFuncArg);
fieldDataFileName = fieldDataFileName.replace("SimID_" + sim.getKey().toString() + "_0_", "SimID_SIMULATIONKEY_JOBINDEX_");
File preexistingFieldDataFile = new File(outputDir, fieldDataFileName);
if (preexistingFieldDataFile.exists()) {
fdiSpecList.add(new FieldDataIdentifierSpec(fieldFuncArg, fakeExtDataId));
continue;
}

//
// If not, check if the field data directory exists as a subdirectory of the parentDir - holding simulation results.
//
File fieldDataDir = new File(parentDir, name);
if (!fieldDataDir.exists()) {
throw new IllegalArgumentException("Field data directory does not exist: " + fieldDataDir.getAbsolutePath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ public void writeFieldFunctionData(OutputContext outputContext, FieldDataIdentif
HashMap<FieldDataIdentifierSpec, Boolean> bFieldDataResample = new HashMap<>();
int i=0;
for (FieldDataIdentifierSpec fdiSpec: argFieldDataIDSpecs) {
File ext_dataDir = new File(this.parentDir, fdiSpec.getFieldFuncArgs().getFieldName());
if (!uniqueFieldDataIDSpecAndFileH.containsKey(fdiSpec)){
File newResampledFieldDataFile = new File(dataDir, SimulationData.createCanonicalResampleFileName(getSimulationJob().getVCDataIdentifier(), fdiSpec.getFieldFuncArgs()));
uniqueFieldDataIDSpecAndFileH.put(fdiSpec,newResampledFieldDataFile);
Expand All @@ -179,6 +178,9 @@ public void writeFieldFunctionData(OutputContext outputContext, FieldDataIdentif
Set<Map.Entry<FieldDataIdentifierSpec, File>> resampleSet = uniqueFieldDataIDSpecAndFileH.entrySet();
for (Map.Entry<FieldDataIdentifierSpec, File> resampleEntry : resampleSet) {
if (resampleEntry.getValue().exists()) {
// field data file has already been written
// 1. in a previous loop iteration
// 2. from pyvcell writing the field data file directly into this directory for an image-based field data
continue;
}
FieldDataIdentifierSpec fieldDataIdSpec = resampleEntry.getKey();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
import cbit.vcell.math.Variable;
import cbit.vcell.math.VariableType;
import cbit.vcell.messaging.server.SimulationTask;
import cbit.vcell.parser.DivideByZeroException;
import cbit.vcell.parser.Expression;
import cbit.vcell.parser.ExpressionException;
import cbit.vcell.simdata.DataSet;
import cbit.vcell.simdata.SimDataBlock;
import cbit.vcell.simdata.SimulationData;
import cbit.vcell.simdata.VCData;
import cbit.vcell.solver.Simulation;
import cbit.vcell.solvers.FiniteVolumeFileWriter;
import org.vcell.util.DataAccessException;
import org.vcell.util.document.ExternalDataIdentifier;
import org.vcell.util.document.User;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -66,15 +70,7 @@ protected void writeFieldData() throws ExpressionException, DataAccessException
);
uniqueFieldDataIDSpecs.add(fieldDataIDSpec);
VariableType varType = fieldDataIDSpec.getFieldFuncArgs().getVariableType();
final VariableType dataVarType;
try {
File ext_data_dir = new File(workingDirectory.getParentFile(), ffa.getFieldName());
VCData vcData = new SimulationData(fieldDataIDSpec.getExternalDataIdentifier(), ext_data_dir, ext_data_dir, null);
SimDataBlock simDataBlock = vcData.getSimDataBlock(null, ffa.getVariableName(), ffa.getTime().evaluateConstant());
dataVarType = simDataBlock.getVariableType();
} catch (IOException e) {
throw new DataAccessException("Error reading field data file: " + e.getMessage());
}
final VariableType dataVarType = getVariableTypeFromFieldDataFiles(fieldDataIDSpec, ffa);
if (varType.equals(VariableType.UNKNOWN)) {
varType = dataVarType;
} else if (!varType.equals(dataVarType)) {
Expand Down Expand Up @@ -104,4 +100,35 @@ protected void writeFieldData() throws ExpressionException, DataAccessException
printWriter.println();
}

private VariableType getVariableTypeFromFieldDataFiles(FieldDataIdentifierSpec fieldDataIDSpec, FieldFunctionArguments ffa) throws DataAccessException {

try {
final VariableType dataVarType;
//
// First, look to see if the processed field data file already exists, if so, use it to determine the variable type
//
DataSet dataSet = new DataSet();
ExternalDataIdentifier existingFieldDataID = new ExternalDataIdentifier(this.simTask.getSimKey(), User.tempUser, ffa.getFieldName());
File existingFieldDataFile = new File(workingDirectory, SimulationData.createCanonicalResampleFileName(existingFieldDataID, ffa));
if (existingFieldDataFile.exists()) {
// field data file may already exist
// 1. from pyvcell writing the field data file directly into this directory for an image-based field data
dataSet.read(existingFieldDataFile, null);
int varTypeInteger = dataSet.getVariableTypeInteger(fieldDataIDSpec.getFieldFuncArgs().getVariableName());
dataVarType = VariableType.getVariableTypeFromInteger(varTypeInteger);
}else {
//
// Else, read the unprocessed simulation results referenced in the FieldDataIdentifierSpec and extract the VariableType
//
File ext_data_dir = new File(workingDirectory.getParentFile(), ffa.getFieldName());
VCData vcData = new SimulationData(fieldDataIDSpec.getExternalDataIdentifier(), ext_data_dir, ext_data_dir, null);
SimDataBlock simDataBlock = vcData.getSimDataBlock(null, ffa.getVariableName(), ffa.getTime().evaluateConstant());
dataVarType = simDataBlock.getVariableType();
}
return dataVarType;
} catch (IOException | ExpressionException | DataAccessException e) {
throw new DataAccessException("Error reading field data file: " + e.getMessage());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.vcell.libvcell;

import cbit.util.xml.VCLoggerException;
import cbit.vcell.mapping.MappingException;
import cbit.vcell.xml.XmlParseException;
import org.junit.jupiter.api.Test;
import org.vcell.sbml.SbmlException;

import javax.xml.stream.XMLStreamException;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

import static org.vcell.libvcell.ModelUtils.*;
import static org.vcell.libvcell.TestUtils.getFileContentsAsString;

public class ModelEntrypointsTest {

@Test
public void test_sbml_to_vcml() throws MappingException, IOException, XmlParseException, VCLoggerException {
String sbmlContent = getFileContentsAsString("/TinySpatialProject_Application0.xml");
File parent_dir = Files.createTempDirectory("sbmlToVcml").toFile();
File vcml_temp_file = new File(parent_dir, "temp.vcml");
sbml_to_vcml(sbmlContent, vcml_temp_file.toPath());
assert(vcml_temp_file.exists());
}

@Test
public void test_vcml_to_sbml() throws MappingException, IOException, XmlParseException, XMLStreamException, SbmlException {
String vcmlContent = getFileContentsAsString("/TinySpatialProject_Application0.vcml");
File parent_dir = Files.createTempDirectory("vcmlToSbml").toFile();
File sbml_temp_file = new File(parent_dir, "temp.sbml");
String applicationName = "unnamed_spatialGeom";
vcml_to_sbml(vcmlContent, applicationName, sbml_temp_file.toPath());
assert(sbml_temp_file.exists());
}

@Test
public void test_vcml_to_vcml() throws MappingException, IOException, XmlParseException, XMLStreamException, SbmlException {
String vcmlContent = getFileContentsAsString("/TinySpatialProject_Application0.vcml");
File parent_dir = Files.createTempDirectory("vcmlToVcml").toFile();
File vcml_temp_file = new File(parent_dir, "temp.vcml");
vcml_to_vcml(vcmlContent, vcml_temp_file.toPath());
assert(vcml_temp_file.exists());
}

}
Loading