Skip to content
This repository was archived by the owner on Sep 1, 2022. It is now read-only.

Commit 2e2f4d6

Browse files
authored
Merge pull request #1344 from Mikhail-Aoun/Add_VLen_Writing_feature
Add VLEN writing feature and test.
2 parents 27d58e5 + 83ce6ff commit 2e2f4d6

File tree

5 files changed

+514
-15
lines changed

5 files changed

+514
-15
lines changed

cdm/src/test/java/ucar/nc2/TestUtils.java

+156-1
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@
3333
package ucar.nc2;
3434

3535
import java.io.*;
36-
36+
import java.util.HashMap;
3737
import ucar.ma2.Array;
38+
import ucar.ma2.InvalidRangeException;
3839
import ucar.nc2.constants.CDM;
3940

4041
/**
@@ -106,4 +107,158 @@ static public boolean close( float d1, float d2) {
106107
else
107108
return Math.abs(d1-d2) < 1.0e-5;
108109
}
110+
111+
/**
112+
* Clone metadata from the given netcdf to the given netcdf file writer.
113+
*
114+
* @param fromNetcdf the cloned netcdf
115+
* @param toWriter the netcdf file writer
116+
*/
117+
public static void cloneMetadata(NetcdfFile fromNetcdf, NetcdfFileWriter toWriter) {
118+
119+
final Group rootFrom = fromNetcdf.getRootGroup();
120+
final Group rootTo = toWriter.addGroup(null, null);
121+
122+
cloneMetadata(toWriter, rootFrom, rootTo);
123+
}
124+
125+
/**
126+
* Clone data from the given netcdf to the given netcdf file writer.
127+
*
128+
* @param fromNetcdf the cloned netcdf
129+
* @param toWriter the netcdf file writer
130+
* @throws IOException
131+
* @throws InvalidRangeException
132+
*/
133+
public static void cloneData(NetcdfFile fromNetcdf, NetcdfFileWriter toWriter)
134+
throws IOException, InvalidRangeException {
135+
136+
final Group rootFrom = fromNetcdf.getRootGroup();
137+
final Group rootTo = toWriter.getNetcdfFile().getRootGroup();
138+
139+
cloneData(toWriter, rootFrom, rootTo);
140+
141+
}
142+
143+
/**
144+
* Clone metadata from the given group to the given group of the netcdf file writer.
145+
*
146+
* @param to the netcdf file writer
147+
* @param groupFrom the cloned metadata group
148+
* @param groupTo the written group
149+
*/
150+
private static void cloneMetadata(final NetcdfFileWriter to, final Group groupFrom, final Group groupTo) {
151+
152+
// dimension
153+
cloneMetadataDimension(to, groupFrom, groupTo);
154+
155+
// attribute
156+
cloneMetadataAttribute(to, groupFrom, groupTo);
157+
158+
// variable
159+
cloneMetadataVariable(to, groupFrom, groupTo);
160+
161+
// enum
162+
cloneMetadataEnum(to, groupFrom, groupTo);
163+
164+
for (final Group gFrom : groupFrom.getGroups()) {
165+
// create new Group
166+
final Group g = to.addGroup(groupTo, gFrom.getShortName());
167+
cloneMetadata(to, gFrom, g);
168+
169+
}
170+
}
171+
172+
/**
173+
* Clone metadata dimension.
174+
*
175+
* @param to the netcdf file writer
176+
* @param groupFrom the cloned metadata dimension group
177+
* @param groupTo the written group
178+
*/
179+
private static void cloneMetadataDimension(final NetcdfFileWriter to, final Group groupFrom, final Group groupTo) {
180+
for (final Dimension dimension : groupFrom.getDimensions()) {
181+
if (!dimension.isVariableLength()) {
182+
to.addDimension(groupTo, dimension.getShortName(), dimension.getLength(), dimension.isShared(),
183+
dimension.isUnlimited(), dimension.isVariableLength());
184+
}
185+
}
186+
}
187+
188+
/**
189+
* Clone metadata attribute.
190+
*
191+
* @param to the netcdf file writer
192+
* @param groupFrom the cloned metadata attribute group
193+
* @param groupTo the written group
194+
*/
195+
private static void cloneMetadataAttribute(final NetcdfFileWriter to, final Group groupFrom, final Group groupTo) {
196+
for (final Attribute attribute : groupFrom.getAttributes()) {
197+
final Attribute att = new Attribute(attribute.getShortName(), attribute);
198+
to.addGroupAttribute(groupTo, att);
199+
}
200+
}
201+
202+
/**
203+
* Clone metadata variable.
204+
*
205+
* @param to the netcdf file writer
206+
* @param groupFrom the cloned metadata variable group
207+
* @param groupTo the written group
208+
*/
209+
private static void cloneMetadataVariable(final NetcdfFileWriter to, final Group groupFrom, final Group groupTo) {
210+
for (final Variable variable : groupFrom.getVariables()) {
211+
212+
final String parsedDim = variable.getDimensionsString();
213+
final Variable v = to.addVariable(groupTo, variable.getShortName(), variable.getDataType(), parsedDim);
214+
215+
for (final Attribute attribute : variable.getAttributes()) {
216+
final Attribute att = new Attribute(attribute.getShortName(), attribute);
217+
v.addAttribute(att);
218+
}
219+
}
220+
221+
}
222+
223+
/**
224+
* Clone metadata enum.
225+
*
226+
* @param to the netcdf file writer
227+
* @param groupFrom the cloned metadata enum group
228+
* @param groupTo the written group
229+
*/
230+
private static void cloneMetadataEnum(final NetcdfFileWriter to, final Group groupFrom, final Group groupTo) {
231+
for (final EnumTypedef enumTypedef : groupFrom.getEnumTypedefs()) {
232+
final EnumTypedef e =
233+
new EnumTypedef(enumTypedef.getShortName(), new HashMap<>(enumTypedef.getMap()), enumTypedef.getBaseType());
234+
to.addTypedef(groupTo, e);
235+
}
236+
}
237+
238+
/**
239+
* Clone data.
240+
*
241+
* @param to the netcdf file writer
242+
* @param groupFrom the cloned metadata enum group
243+
* @param groupTo the written group
244+
* @throws IOException
245+
* @throws InvalidRangeException
246+
*/
247+
private static void cloneData(final NetcdfFileWriter to, final Group groupFrom, final Group groupTo)
248+
throws IOException, InvalidRangeException {
249+
if (null != groupTo) {
250+
for (final Variable variableFrom : groupFrom.getVariables()) {
251+
252+
final Variable variableTo = groupTo.findVariable(variableFrom.getShortName());
253+
if (null != variableTo) {
254+
to.write(variableTo, variableFrom.read().copy());
255+
}
256+
}
257+
258+
for (final Group gFrom : groupFrom.getGroups()) {
259+
final Group gTo = groupTo.findGroup(gFrom.getShortName());
260+
cloneData(to, gFrom, gTo);
261+
}
262+
}
263+
}
109264
}

