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

ucar.nc2.dt.radial.Netcdf2Dataset Maven / Gradle / Ivy

Go to download

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!
/*
 * 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.dt.radial;

import ucar.nc2.dt.*;
import ucar.nc2.dataset.*;
import ucar.nc2.constants.*;
import ucar.nc2.time.CalendarDateUnit;
import ucar.nc2.units.DateUnit;
import ucar.nc2.VariableSimpleIF;
import ucar.nc2.Variable;
import ucar.nc2.Attribute;
import ucar.nc2.Dimension;
import ucar.ma2.*;
import ucar.ma2.DataType;

import java.io.IOException;
import java.util.*;

/**
 * User: yuanho
 * Date: Jun 7, 2007
 * Time: 10:36:52 AM
 */
public class Netcdf2Dataset extends RadialDatasetSweepAdapter implements TypedDatasetFactoryIF {
    private NetcdfDataset ds;
    private boolean isVolume;
    private double latv, lonv, elev;

    /////////////////////////////////////////////////
    // TypedDatasetFactoryIF
  public boolean isMine(NetcdfDataset ds) {
    String format = ds.findAttValueIgnoreCase(null, "format", null);
    if(format != null) {
        if(format.startsWith("nssl/netcdf"))
            return true;
    }

    Dimension az = ds.findDimension("Azimuth");
    Dimension gt = ds.findDimension("Gate");

    if ((null != az) && (null !=  gt)) {
        return true;
    }
        return false;
    }

    public TypedDataset open(NetcdfDataset ncd, ucar.nc2.util.CancelTask task, StringBuilder errlog) throws IOException {
        return new Netcdf2Dataset(ncd);
    }

    public FeatureType getScientificDataType() { return FeatureType.RADIAL; }


    public Netcdf2Dataset() {}

