All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy