// 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()); }
// look if the wanted dimension is in the unknownDims list. private Dimension checkUnknownDims( String wantDim, List<Dimension> unknownDims, Dimension oldDim, String location) { for (Dimension dim : unknownDims) { if (dim.getShortName().equals(wantDim)) { int len = oldDim.getLength(); if (len == 0) dim.setUnlimited(true); // allow zero length dimension !! dim.setLength(len); // use existing (anon) dimension Group parent = dim.getGroup(); parent.addDimensionIfNotExists(dim); // add to the parent unknownDims.remove(dim); // remove from list LOOK is this ok? log.warn("unknownDim {} length set to {}{}", wantDim, oldDim.getLength(), location); return dim; } } return null; }
private FeatureType amendSwath(NetcdfFile ncfile, Element swathElem, Group parent) { FeatureType featureType = FeatureType.SWATH; List<Dimension> unknownDims = new ArrayList<>(); // Dimensions Element d = swathElem.getChild("Dimension"); List<Element> dims = d.getChildren(); for (Element elem : dims) { String name = elem.getChild("DimensionName").getText().trim(); name = NetcdfFile.makeValidCdmObjectName(name); if (name.equalsIgnoreCase("scalar")) continue; String sizeS = elem.getChild("Size").getText().trim(); int length = Integer.parseInt(sizeS); if (length > 0) { Dimension dim = parent.findDimensionLocal(name); if (dim != null) { // already added - may be dimension scale ? if (dim.getLength() != length) { // ok as long as it matches log.error("Conflicting Dimensions = {} {}", dim, ncfile.getLocation()); throw new IllegalStateException("Conflicting Dimensions = " + name); } } else { dim = new Dimension(name, length); if (parent.addDimensionIfNotExists(dim) && showWork) System.out.printf(" Add dimension %s %n", dim); } } else { log.warn("Dimension " + name + " has size " + sizeS, ncfile.getLocation()); Dimension udim = new Dimension(name, 1); udim.setGroup(parent); unknownDims.add(udim); if (showWork) System.out.printf(" Add dimension %s %n", udim); } } // Dimension Maps Element dmap = swathElem.getChild("DimensionMap"); List<Element> dimMaps = dmap.getChildren(); for (Element elem : dimMaps) { String geoDimName = elem.getChild("GeoDimension").getText().trim(); geoDimName = NetcdfFile.makeValidCdmObjectName(geoDimName); String dataDimName = elem.getChild("DataDimension").getText().trim(); dataDimName = NetcdfFile.makeValidCdmObjectName(dataDimName); String offsetS = elem.getChild("Offset").getText().trim(); String incrS = elem.getChild("Increment").getText().trim(); int offset = Integer.parseInt(offsetS); int incr = Integer.parseInt(incrS); // make new variable for this dimension map Variable v = new Variable(ncfile, parent, null, dataDimName); v.setDimensions(geoDimName); v.setDataType(DataType.INT); int npts = (int) v.getSize(); Array data = Array.makeArray(v.getDataType(), npts, offset, incr); v.setCachedData(data, true); v.addAttribute(new Attribute("_DimensionMap", "")); parent.addVariable(v); if (showWork) System.out.printf(" Add dimensionMap %s %n", v); } // Geolocation Variables Group geoFieldsG = parent.findGroup(GEOLOC_FIELDS); if (geoFieldsG == null) geoFieldsG = parent.findGroup(GEOLOC_FIELDS2); if (geoFieldsG != null) { Variable latAxis = null, lonAxis = null; Element floc = swathElem.getChild("GeoField"); List<Element> varsLoc = floc.getChildren(); for (Element elem : varsLoc) { String varname = elem.getChild("GeoFieldName").getText().trim(); Variable v = geoFieldsG.findVariable(varname); // if (v == null) // v = geoFieldsG.findVariable( H4header.createValidObjectName(varname)); assert v != null : varname; AxisType axis = addAxisType(ncfile, v); if (axis == AxisType.Lat) latAxis = v; if (axis == AxisType.Lon) lonAxis = v; Element dimList = elem.getChild("DimList"); List<Element> values = dimList.getChildren("value"); setSharedDimensions(v, values, unknownDims, ncfile.getLocation()); if (showWork) System.out.printf(" set coordinate %s %n", v); } if ((latAxis != null) && (lonAxis != null)) { List<Dimension> xyDomain = CoordinateSystem.makeDomain(new Variable[] {latAxis, lonAxis}); if (xyDomain.size() < 2) featureType = FeatureType.PROFILE; // ?? } } // Data Variables Group dataG = parent.findGroup(DATA_FIELDS); if (dataG == null) dataG = parent.findGroup(DATA_FIELDS2); if (dataG != null) { Element f = swathElem.getChild("DataField"); List<Element> vars = f.getChildren(); for (Element elem : vars) { Element dataFieldNameElem = elem.getChild("DataFieldName"); if (dataFieldNameElem == null) continue; String varname = NetcdfFile.makeValidCdmObjectName(dataFieldNameElem.getText().trim()); Variable v = dataG.findVariable(varname); // if (v == null) // v = dataG.findVariable( H4header.createValidObjectName(varname)); if (v == null) { log.error("Cant find variable {} {}", varname, ncfile.getLocation()); continue; } Element dimList = elem.getChild("DimList"); List<Element> values = dimList.getChildren("value"); setSharedDimensions(v, values, unknownDims, ncfile.getLocation()); } } return featureType; }
private FeatureType amendGrid( Element gridElem, NetcdfFile ncfile, Group parent, String location) { List<Dimension> unknownDims = new ArrayList<>(); // always has x and y dimension String xdimSizeS = gridElem.getChild("XDim").getText().trim(); String ydimSizeS = gridElem.getChild("YDim").getText().trim(); int xdimSize = Integer.parseInt(xdimSizeS); int ydimSize = Integer.parseInt(ydimSizeS); parent.addDimensionIfNotExists(new Dimension("XDim", xdimSize)); parent.addDimensionIfNotExists(new Dimension("YDim", ydimSize)); /* see HdfEosModisConvention UpperLeftPointMtrs=(-20015109.354000,1111950.519667) LowerRightMtrs=(-18903158.834333,-0.000000) Projection=GCTP_SNSOID ProjParams=(6371007.181000,0,0,0,0,0,0,0,0,0,0,0,0) SphereCode=-1 */ Element proj = gridElem.getChild("Projection"); if (proj != null) { Variable crs = new Variable(ncfile, parent, null, HDFEOS_CRS); crs.setDataType(DataType.SHORT); crs.setDimensions(""); // scalar crs.setCachedData(Array.makeArray(DataType.SHORT, 1, 0, 0)); // fake data parent.addVariable(crs); addAttributeIfExists(gridElem, HDFEOS_CRS_Projection, crs, false); addAttributeIfExists(gridElem, HDFEOS_CRS_UpperLeft, crs, true); addAttributeIfExists(gridElem, HDFEOS_CRS_LowerRight, crs, true); addAttributeIfExists(gridElem, HDFEOS_CRS_ProjParams, crs, true); addAttributeIfExists(gridElem, HDFEOS_CRS_SphereCode, crs, false); } // global Dimensions Element d = gridElem.getChild("Dimension"); List<Element> dims = d.getChildren(); for (Element elem : dims) { String name = elem.getChild("DimensionName").getText().trim(); name = NetcdfFile.makeValidCdmObjectName(name); if (name.equalsIgnoreCase("scalar")) continue; String sizeS = elem.getChild("Size").getText().trim(); int length = Integer.parseInt(sizeS); Dimension old = parent.findDimension(name); if ((old == null) || (old.getLength() != length)) { if (length > 0) { Dimension dim = new Dimension(name, length); if (parent.addDimensionIfNotExists(dim) && showWork) System.out.printf(" Add dimension %s %n", dim); } else { log.warn("Dimension {} has size {} {} ", sizeS, name, location); Dimension udim = new Dimension(name, 1); udim.setGroup(parent); unknownDims.add(udim); if (showWork) System.out.printf(" Add dimension %s %n", udim); } } } // Geolocation Variables Group geoFieldsG = parent.findGroup(GEOLOC_FIELDS); if (geoFieldsG == null) geoFieldsG = parent.findGroup(GEOLOC_FIELDS2); if (geoFieldsG != null) { Element floc = gridElem.getChild("GeoField"); List<Element> varsLoc = floc.getChildren(); for (Element elem : varsLoc) { String varname = elem.getChild("GeoFieldName").getText().trim(); Variable v = geoFieldsG.findVariable(varname); // if (v == null) // v = geoFieldsG.findVariable( H4header.createValidObjectName(varname)); assert v != null : varname; Element dimList = elem.getChild("DimList"); List<Element> values = dimList.getChildren("value"); setSharedDimensions(v, values, unknownDims, location); } } // Data Variables Group dataG = parent.findGroup(DATA_FIELDS); if (dataG == null) dataG = parent.findGroup( DATA_FIELDS2); // eg C:\data\formats\hdf4\eos\mopitt\MOP03M-200501-L3V81.0.1.hdf if (dataG != null) { Element f = gridElem.getChild("DataField"); List<Element> vars = f.getChildren(); for (Element elem : vars) { String varname = elem.getChild("DataFieldName").getText().trim(); varname = NetcdfFile.makeValidCdmObjectName(varname); Variable v = dataG.findVariable(varname); // if (v == null) // v = dataG.findVariable( H4header.createValidObjectName(varname)); assert v != null : varname; Element dimList = elem.getChild("DimList"); List<Element> values = dimList.getChildren("value"); setSharedDimensions(v, values, unknownDims, location); } // get projection String projS = null; Element projElem = gridElem.getChild("Projection"); if (projElem != null) projS = projElem.getText().trim(); boolean isLatLon = "GCTP_GEO".equals(projS); // look for XDim, YDim coordinate variables if (isLatLon) { for (Variable v : dataG.getVariables()) { if (v.isCoordinateVariable()) { if (v.getShortName().equals("YDim")) { v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lat.toString())); v.addAttribute(new Attribute(CDM.UNITS, CDM.LAT_UNITS)); } if (v.getShortName().equals("XDim")) v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lon.toString())); } } } } return FeatureType.GRID; }
public Variable makeVariable( NetcdfFile ncfile, int datatype, String shortName, String longName, String abbrev, List groups) throws IOException { int nscans = groups.size(); if (nscans == 0) { throw new IllegalStateException("No data for " + shortName); } // get representative record List firstGroup = (List) groups.get(0); Cinrad2Record firstRecord = (Cinrad2Record) firstGroup.get(0); int ngates = firstRecord.getGateCount(datatype); String scanDimName = "scan" + abbrev; String gateDimName = "gate" + abbrev; Dimension scanDim = new Dimension(scanDimName, nscans); Dimension gateDim = new Dimension(gateDimName, ngates); ncfile.addDimension(null, scanDim); ncfile.addDimension(null, gateDim); ArrayList dims = new ArrayList(); dims.add(scanDim); dims.add(radialDim); dims.add(gateDim); Variable v = new Variable(ncfile, null, null, shortName); v.setDataType(DataType.BYTE); v.setDimensions(dims); 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")); ArrayList dim2 = new ArrayList(); dim2.add(scanDim); dim2.add(radialDim); // add time coordinate variable String timeCoordName = "time" + abbrev; Variable timeVar = new Variable(ncfile, null, null, timeCoordName); timeVar.setDataType(DataType.INT); timeVar.setDimensions(dim2); ncfile.addVariable(null, timeVar); // int julianDays = volScan.getTitleJulianDays(); // Date d = Cinrad2Record.getDate( julianDays, 0); // Date d = Cinrad2Record.getDate(volScan.getTitleJulianDays(), volScan.getTitleMsecs()); Date d = volScan.getStartDate(); String units = "msecs since " + formatter.toDateTimeStringISO(d); timeVar.addAttribute(new Attribute(CDM.LONG_NAME, "time since base date")); timeVar.addAttribute(new Attribute(CDM.UNITS, units)); timeVar.addAttribute(new Attribute(CDM.MISSING_VALUE, new Integer(MISSING_INT))); timeVar.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Time.toString())); // add elevation coordinate variable String elevCoordName = "elevation" + abbrev; Variable elevVar = new Variable(ncfile, null, null, elevCoordName); elevVar.setDataType(DataType.FLOAT); elevVar.setDimensions(dim2); ncfile.addVariable(null, elevVar); elevVar.addAttribute(new Attribute(CDM.UNITS, "degrees")); elevVar.addAttribute( new Attribute( CDM.LONG_NAME, "elevation angle in degres: 0 = parallel to pedestal base, 90 = perpendicular")); elevVar.addAttribute(new Attribute(CDM.MISSING_VALUE, new Float(MISSING_FLOAT))); elevVar.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString())); // add azimuth coordinate variable String aziCoordName = "azimuth" + abbrev; Variable aziVar = new Variable(ncfile, null, null, aziCoordName); aziVar.setDataType(DataType.FLOAT); aziVar.setDimensions(dim2); ncfile.addVariable(null, aziVar); aziVar.addAttribute(new Attribute(CDM.UNITS, "degrees")); aziVar.addAttribute( new Attribute(CDM.LONG_NAME, "azimuth angle in degrees: 0 = true north, 90 = east")); aziVar.addAttribute(new Attribute(CDM.MISSING_VALUE, new Float(MISSING_FLOAT))); aziVar.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialAzimuth.toString())); // add gate coordinate variable String gateCoordName = "distance" + abbrev; Variable gateVar = new Variable(ncfile, null, null, gateCoordName); gateVar.setDataType(DataType.FLOAT); gateVar.setDimensions(gateDimName); Array data = Array.makeArray( DataType.FLOAT, ngates, (double) firstRecord.getGateStart(datatype), (double) firstRecord.getGateSize(datatype)); gateVar.setCachedData(data, false); ncfile.addVariable(null, gateVar); radarRadius = firstRecord.getGateStart(datatype) + ngates * firstRecord.getGateSize(datatype); gateVar.addAttribute(new Attribute(CDM.UNITS, "m")); gateVar.addAttribute(new Attribute(CDM.LONG_NAME, "radial distance to start of gate")); gateVar.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialDistance.toString())); // add number of radials variable String nradialsName = "numRadials" + abbrev; Variable nradialsVar = new Variable(ncfile, null, null, nradialsName); nradialsVar.setDataType(DataType.INT); nradialsVar.setDimensions(scanDim.getName()); nradialsVar.addAttribute(new Attribute(CDM.LONG_NAME, "number of valid radials in this scan")); ncfile.addVariable(null, nradialsVar); // add number of gates variable String ngateName = "numGates" + abbrev; Variable ngateVar = new Variable(ncfile, null, null, ngateName); ngateVar.setDataType(DataType.INT); ngateVar.setDimensions(scanDim.getName()); ngateVar.addAttribute(new Attribute(CDM.LONG_NAME, "number of valid gates in this scan")); ncfile.addVariable(null, ngateVar); makeCoordinateDataWithMissing( datatype, timeVar, elevVar, aziVar, nradialsVar, ngateVar, groups); // back to the data variable String coordinates = timeCoordName + " " + elevCoordName + " " + aziCoordName + " " + gateCoordName; v.addAttribute(new Attribute(_Coordinate.Axes, coordinates)); // make the record map int nradials = radialDim.getLength(); Cinrad2Record[][] map = new Cinrad2Record[nscans][nradials]; for (int i = 0; i < groups.size(); i++) { Cinrad2Record[] mapScan = map[i]; List group = (List) groups.get(i); for (int j = 0; j < group.size(); j++) { Cinrad2Record r = (Cinrad2Record) group.get(j); int radial = r.radial_num - 1; mapScan[radial] = r; } } Vgroup vg = new Vgroup(datatype, map); v.setSPobject(vg); return v; }