    /**
     * Constructor.
     *
     * @param ds must be from netcdf IOSP
     */
    public Netcdf2Dataset(NetcdfDataset ds) {
        super(ds);
        this.ds = ds;
        desc = "Netcdf/NCML 2 radar dataset";

        setEarthLocation();
      try {
        setTimeUnits();
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
      setStartDate();
        setEndDate();
        setBoundingBox();

        
        try {
            addCoordSystem(ds);
        } catch ( IOException e ) {
            e.printStackTrace();
        }

    }

    private void addCoordSystem(NetcdfDataset ds) throws IOException {


  //  int time = ds.findGlobalAttributeIgnoreCase("Time").getNumericValue().intValue();
        double ele = 0;
        Attribute attr = ds.findGlobalAttributeIgnoreCase("Elevation");
        if( attr != null )
            ele = attr.getNumericValue().doubleValue();

        // ncml agg add this sweep variable as agg dimension
        Variable sp = ds.findVariable("sweep");

        if(sp ==  null) {
            // add Elevation
            ds.addDimension( null, new Dimension("Elevation", 1 , true));
            String lName = "elevation angle in degres: 0 = parallel to pedestal base, 90 = perpendicular";
            CoordinateAxis v = new CoordinateAxis1D(ds, null, "Elevation", DataType.DOUBLE, "Elevation", "degrees", lName);
            ds.setValues(v, 1, ele, 0);
            v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString()));
            ds.addVariable(null, v);

        }
        else {
            Array spdata = sp.read();
            float [] spd = (float [])spdata.get1DJavaArray(float.class);
            int spsize = spd.length;

            // add Elevation
            ds.addDimension( null, new Dimension("Elevation", spsize , true));
            String lName = "elevation angle in degres: 0 = parallel to pedestal base, 90 = perpendicular";
            CoordinateAxis v = new CoordinateAxis1D(ds, null, "Elevation", DataType.DOUBLE, "Elevation", "degrees", lName);
            //ds.setValues(v, (ArrayList)spdata);
            v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString()));
            ds.addVariable(null, v);


        }
            ds.addAttribute( null, new Attribute("IsRadial", new Integer(1)));
            attr = ds.findGlobalAttributeIgnoreCase("vcp-value");
            String vcp;
            if(attr == null)
                vcp = "11";
            else
                vcp = attr.getStringValue();

            ds.addAttribute( null, new Attribute("VolumeCoveragePatternName", vcp));
            ds.finish();

    }

    public ucar.unidata.geoloc.EarthLocation getCommonOrigin() {
      return origin;
    }

    public String getRadarID() {
        Attribute ga = ds.findGlobalAttribute("radarName-value");
        if(ga != null)
            return ga.getStringValue();
        else
            return "XXXX";
    }

    public boolean isStationary() {
      return true;
    }

    public String getRadarName() {
      return ds.findGlobalAttribute("ProductStationName").getStringValue();
    }

    public String getDataFormat() {
        return "NetCDF Level II";
    }



    public void setIsVolume(NetcdfDataset nds) {
      String format = nds.findAttValueIgnoreCase(null, "volume", null);
      if( format == null) {
             isVolume = false;
          return;
      }
      if (format.equals("true"))
             isVolume = true;
      else
             isVolume = false;
    }

    public boolean isVolume() {
        return isVolume;
    }


   protected void setEarthLocation() {
    Attribute ga = ds.findGlobalAttribute("Latitude");
    if(ga != null )
        latv = ga.getNumericValue().doubleValue();
    else
        latv = 0.0;

    ga = ds.findGlobalAttribute("Longitude");
    if(ga != null)
        lonv = ga.getNumericValue().doubleValue();
    else
        lonv = 0.0;

    ga = ds.findGlobalAttribute("Height");
    if(ga != null)
      elev = ga.getNumericValue().doubleValue();
    else
      elev = 0.0;

    origin = new ucar.unidata.geoloc.EarthLocationImpl(latv, lonv, elev);
  }


    protected void setTimeUnits() throws Exception {
      List axes = ds.getCoordinateAxes();
      for (int i = 0; i < axes.size(); i++) {
        CoordinateAxis axis = (CoordinateAxis) axes.get(i);
        if (axis.getAxisType() == AxisType.Time) {
          String units = axis.getUnitsString();
          dateUnits =  new DateUnit(units);
          calDateUnits = CalendarDateUnit.of(null, units);
          return;
        }
      }
      parseInfo.append("*** Time Units not Found\n");
    }

    protected void setStartDate() {
      String start_datetime = ds.findAttValueIgnoreCase(null, "time_coverage_start", null);
      if (start_datetime != null)
        startDate = DateUnit.getStandardOrISO(start_datetime);
      else
        parseInfo.append("*** start_datetime not Found\n");
    }

    protected void setEndDate() {
      String end_datetime = ds.findAttValueIgnoreCase(null, "time_coverage_end", null);
      if (end_datetime != null)
        endDate = DateUnit.getStandardOrISO(end_datetime);
      else
        parseInfo.append("*** end_datetime not Found\n");
    }

    protected void addRadialVariable(NetcdfDataset nds, Variable var) {
        RadialVariable rsvar = null;
        String vName = var.getShortName() ;
        int rnk = var.getRank();

        setIsVolume(nds);

        if(isVolume && rnk == 3) {
            VariableSimpleIF v = new MyRadialVariableAdapter(vName, var.getAttributes());
            rsvar = makeRadialVariable(nds, v, var);
        } else if(!isVolume && rnk == 2) {
            VariableSimpleIF v = new MyRadialVariableAdapter(vName, var.getAttributes());
            rsvar = makeRadialVariable(nds, v, var);
        }

        if(rsvar != null)
            dataVariables.add(rsvar);
    }

    protected RadialVariable makeRadialVariable(NetcdfDataset nds, VariableSimpleIF v, Variable v0) {
        return  new Netcdf2Variable(nds, v, v0);
    }


    public void clearDatasetMemory() {
        List  rvars = getDataVariables();
        Iterator iter = rvars.iterator();
        while (iter.hasNext()) {
            RadialVariable radVar = (RadialVariable)iter.next();
            radVar.clearVariableMemory();
        }
    }

    public String getInfo() {
      StringBuilder sbuff = new StringBuilder();
      sbuff.append("Netcdfs2Dataset\n");
      sbuff.append(super.getDetailInfo());
      sbuff.append("\n\n");
      sbuff.append(parseInfo.toString());
      return sbuff.toString();
    }

  private class Netcdf2Variable extends MyRadialVariableAdapter implements RadialDatasetSweep.RadialVariable {
      ArrayList sweeps;
      int nsweeps;
      String name;

      private Netcdf2Variable(NetcdfDataset nds, VariableSimpleIF v, Variable v0) {
        super(v.getShortName(), v0.getAttributes());

        sweeps = new ArrayList();
        nsweeps = 0;
        name = v.getShortName();
        int[] shape = v0.getShape();
        int count = v0.getRank() - 1;

        int ngates = shape[count];
        count--;
        int nrays = shape[count];
        count--;

        if(shape.length == 3)
            nsweeps = shape[count];
        else
            nsweeps = 1;

        for(int i = 0; i< nsweeps; i++)
             sweeps.add( new Netcdf2Sweep(v0, i, nrays, ngates)) ;

      }

      public String toString() {
        return name;
      }
      public float[] readAllData() throws IOException {
        Array allData;
        Sweep spn = (Sweep)sweeps.get(0);
        Variable v = spn.getsweepVar();
        try {
           allData = v.read();
        } catch (IOException e) {
             throw new IOException(e.getMessage());
        }
        return (float []) allData.get1DJavaArray(float.class);
      }

      public int getNumSweeps() {
        return nsweeps;
      }


      public Sweep getSweep(int sweepNo) {
        return (Sweep) sweeps.get(sweepNo);
      }



      public void clearVariableMemory() {
           // doing nothing
      }
      //////////////////////////////////////////////////////////////////////
      private class Netcdf2Sweep implements RadialDatasetSweep.Sweep {
        double meanElevation = Double.NaN;
        double meanAzimuth = Double.NaN;
        int sweepno, nrays, ngates;
        Variable sweepVar;

          
        Netcdf2Sweep(Variable v, int sweepno, int rays, int gates)
        {
            this.sweepno = sweepno;
            this.nrays = rays;
            this.ngates = gates;
            this.sweepVar = v;

            //setMeanElevation();
            //setMeanAzimuth();
        }

        public Variable getsweepVar(){
            return sweepVar;
        }

        public float[] readData() throws java.io.IOException {

            Array allData;
            int [] shape = sweepVar.getShape();
            int [] origind = new int[ sweepVar.getRank()];

            if(isVolume) {
                 origind[0] = sweepno;
                 origind[1] = 0;
                 shape[0] = 1;
            }

            try {
              allData = sweepVar.read(origind, shape);
            } catch (InvalidRangeException e) {
              throw new IOException(e.getMessage());
            }
            int nradials = shape[0];
            int ngates = shape[1];
            IndexIterator dataIter = allData.getIndexIterator();
            for (int j = 0; j < nradials; j++) {
                 for(int i = 0; i < ngates; i++) {
                       float tp = dataIter.getFloatNext();
                       if(tp == -32768.0f || tp == -99900.0f) {
                           dataIter.setFloatCurrent(Float.NaN);
                       }
                 }
            }

            return (float []) allData.get1DJavaArray(float.class);
        }

      //  private Object MUTEX =new Object();
      /* read 1d data ngates */
        public float[] readData(int ray) throws java.io.IOException {

            Array rayData;
            int [] shape = sweepVar.getShape();
            int [] origind = new int[ sweepVar.getRank()];

            if(isVolume) {
              origind[0] = sweepno;
              origind[1] = ray;
              shape[0] = 1;
              shape[1] = 1;
            } else {
              shape[0] = 1;
              origind[0] = ray;
            }

            try {
              rayData = sweepVar.read(origind, shape);
            } catch (ucar.ma2.InvalidRangeException e) {
              throw new IOException(e.getMessage());
            }
            int ngates = shape[1];
            IndexIterator dataIter = rayData.getIndexIterator();
            for(int i = 0; i < ngates; i++) {
               float tp = dataIter.getFloatNext();
               if(tp == -32768.0f || tp == -99900.0f) {
                   dataIter.setFloatCurrent(Float.NaN);
               }
            }
            return (float []) rayData.get1DJavaArray(float.class);
        }

        private void setMeanElevation() {

            if(isVolume) {
                try{
                    Variable sp = ds.findVariable("sweep");
                    Array spData = sp.read();
                    float [] spArray = (float [])spData.get1DJavaArray(float.class);
                    meanElevation = spArray[sweepno];
                } catch (IOException e) {
                    e.printStackTrace();
                    meanElevation = 0.0;
                }
            } else {
                Attribute data = ds.findGlobalAttribute("Elevation");
                meanElevation = data.getNumericValue().doubleValue();
            }
        }

        public float getMeanElevation() {
            if( Double.isNaN(meanElevation) )
                setMeanElevation();
            return (float) meanElevation ;
        }

        public double meanDouble(Array a) {
            double sum = 0;
            int size = 0;

            IndexIterator iterA = a.getIndexIterator();
            while (iterA.hasNext()) {
              double s = iterA.getDoubleNext();

              if (! Double.isNaN(s)) {
                sum += s;
                size ++;
              }
            }
            if (size > 0)
                return sum / size;
            else
                return Double.POSITIVE_INFINITY;
        }

        public int getGateNumber() {
            return ngates;
        }

        public int getRadialNumber() {
            return nrays;
        }
        public RadialDatasetSweep.Type getType() {
          return null;
        }

        public ucar.unidata.geoloc.EarthLocation getOrigin(int ray) {
          return origin;
        }

        public Date getStartingTime() {
          return startDate;
        }

        public Date getEndingTime() {
          return endDate;
        }

        public int getSweepIndex() {
           return sweepno;
        }

     // public int getNumGates() {
     //   return ngates;
     // }

        private void setMeanAzimuth() {
           meanAzimuth = 0.0;
        }

        public float getMeanAzimuth() {
            if(Double.isNaN(meanAzimuth))
                setMeanAzimuth();
            return (float) meanAzimuth;
        }

        public boolean isConic() {
          return true;
        }

        public float getElevation(int ray) throws IOException {
           return  (float)meanElevation;
        }

        public float[] getElevation() throws IOException {

            float [] dataValue = new float[nrays];
            for (int i = 0; i < nrays; i++)  {
              dataValue[i] = (float)meanElevation;
            }
            return dataValue;
        }

        public float[] getAzimuth() throws IOException {
            Array aziData = ds.findVariable("Azimuth").read();
            return (float [])aziData.get1DJavaArray(float.class);
        }


        public float getAzimuth(int ray) throws IOException {
            String aziName = "Azimuth";

             try {
                 Array aziData = ds.findVariable(aziName).read();
                 if(isVolume) {
                     int [] aziOrigin = new int[2];
                     aziOrigin[0] = sweepno;
                     aziOrigin[1] = 0;
                     int [] aziShape = {1, getRadialNumber()};
                     aziData = aziData.section(aziOrigin, aziShape);
                 }
                 Index index = aziData.getIndex();
                 return aziData.getFloat(index.set(ray));
             } catch (ucar.ma2.InvalidRangeException e) {
                 throw new IOException(e);
             }
        }


        public float getRadialDistance(int gate) throws IOException {
            float gateStart =  getRangeToFirstGate();
            Variable gateSize =  ds.findVariable("GateWidth");
            float [] data = (float [])gateSize.read().get1DJavaArray(float.class);
            float dist = gateStart + gate*data[0];

            return dist;
        }

        public float getTime(int ray) throws IOException {
            return startDate.getTime();
        }

        public float getBeamWidth() {
            return 0.95f; // degrees, info from Chris Burkhart
        }

        public float getNyquistFrequency() {
            return 0; // LOOK this may be radial specific
        }

        public float getRangeToFirstGate() {
            Attribute firstGate = ds.findGlobalAttributeIgnoreCase("RangeToFirstGate");
            double gateStart = firstGate.getNumericValue().doubleValue();
            return (float)gateStart;
        }

        public float getGateSize() {
            try {
              return getRadialDistance(1) - getRadialDistance(0);
            } catch (IOException e) {
              e.printStackTrace();
              return 0.0f;
            }
        }

        public boolean isGateSizeConstant() {
           return true;
        }

        public void clearSweepMemory() {

        }
      } // Netcdf2Sweep class

    } // Netcdf2Variable

    private static void testRadialVariable(RadialDatasetSweep.RadialVariable rv) throws IOException {
        int nsweep = rv.getNumSweeps();
        //System.out.println("*** radar Sweep number is: \n" + nsweep);
        Sweep sw;
        float [] az;
        for (int i = 0; i < nsweep; i++) {
          //ucar.unidata.util.Trace.call1("LevelII2Dataset:testRadialVariable getSweep " + i);
          sw = rv.getSweep(i);
          sw.getMeanElevation();
          //ucar.unidata.util.Trace.call2("LevelII2Dataset:testRadialVariable getSweep " + i);
          float me = sw.getMeanElevation();
          System.out.println("*** radar Sweep mean elevation of sweep " + i + " is: " + me);
          int nrays = sw.getRadialNumber();
          az = new float[nrays];
          for (int j = 0; j < nrays; j++) {
            float azi = sw.getAzimuth(j);
            az[j] = azi;
          }
          //System.out.println("*** radar Sweep mean elevation of sweep " + i + " is: " + me);
        }
        sw = rv.getSweep(0);
          //ucar.unidata.util.Trace.call1("LevelII2Dataset:testRadialVariable readData");
        float [] ddd = sw.readData();
        sw.getAzimuth();
        sw.getElevation();
          //ucar.unidata.util.Trace.call2("LevelII2Dataset:testRadialVariable readData");
        assert(null != ddd);
        int nrays = sw.getRadialNumber();
        az = new float[nrays];
        for (int i = 0; i < nrays; i++) {

          int ngates = sw.getGateNumber();
          assert(ngates > 0);
          float [] d = sw.readData(i);
          assert(null != d);
         // float [] e = sw.readDataNew(i);
         // assert(null != e);
          float azi = sw.getAzimuth(i);
          assert(azi > 0);
          az[i] = azi;
          float ele = sw.getElevation(i);
          assert(ele > 0);
          float la = (float) sw.getOrigin(i).getLatitude();
          assert(la > 0);
          float lo = (float) sw.getOrigin(i).getLongitude();
          assert(lo > 0);
          float al = (float) sw.getOrigin(i).getAltitude();
          assert(al > 0);
        }
        assert(0 != nrays);
    }
    public static void main(String args[]) throws Exception, IOException, InstantiationException, IllegalAccessException {
      //String fileIn = "/home/yuanho/NIDS/Reflectivity_0.50_20070329-204156.netcdf";
      String fileIn ="/home/yuanho/nssl/netcdf.ncml";

      RadialDatasetSweep rds = (RadialDatasetSweep) TypedDatasetFactory.open( FeatureType.RADIAL, fileIn, null, new StringBuilder());
      //String st = rds.getStartDate().toString();
      //String et = rds.getEndDate().toString();
      //String id = rds.getRadarID();
      //String name = rds.getRadarName();
      rds.getRadarID();
      rds.getDataVariables();
      RadialDatasetSweep.RadialVariable rf = (RadialDatasetSweep.RadialVariable) rds.getDataVariable("Reflectivity");
      rf.getSweep(0);

      testRadialVariable(rf);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy