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

Write variables with VLEN dimensions to NetCDF-4 #588

Open
cwardgar opened this issue Jul 12, 2016 · 19 comments
Open

Write variables with VLEN dimensions to NetCDF-4 #588

cwardgar opened this issue Jul 12, 2016 · 19 comments

Comments

@cwardgar
Copy link
Contributor

cwardgar commented Jul 12, 2016

I didn't even realize that we don't support this in Nc4Iosp. Maybe we have this documented somewhere, but I only found the clue buried in the source. According to the code, we can't write NC_OPAQUE either, but we don't really have an analogue for that in the CDM.

@DennisHeimbigner Do you plan to take this on?

@cwardgar
Copy link
Contributor Author

Also, I should point out that the helpful error message is only printed for 1-D VLEN variables. Something like:

<netcdf xmlns="https://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2">
  <dimension name="dimA" length="3" />
  <variable name="simpleVar" shape="dimA *" type="int">
    <values>1 2 3</values>
  </variable>
</netcdf>

Is going to print a much less useful message:

java.io.IOException: NetCDF: Variable not found
    at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2859)
    at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2789)
    at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:957)
    at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:941)
    at ucar.nc2.FileWriter2.copyAll(FileWriter2.java:431)
    at ucar.nc2.FileWriter2.copyVarData(FileWriter2.java:384)
    at ucar.nc2.FileWriter2.write(FileWriter2.java:199)
    at ucar.nc2.FileWriter2.write(FileWriter2.java:176)
    at ucar.nc2.ncml.NcMLReader.writeNcMLToFile(NcMLReader.java:1652)
    at ucar.nc2.ui.NcmlEditor.writeNetcdf(NcmlEditor.java:289)
    at ucar.nc2.ui.NcmlEditor$5$1.propertyChange(NcmlEditor.java:159)
    at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:328)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
    at java.awt.Component.firePropertyChange(Component.java:8430)
    at ucar.nc2.ui.dialog.NetcdfOutputChooser.okButtonActionPerformed(NetcdfOutputChooser.java:76)
    at ucar.nc2.ui.dialog.NetcdfOutputChooser.access$200(NetcdfOutputChooser.java:23)
    at ucar.nc2.ui.dialog.NetcdfOutputChooser$2.actionPerformed(NetcdfOutputChooser.java:226)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6535)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6300)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4891)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4713)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2750)
    at java.awt.Component.dispatchEvent(Component.java:4713)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
java.io.IOException: -101: NetCDF: HDF error
    at ucar.nc2.jni.netcdf.Nc4Iosp.close(Nc4Iosp.java:289)
    at ucar.nc2.NetcdfFileWriter.abort(NetcdfFileWriter.java:1035)
    at ucar.nc2.FileWriter2.write(FileWriter2.java:207)
    at ucar.nc2.FileWriter2.write(FileWriter2.java:176)
    at ucar.nc2.ncml.NcMLReader.writeNcMLToFile(NcMLReader.java:1652)
    at ucar.nc2.ui.NcmlEditor.writeNetcdf(NcmlEditor.java:289)
    at ucar.nc2.ui.NcmlEditor$5$1.propertyChange(NcmlEditor.java:159)
    at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:328)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
    at java.awt.Component.firePropertyChange(Component.java:8430)
    at ucar.nc2.ui.dialog.NetcdfOutputChooser.okButtonActionPerformed(NetcdfOutputChooser.java:76)
    at ucar.nc2.ui.dialog.NetcdfOutputChooser.access$200(NetcdfOutputChooser.java:23)
    at ucar.nc2.ui.dialog.NetcdfOutputChooser$2.actionPerformed(NetcdfOutputChooser.java:226)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6535)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6300)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4891)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4713)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2750)
    at java.awt.Component.dispatchEvent(Component.java:4713)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

See https://stackoverflow.com/questions/38103030/how-to-create-a-netcdf-4-file-with-a-variable-length-variable-from-ncml

