ucar.nc2.iosp.dorade.Doradeheader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdm Show documentation
Show all versions of cdm Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
The newest version!
// $Id:Doradeheader.java 63 2006-07-12 21:50:51Z edavis $
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.iosp.dorade;
import ucar.nc2.*;
import ucar.nc2.constants.*;
import ucar.ma2.Array;
import ucar.ma2.DataType;
import ucar.ma2.MAMath;
import ucar.atd.dorade.*;
import java.io.*;
import java.util.*;
public class Doradeheader {
private boolean debug = false;
private ucar.nc2.NetcdfFile ncfile;
private float[] lat_min, lat_max, lon_min, lon_max, hi_max, hi_min;
static public boolean isValidFile(ucar.unidata.io.RandomAccessFile raf) {
try {
java.io.RandomAccessFile file = raf.getRandomAccessFile();
if (file == null) return false;
boolean t = DoradeSweep.isDoradeSweep(file);
if (!t) return false;
} catch (DoradeSweep.DoradeSweepException ex) {
return false;
}
return true;
}
void read(DoradeSweep mySweep, ucar.nc2.NetcdfFile ncfile, PrintStream out) throws IOException, DoradeSweep.DoradeSweepException {
this.ncfile = ncfile;
DoradePARM[] parms = mySweep.getParamList();
int nRays = mySweep.getNRays();
if (debug) System.out.println(parms.length + " params in file");
int numSensor = mySweep.getNSensors();
int [] ncells = new int[numSensor];
Dimension [] gateDim =new Dimension[numSensor];
for(int i = 0; i < numSensor; i++) {
try {
int j = i + 1;
ncells[i] = mySweep.getNCells(i);
gateDim[i] = new Dimension("gate_"+j, ncells[i]);
ncfile.addDimension( null, gateDim[i]);
} catch (Exception ex) {
ex.printStackTrace();
}
}
ArrayList [] dims = new ArrayList[numSensor];
ArrayList dims1 = new ArrayList();
ArrayList [] dims2 = new ArrayList[numSensor];
int nCells = mySweep.getNCells(0);
// Dimension sensorDim = new Dimension("sensor", numSensor, true);
// ncfile.addDimension( null, sensorDim);
Dimension radialDim = new Dimension("radial", nRays);
ncfile.addDimension( null, radialDim);
for(int i = 0; i < numSensor; i++) {
dims[i] = new ArrayList();
dims2[i] = new ArrayList();
dims[i].add( radialDim );
dims[i].add( gateDim[i]);
dims2[i].add( gateDim[i]);
}
// dims1.add( sensorDim);
dims1.add( radialDim);
float [][] altitudes = new float [numSensor][];
float [][] latitudes = new float [numSensor][];
float [][] longitudes = new float [numSensor][];
lat_min = new float[numSensor];
lat_max = new float[numSensor];
lon_min = new float[numSensor];
lon_max = new float[numSensor];
hi_min = new float[numSensor];
hi_max = new float[numSensor];
MAMath.MinMax [] latMinMax = new MAMath.MinMax[numSensor];
MAMath.MinMax [] lonMinMax = new MAMath.MinMax[numSensor];
MAMath.MinMax [] hiMinMax = new MAMath.MinMax[numSensor];
boolean [] isMoving = new boolean[numSensor];
for(int i = 0; i < numSensor; i++) {
try {
int nc = mySweep.getNCells(i);
altitudes[i] = new float [nRays];
latitudes[i] = new float [nRays];
longitudes[i] = new float [nRays];
isMoving[i] = mySweep.sensorIsMoving(i);
altitudes[i] = mySweep.getAltitudes(i);
latitudes[i] = mySweep.getLatitudes(i);
longitudes[i] = mySweep.getLongitudes(i);
} catch (Exception ex) {
ex.printStackTrace();
}
latMinMax[i] = getMinMaxData( latitudes[i]);
lonMinMax[i] = getMinMaxData( longitudes[i]);
hiMinMax[i] = getMinMaxData( altitudes[i]);
float dis = (float )((mySweep.getRangeToFirstCell(i) + (mySweep.getNCells(i)-1) * mySweep.getCellSpacing(i) ) * 1.853 / 111.26 /1000);
lat_min[i] = (float )(latMinMax[i].min - dis);
lat_max[i] = (float )(latMinMax[i].max + dis);
lon_min[i] = (float )(lonMinMax[i].min + dis * Math.cos(latitudes[i][0]));
lon_max[i] = (float )(lonMinMax[i].max - dis * Math.cos(latitudes[i][0]));
hi_min[i] = (float )hiMinMax[i].min;
hi_max[i] = (float )hiMinMax[i].max;
}
//adding the global nc attribute
addNCAttributes(ncfile, mySweep);
// add elevation coordinate variable
String vName = "elevation";
String lName = "elevation angle in degres: 0 = parallel to pedestal base, 90 = perpendicular";
Attribute att = new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString());
addParameter(vName, lName, ncfile, dims1, att, DataType.FLOAT, "degrees");
// add azimuth coordinate variable
vName = "azimuth";
lName = "azimuth angle in degrees: 0 = true north, 90 = east";
att = new Attribute(_Coordinate.AxisType, AxisType.RadialAzimuth.toString());
addParameter(vName, lName, ncfile, dims1, att, DataType.FLOAT, "degrees");
// add gate coordinate variable
for (int i = 0; i < numSensor; i++) {
int j = i + 1;
vName = "distance_"+j;
lName = "Radial distance to the start of gate";
att = new Attribute(_Coordinate.AxisType, AxisType.RadialDistance.toString());
addParameter(vName, lName, ncfile, dims2[i], att, DataType.FLOAT, "meters");
}
// add radial coordinate variable
for (int i = 0; i < numSensor; i++) {
int j = i + 1;
vName = "latitudes_" + j;
lName = "Latitude of the instrument " + j;
att = new Attribute(_Coordinate.AxisType, AxisType.Lat.toString());
addParameter(vName, lName, ncfile, dims1, att, DataType.FLOAT, "degrees");
vName = "longitudes_" + j;
lName = "Longitude of the instrument " + j;
att = new Attribute(_Coordinate.AxisType, AxisType.Lon.toString());
addParameter(vName, lName, ncfile, dims1, att, DataType.FLOAT, "degrees");
vName = "altitudes_" + j;
lName = "Altitude in meters (asl) of the instrument " + j;
att = new Attribute(_Coordinate.AxisType, AxisType.Height.toString());
addParameter(vName, lName, ncfile, dims1, att, DataType.FLOAT, "meters");
vName = "rays_time";
lName = "rays time";
att = new Attribute(_Coordinate.AxisType, AxisType.Time.toString());
addParameter(vName, lName, ncfile, dims1, att, DataType.DOUBLE, "milliseconds since 1970-01-01 00:00 UTC");
}
vName = "Range_to_First_Cell";
lName = "Range to the center of the first cell";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "meters");
vName = "Cell_Spacing";
lName = "Distance between cells";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "meters");
vName = "Fixed_Angle";
lName = "Targeted fixed angle for this scan";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "degrees");
vName = "Nyquist_Velocity";
lName = "Effective unambigous velocity";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "m/s");
vName = "Unambiguous_Range";
lName = "Effective unambigous range";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "meters");
vName = "Radar_Constant";
lName = "Radar constant";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "c");
vName = "rcvr_gain";
lName = "Receiver Gain";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "db");
vName = "ant_gain";
lName = "Antenna Gain";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "db");
vName = "sys_gain";
lName = "System Gain";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "db");
vName = "bm_width";
lName = "Beam Width";
addParameter(vName, lName, ncfile, null, null, DataType.FLOAT, "degrees");
/* Variable ct = new Variable(ncfile, null, null, "radialCoordinateTransform");
ct.setDataType(DataType.CHAR);
ct.setDimensions(""); // scalar
ct.addAttribute( new Attribute("transform_type", "Radial"));
ct.addAttribute( new Attribute("_CoordinateTransformType", "Radial"));
ct.addAttribute( new Attribute("_CoordinateAxes", "elevation azimuth distance_1"));
ncfile.addVariable(null, ct); */
try {
for (int p = 0; p < parms.length; p++) {
String pval = parms[p].getDescription();
nCells = parms[p].getNCells();
int ii = getGateDimsIndex(nCells, gateDim, numSensor);
if (debug) System.out.println("Param "+ p+ " name "+pval+" and ncel "+ nCells);
addVariable(ncfile, dims[ii], parms[p]);
}
} catch (Exception ex) {
ex.printStackTrace();
}
// finish
ncfile.finish();
}
public MAMath.MinMax getMinMaxData( float[] data) {
int[] shape = new int[1];
shape[0] = data.length;
Array a = Array.factory( DataType.FLOAT.getPrimitiveClassType(), shape, data);
return MAMath.getMinMax( a);
}
int getGateDimsIndex(int cell, Dimension [] dList, int numSensor)
{
int j = 0;
for(int i = 0; i < numSensor; i++) {
Dimension d = new Dimension("gate_"+i, cell);
if( dList[i].equals(d)) {
j = i;
break;
}
}
return j;
}
private void makeCoordinateData(Variable elev, Variable azim, DoradeSweep mySweep) {
Object ele = (Object) mySweep.getElevations();
Object azi = (Object) mySweep.getAzimuths();
Array elevData = Array.factory( elev.getDataType().getPrimitiveClassType(), elev.getShape(), ele);
Array aziData = Array.factory( azim.getDataType().getPrimitiveClassType(), azim.getShape(), azi);
elev.setCachedData( elevData, false);
azim.setCachedData( aziData, false);
}
void addParameter(String pName, String longName, NetcdfFile nc, ArrayList dims, Attribute att, DataType dtype, String ut)
{
String vName = pName;
Variable vVar = new Variable(nc, null, null, vName);
vVar.setDataType(dtype);
if( dims != null ) vVar.setDimensions(dims);
else vVar.setDimensions("");
if(att != null ) vVar.addAttribute(att);
vVar.addAttribute( new Attribute(CDM.UNITS, ut));
vVar.addAttribute( new Attribute(CDM.LONG_NAME, longName));
nc.addVariable(null, vVar);
}
void addVariable(NetcdfFile nc, ArrayList dims, DoradePARM dparm)
{
Variable v = new Variable(nc, null, null, dparm.getName() );
v.setDataType( DataType.FLOAT );
v.setDimensions(dims);
ncfile.addVariable(null, v);
v.addAttribute( new Attribute(CDM.LONG_NAME, dparm.getDescription()));
v.addAttribute( new Attribute(CDM.UNITS, dparm.getUnits()));
String coordinates = "elevation azimuth distance_1 " + "latitudes_1 longitudes_1 altitudes_1";
v.addAttribute( new Attribute(_Coordinate.Axes, coordinates));
/*
v.addAttribute( new Attribute(CDM.MISSING_VALUE, new Float(dparm.getBadDataFlag())));
v.addAttribute( new Attribute("_FillValue", new Float(dparm.getBadDataFlag())));
v.addAttribute( new Attribute("scale_factor", dparm.getUnits()));
v.addAttribute( new Attribute("polarization", dparm.getUnits()));
v.addAttribute( new Attribute("Frequencies_GHz", dparm.getUnits()));
v.addAttribute( new Attribute("InterPulsePeriods_secs", dparm.getUnits()));
v.addAttribute( new Attribute("ThresholdValue", new Float(dparm.getThresholdValue())));
v.addAttribute( new Attribute("ThresholdParamName", dparm.getthresholdParamName()));
v.addAttribute( new Attribute("usedPRTs", new Integer(dparm.getusedPRTs())));
v.addAttribute( new Attribute("usedFrequencies", new Integer(dparm.getusedFrequencies())));
*/
}
void addNCAttributes(NetcdfFile nc, DoradeSweep mySweep) throws DoradeSweep.DoradeSweepException
{
nc.addAttribute(null, new Attribute("summary", "Dorade radar data " +
"from radar " + mySweep.getSensorName(0) + " in the project " + mySweep.getProjectName()));
nc.addAttribute(null, new Attribute("radar_name", mySweep.getSensorName(0)));
nc.addAttribute(null, new Attribute("project_name", mySweep.getProjectName()));
nc.addAttribute(null, new Attribute("keywords_vocabulary", "dorade"));
nc.addAttribute(null, new Attribute("geospatial_lat_min", new Float(lat_min[0])));
nc.addAttribute(null, new Attribute("geospatial_lat_max", new Float(lat_max[0])));
nc.addAttribute(null, new Attribute("geospatial_lon_min", new Float(lon_min[0])));
nc.addAttribute(null, new Attribute("geospatial_lon_max", new Float(lon_max[0])));
nc.addAttribute(null, new Attribute("geospatial_vertical_min", new Float(lon_min[0])));
nc.addAttribute(null, new Attribute("geospatial_vertical_max", new Float(lon_max[0])));
Date [] dd = mySweep.getTimes();
nc.addAttribute(null, new Attribute("time_coverage_start", dd[0].toString()));
nc.addAttribute(null, new Attribute("time_coverage_end", dd[dd.length-1].toString()));
nc.addAttribute(null, new Attribute("Content", "This file contains one scan of remotely sensed data"));
nc.addAttribute(null, new Attribute(CDM.CONVENTIONS, _Coordinate.Convention));
nc.addAttribute(null, new Attribute(CF.FEATURE_TYPE, FeatureType.RADIAL.toString()));
nc.addAttribute(null, new Attribute("format", "Unidata/netCDF/Dorade"));
nc.addAttribute(null, new Attribute("Radar_Name", mySweep.getSensorName(0)));
nc.addAttribute(null, new Attribute("Project_name", ""+mySweep.getProjectName()));
nc.addAttribute(null, new Attribute("VolumeCoveragePatternName", mySweep.getScanMode(0).getName()));
nc.addAttribute(null, new Attribute("Volume_Number", ""+mySweep.getVolumnNumber()));
nc.addAttribute(null, new Attribute("Sweep_Number", ""+mySweep.getSweepNumber()));
nc.addAttribute(null, new Attribute("Sweep_Date",
mySweep.formatDate(mySweep.getTime())));
if(mySweep.sensorIsMoving(0) == true)
nc.addAttribute(null, new Attribute("IsStationary", "0"));
else
nc.addAttribute(null, new Attribute("IsStationary", "1"));
}
// Return the string of entity ID for the Dorade image file
DataType getDataType(int format)
{
DataType p;
switch(format)
{
case 1: // 8-bit signed integer format.
p = DataType.SHORT;
break;
case 2: // 16-bit signed integer format.
p = DataType.FLOAT;
break;
case 3: // 32-bit signed integer format.
p = DataType.LONG;
break;
case 4: // 32-bit IEEE float format.
p = DataType.FLOAT;
break;
case 5: // 16-bit IEEE float format.
p = DataType.DOUBLE;
break;
default:
p = null;
break;
} //end of switch
return p;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/* Change History:
$Log: Doradeheader.java,v $
Revision 1.5 2006/04/19 20:24:09 yuanho
radial dataset sweep for all radar dataset
Revision 1.4 2005/08/08 22:45:32 yuanho
spelling bug fix
Revision 1.3 2005/08/03 21:50:45 yuanho
called IsDoradeSweep to check input file, adding global atts.
Revision 1.2 2005/05/11 00:10:03 caron
refactor StuctureData, dt.point
Revision 1.1 2005/04/26 19:39:06 yuanho
iosp for dorade format radar data
Revision 1.8 2004/12/15 22:35:25 caron
add _unsigned
Revision 1.7 2004/12/07 22:13:28 yuanho
add phyElem for 1hour and total precipitation
Revision 1.6 2004/12/07 22:13:15 yuanho
add phyElem for 1hour and total precipitation
Revision 1.5 2004/12/07 01:29:31 caron
redo convention parsing, use _Coordinate encoding.
Revision 1.4 2004/10/29 00:14:11 caron
no message
Revision 1.3 2004/10/19 15:17:22 yuanho
Dorade header DxKm update
Revision 1.2 2004/10/15 23:18:34 yuanho
Dorade projection update
Revision 1.1 2004/10/13 22:57:57 yuanho
no message
Revision 1.4 2004/08/16 20:53:45 caron
2.2 alpha (2)
Revision 1.3 2004/07/12 23:40:17 caron
2.2 alpha 1.0 checkin
Revision 1.2 2004/07/06 19:28:10 caron
pre-alpha checkin
Revision 1.1.1.1 2003/12/04 21:05:27 caron
checkin 2.2
*/
© 2015 - 2024 Weber Informatics LLC | Privacy Policy