From 6fc99362de8b633b017925bf21190bc2ef60c5bc Mon Sep 17 00:00:00 2001 From: Erik Pelgrim Date: Wed, 25 Mar 2026 15:44:13 +0100 Subject: [PATCH 1/7] Add basic DFlowFMNetCDFSampleFile DataObject --- .../DFlowFMNetCDFSampleFile.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java new file mode 100644 index 000000000..19be9daf7 --- /dev/null +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java @@ -0,0 +1,57 @@ +package org.openda.model_dflowfm; + +import org.openda.exchange.AbstractDataObject; +import org.openda.utils.generalJavaUtils.StringUtilities; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +public class DFlowFMNetCDFSampleFile extends AbstractDataObject { + + enum DataFormat {TimeConstant, TimeIndependent} + + private static final String ID_PREFIX = "idPrefix"; + private static final String NETCDF_VARIABLE = "netcdfVariable"; + private static final String DATA_FORMAT = "dataFormat"; + + private Set variablesForExchangeItems = new HashSet<>(); + private DataFormat dataFormat; + private String idPrefix; + + @Override + public void initialize(File workingDir, String[] arguments) { + if (arguments.length < 4) { + throw new RuntimeException(String.format("Incorrect number of arguments. Please specify [%s, %s, %s] as key=value pairs", ID_PREFIX, NETCDF_VARIABLE, NETCDF_VARIABLE)); + } + for (int i = 0; i < arguments.length; i++) { + String argument = arguments[i]; + String[] keyValue = StringUtilities.getKeyValuePair(argument); + if (keyValue == null || keyValue.length != 2) throw new RuntimeException(String.format("Invalid key=value pair: %s", argument)); + String key = keyValue[0]; + String value = keyValue[1]; + switch (key) { + case ID_PREFIX: + idPrefix = value; + continue; + case NETCDF_VARIABLE: + variablesForExchangeItems.add(value); + continue; + case DATA_FORMAT: + dataFormat = DataFormat.valueOf(value); + continue; + default: + throw new RuntimeException(String.format("Unknown key %s. Please only specify [%s, %s, %s] as key=value pairs", key, ID_PREFIX, NETCDF_VARIABLE, NETCDF_VARIABLE)); + } + } + if (idPrefix == null || variablesForExchangeItems.isEmpty() || dataFormat == null) + throw new RuntimeException(String.format("Arguments missing. Please specify [%s, %s, %s] as key=value pairs", ID_PREFIX, NETCDF_VARIABLE, NETCDF_VARIABLE)); + + + } + + @Override + public void finish() { + + } +} From cb4e343a5a4a2aebf94d5083e38371a34a3981d9 Mon Sep 17 00:00:00 2001 From: Erik Pelgrim Date: Wed, 25 Mar 2026 16:24:01 +0100 Subject: [PATCH 2/7] Add basic DFlowFMNetCDFSampleFile DataObject --- .../DFlowFMNetCDFSampleFile.java | 57 ----------- .../DFlowFMNetcdfSampleFile.java | 91 ++++++++++++++++++ .../DFlowFMNetcdfSampleFileTest.java | 25 +++++ .../ExampleTimeConstant.nc | Bin 0 -> 44386 bytes .../ExampleTimeIndependent.nc | Bin 0 -> 40960 bytes 5 files changed, 116 insertions(+), 57 deletions(-) delete mode 100644 model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java create mode 100644 model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java create mode 100644 model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java create mode 100644 model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeConstant.nc create mode 100644 model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeIndependent.nc diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java deleted file mode 100644 index 19be9daf7..000000000 --- a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetCDFSampleFile.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.openda.model_dflowfm; - -import org.openda.exchange.AbstractDataObject; -import org.openda.utils.generalJavaUtils.StringUtilities; - -import java.io.File; -import java.util.HashSet; -import java.util.Set; - -public class DFlowFMNetCDFSampleFile extends AbstractDataObject { - - enum DataFormat {TimeConstant, TimeIndependent} - - private static final String ID_PREFIX = "idPrefix"; - private static final String NETCDF_VARIABLE = "netcdfVariable"; - private static final String DATA_FORMAT = "dataFormat"; - - private Set variablesForExchangeItems = new HashSet<>(); - private DataFormat dataFormat; - private String idPrefix; - - @Override - public void initialize(File workingDir, String[] arguments) { - if (arguments.length < 4) { - throw new RuntimeException(String.format("Incorrect number of arguments. Please specify [%s, %s, %s] as key=value pairs", ID_PREFIX, NETCDF_VARIABLE, NETCDF_VARIABLE)); - } - for (int i = 0; i < arguments.length; i++) { - String argument = arguments[i]; - String[] keyValue = StringUtilities.getKeyValuePair(argument); - if (keyValue == null || keyValue.length != 2) throw new RuntimeException(String.format("Invalid key=value pair: %s", argument)); - String key = keyValue[0]; - String value = keyValue[1]; - switch (key) { - case ID_PREFIX: - idPrefix = value; - continue; - case NETCDF_VARIABLE: - variablesForExchangeItems.add(value); - continue; - case DATA_FORMAT: - dataFormat = DataFormat.valueOf(value); - continue; - default: - throw new RuntimeException(String.format("Unknown key %s. Please only specify [%s, %s, %s] as key=value pairs", key, ID_PREFIX, NETCDF_VARIABLE, NETCDF_VARIABLE)); - } - } - if (idPrefix == null || variablesForExchangeItems.isEmpty() || dataFormat == null) - throw new RuntimeException(String.format("Arguments missing. Please specify [%s, %s, %s] as key=value pairs", ID_PREFIX, NETCDF_VARIABLE, NETCDF_VARIABLE)); - - - } - - @Override - public void finish() { - - } -} diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java new file mode 100644 index 000000000..eaae9fb31 --- /dev/null +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java @@ -0,0 +1,91 @@ +package org.openda.model_dflowfm; + +import org.openda.exchange.AbstractDataObject; +import org.openda.utils.generalJavaUtils.StringUtilities; +import ucar.nc2.NetcdfFile; +import ucar.nc2.Variable; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class DFlowFMNetcdfSampleFile extends AbstractDataObject { + + enum DataFormat {TimeIndependent(1), TimeConstant(2); + + private final int variableDimensions; + + DataFormat(int variableDimensions) { + this.variableDimensions = variableDimensions; + } + + } + + public static final String AREA_NUMBER = "area_number"; + private static final String ID_PREFIX = "idPrefix"; + private static final String NETCDF_VARIABLE = "netcdfVariable"; + private static final String DATA_FORMAT = "dataFormat"; + + private Set variablesForExchangeItems = new HashSet<>(); + private DataFormat dataFormat; + private String idPrefix; + private File file = null; + private NetcdfFile netcdfFile = null; + + @Override + public void initialize(File workingDir, String[] arguments) { + if (arguments.length < 4) + throw new RuntimeException(String.format("Incorrect number of arguments. Please specify [%s, %s, %s] as key=value pairs", ID_PREFIX, NETCDF_VARIABLE, DATA_FORMAT)); + String fileName = arguments[0]; + this.file = new File(workingDir, fileName); + for (int i = 1; i < arguments.length; i++) { + String argument = arguments[i]; + String[] keyValue = StringUtilities.getKeyValuePair(argument); + if (keyValue == null || keyValue.length != 2) throw new RuntimeException(String.format("Invalid key=value pair: %s", argument)); + String key = keyValue[0]; + String value = keyValue[1]; + switch (key) { + case ID_PREFIX: + idPrefix = value; + continue; + case NETCDF_VARIABLE: + variablesForExchangeItems.add(value); + continue; + case DATA_FORMAT: + dataFormat = DataFormat.valueOf(value); + continue; + default: + throw new RuntimeException(String.format("Unknown key %s. Please only specify [%s, %s, %s] as key=value pairs", key, ID_PREFIX, NETCDF_VARIABLE, DATA_FORMAT)); + } + } + if (idPrefix == null || variablesForExchangeItems.isEmpty() || dataFormat == null) + throw new RuntimeException(String.format("Arguments missing. Please specify [%s, %s, %s] as key=value pairs", ID_PREFIX, NETCDF_VARIABLE, DATA_FORMAT)); + + try { + this.netcdfFile = NetcdfFile.open(this.file.getAbsolutePath()); + List variables = netcdfFile.getVariables(); + int[] areaNumbers = null; + for (Variable variable : variables) { + String varName = variable.getShortName(); + int[] shape = variable.getShape(); + if (varName.equals(AREA_NUMBER)) { + areaNumbers = (int[]) variable.read().get1DJavaArray(int.class); + continue; + } + if (!variablesForExchangeItems.contains(varName)) continue; + if (dataFormat.variableDimensions != shape.length) throw new RuntimeException(String.format("Variable %s has %d dimensions, but expected %d dimensions for data format %s", variable.getShortName(), shape.length, dataFormat.variableDimensions, dataFormat.name())); + + } + if (areaNumbers == null) throw new RuntimeException(String.format("Variable %s not found in netCDF file", AREA_NUMBER)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void finish() { + + } +} diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java new file mode 100644 index 000000000..b50849bd9 --- /dev/null +++ b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java @@ -0,0 +1,25 @@ +package org.openda.model_dflowfm; + +import junit.framework.TestCase; +import org.openda.utils.OpenDaTestSupport; + +import java.io.File; +import java.io.IOException; + +public class DFlowFMNetcdfSampleFileTest extends TestCase { + OpenDaTestSupport testData = null; + private File testRunDataRestartFileDir; + + + protected void setUp() throws IOException { + testData = new OpenDaTestSupport(DFlowFMRestartTest.class, "model_dflowfm_blackbox"); + testRunDataRestartFileDir = new File(testData.getTestRunDataDir(), "DFlowFMNetCDFSample"); + } + + public void testTimeConstant() { + DFlowFMNetcdfSampleFile dataObject = new DFlowFMNetcdfSampleFile(); + dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=Phase", "dataFormat=TimeConstant"}); + String[] exchangeItemIDs = dataObject.getExchangeItemIDs(); + assertEquals(0, exchangeItemIDs.length); + } +} diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeConstant.nc b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeConstant.nc new file mode 100644 index 0000000000000000000000000000000000000000..c9d0254f578b7e2adea3c4060454fc7d5f3e11f3 GIT binary patch literal 44386 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 S|Bqci@EUs=(_iE8F8=}&X3kpx literal 0 HcmV?d00001 From ed73f4e4d98bf3a489bf1ad9789fb5b487ffdca7 Mon Sep 17 00:00:00 2001 From: Erik Pelgrim Date: Wed, 25 Mar 2026 17:06:15 +0100 Subject: [PATCH 3/7] Create exchange items --- .../DFlowFMNetcdfSampleFile.java | 39 ++++-- .../DFlowFMNetcdfSampleFileExchangeItem.java | 114 ++++++++++++++++++ .../DFlowFMNetcdfSampleFileTest.java | 4 +- 3 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java index eaae9fb31..aa2865df9 100644 --- a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java @@ -6,10 +6,7 @@ import ucar.nc2.Variable; import java.io.File; -import java.io.IOException; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class DFlowFMNetcdfSampleFile extends AbstractDataObject { @@ -66,20 +63,36 @@ public void initialize(File workingDir, String[] arguments) { try { this.netcdfFile = NetcdfFile.open(this.file.getAbsolutePath()); List variables = netcdfFile.getVariables(); - int[] areaNumbers = null; + Variable areaNumberVar = netcdfFile.findVariable(AREA_NUMBER); + if (areaNumberVar == null) throw new RuntimeException(String.format("Variable %s not found in netCDF file", AREA_NUMBER)); + int[] areaNumbers = (int[]) areaNumberVar.read().get1DJavaArray(int.class); + Map> areaNumberIndexListMap = new LinkedHashMap<>(); + for (int i = 0; i < areaNumbers.length; i++) { + int areaNumber = areaNumbers[i]; + List indexList = areaNumberIndexListMap.computeIfAbsent(areaNumber, k -> new ArrayList<>()); + indexList.add(i); + } + areaNumberIndexListMap.forEach((index, list) -> System.out.printf("Area number %d has %d indices%n", index, list.size())); for (Variable variable : variables) { String varName = variable.getShortName(); int[] shape = variable.getShape(); - if (varName.equals(AREA_NUMBER)) { - areaNumbers = (int[]) variable.read().get1DJavaArray(int.class); - continue; - } if (!variablesForExchangeItems.contains(varName)) continue; - if (dataFormat.variableDimensions != shape.length) throw new RuntimeException(String.format("Variable %s has %d dimensions, but expected %d dimensions for data format %s", variable.getShortName(), shape.length, dataFormat.variableDimensions, dataFormat.name())); - + if (dataFormat.variableDimensions != shape.length) throw new RuntimeException(String.format("Variable %s has length %d dimensions, but expected %d dimensions for data format %s", variable.getShortName(), shape.length, dataFormat.variableDimensions, dataFormat.name())); + double[] values = (double[]) variable.read().get1DJavaArray(Double.class); + if (values.length != areaNumbers.length) throw new RuntimeException(String.format("Variable %s has length %d, but expected length %d equal to the number of areas in variable %s", variable.getShortName(), values.length, areaNumbers.length, AREA_NUMBER)); + Set>> indicesPerAreaNumber = areaNumberIndexListMap.entrySet(); + for (Map.Entry> entry : indicesPerAreaNumber) { + List indices = entry.getValue(); + double[] eiValues = new double[indices.size()]; + for (int i = 0; i < indices.size(); i++) { + eiValues[i] = values[indices.get(i)]; + } + String id = String.format("%s_%s_%d", idPrefix, varName, entry.getKey()); + exchangeItems.put(id, new DFlowFMNetcdfSampleFileExchangeItem(id, indices, eiValues)); + } } - if (areaNumbers == null) throw new RuntimeException(String.format("Variable %s not found in netCDF file", AREA_NUMBER)); - } catch (IOException e) { + + } catch (Exception e) { throw new RuntimeException(e); } } diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java new file mode 100644 index 000000000..fb858678e --- /dev/null +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java @@ -0,0 +1,114 @@ +package org.openda.model_dflowfm; + +import org.openda.interfaces.IExchangeItem; +import org.openda.interfaces.IGeometryInfo; +import org.openda.interfaces.IQuantityInfo; +import org.openda.interfaces.ITimeInfo; + +import java.util.List; + +public class DFlowFMNetcdfSampleFileExchangeItem implements IExchangeItem { + + private final String id; + private final List indices; + private final double[] eiValues; + + public DFlowFMNetcdfSampleFileExchangeItem(String id, List indices, double[] eiValues) { + this.id = id; + this.indices = indices; + this.eiValues = eiValues; + } + + + @Override + public Role getRole() { + return Role.InOut; + } + + @Override + public String getId() { + return id; + } + + @Override + public String getDescription() { + return ""; + } + + @Override + public void copyValuesFromItem(IExchangeItem sourceItem) { + if (sourceItem.getValuesType() != ValueType.doublesType) { + throw new IllegalArgumentException(String.format("Expected sourceItem to have values of type %s, but got %s", ValueType.doublesType, sourceItem.getValuesType())); + } + double[] sourceValues = sourceItem.getValuesAsDoubles(); + System.arraycopy(sourceValues, 0, this.eiValues, 0, sourceValues.length); + } + + @Override + public ITimeInfo getTimeInfo() { + return null; + } + + @Override + public IQuantityInfo getQuantityInfo() { + return null; + } + + @Override + public IGeometryInfo getGeometryInfo() { + return null; + } + + @Override + public ValueType getValuesType() { + return ValueType.doublesType; + } + + @Override + public Object getValues() { + return eiValues; + } + + @Override + public double[] getValuesAsDoubles() { + return eiValues; + } + + @Override + public void axpyOnValues(double alpha, double[] axpyValues) { + for (int i = 0; i < eiValues.length; i++) { + eiValues[i] += alpha * axpyValues[i]; + } + } + + @Override + public void multiplyValues(double[] multiplicationFactors) { + for (int i = 0; i < eiValues.length; i++) { + eiValues[i] *= multiplicationFactors[i]; + } + } + + @Override + public void setValues(Object values) { + + } + + @Override + public void setValuesAsDoubles(double[] values) { + System.arraycopy(values, 0, eiValues, 0, values.length); + } + + @Override + public double[] getTimes() { + return new double[0]; + } + + @Override + public void setTimes(double[] times) { + + } + + public List getIndices() { + return indices; + } +} diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java index b50849bd9..fa9e73d58 100644 --- a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java +++ b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java @@ -18,8 +18,8 @@ protected void setUp() throws IOException { public void testTimeConstant() { DFlowFMNetcdfSampleFile dataObject = new DFlowFMNetcdfSampleFile(); - dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=Phase", "dataFormat=TimeConstant"}); + dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=phase", "dataFormat=TimeIndependent"}); String[] exchangeItemIDs = dataObject.getExchangeItemIDs(); - assertEquals(0, exchangeItemIDs.length); + assertEquals(67, exchangeItemIDs.length); } } From e8e0829fb83fc9cc2a9589fdfcaa7b248b9b0b01 Mon Sep 17 00:00:00 2001 From: Erik Pelgrim Date: Wed, 25 Mar 2026 17:48:06 +0100 Subject: [PATCH 4/7] Implement finish --- .../DFlowFMNetcdfSampleFile.java | 55 +++++++++++++++++-- .../DFlowFMNetcdfSampleFileExchangeItem.java | 8 ++- .../DFlowFMNetcdfSampleFileTest.java | 13 ++++- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java index aa2865df9..c7166f8e4 100644 --- a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java @@ -2,10 +2,13 @@ import org.openda.exchange.AbstractDataObject; import org.openda.utils.generalJavaUtils.StringUtilities; +import ucar.ma2.ArrayFloat; import ucar.nc2.NetcdfFile; +import ucar.nc2.NetcdfFileWriter; import ucar.nc2.Variable; import java.io.File; +import java.io.IOException; import java.util.*; public class DFlowFMNetcdfSampleFile extends AbstractDataObject { @@ -17,7 +20,6 @@ enum DataFormat {TimeIndependent(1), TimeConstant(2); DataFormat(int variableDimensions) { this.variableDimensions = variableDimensions; } - } public static final String AREA_NUMBER = "area_number"; @@ -25,7 +27,8 @@ enum DataFormat {TimeIndependent(1), TimeConstant(2); private static final String NETCDF_VARIABLE = "netcdfVariable"; private static final String DATA_FORMAT = "dataFormat"; - private Set variablesForExchangeItems = new HashSet<>(); + private int[] areaNumbers; + private final Set variablesForExchangeItems = new HashSet<>(); private DataFormat dataFormat; private String idPrefix; private File file = null; @@ -65,14 +68,14 @@ public void initialize(File workingDir, String[] arguments) { List variables = netcdfFile.getVariables(); Variable areaNumberVar = netcdfFile.findVariable(AREA_NUMBER); if (areaNumberVar == null) throw new RuntimeException(String.format("Variable %s not found in netCDF file", AREA_NUMBER)); - int[] areaNumbers = (int[]) areaNumberVar.read().get1DJavaArray(int.class); + areaNumbers = (int[]) areaNumberVar.read().get1DJavaArray(int.class); Map> areaNumberIndexListMap = new LinkedHashMap<>(); for (int i = 0; i < areaNumbers.length; i++) { int areaNumber = areaNumbers[i]; List indexList = areaNumberIndexListMap.computeIfAbsent(areaNumber, k -> new ArrayList<>()); indexList.add(i); } - areaNumberIndexListMap.forEach((index, list) -> System.out.printf("Area number %d has %d indices%n", index, list.size())); + for (Variable variable : variables) { String varName = variable.getShortName(); int[] shape = variable.getShape(); @@ -88,17 +91,59 @@ public void initialize(File workingDir, String[] arguments) { eiValues[i] = values[indices.get(i)]; } String id = String.format("%s_%s_%d", idPrefix, varName, entry.getKey()); - exchangeItems.put(id, new DFlowFMNetcdfSampleFileExchangeItem(id, indices, eiValues)); + exchangeItems.put(id, new DFlowFMNetcdfSampleFileExchangeItem(id, varName, indices, eiValues)); } } } catch (Exception e) { throw new RuntimeException(e); + } finally { + try { + if (netcdfFile != null) netcdfFile.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } } } @Override public void finish() { + NetcdfFileWriter netcdfFileWriter = null; + try { + Map variableValuesMap = new HashMap<>(); + exchangeItems.values().forEach(exchangeItem -> { + DFlowFMNetcdfSampleFileExchangeItem item = (DFlowFMNetcdfSampleFileExchangeItem) exchangeItem; + double[] values = variableValuesMap.computeIfAbsent(item.getVarName(), k -> new double[areaNumbers.length]); + List indices = item.getIndices(); + double[] valuesAsDoubles = item.getValuesAsDoubles(); + for (int i = 0; i < indices.size(); i++) { + values[indices.get(i)] = valuesAsDoubles[i]; + } + }); + netcdfFileWriter = NetcdfFileWriter.openExisting(this.file.getAbsolutePath()); + NetcdfFileWriter finalNetcdfFileWriter = netcdfFileWriter; + variableValuesMap.forEach((varName, values) -> { + try { + Variable variable = finalNetcdfFileWriter.findVariable(varName); + if (variable == null) throw new RuntimeException(String.format("Variable %s not found in netCDF file", varName)); + ArrayFloat.D1 array = new ArrayFloat.D1(values.length); + for (int i = 0; i < values.length; i++) { + array.set(i, (float) values[i]); + } + finalNetcdfFileWriter.write(variable, variable.getShape(), array); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + try { + if (netcdfFileWriter != null) netcdfFileWriter.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } } diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java index fb858678e..7e91426a7 100644 --- a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java @@ -10,11 +10,13 @@ public class DFlowFMNetcdfSampleFileExchangeItem implements IExchangeItem { private final String id; + private final String varName; private final List indices; private final double[] eiValues; - public DFlowFMNetcdfSampleFileExchangeItem(String id, List indices, double[] eiValues) { + public DFlowFMNetcdfSampleFileExchangeItem(String id, String varName, List indices, double[] eiValues) { this.id = id; + this.varName = varName; this.indices = indices; this.eiValues = eiValues; } @@ -111,4 +113,8 @@ public void setTimes(double[] times) { public List getIndices() { return indices; } + + public String getVarName() { + return varName; + } } diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java index fa9e73d58..8e0da48f6 100644 --- a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java +++ b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java @@ -1,10 +1,12 @@ package org.openda.model_dflowfm; import junit.framework.TestCase; +import org.openda.interfaces.IExchangeItem; import org.openda.utils.OpenDaTestSupport; import java.io.File; import java.io.IOException; +import java.util.Arrays; public class DFlowFMNetcdfSampleFileTest extends TestCase { OpenDaTestSupport testData = null; @@ -18,8 +20,15 @@ protected void setUp() throws IOException { public void testTimeConstant() { DFlowFMNetcdfSampleFile dataObject = new DFlowFMNetcdfSampleFile(); - dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=phase", "dataFormat=TimeIndependent"}); + dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=phase", "netcdfVariable=amplitude", "dataFormat=TimeIndependent"}); String[] exchangeItemIDs = dataObject.getExchangeItemIDs(); - assertEquals(67, exchangeItemIDs.length); + assertEquals(134, exchangeItemIDs.length); + for (int i = 0; i < exchangeItemIDs.length; i++) { + IExchangeItem ei = dataObject.getDataObjectExchangeItem(exchangeItemIDs[i]); + double[] values = ei.getValuesAsDoubles(); + Arrays.fill(values, i); + ei.setValuesAsDoubles(values); + } + dataObject.finish(); } } From dbd4c35a2d68918106f3c75d98b0d201ecbc343a Mon Sep 17 00:00:00 2001 From: Erik Pelgrim Date: Wed, 25 Mar 2026 17:51:45 +0100 Subject: [PATCH 5/7] Implement finish, unit test --- .../model_dflowfm/DFlowFMNetcdfSampleFileTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java index 8e0da48f6..4e2d831a5 100644 --- a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java +++ b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java @@ -30,5 +30,17 @@ public void testTimeConstant() { ei.setValuesAsDoubles(values); } dataObject.finish(); + + DFlowFMNetcdfSampleFile dataObjectReloaded = new DFlowFMNetcdfSampleFile(); + dataObjectReloaded.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=phase", "netcdfVariable=amplitude", "dataFormat=TimeIndependent"}); + String[] exchangeItemIdsReloaded = dataObjectReloaded.getExchangeItemIDs(); + assertEquals(134, exchangeItemIdsReloaded.length); + for (int i = 0; i < exchangeItemIdsReloaded.length; i++) { + IExchangeItem ei = dataObjectReloaded.getDataObjectExchangeItem(exchangeItemIdsReloaded[i]); + double[] values = ei.getValuesAsDoubles(); + for (double value : values) { + assertEquals((double) i, value); + } + } } } From 58ad4000eda96a2d357d23c1068c1f4f0a2317f5 Mon Sep 17 00:00:00 2001 From: Erik Pelgrim Date: Thu, 26 Mar 2026 17:04:21 +0100 Subject: [PATCH 6/7] Simplify Exchange Item to 1 value + support TimeConstant data format --- .../DFlowFMNetcdfSampleFile.java | 24 +++++++-------- .../DFlowFMNetcdfSampleFileExchangeItem.java | 22 +++++++------- .../DFlowFMNetcdfSampleFileTest.java | 29 ++++++++++++++++++- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java index c7166f8e4..c35ac7584 100644 --- a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFile.java @@ -15,10 +15,10 @@ public class DFlowFMNetcdfSampleFile extends AbstractDataObject { enum DataFormat {TimeIndependent(1), TimeConstant(2); - private final int variableDimensions; + private final int numberOfDimensions; - DataFormat(int variableDimensions) { - this.variableDimensions = variableDimensions; + DataFormat(int numberOfDimensions) { + this.numberOfDimensions = numberOfDimensions; } } @@ -80,18 +80,14 @@ public void initialize(File workingDir, String[] arguments) { String varName = variable.getShortName(); int[] shape = variable.getShape(); if (!variablesForExchangeItems.contains(varName)) continue; - if (dataFormat.variableDimensions != shape.length) throw new RuntimeException(String.format("Variable %s has length %d dimensions, but expected %d dimensions for data format %s", variable.getShortName(), shape.length, dataFormat.variableDimensions, dataFormat.name())); + if (dataFormat.numberOfDimensions != shape.length) throw new RuntimeException(String.format("Variable %s has length %d dimensions, but expected %d dimensions for data format %s", variable.getShortName(), shape.length, dataFormat.numberOfDimensions, dataFormat.name())); double[] values = (double[]) variable.read().get1DJavaArray(Double.class); - if (values.length != areaNumbers.length) throw new RuntimeException(String.format("Variable %s has length %d, but expected length %d equal to the number of areas in variable %s", variable.getShortName(), values.length, areaNumbers.length, AREA_NUMBER)); + if (values.length != areaNumbers.length * dataFormat.numberOfDimensions) throw new RuntimeException(String.format("Variable %s has length %d, but expected length %d equal to the number of areas in variable %s", variable.getShortName(), values.length, areaNumbers.length, AREA_NUMBER)); Set>> indicesPerAreaNumber = areaNumberIndexListMap.entrySet(); for (Map.Entry> entry : indicesPerAreaNumber) { List indices = entry.getValue(); - double[] eiValues = new double[indices.size()]; - for (int i = 0; i < indices.size(); i++) { - eiValues[i] = values[indices.get(i)]; - } String id = String.format("%s_%s_%d", idPrefix, varName, entry.getKey()); - exchangeItems.put(id, new DFlowFMNetcdfSampleFileExchangeItem(id, varName, indices, eiValues)); + exchangeItems.put(id, new DFlowFMNetcdfSampleFileExchangeItem(id, varName, indices, values[indices.get(0)])); } } @@ -113,11 +109,13 @@ public void finish() { Map variableValuesMap = new HashMap<>(); exchangeItems.values().forEach(exchangeItem -> { DFlowFMNetcdfSampleFileExchangeItem item = (DFlowFMNetcdfSampleFileExchangeItem) exchangeItem; - double[] values = variableValuesMap.computeIfAbsent(item.getVarName(), k -> new double[areaNumbers.length]); + double[] values = variableValuesMap.computeIfAbsent(item.getVarName(), k -> new double[areaNumbers.length * dataFormat.numberOfDimensions]); List indices = item.getIndices(); double[] valuesAsDoubles = item.getValuesAsDoubles(); - for (int i = 0; i < indices.size(); i++) { - values[indices.get(i)] = valuesAsDoubles[i]; + for (int i = 0; i < dataFormat.numberOfDimensions; i++) { + for (int index : indices) { + values[i * areaNumbers.length + index] = valuesAsDoubles[0]; + } } }); diff --git a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java index 7e91426a7..27f627754 100644 --- a/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java +++ b/model_dflowfm_blackbox/java/src/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileExchangeItem.java @@ -12,13 +12,13 @@ public class DFlowFMNetcdfSampleFileExchangeItem implements IExchangeItem { private final String id; private final String varName; private final List indices; - private final double[] eiValues; + private final double[] eiValue; - public DFlowFMNetcdfSampleFileExchangeItem(String id, String varName, List indices, double[] eiValues) { + public DFlowFMNetcdfSampleFileExchangeItem(String id, String varName, List indices, double eiValue) { this.id = id; this.varName = varName; this.indices = indices; - this.eiValues = eiValues; + this.eiValue = new double[]{eiValue}; } @@ -43,7 +43,7 @@ public void copyValuesFromItem(IExchangeItem sourceItem) { throw new IllegalArgumentException(String.format("Expected sourceItem to have values of type %s, but got %s", ValueType.doublesType, sourceItem.getValuesType())); } double[] sourceValues = sourceItem.getValuesAsDoubles(); - System.arraycopy(sourceValues, 0, this.eiValues, 0, sourceValues.length); + System.arraycopy(sourceValues, 0, this.eiValue, 0, sourceValues.length); } @Override @@ -68,25 +68,25 @@ public ValueType getValuesType() { @Override public Object getValues() { - return eiValues; + return eiValue; } @Override public double[] getValuesAsDoubles() { - return eiValues; + return eiValue; } @Override public void axpyOnValues(double alpha, double[] axpyValues) { - for (int i = 0; i < eiValues.length; i++) { - eiValues[i] += alpha * axpyValues[i]; + for (int i = 0; i < eiValue.length; i++) { + eiValue[i] += alpha * axpyValues[i]; } } @Override public void multiplyValues(double[] multiplicationFactors) { - for (int i = 0; i < eiValues.length; i++) { - eiValues[i] *= multiplicationFactors[i]; + for (int i = 0; i < eiValue.length; i++) { + eiValue[i] *= multiplicationFactors[i]; } } @@ -97,7 +97,7 @@ public void setValues(Object values) { @Override public void setValuesAsDoubles(double[] values) { - System.arraycopy(values, 0, eiValues, 0, values.length); + System.arraycopy(values, 0, eiValue, 0, values.length); } @Override diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java index 4e2d831a5..6609bf40d 100644 --- a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java +++ b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java @@ -18,7 +18,7 @@ protected void setUp() throws IOException { testRunDataRestartFileDir = new File(testData.getTestRunDataDir(), "DFlowFMNetCDFSample"); } - public void testTimeConstant() { + public void testTimeIndependent() { DFlowFMNetcdfSampleFile dataObject = new DFlowFMNetcdfSampleFile(); dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=phase", "netcdfVariable=amplitude", "dataFormat=TimeIndependent"}); String[] exchangeItemIDs = dataObject.getExchangeItemIDs(); @@ -43,4 +43,31 @@ public void testTimeConstant() { } } } + + public void testTimeConstant() { + DFlowFMNetcdfSampleFile dataObject = new DFlowFMNetcdfSampleFile(); + dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeConstant.nc", "idPrefix=prefix", "netcdfVariable=friction_coefficient", "dataFormat=TimeConstant"}); + String[] exchangeItemIDs = dataObject.getExchangeItemIDs(); + assertEquals(67, exchangeItemIDs.length); + for (int i = 0; i < exchangeItemIDs.length; i++) { + IExchangeItem ei = dataObject.getDataObjectExchangeItem(exchangeItemIDs[i]); + double[] values = ei.getValuesAsDoubles(); + Arrays.fill(values, i); + ei.setValuesAsDoubles(values); + } + dataObject.finish(); + + DFlowFMNetcdfSampleFile dataObjectReloaded = new DFlowFMNetcdfSampleFile(); + dataObjectReloaded.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeConstant.nc", "idPrefix=prefix", "netcdfVariable=friction_coefficient", "dataFormat=TimeConstant"}); + String[] exchangeItemIdsReloaded = dataObjectReloaded.getExchangeItemIDs(); + assertEquals(67, exchangeItemIdsReloaded.length); + // TODO EP: check for full netcdf contents + for (int i = 0; i < exchangeItemIdsReloaded.length; i++) { + IExchangeItem ei = dataObjectReloaded.getDataObjectExchangeItem(exchangeItemIdsReloaded[i]); + double[] values = ei.getValuesAsDoubles(); + for (double value : values) { + assertEquals((double) i, value); + } + } + } } From e0c133b341a85f7cd4d983733e6922ef715e8be5 Mon Sep 17 00:00:00 2001 From: Erik Pelgrim Date: Thu, 26 Mar 2026 17:48:23 +0100 Subject: [PATCH 7/7] Extend test cases --- .../DFlowFMNetcdfSampleFileTest.java | 7 ++++--- .../ExampleTimeConstant_Expected.nc | Bin 0 -> 44386 bytes .../ExampleTimeIndependent_Expected.nc | Bin 0 -> 40960 bytes 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeConstant_Expected.nc create mode 100644 model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeIndependent_Expected.nc diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java index 6609bf40d..cc53174d6 100644 --- a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java +++ b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/DFlowFMNetcdfSampleFileTest.java @@ -18,7 +18,7 @@ protected void setUp() throws IOException { testRunDataRestartFileDir = new File(testData.getTestRunDataDir(), "DFlowFMNetCDFSample"); } - public void testTimeIndependent() { + public void testTimeIndependent() throws IOException { DFlowFMNetcdfSampleFile dataObject = new DFlowFMNetcdfSampleFile(); dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeIndependent.nc", "idPrefix=prefix", "netcdfVariable=phase", "netcdfVariable=amplitude", "dataFormat=TimeIndependent"}); String[] exchangeItemIDs = dataObject.getExchangeItemIDs(); @@ -42,9 +42,10 @@ public void testTimeIndependent() { assertEquals((double) i, value); } } + OpenDaTestSupport.compareNetcdfFiles(new File(testRunDataRestartFileDir, "ExampleTimeIndependent_Expected.nc"), new File(testRunDataRestartFileDir, "ExampleTimeIndependent.nc")); } - public void testTimeConstant() { + public void testTimeConstant() throws IOException { DFlowFMNetcdfSampleFile dataObject = new DFlowFMNetcdfSampleFile(); dataObject.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeConstant.nc", "idPrefix=prefix", "netcdfVariable=friction_coefficient", "dataFormat=TimeConstant"}); String[] exchangeItemIDs = dataObject.getExchangeItemIDs(); @@ -61,7 +62,6 @@ public void testTimeConstant() { dataObjectReloaded.initialize(testRunDataRestartFileDir, new String[]{"ExampleTimeConstant.nc", "idPrefix=prefix", "netcdfVariable=friction_coefficient", "dataFormat=TimeConstant"}); String[] exchangeItemIdsReloaded = dataObjectReloaded.getExchangeItemIDs(); assertEquals(67, exchangeItemIdsReloaded.length); - // TODO EP: check for full netcdf contents for (int i = 0; i < exchangeItemIdsReloaded.length; i++) { IExchangeItem ei = dataObjectReloaded.getDataObjectExchangeItem(exchangeItemIdsReloaded[i]); double[] values = ei.getValuesAsDoubles(); @@ -69,5 +69,6 @@ public void testTimeConstant() { assertEquals((double) i, value); } } + OpenDaTestSupport.compareNetcdfFiles(new File(testRunDataRestartFileDir, "ExampleTimeConstant_Expected.nc"), new File(testRunDataRestartFileDir, "ExampleTimeConstant.nc")); } } diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeConstant_Expected.nc b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeConstant_Expected.nc new file mode 100644 index 0000000000000000000000000000000000000000..acdb7cbed7b19f8da6f7b428aead3816ce2ff202 GIT binary patch literal 44386 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 literal 0 HcmV?d00001 diff --git a/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeIndependent_Expected.nc b/model_dflowfm_blackbox/java/test/org/openda/model_dflowfm/testData/DFlowFMNetCDFSample/ExampleTimeIndependent_Expected.nc new file mode 100644 index 0000000000000000000000000000000000000000..edbcb562a5116102138c5eed09e338dda4625fc6 GIT binary patch literal 40960 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 literal 0 HcmV?d00001