@chuston
Copy link

chuston commented Dec 7, 2018

I believe I am running into this.

  Dimension referenceDate = netcdf.addDimension(matrixParent, "reference_date", -1, false, false, true);
  Dimension feature = netcdf.addDimension(matrixParent, "feature", rows, true, false, false);
  Dimension time_step = netcdf.addDimension(matrixParent, "time_step", cols, true, false, false);

When I go to write the file, from Java with an NetcdfFileWriter.write(variable, value) call, I get the ENOTAVAR (-49) error. Making the referenceDate dimension a fixed size resolves the error but now I've got 3d matrixes that are half empty.

I have about 11,000 groups of ~30x60 matrixes, roughly 20 to 100 per group, about 500,000 total. It's currently not possible to write these to a NetCDF file from Java?

Is there a work around?

@lesserwhirls
Copy link
Collaborator

Hi @chuston - could you tell us which version of netCDF-java you are using, as well as netCDF-C?

@DennisHeimbigner - can you take a look at this one?

@chuston
Copy link

chuston commented Dec 8, 2018

Thanks for the reply.

Versions
netCDF Java: NetCDF4 v4.5.5 - via maven central
netCDF-C: netcdf @4.6.1_1+dap+netcdf4 (active) via MacPorts
OS: Mac OS/X 10.14.1 w/ jdk1.8.0_161-b12

@lesserwhirls
Copy link
Collaborator

The artifacts on maven central are quite old (not managed by us). If you are using maven/gradle to build, try these instructions to pull v4.6.11 from our nexus server:

https://www.unidata.ucar.edu/software/thredds/current/netcdf-java/reference/BuildDependencies.html

Quite a lot changed between v4.5 and v4.6 in terms of netCDF-4 support, so that might fix the issue. you might also give v5.0.0-beta6 a try as well, as there have been some tweaks there specific to VLEN support.

@chuston
Copy link

chuston commented Dec 11, 2018

Thanks. I followed the instructions at the referenced link.

I am seeing the same results with version edu.ucar:cdm.jar:4.6.11 and edu.ucar:netcdf.jar:4-4.6.11 from the unidata repository at https://artifacts.unidata.ucar.edu/repository/unidata-all/

Exception in thread "main" java.io.IOException: -49: NetCDF: Variable not found
	at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2855)
	at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2809)
	at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:958)
	at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:942)

If I replace the variable length Dimension with a fixed length Dimension the problem goes away.

If I move to 5.0.0-beta6, I see:

Exception in thread "main" java.lang.IllegalArgumentException: variable length dimension cannot be shared or unlimited
	at ucar.nc2.Dimension.<init>(Dimension.java:341)
	at ucar.nc2.NetcdfFileWriter.addDimension(NetcdfFileWriter.java:336)
	at com.jrcs.analytics.util.NetCDFCalendarSequenceExporter.exportCalendarSequences(NetCDFCalendarSequenceExporter.java:215)
	at com.jrcs.analytics.util.NetCDFCalendarSequenceExporter.exportCalendarSequences(NetCDFCalendarSequenceExporter.java:160)
	at com.jrcs.analytics.util.NetCDFCalendarSequenceExporter.main(NetCDFCalendarSequenceExporter.java:142)

I guess I don't know how to create an unshared Dimension. Just using the Dimension constructor leads to a null pointer except during NetcdfFileWriter.create() call. I'll go RTFM some more.

@lesserwhirls
Copy link
Collaborator

It's probably nothing you are doing wrong @chuston - @DennisHeimbigner, any thoughts?

@chuston
Copy link

chuston commented Dec 11, 2018

Okay. I've successfully made my variable length dimension non-shared. (By using Dimension(Sting, length, boolean, boolean, boolean) constructor and Variable's addDimension(Dimension) method. Now know that adding a Dimension to a Group makes it shared and the constructor Dimension(String, int) also defaults to shared.

