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); }
/** * 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; }
/** * 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(); }