cdm/src/test/java/ucar/nc2/TestWrite.java

+29-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
import org.junit.rules.TemporaryFolder;
3737
import org.junit.runners.MethodSorters;
3838
import ucar.ma2.*;
39-
39+
import ucar.unidata.util.test.TestDir;
40+
import java.io.File;
4041
import java.io.IOException;
4142
import java.util.ArrayList;
4243
import java.util.List;
@@ -1040,4 +1041,31 @@ public void testRecordSizeBug() throws IOException, InvalidRangeException {
10401041
ucar.unidata.util.test.CompareNetcdf.compareData(result1, result2);
10411042
}
10421043
}
1044+
1045+
/** Test the cloning of files with vlen in order to demonstrate vlen variable writting. */
1046+
@Test
1047+
public void testNC4CloningVlen() {
1048+
1049+
// GIVEN
1050+
final String filename = tempFolder.getRoot().getAbsolutePath() + "/test-vlen.nc";
1051+
1052+
// -- A nc with VLEN
1053+
final NetcdfFile ncfile = TestDir
1054+
.openFileLocal("vlen-test/SGB1-HKT-00-SRC_C_EUMT_20181109084333_G_O_20170103000340_20170103000359_O_N____.nc");
1055+
1056+
// WHEN
1057+
try (NetcdfFileWriter writer = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf4, filename)) {
1058+
TestUtils.cloneMetadata(ncfile, writer);
1059+
writer.create();
1060+
TestUtils.cloneData(ncfile, writer);
1061+
1062+
} catch (IOException | InvalidRangeException e) {
1063+
Assert.fail(e.getMessage());
1064+
}
1065+
1066+
// THEN
1067+
File f = new File(filename);
1068+
Assert.assertTrue(f.exists());
1069+
}
1070+
10431071
}

0 commit comments

Comments
 (0)