/** * Set the sounding in the table * * @param sounding the sounding * @throws RemoteException Java RMI problem * @throws VisADException problem dissecting data */ private void setSounding(Field sounding) throws VisADException, RemoteException { domainData = null; // domain values Set domain = sounding.getDomainSet(); CoordinateSystem cs = domain.getCoordinateSystem(); float[][] domSamples = domain.getSamples(false); if ((cs != null)) { float[][] domFloats = Set.copyFloats(domSamples); // Must convert from the default coordinate domain system to // the domain coordinate system of the sounding. String fromUnit = sounding.getDomainUnits()[0].toString(); String toUnit = cs.getCoordinateSystemUnits()[0].toString(); if (!fromUnit.equals(toUnit) && SimpleUnit.isCompatible(fromUnit, toUnit)) { float conversionFactor = (float) SimpleUnit.getConversionFactor(fromUnit, toUnit); for (int i = 0; i < domFloats.length; i++) { for (int j = 0; j < domFloats[i].length; j++) { domFloats[i][j] = domFloats[i][j] * conversionFactor; } } } float[][] refData = cs.toReference(domFloats); domainData = new float[][] {domSamples[0], refData[0]}; } // range values RealType[] rangeComps = ((FunctionType) sounding.getType()).getRealComponents(); rangeData = sounding.getFloats(false); // wind if (rangeComps.length > 2) { transformWinds = (showUAndV && !haveUV) || (!showUAndV && haveUV); if (!transformWinds) { for (int i = 2; i < 4; i++) { columnNames[numDomainCols + i] = makeColumnName(rangeComps[i], rangeComps[i].getDefaultUnit()); } } else { RealTupleType refType = windTransform.getReference(); Unit[] refUnits = windTransform.getReferenceUnits(); for (int i = 0; i < 2; i++) { columnNames[numDomainCols + i + 2] = makeColumnName((RealType) refType.getComponent(i), refUnits[i]); } float[][] newVals = windTransform.toReference(Set.copyFloats(new float[][] {rangeData[2], rangeData[3]})); rangeData[2] = newVals[0]; rangeData[3] = newVals[1]; } } sorter.setTableModel(model); }
/** * Build the configuration from the dataset * * @param ncd NetcdfDataset * @return the trajectory configuration */ private static Config buildConfig(NetcdfDataset ncd) { // already did this in isValid, but we'll keep here for later refactor Attribute attrib = ncd.findGlobalAttributeIgnoreCase("center"); if (attrib == null) { return null; } if (!attrib.isString()) { return null; } if (!attrib.getStringValue().equals("UCAR/CDAAC")) { return null; } // Check for start_time, stop_time attrib = ncd.findGlobalAttributeIgnoreCase("start_time"); if (attrib == null) { return null; } if (attrib.isString()) { return null; } double startTime = attrib.getNumericValue().doubleValue(); attrib = ncd.findGlobalAttributeIgnoreCase("stop_time"); if (attrib == null) { return null; } if (attrib.isString()) { return null; } double endTime = attrib.getNumericValue().doubleValue(); // Check that only one dimension and that it is the alt dimension. List list = ncd.getRootGroup().getDimensions(); if (list.size() != 1) { return null; } Dimension d = (Dimension) list.get(0); if (!d.getName().equals(timeDimName)) { return null; } Config trajConfig = new Config(); trajConfig.setTimeDim(d); // Check for latitude variable with time dimension and units convertable to "degrees_north". Variable var = ncd.getRootGroup().findVariable(latVarName); if (var == null) { return null; } list = var.getDimensions(); if (list.size() != 1) { return null; } d = (Dimension) list.get(0); if (!d.getName().equals(timeDimName)) { return null; } String units = var.findAttribute("units").getStringValue(); if (!SimpleUnit.isCompatible(units, "degrees_north")) { return null; } trajConfig.setLatVar(var); // Make the time Variable int numTimes = d.getLength(); double[] times = new double[numTimes]; // Variable timeVar = new Variable(var); // timeVar.setName(timeVarName); VariableDS timeVar = new VariableDS( ncd, ncd.getRootGroup(), null, timeVarName, DataType.DOUBLE, timeDimName, "seconds since 1980-01-06 00:00:00", "Time coordinate"); // Variable timeVar = new Variable(ncd, ncd.getRootGroup(), null, // timeVarName); // timeVar.setDataType(DataType.DOUBLE); // timeVar.setDimensions(list); // Attribute newUnits = // new Attribute("units", "seconds since 1980-01-06 00:00:00"); // timeVar.addAttribute(newUnits); timeVar.setCachedData( Array.makeArray(DataType.DOUBLE, numTimes, endTime, ((startTime - endTime) / numTimes)), true); ncd.addVariable(ncd.getRootGroup(), timeVar); trajConfig.setTimeVar(timeVar); // Check for longitude variable with time dimension and units convertable to "degrees_east". var = ncd.getRootGroup().findVariable(lonVarName); if (var == null) { return null; } list = var.getDimensions(); if (list.size() != 1) { return null; } d = (Dimension) list.get(0); if (!d.getName().equals(timeDimName)) { return null; } units = var.findAttribute("units").getStringValue(); if (!SimpleUnit.isCompatible(units, "degrees_east")) { return null; } trajConfig.setLonVar(var); // Check for altitude variable with time dimension and units convertable to "m". var = ncd.getRootGroup().findVariable(elevVarName); if (var == null) { return null; } list = var.getDimensions(); if (list.size() != 1) { return null; } d = (Dimension) list.get(0); if (!d.getName().equals(timeDimName)) { return null; } units = var.findAttribute("units").getStringValue(); if (!SimpleUnit.isCompatible(units, "meters")) { return null; } trajConfig.setElevVar(var); trajConfig.setTrajectoryId(trajId); return trajConfig; }
protected static double getMetersConversionFactor(String unitsString) throws Exception { SimpleUnit unit = SimpleUnit.factoryWithExceptions(unitsString); return unit.convertTo(1.0, SimpleUnit.meterUnit); }
/** * Setup needed for all SingleTrajectoryObsDatatypes. Can only be called once. * * <p>Units of time varible must be udunits time units. Units of latitude variable must be * convertible to "degrees_north" by udunits. Units of longitude variable must be convertible to * "degrees_east" by udunits. Units of altitude variable must be convertible to "meters" by * udunits. * * @throws IllegalArgumentException if units of time, latitude, longitude, or altitude variables * are not as required. * @throws IllegalStateException if this method has already been called. */ public void setTrajectoryInfo(Config trajConfig) throws IOException { if (timeDim != null) throw new IllegalStateException("The setTrajectoryInfo() method can only be called once."); this.trajectoryId = trajConfig.getTrajectoryId(); this.timeDim = trajConfig.getTimeDim(); this.timeVar = trajConfig.getTimeVar(); this.latVar = trajConfig.getLatVar(); this.lonVar = trajConfig.getLonVar(); this.elevVar = trajConfig.getElevVar(); trajectoryNumPoint = this.timeDim.getLength(); timeVarUnitsString = this.timeVar.findAttribute("units").getStringValue(); // Check that time, lat, lon, elev units are acceptable. if (DateUnit.getStandardDate(timeVarUnitsString) == null) { throw new IllegalArgumentException( "Units of time variable <" + timeVarUnitsString + "> not a date unit."); } String latVarUnitsString = this.latVar.findAttribute("units").getStringValue(); if (!SimpleUnit.isCompatible(latVarUnitsString, "degrees_north")) { throw new IllegalArgumentException( "Units of lat var <" + latVarUnitsString + "> not compatible with \"degrees_north\"."); } String lonVarUnitsString = this.lonVar.findAttribute("units").getStringValue(); if (!SimpleUnit.isCompatible(lonVarUnitsString, "degrees_east")) { throw new IllegalArgumentException( "Units of lon var <" + lonVarUnitsString + "> not compatible with \"degrees_east\"."); } String elevVarUnitsString = this.elevVar.findAttribute("units").getStringValue(); if (!SimpleUnit.isCompatible(elevVarUnitsString, "meters")) { throw new IllegalArgumentException( "Units of elev var <" + elevVarUnitsString + "> not compatible with \"meters\"."); } try { elevVarUnitsConversionFactor = getMetersConversionFactor(elevVarUnitsString); } catch (Exception e) { throw new IllegalArgumentException( "Exception on getMetersConversionFactor() for the units of elev var <" + elevVarUnitsString + ">."); } if (this.ncfile.hasUnlimitedDimension() && this.ncfile.getUnlimitedDimension().equals(timeDim)) { Object result = this.ncfile.sendIospMessage(NetcdfFile.IOSP_MESSAGE_ADD_RECORD_STRUCTURE); if ((result != null) && (Boolean) result) this.recordVar = (Structure) this.ncfile.getRootGroup().findVariable("record"); else this.recordVar = new StructurePseudo(this.ncfile, null, "record", timeDim); } else { this.recordVar = new StructurePseudo(this.ncfile, null, "record", timeDim); } // @todo HACK, HACK, HACK - remove once addRecordStructure() deals with ncd attribute changes. Variable elevVarInRecVar = this.recordVar.findVariable(this.elevVar.getFullNameEscaped()); if (!elevVarUnitsString.equals(elevVarInRecVar.findAttribute("units").getStringValue())) { elevVarInRecVar.addAttribute(new Attribute("units", elevVarUnitsString)); } trajectoryVarsMap = new HashMap(); // for ( Iterator it = this.recordVar.getVariables().iterator(); it.hasNext(); ) for (Iterator it = this.ncfile.getRootGroup().getVariables().iterator(); it.hasNext(); ) { Variable curVar = (Variable) it.next(); if (curVar.getRank() > 0 && !curVar.equals(this.timeVar) && !curVar.equals(this.latVar) && !curVar.equals(this.lonVar) && !curVar.equals(this.elevVar) && (this.recordVar == null ? true : !curVar.equals(this.recordVar))) { MyTypedDataVariable typedVar = new MyTypedDataVariable(new VariableDS(null, curVar, true)); dataVariables.add(typedVar); trajectoryVarsMap.put(typedVar.getShortName(), typedVar); } } trajectory = new SingleTrajectory( this.trajectoryId, trajectoryNumPoint, this.timeVar, timeVarUnitsString, this.latVar, this.lonVar, this.elevVar, dataVariables, trajectoryVarsMap); startDate = trajectory.getTime(0); endDate = trajectory.getTime(trajectoryNumPoint - 1); ((SingleTrajectory) trajectory).setStartDate(startDate); ((SingleTrajectory) trajectory).setEndDate(endDate); }
/** create a NetcdfDataset out of this NetcdfFile, adding coordinates etc. */ public void augmentDataset(NetcdfDataset ds, CancelTask cancelTask) throws IOException { // latitude if (!hasAxisType(ds, AxisType.Lat)) { // already has _CoordinateAxisType if (!addAxisType(ds, "latitude", AxisType.Lat)) { // directly named String vname = ds.findAttValueIgnoreCase(null, "latitude_coordinate", null); if (!addAxisType(ds, vname, AxisType.Lat)) { // attribute named Variable v = hasUnits(ds, "degrees_north,degrees_N,degreesN,degree_north,degree_N,degreeN"); if (v != null) addAxisType(v, AxisType.Lat); // CF-1 } } } // longitude if (!hasAxisType(ds, AxisType.Lon)) { // already has _CoordinateAxisType if (!addAxisType(ds, "longitude", AxisType.Lon)) { // directly named String vname = ds.findAttValueIgnoreCase(null, "longitude_coordinate", null); if (!addAxisType(ds, vname, AxisType.Lon)) { // attribute named Variable v = hasUnits(ds, "degrees_east,degrees_E,degreesE,degree_east,degree_E,degreeE"); if (v != null) addAxisType(v, AxisType.Lon); // CF-1 } } } // altitude if (!hasAxisType(ds, AxisType.Height)) { // already has _CoordinateAxisType if (!addAxisType(ds, "altitude", AxisType.Height)) { // directly named if (!addAxisType(ds, "depth", AxisType.Height)) { // directly named String vname = ds.findAttValueIgnoreCase(null, "altitude_coordinate", null); if (!addAxisType(ds, vname, AxisType.Height)) { // attribute named for (int i = 0; i < ds.getVariables().size(); i++) { VariableEnhanced ve = (VariableEnhanced) ds.getVariables().get(i); String positive = ds.findAttValueIgnoreCase((Variable) ve, "positive", null); if (positive != null) { addAxisType((Variable) ve, AxisType.Height); // CF-1 break; } } } } } } // time if (!hasAxisType(ds, AxisType.Time)) { // already has _CoordinateAxisType if (!addAxisType(ds, "time", AxisType.Time)) { // directly named String vname = ds.findAttValueIgnoreCase(null, "time_coordinate", null); if (!addAxisType(ds, vname, AxisType.Time)) { // attribute named for (int i = 0; i < ds.getVariables().size(); i++) { VariableEnhanced ve = (VariableEnhanced) ds.getVariables().get(i); String unit = ve.getUnitsString(); if (unit == null) continue; if (SimpleUnit.isDateUnit(unit)) { addAxisType((Variable) ve, AxisType.Time); // CF-1 break; } } } } } }
/** * 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 static boolean isValidFile(NetcdfDataset ds) { // Check that has a time dimension and a trajectory dimension. List list = ds.getRootGroup().getDimensions(); if (list.size() != 2) return (false); Dimension d; for (int i = 0; i < 2; i++) { d = (Dimension) list.get(i); if (!d.getShortName().equals(timeDimNameDefault) && !d.getShortName().equals(trajDimNameDefault)) return (false); } // Check that has a trajectory coordinate variable. Variable var = ds.getRootGroup().findVariable(trajVarNameDefault); if (var == null) return (false); list = var.getDimensions(); if (list.size() != 1) return (false); d = (Dimension) list.get(0); if (!d.getShortName().equals(trajDimNameDefault)) return (false); // Check that has a time coordinate variable with units that are udunits time var = ds.getRootGroup().findVariable(timeVarNameDefault); if (var == null) return (false); list = var.getDimensions(); if (list.size() != 1) return (false); d = (Dimension) list.get(0); if (!d.getShortName().equals(timeDimNameDefault)) return (false); String units = var.findAttribute("units").getStringValue(); Date date = DateUnit.getStandardDate("0 " + units); if (date == null) return (false); // Check for variable latitude(time) with units of "deg". var = ds.getRootGroup().findVariable(latVarNameDefault); if (var == null) return (false); list = var.getDimensions(); if (list.size() != 2) return (false); for (int i = 0; i < 2; i++) { d = (Dimension) list.get(i); if (!d.getShortName().equals(timeDimNameDefault) && !d.getShortName().equals(trajDimNameDefault)) return (false); } // units = var.findAttribute( "units").getStringValue(); // if ( ! SimpleUnit.isCompatible( units, "degrees_north")) return( false); // Check for variable longitude(time) with units of "deg". var = ds.getRootGroup().findVariable(lonVarNameDefault); if (var == null) return (false); list = var.getDimensions(); if (list.size() != 2) return (false); for (int i = 0; i < 2; i++) { d = (Dimension) list.get(i); if (!d.getShortName().equals(timeDimNameDefault) && !d.getShortName().equals(trajDimNameDefault)) return (false); } // units = var.findAttribute( "units").getStringValue(); // if ( ! SimpleUnit.isCompatible( units, "degrees_east")) return( false); // Check for variable altitude(time) with units of "m". var = ds.getRootGroup().findVariable(elevVarNameDefault); if (var == null) return (false); list = var.getDimensions(); if (list.size() != 2) return (false); for (int i = 0; i < 2; i++) { d = (Dimension) list.get(i); if (!d.getShortName().equals(timeDimNameDefault) && !d.getShortName().equals(trajDimNameDefault)) return (false); } units = var.findAttribute("units").getStringValue(); if (!SimpleUnit.isCompatible(units, "m")) return (false); return (true); }