// @todo Make sure units are meters public Array getElevation(Range range) throws IOException, InvalidRangeException { List section = new ArrayList(1); section.add(range); Array a = elevVar.read(section); if (elevVarUnitsConversionFactor == 1.0) return (a); for (IndexIterator it = a.getIndexIterator(); it.hasNext(); ) { if (elevVar.getDataType() == DataType.DOUBLE) { double val = it.getDoubleNext(); it.setDoubleCurrent(val * elevVarUnitsConversionFactor); } else if (elevVar.getDataType() == DataType.FLOAT) { float val = it.getFloatNext(); it.setFloatCurrent((float) (val * elevVarUnitsConversionFactor)); } else if (elevVar.getDataType() == DataType.INT) { int val = it.getIntNext(); it.setIntCurrent((int) (val * elevVarUnitsConversionFactor)); } else if (elevVar.getDataType() == DataType.LONG) { long val = it.getLongNext(); it.setLongCurrent((long) (val * elevVarUnitsConversionFactor)); } else { throw new IllegalStateException( "Elevation variable type <" + elevVar.getDataType().toString() + "> not double, float, int, or long."); } } return (a); }
/** * Create a new GridVertCoord for a layer * * @param record layer record * @param levelName name of this level * @param lookup lookup table * @param level1 level 1 * @param level2 level 2 */ GridVertCoord( GridRecord record, String levelName, GridTableLookup lookup, double[] level1, double[] level2) { this.typicalRecord = record; this.levelName = levelName; this.lookup = lookup; // dontUseVertical = !lookup.isVerticalCoordinate(record); positive = lookup.isPositiveUp(record) ? "up" : "down"; units = lookup.getLevelUnit(record); usesBounds = lookup.isLayer(this.typicalRecord); levels = new ArrayList<LevelCoord>(level1.length); for (int i = 0; i < level1.length; i++) { levels.add(new LevelCoord(level1[i], (level2 == null) ? 0.0 : level2[i])); } Collections.sort(levels); if (positive.equals("down")) { Collections.reverse(levels); } dontUseVertical = (levels.size() == 1); }
/** get the shape */ public int[] getShape() { int[] shape = new int[mydims.size()]; for (int i = 0; i < mydims.size(); i++) { Dimension d = mydims.get(i); shape[i] = d.getLength(); } return shape; }
private LatLonRect getBoundingBox(List stnList) { ucar.unidata.geoloc.Station s = (ucar.unidata.geoloc.Station) stnList.get(0); LatLonPointImpl llpt = new LatLonPointImpl(); llpt.set(s.getLatitude(), s.getLongitude()); LatLonRect rect = new LatLonRect(llpt, .001, .001); for (int i = 1; i < stnList.size(); i++) { s = (ucar.unidata.geoloc.Station) stnList.get(i); llpt.set(s.getLatitude(), s.getLongitude()); rect.extend(llpt); } return rect; }
private void makeSelectStations(StringBuffer sbuff, List stations) { // ID id1,id2,id3,...idn // However, it will depend on the dataset as to the variable for the station ID. // For synoptic data it's IDN (e.g. 72469) // for METAR it's ID. // For profiler data, there are two variables IDA and IDB where IDA is the first 4 chars and IDB // is the second 4. sbuff.append("ID "); for (int i = 0; i < stations.size(); i++) { Station s = (Station) stations.get(i); if (i > 0) sbuff.append(","); sbuff.append(s.getName()); } }
/** * Create a new GridVertCoord with the appropriate params * * @param records list of GridRecords that make up this coord * @param levelName the name of the level * @param lookup the lookup table * @param hcs Horizontal coordinate */ GridVertCoord( List<GridRecord> records, String levelName, GridTableLookup lookup, GridHorizCoordSys hcs) { this.typicalRecord = records.get(0); this.levelName = levelName; this.lookup = lookup; dontUseVertical = !lookup.isVerticalCoordinate(typicalRecord); positive = lookup.isPositiveUp(typicalRecord) ? "up" : "down"; units = lookup.getLevelUnit(typicalRecord); usesBounds = lookup.isLayer(this.typicalRecord); addLevels(records); if (typicalRecord.getLevelType1() == 109 && lookup instanceof Grib1GridTableLookup) checkForPressureLevels(records, hcs); if (GridServiceProvider.debugVert) { System.out.println( "GribVertCoord: " + getVariableName() + "(" + typicalRecord.getLevelType1() + ") useVertical= " + (!dontUseVertical) + " positive=" + positive + " units=" + units); } }
private void createProfiles(int nprofiles) throws IOException { this.nprofiles = nprofiles; // add the dimensions Dimension profileDim = ncfile.addDimension(profileDimName, nprofiles); profileDims.add(profileDim); Variable v = ncfile.addVariable(numObsName, DataType.INT, profileDimName); ncfile.addVariableAttribute( v, new Attribute("long_name", "number of children in linked list for this profile")); v = ncfile.addVariable(numProfilesTotalName, DataType.INT, ""); ncfile.addVariableAttribute(v, new Attribute("long_name", "number of valid profiles")); v = ncfile.addVariable(firstObsName, DataType.INT, profileDimName); ncfile.addVariableAttribute( v, new Attribute("long_name", "record number of first obs in linked list for this profile")); // time variable Variable timeVar = ncfile.addStringVariable(timeName, profileDims, 20); ncfile.addVariableAttribute( timeVar, new Attribute("long_name", "ISO-8601 Date - time of observation")); v = ncfile.addVariable(parentStationIndex, DataType.INT, profileDimName); ncfile.addVariableAttribute(v, new Attribute("long_name", "index of parent station")); v = ncfile.addVariable(nextProfileName, DataType.INT, profileDimName); ncfile.addVariableAttribute( v, new Attribute("long_name", "index of next profile in linked list for this station")); }
/** * 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)); }
/** check for Sigma Pressure Levels */ boolean checkForPressureLevels(List<GridRecord> records, GridHorizCoordSys hcs) { GridDefRecord gdr = hcs.getGds(); Grib1GDSVariables g1dr = (Grib1GDSVariables) gdr.getGdsv(); if (g1dr == null || !g1dr.hasVerticalPressureLevels()) return false; // add hybrid numbers coordValues = new double[levels.size()]; for (int i = 0; i < levels.size(); i++) { LevelCoord lc = levels.get(i); coordValues[i] = lc.value1; } int NV = g1dr.getNV(); // add new variables if (NV > 2 && NV < 255) { // Some data doesn't add Pressure Level values factors = g1dr.getVerticalPressureLevels(); } return true; }
public Array getData(Range range, String parameterName) throws IOException, InvalidRangeException { Variable variable = ncfile.getRootGroup().findVariable(parameterName); int varRank = variable.getRank(); int[] varShape = variable.getShape(); List section = new ArrayList(varRank); section.add(range); for (int i = 1; i < varRank; i++) { section.add(new Range(0, varShape[i] - 1)); } Array array = variable.read(section); if (array.getShape()[0] == 1) { return (array.reduce(0)); } else { return (array); } // return( array.getShape()[0] == 1 ? array.reduce( 0 ) : array); }
private void writeHeader(ProfileFeature profile, PointFeature obs) throws IOException { Formatter coordNames = new Formatter().format("%s %s %s", profileTimeName, latName, lonName); List<VariableSimpleIF> coords = new ArrayList<>(); if (useAlt) { coords.add( VariableSimpleImpl.makeScalar( altitudeCoordinateName, "obs altitude", altUnits, DataType.DOUBLE) .add(new Attribute(CF.STANDARD_NAME, "altitude")) .add( new Attribute( CF.POSITIVE, CF1Convention.getZisPositive(altitudeCoordinateName, altUnits)))); coordNames.format(" %s", altitudeCoordinateName); } super.writeHeader( coords, profile.getFeatureData(), obs.getFeatureData(), coordNames.toString()); }
/** * Match levels * * @param records records to match * @return true if they have the same levels */ boolean matchLevels(List<GridRecord> records) { // first create a new list List<LevelCoord> levelList = new ArrayList<LevelCoord>(records.size()); for (GridRecord record : records) { LevelCoord lc = new LevelCoord(record.getLevel1(), record.getLevel2()); if (!levelList.contains(lc)) { levelList.add(lc); } } Collections.sort(levelList); if (positive.equals("down")) { Collections.reverse(levelList); } // gotta equal existing list return levelList.equals(levels); }
private void writeStationData(List<ucar.unidata.geoloc.Station> stnList) throws IOException { this.stnList = stnList; int nstns = stnList.size(); stationMap = new HashMap<String, StationTracker>(2 * nstns); if (debug) System.out.println("stationMap created"); // now write the station data ArrayDouble.D1 latArray = new ArrayDouble.D1(nstns); ArrayDouble.D1 lonArray = new ArrayDouble.D1(nstns); ArrayDouble.D1 altArray = new ArrayDouble.D1(nstns); ArrayObject.D1 idArray = new ArrayObject.D1(String.class, nstns); ArrayObject.D1 descArray = new ArrayObject.D1(String.class, nstns); ArrayObject.D1 wmoArray = new ArrayObject.D1(String.class, nstns); for (int i = 0; i < stnList.size(); i++) { ucar.unidata.geoloc.Station stn = stnList.get(i); stationMap.put(stn.getName(), new StationTracker(i)); latArray.set(i, stn.getLatitude()); lonArray.set(i, stn.getLongitude()); if (useAlt) altArray.set(i, stn.getAltitude()); idArray.set(i, stn.getName()); descArray.set(i, stn.getDescription()); if (useWmoId) wmoArray.set(i, stn.getWmoId()); } try { ncfile.write(latName, latArray); ncfile.write(lonName, lonArray); if (useAlt) ncfile.write(altName, altArray); ncfile.writeStringData(idName, idArray); ncfile.writeStringData(descName, descArray); if (useWmoId) ncfile.writeStringData(wmoName, wmoArray); } catch (InvalidRangeException e) { e.printStackTrace(); throw new IllegalStateException(e); } }
/** * Get the coordinate index for the record * * @param record record in question * @return index or -1 if not found */ private int coordIndex(GridRecord record) { double val = record.getLevel1(); double val2 = record.getLevel2(); if (usesBounds && (val > val2)) { val = record.getLevel2(); val2 = record.getLevel1(); } for (int i = 0; i < levels.size(); i++) { LevelCoord lc = (LevelCoord) levels.get(i); if (usesBounds) { if (ucar.nc2.util.Misc.closeEnough(lc.value1, val) && ucar.nc2.util.Misc.closeEnough(lc.value2, val2)) { return i; } } else { if (ucar.nc2.util.Misc.closeEnough(lc.value1, val)) { return i; } } } return -1; }
/** * Add levels * * @param records GridRecords, one for each level */ void addLevels(List<GridRecord> records) { for (int i = 0; i < records.size(); i++) { GridRecord record = records.get(i); if (coordIndex(record) < 0) { levels.add(new LevelCoord(record.getLevel1(), record.getLevel2())); if (dontUseVertical && (levels.size() > 1)) { if (GridServiceProvider.debugVert) { logger.warn( "GribCoordSys: unused level coordinate has > 1 levels = " + levelName + " " + record.getLevelType1() + " " + levels.size()); } } } } Collections.sort(levels); if (positive.equals("down")) { Collections.reverse(levels); } }
/** * Create a new GeoGrid that is a logical subset of this GeoGrid. * * @param t_range subset the time dimension, or null if you want all of it * @param z_range subset the vertical dimension, or null if you want all of it * @param bbox a lat/lon bounding box, or null if you want all x,y * @param z_stride use only if z_range is null, then take all z with this stride (1 means all) * @param y_stride use this stride on the y coordinate (1 means all) * @param x_stride use this stride on the x coordinate (1 means all) * @return subsetted GeoGrid * @throws InvalidRangeException if bbox does not intersect GeoGrid */ public GeoGrid subset( Range t_range, Range z_range, LatLonRect bbox, int z_stride, int y_stride, int x_stride) throws InvalidRangeException { if ((z_range == null) && (z_stride > 1)) { Dimension zdim = getZDimension(); if (zdim != null) z_range = new Range(0, zdim.getLength() - 1, z_stride); } Range y_range = null, x_range = null; if (bbox != null) { List yx_ranges = gcs.getRangesFromLatLonRect(bbox); y_range = (Range) yx_ranges.get(0); x_range = (Range) yx_ranges.get(1); } if (y_stride > 1) { if (y_range == null) { Dimension ydim = getYDimension(); y_range = new Range(0, ydim.getLength() - 1, y_stride); } else { y_range = new Range(y_range.first(), y_range.last(), y_stride); } } if (x_stride > 1) { if (x_range == null) { Dimension xdim = getXDimension(); x_range = new Range(0, xdim.getLength() - 1, x_stride); } else { x_range = new Range(x_range.first(), x_range.last(), x_stride); } } return subset(t_range, z_range, y_range, x_range); }
/** * Constructor. * * @param dataset belongs to this dataset * @param dsvar wraps this Variable * @param gcs has this grid coordinate system */ public GeoGrid(GridDataset dataset, VariableDS dsvar, GridCoordSys gcs) { this.dataset = dataset; this.vs = dsvar; this.gcs = gcs; CoordinateAxis xaxis = gcs.getXHorizAxis(); if (xaxis instanceof CoordinateAxis1D) { xDimOrgIndex = findDimension(gcs.getXHorizAxis().getDimension(0)); yDimOrgIndex = findDimension(gcs.getYHorizAxis().getDimension(0)); } else { // 2D case yDimOrgIndex = findDimension(gcs.getXHorizAxis().getDimension(0)); xDimOrgIndex = findDimension(gcs.getXHorizAxis().getDimension(1)); } if (gcs.getVerticalAxis() != null) zDimOrgIndex = findDimension(gcs.getVerticalAxis().getDimension(0)); if (gcs.getTimeAxis() != null) { if (gcs.getTimeAxis1D() != null) tDimOrgIndex = findDimension(gcs.getTimeAxis1D().getDimension(0)); else tDimOrgIndex = findDimension(gcs.getTimeAxis().getDimension(1)); } if (gcs.getEnsembleAxis() != null) eDimOrgIndex = findDimension(gcs.getEnsembleAxis().getDimension(0)); if (gcs.getRunTimeAxis() != null) rtDimOrgIndex = findDimension(gcs.getRunTimeAxis().getDimension(0)); // construct canonical dimension list int count = 0; this.mydims = new ArrayList<Dimension>(); if ((rtDimOrgIndex >= 0) && (rtDimOrgIndex != tDimOrgIndex)) { mydims.add(dsvar.getDimension(rtDimOrgIndex)); rtDimNewIndex = count++; } if (eDimOrgIndex >= 0) { mydims.add(dsvar.getDimension(eDimOrgIndex)); eDimNewIndex = count++; } if (tDimOrgIndex >= 0) { mydims.add(dsvar.getDimension(tDimOrgIndex)); tDimNewIndex = count++; } if (zDimOrgIndex >= 0) { mydims.add(dsvar.getDimension(zDimOrgIndex)); zDimNewIndex = count++; } if (yDimOrgIndex >= 0) { mydims.add(dsvar.getDimension(yDimOrgIndex)); yDimNewIndex = count++; } if (xDimOrgIndex >= 0) { mydims.add(dsvar.getDimension(xDimOrgIndex)); xDimNewIndex = count; } }
protected void makeFeatureVariables(StructureData featureData, boolean isExtended) throws IOException { // LOOK why not unlimited here ? Dimension profileDim = writer.addDimension(null, profileDimName, nfeatures); // Dimension profileDim = isExtendedModel ? writer.addUnlimitedDimension(profileDimName) : // writer.addDimension(null, profileDimName, nprofiles); // add the profile Variables using the profile dimension List<VariableSimpleIF> profileVars = new ArrayList<>(); profileVars.add( VariableSimpleImpl.makeScalar(latName, "profile latitude", CDM.LAT_UNITS, DataType.DOUBLE)); profileVars.add( VariableSimpleImpl.makeScalar( lonName, "profile longitude", CDM.LON_UNITS, DataType.DOUBLE)); profileVars.add( VariableSimpleImpl.makeString(profileIdName, "profile identifier", null, id_strlen) .add(new Attribute(CF.CF_ROLE, CF.PROFILE_ID))); // profileId:cf_role = "profile_id"; profileVars.add( VariableSimpleImpl.makeScalar( numberOfObsName, "number of obs for this profile", null, DataType.INT) .add( new Attribute( CF.SAMPLE_DIMENSION, recordDimName))); // rowSize:sample_dimension = "obs" profileVars.add( VariableSimpleImpl.makeScalar( profileTimeName, "nominal time of profile", timeUnit.getUnitsString(), DataType.DOUBLE)); for (StructureMembers.Member m : featureData.getMembers()) { VariableSimpleIF dv = getDataVar(m.getName()); if (dv != null) profileVars.add(dv); } if (isExtended) { profileStruct = (Structure) writer.addVariable(null, profileStructName, DataType.STRUCTURE, profileDimName); addCoordinatesExtended(profileStruct, profileVars); } else { addCoordinatesClassic(profileDim, profileVars, featureVarMap); } }
/** get the rank */ public int getRank() { return mydims.size(); }
private void createStations(List<ucar.unidata.geoloc.Station> stnList) throws IOException { int nstns = stnList.size(); // see if there's altitude, wmoId for any stations for (int i = 0; i < nstns; i++) { ucar.unidata.geoloc.Station stn = stnList.get(i); // if (!Double.isNaN(stn.getAltitude())) // useAlt = true; if ((stn.getWmoId() != null) && (stn.getWmoId().trim().length() > 0)) useWmoId = true; } /* if (useAlt) ncfile.addGlobalAttribute("altitude_coordinate", altName); */ // find string lengths for (int i = 0; i < nstns; i++) { ucar.unidata.geoloc.Station station = stnList.get(i); name_strlen = Math.max(name_strlen, station.getName().length()); desc_strlen = Math.max(desc_strlen, station.getDescription().length()); if (useWmoId) wmo_strlen = Math.max(wmo_strlen, station.getName().length()); } LatLonRect llbb = getBoundingBox(stnList); ncfile.addGlobalAttribute( "geospatial_lat_min", Double.toString(llbb.getLowerLeftPoint().getLatitude())); ncfile.addGlobalAttribute( "geospatial_lat_max", Double.toString(llbb.getUpperRightPoint().getLatitude())); ncfile.addGlobalAttribute( "geospatial_lon_min", Double.toString(llbb.getLowerLeftPoint().getLongitude())); ncfile.addGlobalAttribute( "geospatial_lon_max", Double.toString(llbb.getUpperRightPoint().getLongitude())); // add the dimensions Dimension recordDim = ncfile.addUnlimitedDimension(recordDimName); recordDims.add(recordDim); Dimension stationDim = ncfile.addDimension(stationDimName, nstns); stationDims.add(stationDim); // add the station Variables using the station dimension Variable v = ncfile.addVariable(latName, DataType.DOUBLE, stationDimName); ncfile.addVariableAttribute(v, new Attribute("units", "degrees_north")); ncfile.addVariableAttribute(v, new Attribute("long_name", "station latitude")); v = ncfile.addVariable(lonName, DataType.DOUBLE, stationDimName); ncfile.addVariableAttribute(v, new Attribute("units", "degrees_east")); ncfile.addVariableAttribute(v, new Attribute("long_name", "station longitude")); if (useAlt) { v = ncfile.addVariable(altName, DataType.DOUBLE, stationDimName); ncfile.addVariableAttribute(v, new Attribute("units", "meters")); ncfile.addVariableAttribute(v, new Attribute("long_name", "station altitude")); } v = ncfile.addStringVariable(idName, stationDims, name_strlen); ncfile.addVariableAttribute(v, new Attribute("long_name", "station identifier")); v = ncfile.addStringVariable(descName, stationDims, desc_strlen); ncfile.addVariableAttribute(v, new Attribute("long_name", "station description")); if (useWmoId) { v = ncfile.addStringVariable(wmoName, stationDims, wmo_strlen); ncfile.addVariableAttribute(v, new Attribute("long_name", "station WMO id")); } v = ncfile.addVariable(numProfilesName, DataType.INT, stationDimName); ncfile.addVariableAttribute( v, new Attribute("long_name", "number of profiles in linked list for this station")); v = ncfile.addVariable(firstProfileName, DataType.INT, stationDimName); ncfile.addVariableAttribute( v, new Attribute("long_name", "index of first profile in linked list for this station")); }
/** * 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); */ } }
/** * Get the number of levels * * @return number of levels */ int getNLevels() { return dontUseVertical ? 1 : levels.size(); }
// @todo Make sure units are degrees_east public Array getLongitude(Range range) throws IOException, InvalidRangeException { List section = new ArrayList(1); section.add(range); return (lonVar.read(section)); }
public List getTrajectories() // throws IOException; { List l = new ArrayList(); l.add(trajectory); return (l); }
public List getTrajectoryIds() { List l = new ArrayList(); l.add(trajectoryId); return (l); }
/** * get the ith dimension * * @param i : which dimension * @return ith Dimension */ public Dimension getDimension(int i) { if ((i < 0) || (i >= mydims.size())) return null; return mydims.get(i); }
private void writeDataFinish() throws IOException { // finish global variables ArrayInt.D0 totalArray = new ArrayInt.D0(); totalArray.set(profileIndex); try { ncfile.write(numProfilesTotalName, totalArray); } catch (InvalidRangeException e) { e.printStackTrace(); throw new IllegalStateException(e); } // finish the station data int nstns = stnList.size(); ArrayInt.D1 firstProfileArray = new ArrayInt.D1(nstns); ArrayInt.D1 numProfileArray = new ArrayInt.D1(nstns); ArrayInt.D1 nextProfileArray = new ArrayInt.D1(nprofiles); for (int i = 0; i < stnList.size(); i++) { ucar.unidata.geoloc.Station stn = stnList.get(i); StationTracker tracker = stationMap.get(stn.getName()); numProfileArray.set(i, tracker.numChildren); int first = (tracker.link.size() > 0) ? tracker.link.get(0) : -1; firstProfileArray.set(i, first); if (tracker.link.size() > 0) { // construct forward link List<Integer> nextList = tracker.link; for (int j = 0; j < nextList.size() - 1; j++) { Integer curr = nextList.get(j); Integer next = nextList.get(j + 1); nextProfileArray.set(curr, next); } Integer curr = nextList.get(nextList.size() - 1); nextProfileArray.set(curr, -1); } } try { ncfile.write(firstProfileName, firstProfileArray); ncfile.write(numProfilesName, numProfileArray); ncfile.write(nextProfileName, nextProfileArray); } catch (InvalidRangeException e) { e.printStackTrace(); throw new IllegalStateException(e); } // finish the profile data ArrayInt.D1 nextObsArray = new ArrayInt.D1(recno); ArrayInt.D1 firstObsArray = new ArrayInt.D1(nprofiles); ArrayInt.D1 numObsArray = new ArrayInt.D1(nprofiles); for (int i = 0; i < stnList.size(); i++) { ucar.unidata.geoloc.Station stn = stnList.get(i); StationTracker stnTracker = stationMap.get(stn.getName()); Set<Date> dates = stnTracker.profileMap.keySet(); for (Date date : dates) { ProfileTracker proTracker = stnTracker.profileMap.get(date); int trackerIndex = proTracker.parent_index; numObsArray.set(trackerIndex, proTracker.numChildren); int first = (proTracker.link.size() > 0) ? proTracker.link.get(0) : -1; firstObsArray.set(trackerIndex, first); if (proTracker.link.size() > 0) { // construct forward link List<Integer> nextList = proTracker.link; for (int j = 0; j < nextList.size() - 1; j++) { Integer curr = nextList.get(j); Integer next = nextList.get(j + 1); nextObsArray.set(curr, next); } Integer curr = nextList.get(nextList.size() - 1); nextObsArray.set(curr, -1); } } } try { ncfile.write(firstObsName, firstObsArray); ncfile.write(numObsName, numObsArray); ncfile.write(nextObsName, nextObsArray); } catch (InvalidRangeException e) { e.printStackTrace(); throw new IllegalStateException(e); } // finish the obs data ncfile.updateAttribute( null, new Attribute("time_coverage_start", dateFormatter.toDateTimeStringISO(minDate))); ncfile.updateAttribute( null, new Attribute("time_coverage_end", dateFormatter.toDateTimeStringISO(maxDate))); }
/** * This reads an arbitrary data slice, returning the data in canonical order (rt-e-t-z-y-x). If * any dimension does not exist, ignore it. * * @param rt if < 0, get all of runtime dim; if valid index, fix slice to that value. * @param e if < 0, get all of ensemble dim; if valid index, fix slice to that value. * @param t if < 0, get all of time dim; if valid index, fix slice to that value. * @param z if < 0, get all of z dim; if valid index, fix slice to that value. * @param y if < 0, get all of y dim; if valid index, fix slice to that value. * @param x if < 0, get all of x dim; if valid index, fix slice to that value. * @return data[rt,e,t,z,y,x], eliminating missing or fixed dimension. */ public Array readDataSlice(int rt, int e, int t, int z, int y, int x) throws java.io.IOException { int rank = vs.getRank(); int[] start = new int[rank]; int[] shape = new int[rank]; for (int i = 0; i < rank; i++) { start[i] = 0; shape[i] = 1; } Dimension xdim = getXDimension(); Dimension ydim = getYDimension(); Dimension zdim = getZDimension(); Dimension tdim = getTimeDimension(); Dimension edim = getEnsembleDimension(); Dimension rtdim = getRunTimeDimension(); // construct the shape of the data volume to be read if (rtdim != null) { if ((rt >= 0) && (rt < rtdim.getLength())) start[rtDimOrgIndex] = rt; // fix rt else { shape[rtDimOrgIndex] = rtdim.getLength(); // all of rt } } if (edim != null) { if ((e >= 0) && (e < edim.getLength())) start[eDimOrgIndex] = e; // fix e else { shape[eDimOrgIndex] = edim.getLength(); // all of e } } if (tdim != null) { if ((t >= 0) && (t < tdim.getLength())) start[tDimOrgIndex] = t; // fix t else { shape[tDimOrgIndex] = tdim.getLength(); // all of t } } if (zdim != null) { if ((z >= 0) && (z < zdim.getLength())) start[zDimOrgIndex] = z; // fix z else { shape[zDimOrgIndex] = zdim.getLength(); // all of z } } if (ydim != null) { if ((y >= 0) && (y < ydim.getLength())) start[yDimOrgIndex] = y; // fix y else { shape[yDimOrgIndex] = ydim.getLength(); // all of y } } if (xdim != null) { if ((x >= 0) && (x < xdim.getLength())) // all of x start[xDimOrgIndex] = x; // fix x else { shape[xDimOrgIndex] = xdim.getLength(); // all of x } } if (debugArrayShape) { System.out.println("read shape from org variable = "); for (int i = 0; i < rank; i++) System.out.println( " start = " + start[i] + " shape = " + shape[i] + " name = " + vs.getDimension(i).getName()); } // read it Array dataVolume; try { dataVolume = vs.read(start, shape); } catch (Exception ex) { log.error( "GeoGrid.getdataSlice() on dataset " + getFullName() + " " + dataset.getLocation(), ex); throw new java.io.IOException(ex.getMessage()); } // LOOK: the real problem is the lack of named dimensions in the Array object // figure out correct permutation for canonical ordering for permute List<Dimension> oldDims = new ArrayList<Dimension>(vs.getDimensions()); int[] permuteIndex = new int[dataVolume.getRank()]; int count = 0; if (oldDims.contains(rtdim)) permuteIndex[count++] = oldDims.indexOf(rtdim); if (oldDims.contains(edim)) permuteIndex[count++] = oldDims.indexOf(edim); if (oldDims.contains(tdim)) permuteIndex[count++] = oldDims.indexOf(tdim); if (oldDims.contains(zdim)) permuteIndex[count++] = oldDims.indexOf(zdim); if (oldDims.contains(ydim)) permuteIndex[count++] = oldDims.indexOf(ydim); if (oldDims.contains(xdim)) permuteIndex[count] = oldDims.indexOf(xdim); if (debugArrayShape) { System.out.println("oldDims = "); for (Dimension oldDim : oldDims) System.out.println(" oldDim = " + oldDim.getName()); System.out.println("permute dims = "); for (int aPermuteIndex : permuteIndex) System.out.println(" oldDim index = " + aPermuteIndex); } // check to see if we need to permute boolean needPermute = false; for (int i = 0; i < permuteIndex.length; i++) { if (i != permuteIndex[i]) needPermute = true; } // permute to the order rt,e,t,z,y,x if (needPermute) dataVolume = dataVolume.permute(permuteIndex); // eliminate fixed dimensions, but not all dimensions of length 1. count = 0; if (rtdim != null) { if (rt >= 0) dataVolume = dataVolume.reduce(count); else count++; } if (edim != null) { if (e >= 0) dataVolume = dataVolume.reduce(count); else count++; } if (tdim != null) { if (t >= 0) dataVolume = dataVolume.reduce(count); else count++; } if (zdim != null) { if (z >= 0) dataVolume = dataVolume.reduce(count); else count++; } if (ydim != null) { if (y >= 0) dataVolume = dataVolume.reduce(count); else count++; } if (xdim != null) { if (x >= 0) dataVolume = dataVolume.reduce(count); } return dataVolume; }
public static void main(String args[]) throws Exception { long start = System.currentTimeMillis(); Map<String, ucar.unidata.geoloc.Station> staHash = new HashMap<String, ucar.unidata.geoloc.Station>(); String location = "R:/testdata/sounding/netcdf/Upperair_20070401_0000.nc"; NetcdfDataset ncfile = NetcdfDataset.openDataset(location); ncfile.sendIospMessage(NetcdfFile.IOSP_MESSAGE_ADD_RECORD_STRUCTURE); // look through record varibles, for those that have "manLevel" dimension // make a StructureData object for those StructureMembers sm = new StructureMembers("manLevel"); Dimension manDim = ncfile.findDimension("manLevel"); Structure record = (Structure) ncfile.findVariable("record"); List<Variable> allList = record.getVariables(); List<VariableSimpleIF> varList = new ArrayList<VariableSimpleIF>(); for (Variable v : allList) { if ((v.getRank() == 1) && v.getDimension(0).equals(manDim)) { // public VariableDS(NetcdfDataset ds, Group group, Structure parentStructure, String // shortName, DataType dataType, // String dims, String units, String desc) { varList.add( new VariableDS( ncfile, null, null, v.getShortName(), v.getDataType(), "", v.getUnitsString(), v.getDescription())); // (String name, String desc, String units, DataType dtype, int []shape) sm.addMember( v.getShortName(), v.getDescription(), v.getUnitsString(), v.getDataType(), new int[0]); // scalar } } ArrayStructureMA manAS = new ArrayStructureMA(sm, new int[] {manDim.getLength()}); // need the date units Variable time = ncfile.findVariable("synTime"); String timeUnits = ncfile.findAttValueIgnoreCase(time, "units", null); timeUnits = StringUtil.remove(timeUnits, '('); // crappy fsl'ism timeUnits = StringUtil.remove(timeUnits, ')'); DateUnit timeUnit = new DateUnit(timeUnits); // extract stations int nrecs = 0; StructureDataIterator iter = record.getStructureIterator(); while (iter.hasNext()) { StructureData sdata = iter.next(); String name = sdata.getScalarString("staName"); ucar.unidata.geoloc.Station s = staHash.get(name); if (s == null) { float lat = sdata.convertScalarFloat("staLat"); float lon = sdata.convertScalarFloat("staLon"); float elev = sdata.convertScalarFloat("staElev"); s = new StationImpl(name, "", lat, lon, elev); staHash.put(name, s); } nrecs++; } List<ucar.unidata.geoloc.Station> stnList = Arrays.asList(staHash.values().toArray(new ucar.unidata.geoloc.Station[staHash.size()])); Collections.sort(stnList); // create the writer WriterProfileObsDataset writer = new WriterProfileObsDataset(location + ".out", "rewrite " + location); writer.writeHeader(stnList, varList, nrecs, "prMan"); // extract records iter = record.getStructureIterator(); while (iter.hasNext()) { StructureData sdata = iter.next(); String name = sdata.getScalarString("staName"); double timeValue = sdata.convertScalarDouble("synTime"); Date date = timeUnit.makeDate(timeValue); // transfer to the ArrayStructure List<String> names = sm.getMemberNames(); for (String mname : names) { manAS.setMemberArray(mname, sdata.getArray(mname)); } // each level is weritten as a seperate structure int numMand = sdata.getScalarInt("numMand"); if (numMand >= manDim.getLength()) continue; for (int i = 0; i < numMand; i++) { StructureData useData = manAS.getStructureData(i); writer.writeRecord(name, date, useData); } } writer.finish(); long took = System.currentTimeMillis() - start; System.out.println("That took = " + took); }
private void makeCoordinateDataWithMissing( int datatype, Variable time, Variable elev, Variable azi, Variable nradialsVar, Variable ngatesVar, List groups) { Array timeData = Array.factory(time.getDataType().getPrimitiveClassType(), time.getShape()); Index timeIndex = timeData.getIndex(); Array elevData = Array.factory(elev.getDataType().getPrimitiveClassType(), elev.getShape()); Index elevIndex = elevData.getIndex(); Array aziData = Array.factory(azi.getDataType().getPrimitiveClassType(), azi.getShape()); Index aziIndex = aziData.getIndex(); Array nradialsData = Array.factory(nradialsVar.getDataType().getPrimitiveClassType(), nradialsVar.getShape()); IndexIterator nradialsIter = nradialsData.getIndexIterator(); Array ngatesData = Array.factory(ngatesVar.getDataType().getPrimitiveClassType(), ngatesVar.getShape()); IndexIterator ngatesIter = ngatesData.getIndexIterator(); // first fill with missing data IndexIterator ii = timeData.getIndexIterator(); while (ii.hasNext()) ii.setIntNext(MISSING_INT); ii = elevData.getIndexIterator(); while (ii.hasNext()) ii.setFloatNext(MISSING_FLOAT); ii = aziData.getIndexIterator(); while (ii.hasNext()) ii.setFloatNext(MISSING_FLOAT); // now set the coordinate variables from the Cinrad2Record radial int last_msecs = Integer.MIN_VALUE; int nscans = groups.size(); try { for (int scan = 0; scan < nscans; scan++) { List scanGroup = (List) groups.get(scan); int nradials = scanGroup.size(); Cinrad2Record first = null; for (int j = 0; j < nradials; j++) { Cinrad2Record r = (Cinrad2Record) scanGroup.get(j); if (first == null) first = r; int radial = r.radial_num - 1; timeData.setInt(timeIndex.set(scan, radial), r.data_msecs); elevData.setFloat(elevIndex.set(scan, radial), r.getElevation()); aziData.setFloat(aziIndex.set(scan, radial), r.getAzimuth()); if (r.data_msecs < last_msecs) logger.warn("makeCoordinateData time out of order " + r.data_msecs); last_msecs = r.data_msecs; } nradialsIter.setIntNext(nradials); ngatesIter.setIntNext(first.getGateCount(datatype)); } } catch (java.lang.ArrayIndexOutOfBoundsException ae) { logger.debug("Cinrad2IOSP.uncompress ", ae); } time.setCachedData(timeData, false); elev.setCachedData(elevData, false); azi.setCachedData(aziData, false); nradialsVar.setCachedData(nradialsData, false); ngatesVar.setCachedData(ngatesData, false); }