diff --git a/pyproject.toml b/pyproject.toml index eb8cd13..e8b84ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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 ", "Ezequiel Valencia "] repository = "https://github.com/virtualcell/libvcell" diff --git a/vcell-native/src/main/java/org/vcell/libvcell/SolverUtils.java b/vcell-native/src/main/java/org/vcell/libvcell/SolverUtils.java index 31352c7..29579c4 100644 --- a/vcell-native/src/main/java/org/vcell/libvcell/SolverUtils.java +++ b/vcell-native/src/main/java/org/vcell/libvcell/SolverUtils.java @@ -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; @@ -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; @@ -49,17 +51,35 @@ 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) { @@ -67,6 +87,21 @@ private static FieldDataIdentifierSpec[] getFieldDataIdentifierSpecs(Simulation 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()); diff --git a/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFVSolverStandalone.java b/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFVSolverStandalone.java index 8b2dde0..c1072ef 100644 --- a/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFVSolverStandalone.java +++ b/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFVSolverStandalone.java @@ -167,7 +167,6 @@ public void writeFieldFunctionData(OutputContext outputContext, FieldDataIdentif HashMap 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); @@ -179,6 +178,9 @@ public void writeFieldFunctionData(OutputContext outputContext, FieldDataIdentif Set> resampleSet = uniqueFieldDataIDSpecAndFileH.entrySet(); for (Map.Entry 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(); diff --git a/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFiniteVolumeFileWriter.java b/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFiniteVolumeFileWriter.java index aebd22c..3813594 100644 --- a/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFiniteVolumeFileWriter.java +++ b/vcell-native/src/main/java/org/vcell/libvcell/solvers/LocalFiniteVolumeFileWriter.java @@ -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; @@ -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)) { @@ -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()); + } + } + } diff --git a/vcell-native/src/test/java/org/vcell/libvcell/ModelEntrypointsTest.java b/vcell-native/src/test/java/org/vcell/libvcell/ModelEntrypointsTest.java new file mode 100644 index 0000000..b6ae444 --- /dev/null +++ b/vcell-native/src/test/java/org/vcell/libvcell/ModelEntrypointsTest.java @@ -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()); + } + +} diff --git a/vcell-native/src/test/java/org/vcell/libvcell/EntrypointsTest.java b/vcell-native/src/test/java/org/vcell/libvcell/SolverEntrypointsTest.java similarity index 59% rename from vcell-native/src/test/java/org/vcell/libvcell/EntrypointsTest.java rename to vcell-native/src/test/java/org/vcell/libvcell/SolverEntrypointsTest.java index f93c3c3..e3b890c 100644 --- a/vcell-native/src/test/java/org/vcell/libvcell/EntrypointsTest.java +++ b/vcell-native/src/test/java/org/vcell/libvcell/SolverEntrypointsTest.java @@ -6,30 +6,21 @@ import cbit.vcell.parser.ExpressionException; import cbit.vcell.solver.SolverException; import cbit.vcell.xml.XmlParseException; -import org.apache.commons.compress.archivers.tar.TarArchiveEntry; -import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.junit.jupiter.api.Test; -import org.vcell.sbml.SbmlException; -import javax.xml.stream.XMLStreamException; import java.beans.PropertyVetoException; -import java.io.*; -import java.nio.charset.StandardCharsets; +import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Objects; import java.util.UUID; -import java.util.stream.Collectors; -import java.util.zip.GZIPInputStream; import static org.junit.jupiter.api.Assertions.*; import static org.vcell.libvcell.SolverUtils.sbmlToFiniteVolumeInput; import static org.vcell.libvcell.SolverUtils.vcmlToFiniteVolumeInput; -import static org.vcell.libvcell.ModelUtils.sbml_to_vcml; -import static org.vcell.libvcell.ModelUtils.vcml_to_sbml; -import static org.vcell.libvcell.ModelUtils.vcml_to_vcml; +import static org.vcell.libvcell.TestUtils.*; -public class EntrypointsTest { +public class SolverEntrypointsTest { @Test public void testSbmlToFiniteVolumeInput() throws PropertyVetoException, SolverException, ExpressionException, MappingException, VCLoggerException, IOException { @@ -59,6 +50,23 @@ public void testSbmlToFiniteVolumeInput_vcml_instead() throws IOException { assertEquals("expecting SBML content, not VCML", exc.getMessage()); } + @Test + public void testVcmlToFiniteVolumeInput_field_data_already_sampled() throws SolverException, ExpressionException, MappingException, IOException, XmlParseException, MathException, InterruptedException { + String vcmlContent = getFileContentsAsString("/FieldDataDemo.vcml"); + File parent_dir = Files.createTempDirectory("vcmlToFiniteVolumeInput_"+UUID.randomUUID()).toFile(); + File output_dir = new File(parent_dir, "output_dir"); + assertEquals(0, countFiles(output_dir)); + // prepopulate the output_dir with the resampled field data files, should use these instead. + extractTgz(SolverEntrypointsTest.class.getResourceAsStream("/test2_lsm_DEMO_resampled.tgz"), output_dir); + listFilesInDirectory(output_dir); + assertEquals(2, countFiles(output_dir)); + + String simulationName = "Simulation0"; + vcmlToFiniteVolumeInput(vcmlContent, simulationName, parent_dir, output_dir); + listFilesInDirectory(output_dir); + assertEquals(6, countFiles(output_dir)); + } + @Test public void testVcmlToFiniteVolumeInput_field_data() throws SolverException, ExpressionException, MappingException, IOException, XmlParseException, MathException, InterruptedException { String vcmlContent = getFileContentsAsString("/FieldDataDemo.vcml"); @@ -66,7 +74,7 @@ public void testVcmlToFiniteVolumeInput_field_data() throws SolverException, Exp File output_dir = new File(parent_dir, "output_dir"); File ext_data_dir = new File(parent_dir, "test2_lsm_DEMO"); assertEquals(0, countFiles(ext_data_dir)); - extractTgz(EntrypointsTest.class.getResourceAsStream("/test2_lsm_DEMO.tgz"), parent_dir); + extractTgz(SolverEntrypointsTest.class.getResourceAsStream("/test2_lsm_DEMO.tgz"), parent_dir); listFilesInDirectory(ext_data_dir); assertEquals(10, countFiles(ext_data_dir)); @@ -79,7 +87,7 @@ public void testVcmlToFiniteVolumeInput_field_data() throws SolverException, Exp } @Test - public void testVcmlToFiniteVolumeInput_field_data_not_found() throws SolverException, ExpressionException, MappingException, IOException, XmlParseException, MathException, InterruptedException { + public void testVcmlToFiniteVolumeInput_field_data_not_found() throws IOException { String vcmlContent = getFileContentsAsString("/FieldDataDemo.vcml"); File parent_dir = Files.createTempDirectory("vcmlToFiniteVolumeInput_"+UUID.randomUUID()).toFile(); File output_dir = new File(parent_dir, "output_dir"); @@ -87,7 +95,7 @@ public void testVcmlToFiniteVolumeInput_field_data_not_found() throws SolverExce File ext_data_dir_MISSPELLED = new File(parent_dir, "test2_lsm_DEMO_MISSPELLED"); assertEquals(0, countFiles(ext_data_dir)); assertEquals(0, countFiles(ext_data_dir_MISSPELLED)); - extractTgz(EntrypointsTest.class.getResourceAsStream("/test2_lsm_DEMO.tgz"), parent_dir); + extractTgz(SolverEntrypointsTest.class.getResourceAsStream("/test2_lsm_DEMO.tgz"), parent_dir); Files.move(ext_data_dir.toPath(), ext_data_dir_MISSPELLED.toPath()).toFile(); assertEquals(0, countFiles(ext_data_dir)); listFilesInDirectory(ext_data_dir_MISSPELLED); @@ -112,34 +120,6 @@ public void testVcmlToFiniteVolumeInput() throws SolverException, ExpressionExce assertEquals(4, countFiles(output_dir)); } - @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()); - } - @Test public void testVcmlToFiniteVolumeInput_bad_simname() throws IOException { String vcmlContent = getFileContentsAsString("/TinySpatialProject_Application0.vcml"); @@ -177,75 +157,4 @@ public void testVcmlToFiniteVolumeInput_sbml_instead() throws IOException { assertEquals("expecting VCML content, not SBML", exc.getMessage()); } - private static String getFileContentsAsString(String filename) throws IOException { - try (InputStream inputStream = EntrypointsTest.class.getResourceAsStream(filename)) { - if (inputStream == null) { - throw new FileNotFoundException("file not found! " + filename); - } - return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)) - .lines().collect(Collectors.joining("\n")); - } - } - - private static byte[] getFileContentsAsBytes(String filename) throws IOException { - try (InputStream inputStream = EntrypointsTest.class.getResourceAsStream(filename)) { - if (inputStream == null) { - throw new FileNotFoundException("file not found! " + filename); - } - try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { - byte[] buffer = new byte[1024]; - int length; - while ((length = inputStream.read(buffer)) != -1) { - byteArrayOutputStream.write(buffer, 0, length); - } - return byteArrayOutputStream.toByteArray(); - } - } - } - - private int countFiles(File dir) { - File[] files = dir.listFiles(); - if (files == null) { - return 0; - } - return Objects.requireNonNull(dir.listFiles()).length; - } - - private void listFilesInDirectory(File dir) { - File[] files = dir.listFiles(); - if (files != null) { - for (File file : files) { - System.out.println(file.getAbsolutePath()); - } - } - } - - public static void extractTgz(InputStream tgzFileStream, File outputDir) throws IOException { - try (GZIPInputStream gis = new GZIPInputStream(tgzFileStream); - TarArchiveInputStream tis = new TarArchiveInputStream(gis)) { - - TarArchiveEntry entry; - while ((entry = tis.getNextTarEntry()) != null) { - File outputFile = new File(outputDir, entry.getName()); - if (entry.isDirectory()) { - if (!outputFile.exists()) { - outputFile.mkdirs(); - } - } else { - File parent = outputFile.getParentFile(); - if (!parent.exists()) { - parent.mkdirs(); - } - try (OutputStream os = Files.newOutputStream(outputFile.toPath())) { - byte[] buffer = new byte[1024]; - int len; - while ((len = tis.read(buffer)) != -1) { - os.write(buffer, 0, len); - } - } - } - } - } - } - } diff --git a/vcell-native/src/test/java/org/vcell/libvcell/TestUtils.java b/vcell-native/src/test/java/org/vcell/libvcell/TestUtils.java new file mode 100644 index 0000000..f032a20 --- /dev/null +++ b/vcell-native/src/test/java/org/vcell/libvcell/TestUtils.java @@ -0,0 +1,86 @@ +package org.vcell.libvcell; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.zip.GZIPInputStream; + +public class TestUtils { + public static String getFileContentsAsString(String filename) throws IOException { + try (InputStream inputStream = ModelEntrypointsTest.class.getResourceAsStream(filename)) { + if (inputStream == null) { + throw new FileNotFoundException("file not found! " + filename); + } + return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)) + .lines().collect(Collectors.joining("\n")); + } + } + + public static byte[] getFileContentsAsBytes(String filename) throws IOException { + try (InputStream inputStream = SolverEntrypointsTest.class.getResourceAsStream(filename)) { + if (inputStream == null) { + throw new FileNotFoundException("file not found! " + filename); + } + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + byteArrayOutputStream.write(buffer, 0, length); + } + return byteArrayOutputStream.toByteArray(); + } + } + } + + public static int countFiles(File dir) { + File[] files = dir.listFiles(); + if (files == null) { + return 0; + } + return Objects.requireNonNull(dir.listFiles()).length; + } + + public static void listFilesInDirectory(File dir) { + File[] files = dir.listFiles(); + if (files != null) { + for (File file : files) { + System.out.println(file.getAbsolutePath()); + } + } + } + + public static void extractTgz(InputStream tgzFileStream, File outputDir) throws IOException { + try (GZIPInputStream gis = new GZIPInputStream(tgzFileStream); + TarArchiveInputStream tis = new TarArchiveInputStream(gis)) { + + TarArchiveEntry entry; + while ((entry = tis.getNextTarEntry()) != null) { + File outputFile = new File(outputDir, entry.getName()); + if (entry.isDirectory()) { + if (!outputFile.exists()) { + outputFile.mkdirs(); + } + } else { + File parent = outputFile.getParentFile(); + if (!parent.exists()) { + parent.mkdirs(); + } + try (OutputStream os = Files.newOutputStream(outputFile.toPath())) { + byte[] buffer = new byte[1024]; + int len; + while ((len = tis.read(buffer)) != -1) { + os.write(buffer, 0, len); + } + } + } + } + } + } + + +} diff --git a/vcell-native/src/test/resources/test2_lsm_DEMO_resampled.tgz b/vcell-native/src/test/resources/test2_lsm_DEMO_resampled.tgz new file mode 100644 index 0000000..c2fd6d7 Binary files /dev/null and b/vcell-native/src/test/resources/test2_lsm_DEMO_resampled.tgz differ diff --git a/vcell_submodule b/vcell_submodule index ac098f0..0c860b5 160000 --- a/vcell_submodule +++ b/vcell_submodule @@ -1 +1 @@ -Subproject commit ac098f087c19997fca9074a65e6cbcbefbc15d46 +Subproject commit 0c860b574b260cf14d31f19b448c6dc5b240d0e7