Nc4Iosp:2492 (createVariable) agrees the dimension is not shared.

Now, with 5.0.0-beta6, I am back to err -49 EVARNOTFOUND:

Exception in thread "main" java.io.IOException: -49: NetCDF: Variable not found
	at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2971)
	at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2925)
	at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:1019)
	at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:999)

@DennisHeimbigner
Copy link
Contributor

First, I need to understand exactly what you meta-data
is creating. You have this code:

Dimension referenceDate = netcdf.addDimension(matrixParent, "reference_date", -1, false, false, true);
Dimension feature = netcdf.addDimension(matrixParent, "feature", rows, true, false, false);
Dimension time_step = netcdf.addDimension(matrixParent, "time_step", cols, true, false, false);

So we have three dimensions:

  1. "referenceDate" is variable length
  2. "feature" is fixed and of size "rows"
  3. "time_step" is fixed and of size "cols"

I assume that "netcdf" is of type NetcdfFileWriter.

So, somewhere, you create a variable that uses these three dimensions
in this order and does not work as expected.

Something like this.

List dimlist = new ArrayList<>;
dimlist.add(referenceDate);
dimlist.add(feature);
dimlist.add(time_step);
Variable v = netcdf.addVariable(netcdf, matrixParent, null, "vname",
DataType.FLOAT, dimlist);

The order of the dimensions is important because I believe that
at some point we changed the code to only allow a variable length
dimension as the last dimension for a variable. So please verify
the order of the dimensions in your code.

Sometimes we see people using a variable length dimension when what
they really want is an unlimited dimension. Would that work for you?

@chuston
Copy link

chuston commented Dec 11, 2018

Thanks for the reply.

Unlimited vs Variable: My understanding is that UNLIMITED is to allow appending data in the future. VARIABLE is to accommodate irregularly shaped variables. I'm after the latter.

I have about 11,000 groups of ~30x60 matrixes, roughly 20 to 100 per group, I'm attempting to write those as 3d matrixes. I'm doing this mainly because it appears I have to define all of the Variables before I write to them. I can easily see the total number of groups, but to see the number of matrixes in each group I have to read gigs of data and fetch extra info from a DB - very time consuming. Ideally, I'd be able to just add 1 new variable at a time and write to it.

To work around both the inability to append new variables and the inability to write variable dimensions - I'm writing new code to generate all 500,000 matrixes, store them as serialized Java objects, then create a NetCDF from the serialized matrixes. (And wondering if a directory full of CSVs wouldn't be the better way to go.)

Dimensions. I've tried both VARLEN as first dimension and as last dimension:

		List<Dimension> matrixDims = new ArrayList<>(3);
		matrixDims.add(feature);
		matrixDims.add(time_step);
		matrixDims.add(referenceDate);

Both ways produce EVARNOTFOUND (-49):

Exception in thread "main" java.io.IOException: -49: NetCDF: Variable not found
	at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2971)
	at ucar.nc2.jni.netcdf.Nc4Iosp.writeData(Nc4Iosp.java:2925)
	at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:1019)
	at ucar.nc2.NetcdfFileWriter.write(NetcdfFileWriter.java:999)

@DennisHeimbigner
Copy link
Contributor

ok, so unlimited won't work for you.

I'd be able to just add 1 new variable at a time and write to it.
Since you are creating a netcdf-4 file, this is actually doable. Have you tried it?

In any case, we still have to deal with this error:

Exception in thread "main" java.io.IOException: -49: NetCDF: Variable not found
Can you give me an excerpt of your code that surrounds this error.
I assume it is probably this method in NetcdfFileWriter. write(Variable v, Array values).
Before calling write, see if you can properly access v, by printing its name, for example.

@DennisHeimbigner
Copy link
Contributor

Another thought: try creating one variable and then close the dataset without
trying to write any data. Assuming that works, try dumping the file's metadata
using ncdump.

