public void testAggCoordVar(NetcdfFile ncfile) { Variable time = ncfile.findVariable("time"); assert null != time; assert time.getShortName().equals("time"); assert time.getRank() == 1 : time.getRank(); assert time.getShape()[0] == 3; assert time.getDataType() == DataType.INT; assert time.getDimension(0) == ncfile.findDimension("time"); try { Array data = time.read(); assert (data instanceof ArrayInt.D1) : data.getClass().getName(); ArrayInt.D1 dataI = (ArrayInt.D1) data; assert dataI.get(0) == 0; assert dataI.get(1) == 10; assert dataI.get(2) == 99; } catch (IOException io) { io.printStackTrace(); assert false; } }
/* Structure { int a_name; byte b_name(3); byte c_name(3); short d_name(3); int e_name(3); long f_name(3); int g_name(3); short h_name(3); int i_name(3); long j_name(3); float k_name(3); double l_name(3); } CompoundNative(15); type = Layout(8); type= 1 (contiguous) storageSize = (15,144) dataSize=0 dataAddress=2048 */ @Test public void testReadH5StructureArrayMembers() throws java.io.IOException { try (NetcdfFile ncfile = TestH5.openH5("complex/compound_native.h5")) { Variable dset = ncfile.findVariable("CompoundNative"); assert (null != dset); assert (dset.getDataType() == DataType.STRUCTURE); assert (dset.getRank() == 1); assert (dset.getSize() == 15); Dimension d = dset.getDimension(0); assert (d.getLength() == 15); Structure s = (Structure) dset; // read all with the iterator StructureDataIterator iter = s.getStructureIterator(); while (iter.hasNext()) { StructureData sd = iter.next(); for (StructureMembers.Member m : sd.getMembers()) { Array data = sd.getArray(m); NCdumpW.printArray(data, m.getName(), out, null); } } } System.out.println("*** testReadH5StructureArrayMembers ok"); }
public void testAggCoordVar2(NetcdfFile ncfile) { Variable time = ncfile.findVariable("time"); assert null != time; assert time.getShortName().equals("time"); assert time.getRank() == 1 : time.getRank(); assert time.getShape()[0] == 3; assert time.getDataType() == DataType.INT; assert time.getDimension(0) == ncfile.findDimension("time"); try { Array data = time.read(); assert (data instanceof ArrayInt); IndexIterator dataI = data.getIndexIterator(); assert dataI.getIntNext() == 0 : dataI.getIntCurrent(); assert dataI.getIntNext() == 1 : dataI.getIntCurrent(); assert dataI.getIntNext() == 2 : dataI.getIntCurrent(); } catch (IOException io) { io.printStackTrace(); assert false; } }
public void testAggCoordVar(NetcdfFile ncfile) { Variable time = ncfile.findVariable("time"); assert null != time; assert time.getShortName().equals("time"); assert time.getRank() == 1; assert time.getSize() == 3; assert time.getShape()[0] == 3; assert time.getDataType() == DataType.DOUBLE; assert time.getDimension(0) == ncfile.findDimension("time"); try { Array data = time.read(); assert data.getRank() == 1; assert data.getSize() == 3; assert data.getShape()[0] == 3; assert data.getElementType() == double.class; int count = 0; IndexIterator dataI = data.getIndexIterator(); while (dataI.hasNext()) { assert Misc.closeEnough(dataI.getDoubleNext(), result[count]); count++; } } catch (IOException io) { io.printStackTrace(); assert false; } }
public void testScan() throws IOException, InvalidRangeException { String xml = "<?xml version='1.0' encoding='UTF-8'?>\n" + "<netcdf xmlns='http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2'>\n" + " <variable name='time' type='int' shape='time'>\n" + " <attribute name='long_name' type='string' value='time coordinate' />\n" + " <attribute name='units' type='string' value='days since 2001-8-31 00:00:00 UTC' />\n" + " <values start='0' increment='10' />\n" + " </variable>\n" + " <aggregation dimName='time' type='joinNew'>\n" + " <variableAgg name='T'/>\n" + " <scan location='src/test/data/ncml/nc/' suffix='Dir.nc' subdirs='false'/>\n" + " </aggregation>\n" + "</netcdf>"; String filename = "file:./" + TestNcML.topDir + "aggSynScan.xml"; NetcdfFile ncfile = NcMLReader.readNcML(new StringReader(xml), null); testDimensions(ncfile); testCoordVar(ncfile); testAggCoordVarScan(ncfile); testReadData(ncfile, "T"); testReadSlice(ncfile, "T"); ncfile.close(); }
/* Structure { int LAT[0]; ... int LAT[149]; } IMAGE_LAT_ARRAY(3600); type = Layout(8); type= 2 (chunked) storageSize = (1,600) dataSize=0 dataAddress=2548046 */ @Test public void testReadOneAtATime() throws java.io.IOException, InvalidRangeException { try (NetcdfFile ncfile = TestH5.openH5("IASI/IASI.h5")) { Variable dset = ncfile.findVariable("U-MARF/EPS/IASI_xxx_1C/DATA/IMAGE_LAT_ARRAY"); assert (null != dset); assert (dset.getDataType() == DataType.STRUCTURE); assert (dset.getRank() == 1); assert (dset.getSize() == 3600); Dimension d = dset.getDimension(0); assert (d.getLength() == 3600); Structure s = (Structure) dset; // read last one - chunked StructureData sd = s.readStructure(3599); assert sd.getScalarInt("LAT[0]") == 70862722; assert sd.getScalarInt("LAT[149]") == 85302263; // read one at a time for (int i = 3590; i < d.getLength(); i++) { s.readStructure(i); System.out.println(" read structure " + i); } } System.out.println("*** testReadIASI ok"); }
public void testNcmlCached() throws IOException, InvalidRangeException { System.out.println("\n TestNcmlAggExistingCached.acquire at " + new Date()); NetcdfFile ncfile = NetcdfDataset.acquireDataset(filename, null); testAggCoordVar(ncfile); ncfile.close(); System.out.println("\n TestNcmlAggExistingCached.acquire again at " + new Date()); ncfile = NetcdfDataset.acquireDataset(filename, null); testAggCoordVar(ncfile); ncfile.close(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("\n TestNcmlAggExistingCached.acquire after sleeping " + new Date()); ncfile = NetcdfDataset.acquireDataset(filename, null); testAggCoordVar(ncfile); ncfile.close(); NetcdfDataset.getNetcdfFileCache().clearCache(false); System.out.println("\n TestNcmlAggExistingCached.acquire after flushing cache " + new Date()); ncfile = NetcdfDataset.acquireDataset(filename, null); testAggCoordVar(ncfile); testAggCoordVarSubset(ncfile); ncfile.close(); }
/** * Build the netCDF file * * @throws IOException problem reading the file */ protected void buildNCFile() throws IOException { Trace.call1("GEMPAKSIOSP: buildNCFile"); ncfile.empty(); fillNCFile(); addGlobalAttributes(); ncfile.finish(); Trace.call2("GEMPAKSIOSP: buildNCFile"); // System.out.println(ncfile); }
public static boolean isMine(NetcdfFile ncfile) { String satName = ncfile.findAttValueIgnoreCase(null, "SATNAME", null); if ((satName == null) || !(satName.equalsIgnoreCase("Aqua"))) return false; String instName = ncfile.findAttValueIgnoreCase(null, "INTRUMENT_NAME", null); if ((instName == null) || !(instName.equalsIgnoreCase("modis"))) return false; return true; }
/** Create a DAS for this netcdf file */ NcDAS(NetcdfFile ncfile) { // Variable attributes Iterator iter = ncfile.getVariables().iterator(); while (iter.hasNext()) { Variable v = (Variable) iter.next(); doVariable(v, null); } // Global attributes opendap.dap.AttributeTable gtable = new opendap.dap.AttributeTable("NC_GLOBAL"); int count = addAttributes(gtable, null, ncfile.getGlobalAttributes().iterator()); if (count > 0) try { addAttributeTable("NC_GLOBAL", gtable); } catch (AttributeExistsException e) { log.error("Cant add NC_GLOBAL", e); } // unlimited dimension iter = ncfile.getDimensions().iterator(); while (iter.hasNext()) { Dimension d = (Dimension) iter.next(); if (d.isUnlimited()) { opendap.dap.AttributeTable table = new opendap.dap.AttributeTable("DODS_EXTRA"); try { table.appendAttribute("Unlimited_Dimension", opendap.dap.Attribute.STRING, d.getName()); addAttributeTable("DODS_EXTRA", table); } catch (Exception e) { log.error("Error adding Unlimited_Dimension =" + e); } break; } } // unused dimensions opendap.dap.AttributeTable dimTable = null; iter = ncfile.getDimensions().iterator(); while (iter.hasNext()) { Dimension d = (Dimension) iter.next(); if (null == usedDims.get(d.getName())) { if (dimTable == null) dimTable = new opendap.dap.AttributeTable("EXTRA_DIMENSION"); try { dimTable.appendAttribute( d.getName(), opendap.dap.Attribute.INT32, Integer.toString(d.getLength())); } catch (Exception e) { log.error("Error adding Unlimited_Dimension =" + e); } } } if (dimTable != null) try { addAttributeTable("EXTRA_DIMENSION", dimTable); } catch (AttributeExistsException e) { log.error("Cant add EXTRA_DIMENSION", e); } }
void writeNetCDF(String filename) { try { FileWriter2 writer = new FileWriter2(ds, filename, NetcdfFileWriter.Version.netcdf3); NetcdfFile result = writer.write(); result.close(); JOptionPane.showMessageDialog(this, "File successfully written"); } catch (Exception ioe) { JOptionPane.showMessageDialog(this, "ERROR: " + ioe.getMessage()); ioe.printStackTrace(); } }
public void testNcmlDirect() throws IOException, InvalidRangeException { NetcdfFile ncfile = NetcdfDataset.openDataset(filename, false, null); System.out.println("\n TestNcmlAggExistingCached.open " + filename); // System.out.println(" "+ ncfile); testAggCoordVar(ncfile); testAggCoordVarSubset(ncfile); testAggCoordVarSubsetDefeatLocalCache(ncfile); ncfile.close(); }
public static boolean isMine(NetcdfFile ncfile) { if (!ncfile.getFileTypeId().equals("HDF5")) return false; Group loc = ncfile.findGroup("VHRR/Geo-Location"); if (null == loc) return false; if (null == loc.findVariable("Latitude")) return false; if (null == loc.findVariable("Longitude")) return false; if (null == ncfile.findGroup("VHRR/Image Data")) return false; return true; }
public static void main(String args[]) throws Exception { // String fileIn = // "C:/data/bufr/edition3/newIdd/IcingTropopause/IcingTropopause_20080529_0000.bufr"; String fileIn = "C:\\data\\bufr\\edition3\\meteosat\\METEOSAT7-MVIRI-MTPHRWW-NA-1-20080405123005.000000000Z-909326.bfr "; NetcdfFile ncf = NetcdfDataset.openFile(fileIn, null); System.out.println(ncf.toString()); new Write2ncRect(ncf, "C:/data/bufr2nc.meteosat.nc", true); }
public void testNoCoord() throws IOException, InvalidRangeException { String filename = "file:./" + TestNcML.topDir + "aggSynNoCoord.xml"; NetcdfFile ncfile = NcMLReader.readNcML(filename, null); testDimensions(ncfile); testCoordVar(ncfile); testAggCoordVarNoCoord(ncfile); testReadData(ncfile, "T"); testReadSlice(ncfile, "T"); ncfile.close(); }
/** Add on global attributes for all types */ protected void addGlobalAttributes() { // global stuff ncfile.addAttribute(null, new Attribute("Conventions", getConventions())); String fileType = "GEMPAK " + gemreader.getFileType(); ncfile.addAttribute(null, new Attribute("file_format", fileType)); ncfile.addAttribute( null, new Attribute( "history", "Direct read of " + fileType + " into NetCDF-Java 4.2 API")); // at " + dateFormat.toDateTimeStringISO(new // Date()))); ncfile.addAttribute(null, new Attribute(CF.FEATURE_TYPE, getCFFeatureType())); }
public void testReadStandardVar() throws Exception { ncfileRead = NetcdfFile.open(filename); dsRead = NetcdfDataset.openDataset(filename); readDouble(); readByte2Short(); readByte(); readShortMissing(); readShort2FloatMissing(); readDoubleMissing(); ncfileRead.close(); dsRead.close(); }
/** * Set the name, converting to valid CDM object name if needed. * * @param name set to this value * @return valid CDM object name */ public String setName(String name) { if (immutable) throw new IllegalStateException("Cant modify"); this.name = (name == null || name.length() == 0) ? null : NetcdfFile.makeValidCdmObjectName(name); hashCode = 0; return this.name; }
private void makeVariableNoCoords( NetcdfFile ncfile, int datatype, String shortName, String longName, Variable from) { Variable v = new Variable(ncfile, null, null, shortName); v.setDataType(DataType.BYTE); v.setDimensions(from.getDimensions()); ncfile.addVariable(null, v); v.addAttribute(new Attribute(CDM.UNITS, Cinrad2Record.getDatatypeUnits(datatype))); v.addAttribute(new Attribute(CDM.LONG_NAME, longName)); byte[] b = new byte[2]; b[0] = Cinrad2Record.MISSING_DATA; b[1] = Cinrad2Record.BELOW_THRESHOLD; Array missingArray = Array.factory(DataType.BYTE.getPrimitiveClassType(), new int[] {2}, b); v.addAttribute(new Attribute(CDM.MISSING_VALUE, missingArray)); v.addAttribute( new Attribute("signal_below_threshold", new Byte(Cinrad2Record.BELOW_THRESHOLD))); v.addAttribute( new Attribute(CDM.SCALE_FACTOR, new Float(Cinrad2Record.getDatatypeScaleFactor(datatype)))); v.addAttribute( new Attribute(CDM.ADD_OFFSET, new Float(Cinrad2Record.getDatatypeAddOffset(datatype)))); v.addAttribute(new Attribute(CDM.UNSIGNED, "true")); Attribute fromAtt = from.findAttribute(_Coordinate.Axes); v.addAttribute(new Attribute(_Coordinate.Axes, fromAtt)); Vgroup vgFrom = (Vgroup) from.getSPobject(); Vgroup vg = new Vgroup(datatype, vgFrom.map); v.setSPobject(vg); }
/** * String representation. * * @param strict if true, write in strict adherence to CDL definition. * @return CDL representation. */ public String writeCDL(boolean strict) { StringBuilder buff = new StringBuilder(); String name = strict ? NetcdfFile.escapeNameCDL(getName()) : getName(); buff.append(" enum ").append(name).append(" { "); int count = 0; List<Object> keyset = Arrays.asList(map.keySet().toArray()); // Collections.sort(keyset); for (Object key : keyset) { String s = map.get(key); if (0 < count++) buff.append(", "); if (strict) buff.append(NetcdfFile.escapeNameCDL(s)).append(" = ").append(key); else buff.append("'").append(s).append("' = ").append(key); } buff.append("};"); return buff.toString(); }
public List<VariableBean> getVariableBeans(NetcdfFile ds) { List<VariableBean> vlist = new ArrayList<VariableBean>(); for (Variable v : ds.getVariables()) { vlist.add(new VariableBean(v)); } return vlist; }
public void showAtts() { if (ds == null) return; if (attTable == null) { // global attributes attTable = new BeanTableSorted( AttributeBean.class, (PreferencesExt) prefs.node("AttributeBeans"), false); PopupMenu varPopup = new ucar.nc2.ui.widget.PopupMenu(attTable.getJTable(), "Options"); varPopup.addAction( "Show Attribute", new AbstractAction() { public void actionPerformed(ActionEvent e) { AttributeBean bean = (AttributeBean) attTable.getSelectedBean(); if (bean != null) { infoTA.setText(bean.att.toString()); infoTA.gotoTop(); infoWindow.show(); } } }); attWindow = new IndependentWindow("Global Attributes", BAMutil.getImage("netcdfUI"), attTable); attWindow.setBounds( (Rectangle) prefs.getBean("AttWindowBounds", new Rectangle(300, 100, 500, 800))); } List<AttributeBean> attlist = new ArrayList<AttributeBean>(); for (Attribute att : ds.getGlobalAttributes()) { attlist.add(new AttributeBean(att)); } attTable.setBeans(attlist); attWindow.show(); }
/** * CDL representation * * @param strict if true, create strict CDL, escaping names * @return CDL representation */ public String toString(boolean strict) { StringBuilder buff = new StringBuilder(); buff.append(strict ? NetcdfFile.escapeNameCDL(getName()) : getName()); if (isString()) { buff.append(" = "); for (int i = 0; i < getLength(); i++) { if (i != 0) buff.append(", "); String val = getStringValue(i); if (val != null) buff.append("\"").append(NCdumpW.encodeString(val)).append("\""); } } else { buff.append(" = "); for (int i = 0; i < getLength(); i++) { if (i != 0) buff.append(", "); buff.append(getNumericValue(i)); if (dataType == DataType.FLOAT) buff.append("f"); else if (dataType == DataType.SHORT) { if (isUnsigned()) buff.append("US"); else buff.append("S"); } else if (dataType == DataType.BYTE) { if (isUnsigned()) buff.append("UB"); else buff.append("B"); } else if (dataType == DataType.LONG) { if (isUnsigned()) buff.append("UL"); else buff.append("L"); } else if (dataType == DataType.INT) { if (isUnsigned()) buff.append("U"); } } } return buff.toString(); }
public void readByte2Short() throws Exception { Variable t2 = null; assert (null != (t2 = ncfileRead.findVariable("t2"))); assert (t2.getDataType() == DataType.BYTE); Attribute att = t2.findAttribute(CDM.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 static Map<String, Metadata> readFile(String file) throws Exception { NetcdfFile n = NetcdfFile.open(file); System.out.println("Opened: " + file); /* Determine the size of our grid */ int xLen = n.findDimension("x").getLength(); int yLen = n.findDimension("y").getLength(); System.out.println("Grid size: " + xLen + "x" + yLen); /* What time is this set of readings for? */ Variable timeVar = n.findVariable("time"); String timeStr = timeVar.getUnitsString().toUpperCase(); timeStr = timeStr.replace("HOURS SINCE ", ""); timeStr = timeStr.replace("HOUR SINCE ", ""); /* Find the base date (the day) the reading was taken */ Date baseDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse(timeStr); /* Get the number of hours since the base date this reading was taken */ int offset = timeVar.read().getInt(0); /* Generate the actual date for this reading */ Calendar calendar = Calendar.getInstance(); calendar.setTime(baseDate); calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + offset); System.out.println("Time of collection: " + calendar.getTime()); /* We'll keep a mapping of geolocations -> Galileo Metadata */ Map<String, Metadata> metaMap = new HashMap<>(); /* Determine the lat, lon coordinates for the grid points, and get each * reading at each grid point. */ NetcdfDataset dataset = new NetcdfDataset(n); @SuppressWarnings("resource") GridDataset gridData = new GridDataset(dataset); for (GridDatatype g : gridData.getGrids()) { /* Let's look at 3D variables: these have WxH dimensions, plus a * single plane. A 4D variable would contain elevation * and multiple planes as a result */ if (g.getShape().length == 3) { convert3DVariable(g, calendar.getTime(), metaMap); } } return metaMap; }
/* Structure { int a_name; String b_name(4); char c_name(6); short d_name(5, 4); float e_name; double f_name(10); byte g_name; } CompoundComplex(6); type = Layout(8); type= 1 (contiguous) storageSize = (6,224) dataSize=0 dataAddress=2048 */ @Test public void testReadH5Structure() throws java.io.IOException { int a_name = 0; String[] b_name = new String[] { "A fight is a contract that takes two people to honor.", "A combative stance means that you've accepted the contract.", "In which case, you deserve what you get.", " -- Professor Cheng Man-ch'ing" }; String c_name = "Hello!"; // H5header.setDebugFlags(new ucar.nc2.util.DebugFlagsImpl("H5header/header")); try (NetcdfFile ncfile = TestH5.openH5("complex/compound_complex.h5")) { Variable dset = ncfile.findVariable("CompoundComplex"); assert (null != dset); assert (dset.getDataType() == DataType.STRUCTURE); assert (dset.getRank() == 1); assert (dset.getSize() == 6); Dimension d = dset.getDimension(0); assert (d.getLength() == 6); Structure s = (Structure) dset; // read all with the iterator StructureDataIterator iter = s.getStructureIterator(); while (iter.hasNext()) { StructureData sd = iter.next(); assert sd.getScalarInt("a_name") == a_name; a_name++; assert sd.getScalarString("c_name").equals(c_name); String[] results = sd.getJavaArrayString(sd.findMember("b_name")); assert results.length == b_name.length; int count = 0; for (String r : results) assert r.equals(b_name[count++]); for (StructureMembers.Member m : sd.getMembers()) { Array data = sd.getArray(m); NCdumpW.printArray(data, m.getName(), out, null); } } } System.out.println("*** testReadH5Structure ok"); }
/** * Add this coord as a dimension to the netCDF file * * @param ncfile file to add to * @param g group in the file */ void addDimensionsToNetcdfFile(NetcdfFile ncfile, Group g) { if (dontUseVertical) { return; } int nlevs = levels.size(); if (coordValues != null) nlevs = coordValues.length; ncfile.addDimension(g, new Dimension(getVariableName(), nlevs, true)); }
// convert to shared dimensions private void setSharedDimensions( Variable v, List<Element> values, List<Dimension> unknownDims, String location) { if (values.size() == 0) return; // remove the "scalar" dumbension Iterator<Element> iter = values.iterator(); while (iter.hasNext()) { Element value = iter.next(); String dimName = value.getText().trim(); if (dimName.equalsIgnoreCase("scalar")) iter.remove(); } // gotta have same number of dimensions List<Dimension> oldDims = v.getDimensions(); if (oldDims.size() != values.size()) { log.error("Different number of dimensions for {} {}", v, location); return; } List<Dimension> newDims = new ArrayList<>(); Group group = v.getParentGroup(); for (int i = 0; i < values.size(); i++) { Element value = values.get(i); String dimName = value.getText().trim(); dimName = NetcdfFile.makeValidCdmObjectName(dimName); Dimension dim = group.findDimension(dimName); Dimension oldDim = oldDims.get(i); if (dim == null) dim = checkUnknownDims(dimName, unknownDims, oldDim, location); if (dim == null) { log.error( "Unknown Dimension= {} for variable = {} {} ", dimName, v.getFullName(), location); return; } if (dim.getLength() != oldDim.getLength()) { log.error( "Shared dimension (" + dim.getShortName() + ") has different length than data dimension (" + oldDim.getShortName() + ") shared=" + dim.getLength() + " org=" + oldDim.getLength() + " for " + v + " " + location); return; } newDims.add(dim); } v.setDimensions(newDims); if (showWork) System.out.printf(" set shared dimensions for %s %n", v.getNameAndDimensions()); }
/** * Amend the given NetcdfFile with metadata from HDF-EOS structMetadata. All Variables named * StructMetadata.n, where n= 1, 2, 3 ... are read in and their contents concatenated to make the * structMetadata String. * * @param ncfile Amend this file * @param eosGroup the group containing variables named StructMetadata.* * @throws IOException on read error * @return true if HDF-EOS info was found */ public static boolean amendFromODL(NetcdfFile ncfile, Group eosGroup) throws IOException { String smeta = getStructMetadata(eosGroup); if (smeta == null) return false; HdfEos fixer = new HdfEos(); fixer.fixAttributes(ncfile.getRootGroup()); fixer.amendFromODL(ncfile, smeta); return true; }
public void test1() throws IOException, InvalidRangeException { String filename = "file:./" + TestNcML.topDir + "aggSynthetic.xml"; NetcdfFile ncfile = NcMLReader.readNcML(filename, null); Variable v = ncfile.findVariable("time"); assert v != null; String testAtt = ncfile.findAttValueIgnoreCase(v, "units", null); assert testAtt != null; assert testAtt.equals("months since 2000-6-16 6:00"); testDimensions(ncfile); testCoordVar(ncfile); testAggCoordVar(ncfile); testReadData(ncfile, "T"); testReadSlice(ncfile, "T"); ncfile.close(); }