/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.dataset;
import junit.framework.*;
import ucar.ma2.*;
import ucar.nc2.*;
import ucar.nc2.util.CompareNetcdf;
import ucar.nc2.util.CompareNetcdf2;
import java.io.IOException;
import java.util.*;
/** Test TestStandardVar in JUnit framework. */
public class TestStandardVar extends TestCase {
private String filename = TestAll.cdmLocalTestDataDir +"standardVar.nc";
public TestStandardVar( String name) {
super(name);
}
public void testWriteStandardVar() throws Exception {
NetcdfFileWriteable ncfile = new NetcdfFileWriteable(filename, false);
// define dimensions
Dimension latDim = ncfile.addDimension("lat", 2);
Dimension lonDim = ncfile.addDimension("lon", 3);
ArrayList dims = new ArrayList();
dims.add(latDim);
dims.add(lonDim);
// case 1
ncfile.addVariable("t1", DataType.DOUBLE, dims);
ncfile.addVariableAttribute("t1", "scale_factor", new Double(2.0));
ncfile.addVariableAttribute("t1", "add_offset", new Double(77.0));
// case 2
ncfile.addVariable("t2", DataType.BYTE, dims);
ncfile.addVariableAttribute("t2", "scale_factor", new Short( (short) 2));
ncfile.addVariableAttribute("t2", "add_offset", new Short( (short) 77));
// case 3
ncfile.addVariable("t3", DataType.BYTE, dims);
ncfile.addVariableAttribute("t3", "_FillValue", new Byte( (byte) 255));
// case 4
ncfile.addVariable("t4", DataType.SHORT, dims);
ncfile.addVariableAttribute("t4", "missing_value", new Short( (short) -9999));
// case 5
ncfile.addVariable("t5", DataType.SHORT, dims);
ncfile.addVariableAttribute("t5", "missing_value", new Short( (short) -9999));
ncfile.addVariableAttribute("t5", "scale_factor", new Short( (short) 2));
ncfile.addVariableAttribute("t5", "add_offset", new Short( (short) 77));
// case 1
ncfile.addVariable("m1", DataType.DOUBLE, dims);
ncfile.addVariableAttribute("m1", "missing_value", -999.99);
// create the file
ncfile.create();
// write t1
ArrayDouble A = new ArrayDouble.D2(latDim.getLength(), lonDim.getLength());
int i,j;
Index ima = A.getIndex();
// write
for (i=0; i<latDim.getLength(); i++)
for (j=0; j<lonDim.getLength(); j++)
A.setDouble(ima.set(i,j), (double) (i*10.0+j));
int[] origin = new int[2];
ncfile.write("t1", origin, A);
// write t2
ArrayByte Ab = new ArrayByte.D2(latDim.getLength(), lonDim.getLength());
ima = Ab.getIndex();
for (i=0; i<latDim.getLength(); i++)
for (j=0; j<lonDim.getLength(); j++)
Ab.setByte(ima.set(i,j), (byte) (i*10+j));
ncfile.write("t2", origin, Ab);
// write t3
ncfile.write("t3", origin, Ab);
// write t4
Array As = new ArrayShort.D2(latDim.getLength(), lonDim.getLength());
ima = As.getIndex();
for (i=0; i<latDim.getLength(); i++)
for (j=0; j<lonDim.getLength(); j++)
As.setShort(ima.set(i,j), (short) (i*10+j));
ncfile.write("t4", origin, As);
As.setShort(ima.set(0, 0), (short) -9999);
ncfile.write("t5", origin, As);
// write m1
ArrayDouble.D2 Ad = new ArrayDouble.D2(latDim.getLength(), lonDim.getLength());
for (i=0; i<latDim.getLength(); i++)
for (j=0; j<lonDim.getLength(); j++)
Ad.setDouble(ima.set(i,j), (double) (i*10.0+j));
Ad.set(1,1,-999.99);
ncfile.write("m1", new int[2], Ad);
// all done
ncfile.close();
System.out.println( "**************TestStandardVar Write done");
}
private NetcdfFile ncfileRead;
private NetcdfDataset dsRead;
public void testReadStandardVar() throws Exception {
ncfileRead = NetcdfFile.open(filename);
dsRead = NetcdfDataset.openDataset(filename);
readDouble();
readByte2Short();
readByte();
readShortMissing();
readShort2FloatMissing();
readDoubleMissing();
ncfileRead.close();
dsRead.close();
}
public void readDouble() throws Exception {
Variable t1 = null;
assert(null != (t1 = ncfileRead.findVariable("t1")));
assert( t1.getDataType() == DataType.DOUBLE);
Attribute att = t1.findAttribute("scale_factor");
assert( null != att);
assert( !att.isArray());
assert( 1 == att.getLength());
assert( 2.0 == att.getNumericValue().doubleValue());
assert( DataType.DOUBLE == att.getDataType());
// read
Array A = t1.read();
int i,j;
Index ima = A.getIndex();
int[] shape = A.getShape();
for (i=0; i<shape[0]; i++) {
for (j=0; j<shape[1]; j++) {
assert( A.getDouble(ima.set(i,j)) == (double) (i*10.0+j));
}
}
assert(null != (t1 = dsRead.findVariable("t1")));
assert t1 instanceof VariableEnhanced;
VariableEnhanced dsVar = (VariableEnhanced) t1;
assert( dsVar.getDataType() == DataType.DOUBLE);
A = dsVar.read();
ima = A.getIndex();
shape = A.getShape();
for (i=0; i<shape[0]; i++) {
for (j=0; j<shape[1]; j++) {
assert( A.getDouble(ima.set(i,j)) == (2.0 * (i*10.0+j) + 77.0));
}
}
assert( null == t1.findAttribute("scale_factor"));
assert( null == t1.findAttribute("add_offset"));
System.out.println( "**************TestStandardVar ReadDouble");
}
public void readByte2Short() throws Exception {
Variable t2 = null;
assert(null != (t2 = ncfileRead.findVariable("t2")));
assert( t2.getDataType() == DataType.BYTE);
Attribute att = t2.findAttribute("scale_factor");
assert( null != att);
assert( !att.isArray());
assert( 1 == att.getLength());
assert( 2 == att.getNumericValue().doubleValue());
assert( DataType.SHORT == att.getDataType());
assert(null != (t2 = dsRead.findVariable("t2")));
assert t2 instanceof VariableEnhanced;
VariableDS vs = (VariableDS) t2;
assert( vs.getDataType() == DataType.SHORT) : vs.getDataType();
assert( !vs.hasMissing());
Array A = vs.read();
assert( A.getElementType() == short.class) : A.getElementType();
Index ima = A.getIndex();
int[] shape = A.getShape();
int i,j;
for (i=0; i<shape[0]; i++) {
for (j=0; j<shape[1]; j++) {
assert( A.getShort(ima.set(i,j)) == (2 * (i*10+j) + 77));
}
}
System.out.println( "**************TestStandardVar readByte2Short");
}
public void readByte() throws Exception {
Variable v = null;
assert(null != (v = ncfileRead.findVariable("t3")));
assert( v.getDataType() == DataType.BYTE);
assert(null != (v = dsRead.findVariable("t3")));
assert v instanceof VariableEnhanced;
assert v instanceof VariableDS;
VariableDS vs = (VariableDS) v;
assert( vs.getDataType() == DataType.BYTE);
Attribute att = vs.findAttribute("_FillValue");
assert( null != att);
assert( !att.isArray());
assert( 1 == att.getLength());
System.out.println("_FillValue = "+att.getNumericValue().byteValue());
assert( ((byte) 255) == att.getNumericValue().byteValue());
assert( DataType.BYTE == att.getDataType());
assert( vs.hasMissing());
assert( vs.hasFillValue());
assert( vs.isMissing( (double) ((byte) 255)));
assert( vs.isFillValue( (double) ((byte) 255)));
Array A = vs.read();
assert( A.getElementType() == byte.class) : A.getElementType();
Index ima = A.getIndex();
int[] shape = A.getShape();
int i,j;
for (i=0; i<shape[0]; i++) {
for (j=0; j<shape[1]; j++) {
assert( A.getFloat(ima.set(i,j)) == (i*10+j));
}
}
System.out.println( "**************TestStandardVar ReadByte");
}
public void readShortMissing() throws Exception {
Variable v = null;
assert(null != (v = ncfileRead.findVariable("t4")));
assert( v.getDataType() == DataType.SHORT);
// default use of missing_value
assert(null != (v = dsRead.findVariable("t4")));
assert v instanceof VariableEnhanced;
assert v instanceof VariableDS;
VariableDS vs = (VariableDS) v;
assert( vs.getDataType() == DataType.SHORT);
Attribute att = vs.findAttribute("missing_value");
assert( null != att);
assert( !att.isArray());
assert( 1 == att.getLength());
System.out.println("missing_value = "+att.getNumericValue().shortValue());
assert( ((short) -9999) == att.getNumericValue().shortValue());
assert( DataType.SHORT == att.getDataType());
assert( vs.hasMissing());
assert( vs.hasMissingValue());
assert( vs.isMissing( (double) ((short) -9999)));
assert( vs.isMissingValue( (double) ((short) -9999)));
Array A = vs.read();
Index ima = A.getIndex();
int[] shape = A.getShape();
int i,j;
for (i=0; i<shape[0]; i++) {
for (j=0; j<shape[1]; j++) {
assert( A.getFloat(ima.set(i,j)) == (i*10+j));
}
}
// turn off missing data
vs.setMissingDataIsMissing( false);
assert( vs.getDataType() == DataType.SHORT);
assert( !vs.hasMissing());
assert( vs.hasMissingValue());
assert( !vs.isMissing( (double) ((short) -9999)));
assert( vs.isMissingValue( (double) ((short) -9999)));
vs.setMissingDataIsMissing(true);
assert( vs.hasMissing());
assert( vs.isMissing( (double) ((short) -9999)));
System.out.println( "**************TestStandardVar Read readShortMissing");
}
public void readShort2FloatMissing() throws Exception {
Variable v = null;
assert(null != (v = ncfileRead.findVariable("t5")));
assert( v.getDataType() == DataType.SHORT);
// standard convert with missing data
assert(null != (v = dsRead.findVariable("t5")));
assert v instanceof VariableEnhanced;
assert v instanceof VariableDS;
VariableDS vs = (VariableDS) v;
assert( vs.getDataType() == DataType.FLOAT);
assert( vs.hasMissing());
assert( vs.hasMissingValue());
double mv = 2 * (-9999) + 77;
assert( vs.isMissing( (double) mv));
assert( vs.isMissingValue( (double) mv));
Array A = vs.read();
Index ima = A.getIndex();
int[] shape = A.getShape();
int i,j;
assert (vs.isMissing(A.getFloat(ima.set(0,0))));
for (i=0; i<shape[0]; i++) {
for (j=1; j<shape[1]; j++) {
float val = A.getFloat(ima.set(i,j));
float want = 2* (i*10+j) + 77;
if( val != want)
System.out.println(i+" "+j+" "+val+" "+ want);
assert( val == want);
}
}
// useNaNs
vs.setUseNaNs(true);
assert( vs.getDataType() == DataType.FLOAT);
assert( vs.hasMissing());
assert( vs.hasMissingValue());
double mv2 = 2 * (-9999) + 77;
assert( vs.isMissing( (double) mv2));
assert( vs.isMissingValue( (double) mv2));
Array A2 = vs.read();
Index ima2 = A2.getIndex();
int[] shape2 = A2.getShape();
double mval = A2.getFloat(ima2.set(0,0));
assert vs.isMissing(mval);
assert Double.isNaN(mval);
for (i=0; i<shape2[0]; i++) {
for (j=1; j<shape2[1]; j++) {
float val = A2.getFloat(ima2.set(i,j));
float want = 2* (i*10+j) + 77;
if( val != want)
System.out.println(i+" "+j+" "+val+" "+ want);
assert( val == want) : val+" != "+ want;
}
}
assert( null == vs.findAttribute("scale_factor"));
assert( null == vs.findAttribute("add_offset"));
assert( null == vs.findAttribute("missing_value"));
System.out.println( "**************TestStandardVar Read readShort2FloatMissing");
}
public void readDoubleMissing() throws Exception {
VariableDS v = null;
assert(null != (v = (VariableDS) dsRead.findVariable("m1")));
assert( v.getDataType() == DataType.DOUBLE);
Array A = v.read();
Index ima = A.getIndex();
double val = A.getFloat(ima.set(1,1));
assert Double.isNaN(val);
assert v.isMissing(val);
// reread with useNans off
v.setUseNaNs(false);
v.createNewCache();
A = v.read();
ima = A.getIndex();
val = A.getFloat(ima.set(1,1));
assert TestAll.closeEnough(val, -999.99) : val;
assert v.isMissing(val);
}
public void testEnhanceDefer() throws IOException {
NetcdfDataset ncd = NetcdfDataset.openDataset(filename, EnumSet.of(NetcdfDataset.Enhance.ScaleMissing), -1, null, null);
VariableDS enhancedVar = (VariableDS) ncd.findVariable("t1");
NetcdfDataset ncdefer = NetcdfDataset.openDataset(filename, EnumSet.of(NetcdfDataset.Enhance.ScaleMissingDefer), -1, null, null);
VariableDS deferVar = (VariableDS) ncdefer.findVariable("t1");
Array data = enhancedVar.read();
Array dataDefer = deferVar.read();
System.out.printf("Enhanced=");
NCdumpW.printArray(data);
System.out.printf("%nDeferred=");
NCdumpW.printArray(dataDefer);
System.out.printf("%nProcessed=");
CompareNetcdf2 nc = new CompareNetcdf2(new Formatter(System.out), false, false, true);
assert !nc.compareData(enhancedVar.getShortName(), data, dataDefer, false);
IndexIterator ii = dataDefer.getIndexIterator();
while (ii.hasNext()) {
double val = deferVar.convertScaleOffsetMissing(ii.getDoubleNext());
ii.setDoubleCurrent(val);
}
NCdumpW.printArray(dataDefer);
assert nc.compareData(enhancedVar.getShortName(), data, dataDefer, false);
ncd.close();
ncdefer.close();
}
// for jon blower
private Array getEnhancedArray(VariableDS vds) throws IOException {
Array data = vds.read();
EnumSet<NetcdfDataset.Enhance> mode = vds.getEnhanceMode();
if (mode.contains(NetcdfDataset.Enhance.ScaleMissing))
return data;
if (!mode.contains(NetcdfDataset.Enhance.ScaleMissingDefer))
throw new IllegalStateException("Must include "+NetcdfDataset.Enhance.ScaleMissingDefer);
IndexIterator ii = data.getIndexIterator();
while (ii.hasNext()) {
double val = vds.convertScaleOffsetMissing(ii.getDoubleNext());
ii.setDoubleCurrent(val);
}
return data;
}
}