ALso, I am afraid we will need a minimal example showing this problem.
One with only a single variable and with smaller dimension sizes.

@chuston
Copy link

chuston commented Dec 11, 2018

The following unit test replicates both that pattern I'm using to write and the problem:

	@Test
	void testWriteVarLenMatrix() throws Throwable {
		NetcdfFileWriter netcdf = null;
		File outFile = File.createTempFile("test", ".nc");
		System.err.println("using temp: " + outFile.getAbsolutePath());
		netcdf = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf4, outFile.getAbsolutePath());
		Group matrixParent = netcdf.addGroup(null, "matrix");
		
		Dimension feature = new Dimension("feature", 30, true, false, false);
		Dimension time_step = new Dimension("time_step", 60, true, false, false);
		matrixParent.addDimension(feature);
		matrixParent.addDimension(time_step);

		Dimension referenceDate = new Dimension("reference_date", -1, false, false, true);
		
		List<Dimension> matrixDims = new ArrayList<>(3);
		matrixDims.add(feature);
		matrixDims.add(time_step);
		matrixDims.add(referenceDate);

		Variable matrixVarDef = netcdf.addVariable(matrixParent,"tryme", DataType.DOUBLE, matrixDims);
		
		netcdf.create();
		
		// can I find it again?
		Variable matrixVarFound = matrixParent.findVariable("tryme");
		int shape[] = new int[] {30,60,5};
		ArrayDouble.D3 testMatrix = (ArrayDouble.D3) Array.factory(DataType.DOUBLE, shape);
		Index idx = testMatrix.getIndex();
		// fill it up
		for (int i = 0; i < shape[0]; i++) {
			for (int j = 0; j < shape[1]; j++) {
				for (int k = 0; k < shape[2]; k++) {
					idx.set(i,j,k);
					testMatrix.set(idx, i+j+k);
				}
			}
		}
		
		netcdf.write(matrixVarFound, testMatrix);
		netcdf.close();
	}

I did try to append variables with alternating calls to setRedefineMode(true) and setRedefineMode(false). I don't recall the errors and it was before updating the java libs to 4.6_11 or greater. However, I read that doing this would cause the file to be copied over and over - meaning I'd have \sum _{i=0}^{11000} i rewrites of the file. Is that still true?

@DennisHeimbigner
Copy link
Contributor

Thanks, the test case should help a lot.
Again, assuming you are using netcdf-4 (as you are)
and assuming you do not close the file between calls to setRedefineMode,
it should not rewrite the file. Where did you read that? That documentation may
need updating. In any case, if you do this and the run time explodes you will
know that I was wrong and it is copying -- which is a second error that would need
fixing.

@chuston
Copy link

chuston commented Dec 11, 2018

The following quick and dirty example executes without err (no variable length dimensions) but indicated that the file was rewritten during setRedefineMode(false) (with cdm and netcdf4 jars from 5.0.0-beta6)

