ucar.atd.dorade.DoradeSweep Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package ucar.atd.dorade;
import ucar.atd.dorade.DoradeDescriptor.DescriptorException;
import ucar.nc2.constants.CDM;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.util.Date;
public class DoradeSweep {
/**
* Bad data value flag
*
* @see #getRayData
*/
public static final float BAD_VALUE = DoradePARM.BAD_VALUE;
DoradeSSWB mySSWB;
DoradeVOLD myVOLD;
DoradeSWIB mySWIB;
boolean littleEndian;
public static class DoradeSweepException extends IOException {
protected DoradeSweepException(String message) {
super(message);
}
protected DoradeSweepException(Exception ex) {
super(ex);
}
}
public static class MovingSensorException extends IOException {
protected MovingSensorException(String message) {
super(message);
}
protected MovingSensorException(Exception ex) {
super(ex);
}
}
/**
* Construct a DoradeSweep
using the named DORADE sweep file.
*
* @param filename the DORADE sweepfile to load
* @throws DoradeSweepException
* @throws java.io.FileNotFoundException
*/
public DoradeSweep(String filename)
throws DoradeSweepException, java.io.FileNotFoundException {
try (RandomAccessFile file = new RandomAccessFile(filename, "r")) {
littleEndian = DoradeDescriptor.sweepfileIsLittleEndian(file);
mySSWB = new DoradeSSWB(file, littleEndian);
myVOLD = new DoradeVOLD(file, littleEndian);
mySWIB = new DoradeSWIB(file, littleEndian, myVOLD);
} catch (Exception ex) {
throw new DoradeSweepException(ex);
}
}
public DoradeSweep(RandomAccessFile file)
throws DoradeSweepException, java.io.FileNotFoundException {
//file = new RandomAccessFile(filename, "r");
try {
littleEndian = DoradeDescriptor.sweepfileIsLittleEndian(file);
mySSWB = new DoradeSSWB(file, littleEndian);
myVOLD = new DoradeVOLD(file, littleEndian);
mySWIB = new DoradeSWIB(file, littleEndian, myVOLD);
} catch (Exception ex) {
throw new DoradeSweepException(ex);
}
}
/**
* Is this sweepfile little-endian?
*
* @return a boolean indicating whether the file is little-endian
*/
public boolean isLittleEndian() {
return littleEndian;
}
/**
* Get the array of available parameters.
*
* @return the array of available parameters
*/
public DoradePARM[] getParamList() {
return myVOLD.getParamList();
}
/**
* Get the parameter descriptor with the given name, ignoring case.
* If no such descriptor exists, null
is returned.
*
* @param name the name of the desired parameter
* @return the DoradePARM
from this sweep with the given name,
* or null
if no such parameter exists.
*/
public DoradePARM lookupParamIgnoreCase(String name) {
DoradePARM[] list = getParamList();
for (DoradePARM aList : list) {
if (aList.getName().equalsIgnoreCase(name))
return aList;
}
return null;
}
/**
* Get the number of rays in this sweep.
*
* @return the number of rays in the sweep
*/
public int getNRays() {
return mySWIB.getNRays();
}
/**
* Get the number of sensors associated with this sweep.
*
* @return the number of sensors associated with the sweep
*/
public int getNSensors() {
return myVOLD.getNSensors();
}
/**
* Get the name of a selected sensor.
*
* @param which the index of the sensor of interest
* @return the name of the sensor
* @see #getNSensors
*/
public String getSensorName(int which) {
return myVOLD.getSensorName(which);
}
/**
* Return whether the selected sensor is moving.
*
* @param which the index of the sensor of interest
* @return whether the selected sensor is moving
* @throws DoradeSweepException
* @see #getNSensors
*/
public boolean sensorIsMoving(int which) throws DoradeSweepException {
try {
getLatitude(which);
getLongitude(which);
getAltitude(which);
} catch (MovingSensorException mpex) {
return true;
}
return false;
}
/**
* Get the sensor latitude for a non-moving sensor
*
* @param which the index of the sensor of interest
* @return static latitude in degrees
* @throws MovingSensorException if the sensor is moving
* @see #getLatitudes
* @see #sensorIsMoving
* @see #getNSensors
*/
public float getLatitude(int which) throws MovingSensorException {
//
// Look for per-ray latitudes first. Return the fixed sensor latitude
// if no per-ray positions are available.
//
float[] lats = mySWIB.getLatitudes();
if (lats == null)
return myVOLD.getRADD(which).getLatitude();
//
// We have per-ray locations. Loop through them, and return
// null if this is not a static platform
//
for (int r = 1; r < lats.length; r++)
if (lats[r] != lats[0])
throw new MovingSensorException("sensor is not static");
return lats[0];
}
/**
* Get the sensor longitude for a non-moving sensor
*
* @param which the index of the sensor of interest
* @return static longitude in degrees
* @throws MovingSensorException if the sensor is moving
* @see #getLongitudes
* @see #sensorIsMoving
* @see #getNSensors
*/
public float getLongitude(int which) throws MovingSensorException {
//
// Look for per-ray longitudes first. Return the fixed sensor longitude
// if no per-ray positions are available.
//
float[] lons = mySWIB.getLongitudes();
if (lons == null)
return myVOLD.getRADD(which).getLongitude();
//
// We have per-ray locations. Loop through them, and return
// null if this is not a static platform
//
for (int r = 1; r < lons.length; r++)
if (lons[r] != lons[0])
throw new MovingSensorException("sensor is not static");
return lons[0];
}
/**
* Get the sensor altitude for a non-moving sensor
*
* @param which the index of the sensor of interest
* @return static altitude in km MSL
* @throws MovingSensorException if the sensor is moving
* @see #getAltitudes
* @see #sensorIsMoving
* @see #getNSensors
*/
public float getAltitude(int which) throws MovingSensorException {
//
// Look for per-ray altitudes first. Return the fixed sensor altitude
// if no per-ray positions are available.
//
float[] alts = mySWIB.getAltitudes();
if (alts == null)
return myVOLD.getRADD(which).getAltitude();
//
// We have per-ray locations. Loop through them, and return
// null if this is not a static platform
//
for (int r = 1; r < alts.length; r++)
if (alts[r] != alts[0])
throw new MovingSensorException("sensor is not static");
return alts[0];
}
/**
* Get the per-ray array of sensor latitudes.
*
* @param which the index of the sensor of interest
* @return a per-ray array of sensor latitudes
* @see #getLatitude
* @see #getNSensors
*/
public float[] getLatitudes(int which) {
//
// Try for per-ray location information.
//
float[] lats = mySWIB.getLatitudes();
//
// If we don't have per-ray location information, just replicate
// the sensor fixed latitude.
//
if (lats == null) {
float fixedLat = myVOLD.getRADD(which).getLatitude();
lats = new float[getNRays()];
for (int r = 0; r < getNRays(); r++)
lats[r] = fixedLat;
}
return lats;
}
/**
* Get the per-ray array of sensor longitudes.
*
* @param which the index of the sensor of interest
* @return a per-ray array of sensor longitudes
* @see #getLongitude
* @see #getNSensors
*/
public float[] getLongitudes(int which) {
//
// Try for per-ray location information.
//
float[] lons = mySWIB.getLongitudes();
//
// If we don't have per-ray location information, just replicate
// the sensor fixed latitude.
//
if (lons == null) {
float fixedLon = myVOLD.getRADD(which).getLongitude();
lons = new float[getNRays()];
for (int r = 0; r < getNRays(); r++)
lons[r] = fixedLon;
}
return lons;
}
/**
* Get the per-ray array of sensor altitudes.
*
* @param which the index of the sensor of interest
* @return a per-ray array of sensor altitudes
* @see #getAltitude
* @see #getNSensors
* @see #getNRays
*/
public float[] getAltitudes(int which) {
//
// Try for per-ray location information.
//
float[] alts = mySWIB.getAltitudes();
//
// If we don't have per-ray location information, just replicate
// the sensor fixed altitude.
//
if (alts == null) {
float fixedAlt = myVOLD.getRADD(which).getAltitude();
alts = new float[getNRays()];
for (int r = 0; r < getNRays(); r++)
alts[r] = fixedAlt;
}
return alts;
}
/**
* Get the fixed angle for this sweep.
*
* @return the fixed angle of the sweep, in degrees
*/
public float getFixedAngle() {
return mySWIB.getFixedAngle();
}
// unidata added
public int getSweepNumber() {
return mySWIB.getSweepNumber();
}
/**
* Get the (start) time for this sweep.
*
* @return the start time of the sweep
*/
public Date getTime() {
return mySSWB.getStartTime();
}
// unidata added
public Date[] getTimes() {
return mySWIB.getTimes();
}
// unidata added
public Date getRayTime(int ray) {
return mySWIB.getRayTime(ray);
}
/**
* Get the array of data for the given parameter and ray.
*
* @param param the parameter of interest
* @param ray the index of the ray of interest
* @return an array containing unpacked values for every cell for the given
* parameter and ray. Cells having bad or missing data will hold the
* value BAD_VALUE
* @throws DoradeSweepException
* @see #getNCells
* @see #getNRays
* @see #BAD_VALUE
*/
public float[] getRayData(DoradePARM param, int ray)
throws DoradeSweepException {
return getRayData(param, ray, null);
}
/**
* Get the array of data for the given parameter and ray.
*
* @param param the parameter of interest
* @param ray the index of the ray of interest
* @param workingArray If non-null and the same length as what is needed use this instead.
* @return an array containing unpacked values for every cell for the given
* parameter and ray. Cells having bad or missing data will hold the
* value BAD_VALUE
* @throws DoradeSweepException
* @see #getNCells
* @see #getNRays
* @see #BAD_VALUE
*/
public float[] getRayData(DoradePARM param, int ray, float[] workingArray)
throws DoradeSweepException {
try {
return mySWIB.getRayData(param, ray, workingArray);
} catch (DescriptorException ex) {
throw new DoradeSweepException(ex);
}
}
/**
* Get the range to the leading edge of the first cell for the given sensor.
*
* @param which index of the sensor of interest
* @return range to the leading edge of the first cell for the given sensor,
* in meters
* @see #getNSensors
*/
public float getRangeToFirstCell(int which) {
return myVOLD.getRADD(which).getRangeToFirstCell();
}
/**
* Return the cell spacing for the given sensor, if constant, otherwise
* return -1
*
* @param which index of the sensor of interest
* @return the constant cell spacing in meters, or -1 if the cell spacing
* varies
* @see #getNSensors
*/
public float getCellSpacing(int which) {
try {
return myVOLD.getRADD(which).getCellSpacing();
} catch (DescriptorException ex) {
return -1;
}
}
/**
* Get the number of data cells (gates) per ray for the given sensor.
*
* @param which index of the sensor of interest
* @return the number of cells per ray for the given sensor
* @see #getNSensors
*/
public int getNCells(int which) {
return myVOLD.getRADD(which).getNCells();
}
public short getVolumnNumber() {
return myVOLD.getVolumeNumber();
}
public String getProjectName() {
return myVOLD.getProjectName();
}
/**
* Get the azimuths for all rays in the sweep.
*
* @return array of azimuths for all rays in the sweep, in degrees
* @see #getNRays
*/
public float[] getAzimuths() {
return mySWIB.getAzimuths();
}
/**
* Get the elevations for all rays in the sweep.
*
* @return array of elevations for all rays in the sweep, in degrees
* @see #getNRays
*/
public float[] getElevations() {
return mySWIB.getElevations();
}
/**
* Return a string with a reasonable representation in UTC of the
* given Date
.
*
* @param date Date
to be represented
* @return a string containing a UTC representation of the date
*/
public static String formatDate(Date date) {
return DoradeDescriptor.formatDate(date);
}
/**
* DoradeSweep
class test method. Usage:
*
* $ java ucar.atd.dorade.DoradeSweep <DORADE_sweepfile>
*
*/
public static void main(String[] args) {
try {
if (args.length == 0) {
System.err.println("Usage: DoradeSweep ");
System.exit(1);
}
DoradeSweep sweepfile = new DoradeSweep(args[0]);
DoradePARM[] params = sweepfile.getParamList();
System.out.println(params.length + " params in file");
for (DoradePARM param : params) mainGetParam(sweepfile, param);
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static void mainGetParam(DoradeSweep sweepfile, DoradePARM param) throws DoradeSweepException {
System.out.print("getting " + param.getName());
for (int r = 0; r < sweepfile.getNRays(); r++) {
float[] vals = sweepfile.getRayData(param, r);
int nCells = vals.length;
if (r == 0)
System.out.println(" (" + nCells + " cells x " +
sweepfile.getNRays() + " rays)");
}
}
public ScanMode getScanMode() {
return myVOLD.getRADD(0).getScanMode();
}
// unidata added
public static boolean isDoradeSweep(RandomAccessFile file) throws DoradeSweepException {
try {
if (findName(file, "SSWB") || findName(file, "COMM"))
return true;
} catch (Exception ex) {
throw new DoradeSweepException(ex);
}
return false;
}
// Unidata added: finding the first 4 byte for string matching
private static boolean findName(RandomAccessFile file, String expectedName) throws IOException {
byte[] nameBytes = new byte[4];
//try {
long filepos = file.getFilePointer();
file.seek(0);
if (file.read(nameBytes, 0, 4) == -1)
return false; // EOF
file.seek(filepos);
//} catch (Exception ex) {
// throw new IOException();
//}
return expectedName.equals(new String(nameBytes, CDM.utf8Charset));
}
// unidata added
public ScanMode getScanMode(int which) {
return myVOLD.getRADD(which).getScanMode();
}
// unidata added
public float getUnambiguousVelocity(int which) {
return myVOLD.getRADD(which).getUnambiguousVelocity();
}
//unidata added
public float getunambiguousRange(int which) {
return myVOLD.getRADD(which).getunambiguousRange();
}
// unidata added
public float getradarConstant(int which) {
return myVOLD.getRADD(which).getradarConstant();
}
// unidata added
public float getrcvrGain(int which) {
return myVOLD.getRADD(which).getrcvrGain();
}
// unidata added
public float getantennaGain(int which) {
return myVOLD.getRADD(which).getantennaGain();
}
// unidata added
public float getsystemGain(int which) {
return myVOLD.getRADD(which).getsystemGain();
}
// unidata added
public float gethBeamWidth(int which) {
return myVOLD.getRADD(which).gethBeamWidth();
}
// unidata added
public float getpeakPower(int which) {
return myVOLD.getRADD(which).getpeakPower();
}
// unidata added
public float getnoisePower(int which) {
return myVOLD.getRADD(which).getnoisePower();
}
}