/** * Wrap the given Variable, making it into a VariableDS. Delegate data reading to the original * variable. Take all metadata from original variable. Does not share cache, iosp. * * @param g logical container, if null use orgVar's group * @param orgVar the original Variable to wrap. The original Variable is not modified. Must not be * a Structure, use StructureDS instead. * @param enhance if true, use NetcdfDataset.defaultEnhanceMode to define what enhancements are * made. Note that this can change DataType and data values. You can also call enhance() * later. If orgVar is VariableDS, then enhance is inherited from there, and this parameter is * ignored. */ public VariableDS(Group g, Variable orgVar, boolean enhance) { super(orgVar); if (g != null) this.group = g; // otherwise super() sets group; this affects the long name and the dimensions. setDimensions(getDimensionsString()); // reset the dimensions if (orgVar instanceof Structure) throw new IllegalArgumentException( "VariableDS must not wrap a Structure; name=" + orgVar.getName()); // dont share cache, iosp : all IO is delegated this.ncfile = null; this.spiObject = null; createNewCache(); this.orgVar = orgVar; this.orgDataType = orgVar.getDataType(); if (orgVar instanceof VariableDS) { VariableDS ncVarDS = (VariableDS) orgVar; this.enhanceProxy = ncVarDS.enhanceProxy; this.scaleMissingProxy = ncVarDS.scaleMissingProxy; this.enhanceMode = ncVarDS.enhanceMode; } else { this.enhanceProxy = new EnhancementsImpl(this); if (enhance) { enhance(NetcdfDataset.getDefaultEnhanceMode()); } else { this.scaleMissingProxy = new EnhanceScaleMissingImpl(); } } }
/** * Make a new VariableDS, delegate data reading to the original variable, but otherwise dont take * any info from it. This is used by NcML explicit mode. * * @param group the containing group; may not be null * @param parent parent Structure, may be null * @param shortName variable shortName, must be unique within the Group * @param orgVar the original Variable to wrap. The original Variable is not modified. Must not be * a Structure, use StructureDS instead. */ public VariableDS(Group group, Structure parent, String shortName, Variable orgVar) { super(null, group, parent, shortName); setDimensions(getDimensionsString()); // reset the dimensions if (orgVar instanceof Structure) throw new IllegalArgumentException( "VariableDS must not wrap a Structure; name=" + orgVar.getName()); // dont share cache, iosp : all IO is delegated this.ncfile = null; this.spiObject = null; createNewCache(); this.orgVar = orgVar; this.orgDataType = orgVar.getDataType(); this.enhanceProxy = new EnhancementsImpl(this); this.scaleMissingProxy = new EnhanceScaleMissingImpl(); }
/** * Add this coord as a variable in the netCDF file * * @param ncfile netCDF file to add to * @param g group in file */ void addToNetcdfFile(NetcdfFile ncfile, Group g) { if (dontUseVertical) { typicalRecord = null; return; } if (g == null) { g = ncfile.getRootGroup(); } // coordinate axis Variable v = new Variable(ncfile, g, null, getVariableName()); v.setDataType(DataType.DOUBLE); String desc = lookup.getLevelDescription(typicalRecord); if (lookup instanceof Grib2GridTableLookup && usesBounds) { desc = "Layer between " + desc; } v.addAttribute(new Attribute("long_name", desc)); v.addAttribute(new Attribute("units", lookup.getLevelUnit(typicalRecord))); // positive attribute needed for CF-1 Height and Pressure if (positive != null) { v.addAttribute(new Attribute("positive", positive)); } if (units != null) { AxisType axisType; if (SimpleUnit.isCompatible("millibar", units)) { axisType = AxisType.Pressure; } else if (SimpleUnit.isCompatible("m", units)) { axisType = AxisType.Height; } else { axisType = AxisType.GeoZ; } if (lookup instanceof Grib2GridTableLookup || lookup instanceof Grib1GridTableLookup) { v.addAttribute( new Attribute("GRIB_level_type", Integer.toString(typicalRecord.getLevelType1()))); } else { v.addAttribute( new Attribute("level_type", Integer.toString(typicalRecord.getLevelType1()))); } v.addAttribute(new Attribute(_Coordinate.AxisType, axisType.toString())); } if (coordValues == null) { coordValues = new double[levels.size()]; for (int i = 0; i < levels.size(); i++) { LevelCoord lc = (LevelCoord) levels.get(i); coordValues[i] = lc.mid; } } Array dataArray = Array.factory(DataType.DOUBLE, new int[] {coordValues.length}, coordValues); v.setDimensions(getVariableName()); v.setCachedData(dataArray, true); ncfile.addVariable(g, v); if (usesBounds) { String boundsDimName = "bounds_dim"; if (g.findDimension(boundsDimName) == null) { ncfile.addDimension(g, new Dimension(boundsDimName, 2, true)); } String bname = getVariableName() + "_bounds"; v.addAttribute(new Attribute("bounds", bname)); v.addAttribute(new Attribute(_Coordinate.ZisLayer, "true")); Variable b = new Variable(ncfile, g, null, bname); b.setDataType(DataType.DOUBLE); b.setDimensions(getVariableName() + " " + boundsDimName); b.addAttribute(new Attribute("long_name", "bounds for " + v.getName())); b.addAttribute(new Attribute("units", lookup.getLevelUnit(typicalRecord))); Array boundsArray = Array.factory(DataType.DOUBLE, new int[] {coordValues.length, 2}); ucar.ma2.Index ima = boundsArray.getIndex(); for (int i = 0; i < coordValues.length; i++) { LevelCoord lc = (LevelCoord) levels.get(i); boundsArray.setDouble(ima.set(i, 0), lc.value1); boundsArray.setDouble(ima.set(i, 1), lc.value2); } b.setCachedData(boundsArray, true); ncfile.addVariable(g, b); } if (factors != null) { // check if already created if (g == null) { g = ncfile.getRootGroup(); } if (g.findVariable("hybrida") != null) return; v.addAttribute(new Attribute("standard_name", "atmosphere_hybrid_sigma_pressure_coordinate")); v.addAttribute(new Attribute("formula_terms", "ap: hybrida b: hybridb ps: Pressure")); // create hybrid factor variables // add hybrida variable Variable ha = new Variable(ncfile, g, null, "hybrida"); ha.setDataType(DataType.DOUBLE); ha.addAttribute(new Attribute("long_name", "level_a_factor")); ha.addAttribute(new Attribute("units", "")); ha.setDimensions(getVariableName()); // add data int middle = factors.length / 2; double[] adata; double[] bdata; if (levels.size() < middle) { // only partial data wanted adata = new double[levels.size()]; bdata = new double[levels.size()]; } else { adata = new double[middle]; bdata = new double[middle]; } for (int i = 0; i < middle && i < levels.size(); i++) adata[i] = factors[i]; Array haArray = Array.factory(DataType.DOUBLE, new int[] {adata.length}, adata); ha.setCachedData(haArray, true); ncfile.addVariable(g, ha); // add hybridb variable Variable hb = new Variable(ncfile, g, null, "hybridb"); hb.setDataType(DataType.DOUBLE); hb.addAttribute(new Attribute("long_name", "level_b_factor")); hb.addAttribute(new Attribute("units", "")); hb.setDimensions(getVariableName()); // add data for (int i = 0; i < middle && i < levels.size(); i++) bdata[i] = factors[i + middle]; Array hbArray = Array.factory(DataType.DOUBLE, new int[] {bdata.length}, bdata); hb.setCachedData(hbArray, true); ncfile.addVariable(g, hb); /* // TODO: delete next time modifying code double[] adata = new double[ middle ]; for( int i = 0; i < middle; i++ ) adata[ i ] = factors[ i ]; Array haArray = Array.factory(DataType.DOUBLE, new int[]{adata.length}, adata); ha.setCachedData(haArray, true); ncfile.addVariable(g, ha); // add hybridb variable Variable hb = new Variable(ncfile, g, null, "hybridb"); hb.setDataType(DataType.DOUBLE); hb.addAttribute(new Attribute("long_name", "level_b_factor" )); //hb.addAttribute(new Attribute("standard_name", "atmosphere_hybrid_sigma_pressure_coordinate" )); hb.addAttribute(new Attribute("units", "")); hb.setDimensions(getVariableName()); // add data double[] bdata = new double[ middle ]; for( int i = 0; i < middle; i++ ) bdata[ i ] = factors[ i + middle ]; Array hbArray = Array.factory(DataType.DOUBLE, new int[]{bdata.length}, bdata); hb.setCachedData(hbArray, true); ncfile.addVariable(g, hb); */ } }
/** * Constructor * * @param ncVar: the netcdf Variable */ NcSDFloat64(Variable ncVar) { super(ncVar.getName()); this.ncVar = ncVar; }