There is a message sent to stdout saying Cannot find variable trymeToo to copy to new file. However, both tryme and trymeToo are successfully written to the final file.

	void testWriteVarLenMatrix() throws Throwable {
		NetcdfFileWriter netcdf = null;
		File outFile = File.createTempFile("test", ".nc");
		System.err.println("using temp: " + outFile.getAbsolutePath());
		netcdf = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf4, outFile.getAbsolutePath());
		Group matrixParent = netcdf.addGroup(null, "matrix");
		
		Dimension feature = new Dimension("feature", 30, true, false, false);
		Dimension time_step = new Dimension("time_step", 60, true, false, false);
		matrixParent.addDimension(feature);
		matrixParent.addDimension(time_step);

		Dimension referenceDate = new Dimension("reference_date", 5, false, false, false);
		
		List<Dimension> matrixDims = new ArrayList<>(3);
		matrixDims.add(feature);
		matrixDims.add(time_step);
		matrixDims.add(referenceDate);

		Variable matrixVarDef = netcdf.addVariable(matrixParent,"tryme", DataType.DOUBLE, matrixDims);
		
		netcdf.create();
		
		// can I find it again?
		Variable matrixVarFound = matrixParent.findVariable("tryme");
		int shape[] = new int[] {30,60,5};
		ArrayDouble.D3 testMatrix = (ArrayDouble.D3) Array.factory(DataType.DOUBLE, shape);
		Index idx = testMatrix.getIndex();
		// fill it up
		for (int i = 0; i < shape[0]; i++) {
			for (int j = 0; j < shape[1]; j++) {
				for (int k = 0; k < shape[2]; k++) {
					idx.set(i,j,k);
					testMatrix.set(idx, i+j+k);
				}
			}
		}
		
		netcdf.write(matrixVarFound, testMatrix);
		
		netcdf.setRedefineMode(true);
		Dimension referenceDateToo = new Dimension("reference_date", 5, false, false, false);
		List<Dimension> matrixDimsToo = new ArrayList<>(3);
		matrixDimsToo.add(feature);
		matrixDimsToo.add(time_step);
		matrixDimsToo.add(referenceDateToo);
		Variable anotherVarDef = netcdf.addVariable(matrixParent, "trymeToo", DataType.DOUBLE, matrixDimsToo);
		
		boolean didRewrite = netcdf.setRedefineMode(false);
		
		if (didRewrite == true) {
			System.err.println("Rewrote file.");
		}
		
		// can I find it again?
		Variable matrixVarTooFound = matrixParent.findVariable("trymeToo");
		ArrayDouble.D3 testMatrixToo = (ArrayDouble.D3) Array.factory(DataType.DOUBLE, shape);
		Index idxToo = testMatrixToo.getIndex();
		// fill it up
		for (int i = 0; i < shape[0]; i++) {
			for (int j = 0; j < shape[1]; j++) {
				for (int k = 0; k < shape[2]; k++) {
					idxToo.set(i,j,k);
					testMatrixToo.set(idxToo, i+j+k);
				}
			}
		}
		netcdf.write(matrixVarTooFound, testMatrixToo);
		
		netcdf.close();
	}

@DennisHeimbigner
Copy link
Contributor

Interesting. The underlying netcdf-4 code in the netcdf-c library does not require
re-writing (in fact it does not require calling redefine at all. So, that is another problem.
So, I stopped the test case after the variable was created and used ncdump -h to
see what it looked like, and got this:

netcdf test7430552630104786791 {
dimensions:
feature = 30 ;
time_step = 60 ;
tryme_Dim2 = 4294967295 ;
variables:
double tryme(feature, time_step, tryme_Dim2) ;
}
the "tryme_Dim2" is being synthesized and its size as signed is -1.
So the code is completely hosed. This does not surprise me because
vlen's are known to have problems. I just did not know about this one.
Fixing this is going to take a while.

@DennisHeimbigner
Copy link
Contributor

So with respect to rewriting the file. The method Nc4Iosp.rewriteheader
always returns false, which causes NetcdfFileWriter to rewrite the whole file.
I believe this is incorrect behavior and Nc4Iosp.rewriteheader should
always return true because the header never needs to be rewritten,
so it is proper to pretend that it always rewrites it.

@DennisHeimbigner
Copy link
Contributor

DennisHeimbigner commented Dec 12, 2018

Ok, there are two problems.

  1. The NC4Iosp for the NetcdfFileWriter.spiw is not being created: its value is null:
    easily fixed.
  2. As Christian originally noted. The Nc4Iosp code does not support writing VLENs:
    hard to fix.

We need a command decision from Sean about adding VLEN support.

@DennisHeimbigner
Copy link
Contributor

I took a closer look at Nc4Iosp.java and the situation is that has code
for reading files with VLENs (mostly).
But the create file and write file code completely ignores the possibility of
variable length dimensions, so all sorts of errors occur when trying to use them.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants