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); }
/** * Make the missing variable * * @return the missing variable */ protected Variable makeMissingVariable() { Variable var = new Variable(ncfile, null, null, MISSING_VAR); var.setDataType(DataType.BYTE); var.setDimensions((List<Dimension>) null); var.addAttribute(new Attribute("description", "missing flag - 1 means all params are missing")); var.addAttribute(new Attribute("missing_value", new Byte((byte) 1))); return var; }
/** * Make a variable from a GempakParmaeter * * @param param GempakParameter * @param dims Variable dimensions * @return the Variable */ protected Variable makeParamVariable(GempakParameter param, List<Dimension> dims) { Variable var = new Variable(ncfile, null, null, param.getName()); var.setDataType(DataType.FLOAT); var.setDimensions(dims); var.addAttribute(new Attribute("long_name", param.getDescription())); String units = param.getUnit(); if ((units != null) && !units.equals("")) { var.addAttribute(new Attribute(CDM.UNITS, units)); } var.addAttribute(new Attribute("missing_value", RMISS)); return var; }
/** * Add this as a variable to the netCDF file * * @param ncfile the netCDF file * @param g the group in the file */ void addToNetcdfFile(NetcdfFile ncfile, Group g) { Variable v = new Variable(ncfile, g, null, getName()); v.setDimensions(v.getShortName()); v.setDataType(DataType.STRING); v.addAttribute(new Attribute("long_name", "ensemble")); v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Ensemble.toString())); String[] data = new String[getNEnsembles()]; for (int i = 0; i < getNEnsembles(); i++) { EnsCoord ec = ensCoords.get(i); data[i] = Grib2Tables.codeTable4_6(ec.type) + " " + ec.number; } Array dataArray = Array.factory(DataType.STRING, new int[] {getNEnsembles()}, data); v.setCachedData(dataArray, false); ncfile.addVariable(g, v); }
/** * Define Dimensions, Variables, Attributes in ncfile * * @param raf ucar.unidata.io.RandomAccessFile corresponds of SIGMET datafile. * @param ncfile an empty NetcdfFile object which will be filled. * @param hdrNames java.util.Map with values for "StationName.." Attributes * @return ArrayList of Variables of ncfile */ public ArrayList<Variable> init( ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile, java.util.Map<String, String> hdrNames) throws java.io.IOException { // prepare attribute values String[] data_name = { " ", "TotalPower", "Reflectivity", "Velocity", "Width", "Differential_Reflectivity" }; String[] unit = {" ", "dbZ", "dbZ", "m/sec", "m/sec", "dB"}; int[] type = {1, 2, 3, 4, 5}; String def_datafile = "SIGMET-IRIS"; String tim = ""; int ngates = 0; recHdr = readRecordsHdr(raf); hdrNames = readStnNames(raf); String stnName = hdrNames.get("StationName"); String stnName_util = hdrNames.get("StationName_SetupUtility"); float radar_lat = recHdr.get("radar_lat").floatValue(); // System.out.println("rad_lat="+radar_lat); float radar_lon = recHdr.get("radar_lon").floatValue(); // System.out.println("rad_lon="+radar_lon); short ground_height = recHdr.get("ground_height").shortValue(); // System.out.println("ground_H="+ground_height); short radar_height = recHdr.get("radar_height").shortValue(); // System.out.println("radar_H="+radar_height); int radar_alt = (recHdr.get("radar_alt").intValue()) / 100; // System.out.println("rad_alt="+radar_alt); short num_rays = recHdr.get("num_rays").shortValue(); // System.out.println("num_rays="+num_rays); short bins = recHdr.get("bins").shortValue(); // System.out.println("bins="+bins); float range_first = (recHdr.get("range_first").intValue()) * 0.01f; // System.out.println("range_1st="+range_first); float range_last = (recHdr.get("range_last").intValue()) * 0.01f; // System.out.println("step="+step); short number_sweeps = recHdr.get("number_sweeps").shortValue(); // System.out.println("number_sweeps="+number_sweeps); int nparams = (recHdr.get("nparams").intValue()); // System.out.println("nparams="+nparams); short year = recHdr.get("year").shortValue(); // System.out.println("year="+year); short month = recHdr.get("month").shortValue(); short day = recHdr.get("day").shortValue(); int base_time = (recHdr.get("base_time").intValue()); // define number of gates for every sweep sweep_bins = new int[nparams * number_sweeps]; if (number_sweeps > 1) { sweep_bins = volScan.getNumberGates(); } else { for (int kk = 0; kk < nparams; kk++) { sweep_bins[kk] = bins; } } // add Dimensions Dimension scanR = new Dimension("scanR", number_sweeps, true); Dimension radial = new Dimension("radial", num_rays, true); Dimension[] gateR = new Dimension[number_sweeps]; String dim_name = "gateR"; for (int j = 0; j < number_sweeps; j++) { if (number_sweeps > 1) { dim_name = "gateR_sweep_" + (j + 1); } gateR[j] = new Dimension(dim_name, sweep_bins[j], true); } ncfile.addDimension(null, scanR); ncfile.addDimension(null, radial); for (int j = 0; j < number_sweeps; j++) { ncfile.addDimension(null, gateR[j]); } ArrayList<Dimension> dims0 = new ArrayList<Dimension>(); ArrayList<Dimension> dims1 = new ArrayList<Dimension>(); ArrayList<Dimension> dims2 = new ArrayList<Dimension>(); ArrayList<Dimension> dims3 = new ArrayList<Dimension>(); ArrayList<Variable> varList = new ArrayList<Variable>(); Variable[][] v = new Variable[nparams][number_sweeps]; String var_name = ""; for (int j = 0; j < nparams; j++) { int tp = type[j]; var_name = data_name[tp]; for (int jj = 0; jj < number_sweeps; jj++) { if (number_sweeps > 1) { var_name = data_name[tp] + "_sweep_" + (jj + 1); } v[j][jj] = new Variable(ncfile, null, null, var_name); v[j][jj].setDataType(DataType.FLOAT); dims2.add(radial); dims2.add(gateR[jj]); v[j][jj].setDimensions(dims2); v[j][jj].addAttribute(new Attribute(CDM.LONG_NAME, var_name)); v[j][jj].addAttribute(new Attribute(CDM.UNITS, unit[tp])); String coordinates = "time elevationR azimuthR distanceR"; v[j][jj].addAttribute(new Attribute(_Coordinate.Axes, coordinates)); v[j][jj].addAttribute(new Attribute(CDM.MISSING_VALUE, -999.99f)); ncfile.addVariable(null, v[j][jj]); varList.add(v[j][jj]); dims2.clear(); } } tsu_sec = new int[number_sweeps]; String[] tsu = new String[number_sweeps]; String[] time_units = new String[number_sweeps]; tsu_sec = volScan.getStartSweep(); for (int i = 0; i < number_sweeps; i++) { String st1 = Short.toString(month); if (st1.length() < 2) st1 = "0" + st1; String st2 = Short.toString(day); if (st2.length() < 2) st2 = "0" + st2; date0 = String.valueOf(year) + "-" + st1 + "-" + st2; tsu[i] = date0 + "T" + calcTime(tsu_sec[i], 0) + "Z"; } for (int j = 0; j < number_sweeps; j++) { time_units[j] = "secs since " + tsu[j]; } dims0.add(radial); // add "time" variable Variable[] time = new Variable[number_sweeps]; String tm = "time"; String tm_name = ""; for (int j = 0; j < number_sweeps; j++) { tm_name = tm; if (number_sweeps > 1) { tm_name = tm + "_sweep_" + (j + 1); } time[j] = new Variable(ncfile, null, null, tm_name); time[j].setDataType(DataType.INT); time[j].setDimensions(dims0); time[j].addAttribute(new Attribute(CDM.LONG_NAME, "time from start of sweep")); time[j].addAttribute(new Attribute(CDM.UNITS, time_units[j])); time[j].addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Time.toString())); time[j].addAttribute(new Attribute(CDM.MISSING_VALUE, -99)); ncfile.addVariable(null, time[j]); varList.add(time[j]); } // add "elevationR" variable Variable[] elevationR = new Variable[number_sweeps]; String ele = "elevationR"; String ele_name = ""; for (int j = 0; j < number_sweeps; j++) { ele_name = ele; if (number_sweeps > 1) { ele_name = ele + "_sweep_" + (j + 1); } elevationR[j] = new Variable(ncfile, null, null, ele_name); elevationR[j].setDataType(DataType.FLOAT); elevationR[j].setDimensions(dims0); elevationR[j].addAttribute(new Attribute(CDM.LONG_NAME, "elevation angle")); elevationR[j].addAttribute(new Attribute(CDM.UNITS, "degrees")); elevationR[j].addAttribute( new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString())); elevationR[j].addAttribute(new Attribute(CDM.MISSING_VALUE, -999.99f)); ncfile.addVariable(null, elevationR[j]); varList.add(elevationR[j]); } // add "azimuthR" variable Variable[] azimuthR = new Variable[number_sweeps]; String azim = "azimuthR"; String azim_name = ""; for (int j = 0; j < number_sweeps; j++) { azim_name = azim; if (number_sweeps > 1) { azim_name = azim + "_sweep_" + (j + 1); } azimuthR[j] = new Variable(ncfile, null, null, azim_name); azimuthR[j].setDataType(DataType.FLOAT); azimuthR[j].setDimensions(dims0); azimuthR[j].addAttribute(new Attribute(CDM.LONG_NAME, "azimuth angle")); azimuthR[j].addAttribute(new Attribute(CDM.UNITS, "degrees")); azimuthR[j].addAttribute( new Attribute(_Coordinate.AxisType, AxisType.RadialAzimuth.toString())); azimuthR[j].addAttribute(new Attribute(CDM.MISSING_VALUE, -999.99f)); ncfile.addVariable(null, azimuthR[j]); varList.add(azimuthR[j]); } // add "distanceR" variable Variable[] distanceR = new Variable[number_sweeps]; String dName = "distanceR"; String dist_name = ""; for (int j = 0; j < number_sweeps; j++) { dist_name = dName; if (number_sweeps > 1) { dist_name = dName + "_sweep_" + (j + 1); } distanceR[j] = new Variable(ncfile, null, null, dist_name); distanceR[j].setDataType(DataType.FLOAT); dims1.add(gateR[j]); distanceR[j].setDimensions(dims1); distanceR[j].addAttribute(new Attribute(CDM.LONG_NAME, "radial distance")); distanceR[j].addAttribute(new Attribute(CDM.UNITS, "m")); distanceR[j].addAttribute( new Attribute(_Coordinate.AxisType, AxisType.RadialDistance.toString())); ncfile.addVariable(null, distanceR[j]); varList.add(distanceR[j]); dims1.clear(); } // add "numGates" variable dims3.add(scanR); Variable numGates = new Variable(ncfile, null, null, "numGates"); numGates.setDataType(DataType.INT); numGates.setDimensions(dims3); numGates.addAttribute(new Attribute(CDM.LONG_NAME, "number of gates in the sweep")); ncfile.addVariable(null, numGates); varList.add(numGates); // add global attributes ncfile.addAttribute(null, new Attribute("definition", "SIGMET-IRIS RAW")); ncfile.addAttribute( null, new Attribute("description", "SIGMET-IRIS data are reading by Netcdf IOSP")); ncfile.addAttribute(null, new Attribute("StationName", stnName)); ncfile.addAttribute(null, new Attribute("StationName_SetupUtility", stnName_util)); ncfile.addAttribute(null, new Attribute("radar_lat", radar_lat)); ncfile.addAttribute(null, new Attribute("radar_lon", radar_lon)); ncfile.addAttribute(null, new Attribute("ground_height", ground_height)); ncfile.addAttribute(null, new Attribute("radar_height", radar_height)); ncfile.addAttribute(null, new Attribute("radar_alt", radar_alt)); ncfile.addAttribute(null, new Attribute("num_data_types", nparams)); ncfile.addAttribute(null, new Attribute("number_sweeps", number_sweeps)); String sn = "start_sweep"; String snn = ""; for (int j = 0; j < number_sweeps; j++) { snn = sn; if (number_sweeps > 1) { snn = sn + "_" + (j + 1); } ncfile.addAttribute(null, new Attribute(snn, tsu[j])); } ncfile.addAttribute(null, new Attribute("num_rays", num_rays)); ncfile.addAttribute(null, new Attribute("max_number_gates", bins)); ncfile.addAttribute(null, new Attribute("range_first", range_first)); ncfile.addAttribute(null, new Attribute("range_last", range_last)); ncfile.addAttribute(null, new Attribute("DataType", "Radial")); ncfile.addAttribute(null, new Attribute(CDM.CONVENTIONS, _Coordinate.Convention)); // --------- fill all of values in the ncfile ------ doNetcdfFileCoordinate( ncfile, volScan.base_time, volScan.year, volScan.month, volScan.day, varList, recHdr); ncfile.finish(); return varList; }
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; }
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; }
/** * Make a station variable * * @param varname variable name * @param firstDim station dimension * @return corresponding variable */ protected Variable makeStationVariable(String varname, Dimension firstDim) { String longName = varname; String unit = null; DataType type = DataType.CHAR; List<Dimension> dims = new ArrayList<Dimension>(); List<Attribute> attrs = new ArrayList<Attribute>(); if (firstDim != null) { dims.add(firstDim); } if (varname.equals(GempakStation.STID)) { longName = "Station identifier"; dims.add(DIM_LEN8); } else if (varname.equals(GempakStation.STNM)) { longName = "WMO station id"; type = DataType.INT; } else if (varname.equals(GempakStation.SLAT)) { longName = "latitude"; unit = "degrees_north"; type = DataType.FLOAT; attrs.add(new Attribute("standard_name", "latitude")); } else if (varname.equals(GempakStation.SLON)) { longName = "longitude"; unit = "degrees_east"; type = DataType.FLOAT; attrs.add(new Attribute("standard_name", "longitude")); } else if (varname.equals(GempakStation.SELV)) { longName = "altitude"; unit = "meter"; type = DataType.FLOAT; attrs.add(new Attribute(CF.POSITIVE, CF.POSITIVE_UP)); attrs.add(new Attribute("standard_name", "station_altitude")); } else if (varname.equals(GempakStation.STAT)) { longName = "state or province"; dims.add(DIM_LEN2); } else if (varname.equals(GempakStation.COUN)) { longName = "country code"; dims.add(DIM_LEN2); } else if (varname.equals(GempakStation.STD2)) { longName = "Extended station id"; dims.add(DIM_LEN4); } else if (varname.equals(GempakStation.SPRI)) { longName = "Station priority"; type = DataType.INT; } else if (varname.equals(GempakStation.SWFO)) { longName = "WFO code"; dims.add(DIM_LEN4); } else if (varname.equals(GempakStation.WFO2)) { longName = "Second WFO code"; dims.add(DIM_LEN4); } Variable v = new Variable(ncfile, null, null, varname); v.setDataType(type); v.addAttribute(new Attribute("long_name", longName)); if (unit != null) { v.addAttribute(new Attribute(CDM.UNITS, unit)); } if (type.equals(DataType.FLOAT)) { v.addAttribute(new Attribute("missing_value", RMISS)); } else if (type.equals(DataType.INT)) { v.addAttribute(new Attribute("missing_value", IMISS)); } if (!attrs.isEmpty()) { for (Attribute attr : attrs) { v.addAttribute(attr); } } if (!dims.isEmpty()) { v.setDimensions(dims); } else { v.setDimensions((String) null); } return v; }
/** * 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); */ } }
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; }
public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask cancelTask) throws IOException { NexradStationDB.init(); volScan = new Cinrad2VolumeScan(raf, cancelTask); if (volScan.hasDifferentDopplarResolutions()) throw new IllegalStateException("volScan.hasDifferentDopplarResolutions"); radialDim = new Dimension("radial", volScan.getMaxRadials()); ncfile.addDimension(null, radialDim); makeVariable( ncfile, Cinrad2Record.REFLECTIVITY, "Reflectivity", "Reflectivity", "R", volScan.getReflectivityGroups()); int velocity_type = (volScan.getDopplarResolution() == Cinrad2Record.DOPPLER_RESOLUTION_HIGH_CODE) ? Cinrad2Record.VELOCITY_HI : Cinrad2Record.VELOCITY_LOW; Variable v = makeVariable( ncfile, velocity_type, "RadialVelocity", "Radial Velocity", "V", volScan.getVelocityGroups()); makeVariableNoCoords( ncfile, Cinrad2Record.SPECTRUM_WIDTH, "SpectrumWidth", "Spectrum Width", v); if (volScan.getStationId() != null) { ncfile.addAttribute(null, new Attribute("Station", volScan.getStationId())); ncfile.addAttribute(null, new Attribute("StationName", volScan.getStationName())); ncfile.addAttribute( null, new Attribute("StationLatitude", new Double(volScan.getStationLatitude()))); ncfile.addAttribute( null, new Attribute("StationLongitude", new Double(volScan.getStationLongitude()))); ncfile.addAttribute( null, new Attribute("StationElevationInMeters", new Double(volScan.getStationElevation()))); double latRadiusDegrees = Math.toDegrees(radarRadius / ucar.unidata.geoloc.Earth.getRadius()); ncfile.addAttribute( null, new Attribute( "geospatial_lat_min", new Double(volScan.getStationLatitude() - latRadiusDegrees))); ncfile.addAttribute( null, new Attribute( "geospatial_lat_max", new Double(volScan.getStationLatitude() + latRadiusDegrees))); double cosLat = Math.cos(Math.toRadians(volScan.getStationLatitude())); double lonRadiusDegrees = Math.toDegrees(radarRadius / cosLat / ucar.unidata.geoloc.Earth.getRadius()); ncfile.addAttribute( null, new Attribute( "geospatial_lon_min", new Double(volScan.getStationLongitude() - lonRadiusDegrees))); ncfile.addAttribute( null, new Attribute( "geospatial_lon_max", new Double(volScan.getStationLongitude() + lonRadiusDegrees))); // add a radial coordinate transform (experimental) Variable ct = new Variable(ncfile, null, null, "radialCoordinateTransform"); ct.setDataType(DataType.CHAR); ct.setDimensions(""); // scalar ct.addAttribute(new Attribute("transform_name", "Radial")); ct.addAttribute(new Attribute("center_latitude", new Double(volScan.getStationLatitude()))); ct.addAttribute(new Attribute("center_longitude", new Double(volScan.getStationLongitude()))); ct.addAttribute(new Attribute("center_elevation", new Double(volScan.getStationElevation()))); ct.addAttribute(new Attribute(_Coordinate.TransformType, "Radial")); ct.addAttribute( new Attribute(_Coordinate.AxisTypes, "RadialElevation RadialAzimuth RadialDistance")); Array data = Array.factory(DataType.CHAR.getPrimitiveClassType(), new int[0], new char[] {' '}); ct.setCachedData(data, true); ncfile.addVariable(null, ct); } DateFormatter formatter = new DateFormatter(); ncfile.addAttribute(null, new Attribute(CDM.CONVENTIONS, _Coordinate.Convention)); ncfile.addAttribute(null, new Attribute("format", volScan.getDataFormat())); ncfile.addAttribute(null, new Attribute(CF.FEATURE_TYPE, FeatureType.RADIAL.toString())); // Date d = Cinrad2Record.getDate(volScan.getTitleJulianDays(), volScan.getTitleMsecs()); // ncfile.addAttribute(null, new Attribute("base_date", formatter.toDateOnlyString(d))); ncfile.addAttribute( null, new Attribute( "time_coverage_start", formatter.toDateTimeStringISO(volScan.getStartDate()))); ; // .toDateTimeStringISO(d))); ncfile.addAttribute( null, new Attribute("time_coverage_end", formatter.toDateTimeStringISO(volScan.getEndDate()))); ncfile.addAttribute( null, new Attribute(CDM.HISTORY, "Direct read of Nexrad Level 2 file into NetCDF-Java 2.2 API")); ncfile.addAttribute(null, new Attribute("DataType", "Radial")); ncfile.addAttribute( null, new Attribute( "Title", "Nexrad Level 2 Station " + volScan.getStationId() + " from " + formatter.toDateTimeStringISO(volScan.getStartDate()) + " to " + formatter.toDateTimeStringISO(volScan.getEndDate()))); ncfile.addAttribute( null, new Attribute( "Summary", "Weather Surveillance Radar-1988 Doppler (WSR-88D) " + "Level II data are the three meteorological base data quantities: reflectivity, mean radial velocity, and " + "spectrum width.")); ncfile.addAttribute( null, new Attribute( "keywords", "WSR-88D; NEXRAD; Radar Level II; reflectivity; mean radial velocity; spectrum width")); ncfile.addAttribute( null, new Attribute( "VolumeCoveragePatternName", Cinrad2Record.getVolumeCoveragePatternName(volScan.getVCP()))); ncfile.addAttribute( null, new Attribute("VolumeCoveragePattern", new Integer(volScan.getVCP()))); ncfile.addAttribute( null, new Attribute( "HorizonatalBeamWidthInDegrees", new Double(Cinrad2Record.HORIZONTAL_BEAM_WIDTH))); ncfile.finish(); }
public static NetcdfDataset buildStation(IObservationGroup obsGroup) { if (obsGroup.getDepths().length > 1) { return buildStationProfile(obsGroup); } NetcdfDataset ncds = null; File temp = null; try { /* Instantiate an empty NetcdfDataset object from the template ncml */ temp = File.createTempFile("ooi", ".ncml"); ncds = getNcdsFromTemplate(temp, "station.ncml"); Map<String, String> allAttributes = new HashMap<String, String>(); allAttributes.putAll(obsGroup.getAttributes()); /* Do the station Id */ ArrayInt.D0 aid = new ArrayInt.D0(); aid.set(obsGroup.getId()); ncds.findVariable("stnId").setCachedData(aid); /* Do the times */ Number[] times = obsGroup.getTimes(); IObservationGroup.DataType tdt = obsGroup.getTimeDataType(); ncds.findDimension("time").setLength(times.length); Variable tvar = ncds.findVariable("time"); tvar.setDataType(getNcDataType(tdt)); tvar.setCachedData(getNcArray(times, tdt)); /* Do the lat & lon */ IObservationGroup.DataType lldt = obsGroup.getLatLonDataType(); DataType ncdtLl = getNcDataType(lldt); Variable laVar = ncds.findVariable("lat"); laVar.setDataType(ncdtLl); laVar.setCachedData(getNcScalar(obsGroup.getLat(), lldt)); Variable loVar = ncds.findVariable("lon"); loVar.setDataType(ncdtLl); loVar.setCachedData(getNcScalar(obsGroup.getLon(), lldt)); /* Do the depth */ IObservationGroup.DataType ddt = obsGroup.getDepthDataType(); VariableDS zVar = new VariableDS( ncds, null, null, "stnDepth", getNcDataType(ddt), "", "m", "station depth"); zVar.addAttribute(new Attribute("positive", "down")); ncds.addVariable(null, zVar); Number depth = obsGroup.getDepths()[0]; zVar.setCachedData(getNcScalar(obsGroup.getDepths()[0], ddt)); /* Do the data variables */ for (VariableParams dn : obsGroup.getDataNames()) { DataType ncdtData = getNcDataType(dn.getDataType()); VariableDS dvar = new VariableDS( ncds, null, null, dn.getShortName(), ncdtData, "time", dn.getUnits(), dn.getDescription()); dvar.addAttribute(new Attribute(CF.COORDINATES, "time lon lat")); dvar.addAttribute(new Attribute(CF.STANDARD_NAME, dn.getStandardName())); Array adata = Array.factory(ncdtData, new int[] {times.length}); IndexIterator aii = adata.getIndexIterator(); dvar.setCachedData(adata); ncds.addVariable(null, dvar); for (int ti = 0; ti < times.length; ti++) { putArrayData(aii, ncdtData, obsGroup.getData(dn, times[ti], depth)); } } /* Add global attributes */ for (String key : allAttributes.keySet()) { ncds.addAttribute(null, new Attribute(key, allAttributes.get(key))); } } catch (FileNotFoundException ex) { Logger.getLogger(NcdsFactory.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(NcdsFactory.class.getName()).log(Level.SEVERE, null, ex); } finally { if (temp != null) { if (!temp.delete()) { temp.deleteOnExit(); } } if (ncds != null) { ncds.finish(); } } return ncds; }
public static NetcdfDataset buildTrajectory(List<IObservationGroup> obsGroups) { // IObservationGroup.DataType tdt = IObservationGroup.DataType.values()[0]; // IObservationGroup.DataType lldt = IObservationGroup.DataType.values()[0]; // IObservationGroup.DataType ddt = IObservationGroup.DataType.values()[0]; // for(IObservationGroup og : obsGroups) { // tdt = (og.getTimeDataType().compareTo(tdt) > 0) ? og.getTimeDataType() : tdt; // lldt = (og.getLatLonDataType().compareTo(lldt) > 0) ? og.getLatLonDataType() : // lldt; // ddt = (og.getDepthDataType().compareTo(ddt) > 0) ? og.getDepthDataType() : ddt; // } NetcdfDataset ncds = null; File temp = null; try { /* Instantiate an empty NetcdfDataset object from the template ncml */ temp = File.createTempFile("ooi", ".ncml"); ncds = getNcdsFromTemplate(temp, "trajectory.ncml"); int nobs = obsGroups.size(); List<Number> allDepths = new ArrayList<Number>(); List<VariableParams> allDn = new ArrayList<VariableParams>(); int nt = nobs; int nd = 0; for (IObservationGroup og : obsGroups) { nd = Math.max(nd, og.getDepths().length); for (Number d : og.getDepths()) { if (!allDepths.contains(d)) { allDepths.add(d); } } for (VariableParams dn : og.getDataNames()) { if (!allDn.contains(dn)) { allDn.add(dn); } } } /* Do the trajectory ID */ /* Do the times */ Number[] times = obsGroups.get(0).getTimes(); IObservationGroup.DataType tdt = obsGroups.get(0).getTimeDataType(); DataType ncdtTime = getNcDataType(tdt); ncds.findDimension("time").setLength(nt); Array tarr = Array.factory(ncdtTime, new int[] {nt}); IndexIterator tii = tarr.getIndexIterator(); Variable tvar = ncds.findVariable("time"); tvar.setDataType(getNcDataType(tdt)); tvar.setCachedData(tarr); /* Do the lats */ IObservationGroup.DataType lldt = obsGroups.get(0).getLatLonDataType(); DataType ncdtLl = getNcDataType(lldt); Array laarr = Array.factory(ncdtLl, new int[] {nt}); IndexIterator laii = laarr.getIndexIterator(); Variable lavar = ncds.findVariable("lat"); lavar.setDataType(ncdtLl); lavar.setCachedData(laarr); /* Do the lons */ Array loarr = Array.factory(ncdtLl, new int[] {nt}); IndexIterator loii = loarr.getIndexIterator(); Variable lovar = ncds.findVariable("lon"); lovar.setDataType(ncdtLl); lovar.setCachedData(loarr); /* Iterate over the observation groups and fill the data */ Map<String, String> allAttributes = new HashMap<String, String>(); IObservationGroup og; HashMap<String, IndexIterator> darrs = new HashMap<String, IndexIterator>(); Number time; Number depth = allDepths.get(0); for (int obs = 0; obs < nobs; obs++) { og = obsGroups.get(obs); time = og.getTimes()[0]; putArrayData(tii, ncdtTime, time); putArrayData(loii, ncdtLl, og.getLon()); putArrayData(laii, ncdtLl, og.getLat()); for (VariableParams dn : allDn) { if (og.getDataNames().contains(dn)) { DataType ncdtData = getNcDataType(dn.getDataType()); VariableDS dvar = (VariableDS) ncds.findVariable(dn.getShortName()); if (dvar == null) { dvar = new VariableDS( ncds, null, null, dn.getShortName(), ncdtData, "time", dn.getUnits(), dn.getDescription()); dvar.addAttribute(new Attribute(CF.COORDINATES, "time lon lat")); // dvar.addAttribute(new Attribute("missing_value", // missingData)); dvar.addAttribute(new Attribute(CF.STANDARD_NAME, dn.getStandardName())); Array darr = Array.factory(ncdtData, new int[] {nt}); dvar.setCachedData(darr); darrs.put(dn.getStandardName(), darr.getIndexIterator()); ncds.addVariable(null, dvar); } putArrayData(darrs.get(dn.getStandardName()), ncdtData, og.getData(dn, time, depth)); } else { /* * station doesn't have this variable - don't believe * this can even happen... * * NOTE: This would indicate a problem with the above processing where the data-name list * has been modified prior to contains-checking */ } } } /* Add global attributes */ for (String key : allAttributes.keySet()) { ncds.addAttribute(null, new Attribute(key, allAttributes.get(key))); } } catch (FileNotFoundException ex) { Logger.getLogger(NcdsFactory.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(NcdsFactory.class.getName()).log(Level.SEVERE, null, ex); } finally { if (temp != null) { if (!temp.delete()) { temp.deleteOnExit(); } } if (ncds != null) { ncds.finish(); } } return ncds; }