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

ucar.nc2.iosp.nowrad.NOWRadheader Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
 * See LICENSE for license information.
 */



package ucar.nc2.iosp.nowrad;

//~--- non-JDK imports --------------------------------------------------------

import ucar.ma2.Array;
import ucar.ma2.DataType;
import ucar.nc2.Attribute;
import ucar.nc2.Dimension;
import ucar.nc2.Variable;
import ucar.nc2.constants.AxisType;
import ucar.nc2.constants.CDM;
import ucar.nc2.constants.FeatureType;
import ucar.nc2.constants._Coordinate;
import ucar.nc2.units.DateFormatter;
import ucar.unidata.geoloc.LatLonPointImpl;
import ucar.unidata.geoloc.ProjectionImpl;
import ucar.unidata.geoloc.ProjectionPointImpl;
import ucar.unidata.geoloc.projection.LambertConformal;
import ucar.unidata.util.Parameter;
import ucar.unidata.util.StringUtil2;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * Created by IntelliJ IDEA.
 * User: yuanho
 * Date: Feb 10, 2010
 * Time: 11:21:19 AM
 * To change this template use File | Settings | File Templates.
 */
public class NOWRadheader {
    final static int                NEXET        = 2;        // Echo Tops Composite
    final static int                NEXLH        = 5;        // Layer Reflectivity - High
    final static int                NEXLL        = 3;        // Layer Reflectivity - Low
    final static int                NEXLM        = 4;        // Layer Reflectivity - Mid
    final static int                NEXVI        = 6;        // Vert. Integrated Liquid Water
    final static int                NOWRADHF     = 0;        // 2km Base Reflectivity
    final static int                USRADHF      = 1;        // 8km Base Reflectivity
    static public String            mons[]       = {
        "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
    };
    static private org.slf4j.Logger log          = org.slf4j.LoggerFactory.getLogger(NOWRadheader.class);
    DateFormatter                   formatter    = new DateFormatter();

    // private PrintStream out = System.out;
    // private Vinfo myInfo;
    private String              cmemo, ctilt, ctitle, cunit, cname;
    private ucar.nc2.NetcdfFile ncfile;

    // message header block
    // production dessciption block
    private int                              numX;
    private int                              numY;
    ucar.unidata.io.RandomAccessFile raf;

    /**
     * check if this file is a nids / tdwr file
     * @param raf    input file
     * @return  true  if valid
     */
    public boolean isValidFile(ucar.unidata.io.RandomAccessFile raf) {
        try {
            long t = raf.length();

            if (t == 0) {
                throw new IOException("zero length file ");
            }
             
        } catch (IOException e) {
            return (false);
        }

        try {
            int p = this.readTop(raf);

            if (p == 0) {
                return false;
            }
        } catch (IOException e) {
            return (false);
        }

        return true;
    }

    /**
     * read the header of input file and parsing the NOWRAD part
     * @param raf    input file
     * @return        1 if checking passing
     * @throws IOException
     */
    int readTop(ucar.unidata.io.RandomAccessFile raf) throws IOException {
        int pos = 0;

        // long     actualSize = 0;
        raf.seek(pos);

        int readLen = 35;

        // Read in the contents of the NEXRAD Level III product head
        byte[] b = new byte[readLen];

        int rc = raf.read(b);

        if (rc != readLen) {
            return 0;
        }

        // check
        if ((convertunsignedByte2Short(b[0]) != 0x00) || (convertunsignedByte2Short(b[1]) != 0xF0)
                || (convertunsignedByte2Short(b[2]) != 0x09)) {
            return 0;
        }

        String pidd  = new String(b, 15, 5, CDM.utf8Charset);

        if (pidd.contains("NOWRA") || pidd.contains("USRAD") || pidd.contains("NEX")) {
            return 1;
        } else {
            return 0;
        }
    }

    public byte[] getData(int offset) throws IOException {
        int    readLen = (int) raf.length();
        byte[] b       = new byte[readLen];
        int    pos     = 0;

        raf.seek(pos);
        raf.readFully(b);

        return b;
    }

    // ////////////////////////////////////////////////////////////////////////////////

    public void setProperty(String name, String value) {}

    /**
     * read and parse the header of the nids/tdwr file
     * @param raf       input file
     * @param ncfile    output file
     * @throws IOException
     */
    void read(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile) throws Exception {
        this.raf = raf;

        int rc;    /* function return status */
        int hoffset;
        int readLen = 250;

        this.ncfile = ncfile;

        int pos = 0;

        raf.seek(pos);

        byte[] b = new byte[readLen];

        rc = raf.read(b);

        if (rc != readLen) {
            log.warn(" error reading nids product header " + raf.getLocation());
        }

        int    hsize   = b[3];
        String product = new String(b, 15, 8, CDM.utf8Charset);

        // image lines
        //byte[] bt   = new byte[] { (byte) 0xF0, (byte) 0x0A };
        int    t1 = 0  ;
        int ii = 0;
        for(int i = 0; i < readLen; i++ ){
            if(convertunsignedByte2Short(b[i+hsize]) == 0xF0 &&
                     convertunsignedByte2Short(b[i+1+hsize]) == 0x0A ){
                t1 = i + hsize;
                ii = i;
                break;
            }
        }
        if(t1 == 0)
            return;
        // if(convertunsignedByte2Short(b[6+hsize]) != 0xF0 ||
        // convertunsignedByte2Short(b[7+hsize]) != 0x0A )
        // return;
        String lstr = trim(new String(b, t1 + 2, 4, CDM.utf8Charset));

        numY = Integer.parseInt(lstr);

        String estr = trim(new String(b, t1 + 6, 5, CDM.utf8Charset));

        numX = Integer.parseInt(estr);
        //bt   = new byte[] { (byte) 0xF0, (byte) 0x03 };

        t1   = 0;
        for(int i = ii; i < readLen; i++ ){
            if(convertunsignedByte2Short(b[i+hsize]) == 0xF0 &&
                    convertunsignedByte2Short(b[i+1+hsize]) == 0x03 ){
                t1 = i + hsize;
                ii = i;
                break;
            }
        }
        if(t1 == 0)
            return;
        // if((lstr.length()+estr.length() < 8))
        // hsize = hsize -2;

        // if(convertunsignedByte2Short(b[18+hsize]) != 0xF0 ||
        // convertunsignedByte2Short(b[19+hsize]) != 0x03 )
        // return;
        int    off = 0;

        if (product.contains("USRADHF")) {
            off = 3;
        }

        // Image time, HHMMSS.  The time will be in the form HH:MM, so look :
        String ts = new String(b, t1 + 22 + off, 2, CDM.utf8Charset);
        int    hr = Integer.parseInt(ts);

        ts = new String(b, t1 + 25 + off, 2, CDM.utf8Charset);

        int min = Integer.parseInt(ts);

        ts = new String(b, t1 + 28 + off, 2, CDM.utf8Charset);

        int dd = Integer.parseInt(ts);

        ts = new String(b, t1 + 31 + off, 3, CDM.utf8Charset);

        String mon   = ts;
        int    month = getMonth(mon);

        ts = new String(b, t1 + 35 + off, 2, CDM.utf8Charset);

        int              year = Integer.parseInt(ts);
        SimpleDateFormat sdf  = new SimpleDateFormat();

        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        sdf.applyPattern("yyyy/MM/dd HH:mm");

        Date   date = sdf.parse(year + "/" + month + "/" + dd + " " + hr + ":" + min);

        //bt = new byte[] { (byte) 0xF0, (byte) 0x0b };
        t1 = 0;

        for(int i = ii; i < readLen; i++ ){
            if(convertunsignedByte2Short(b[i+hsize]) == 0xF0 &&
                    convertunsignedByte2Short(b[i+1+hsize]) == 0x0b ) {
                t1 = i + hsize;
                break;
            }
        }
        if(t1 == 0)
            return;
        // if( convertunsignedByte2Short(b[101 + hsize]) != 0xF0 ||
        // convertunsignedByte2Short(b[102 + hsize]) != 0x0b )
        // return;
        if (product.contains("NOWRAD")) {
            String ot = new String(b, t1 + 2, 68, CDM.utf8Charset);

            //List toks = StringUtil.split(ot, " ", true, true);
            String[] toks = StringUtil2.splitString(ot);
            double       nav1 = Math.toDegrees(Double.parseDouble(toks[1]));    // lon
            double       nav2 = Math.toDegrees(Double.parseDouble(toks[2]));    // lat
            double       nav3 = Math.toDegrees(Double.parseDouble(toks[3]));
            double       nav4 = Math.toDegrees(Double.parseDouble(toks[4]));    // lat sp
            double       nav5 = Math.toDegrees(Double.parseDouble(toks[5]));    // lon sp

            // lower left and upper right corner
            float rlat1;
            float rlon1;
            float rlat2;
            float rlon2;

            rlat1   = (float) (nav2 - (numY - 1) * nav4);
            rlon1   = (float) (nav1 + nav3);
            rlat2   = (float) nav2;
            rlon2   = (float) (nav1 - nav3);
            hoffset = t1 + 71;    // 172 + hsize;

            // start of the image sequence
            if ((convertunsignedByte2Short(b[172 + hsize]) != 0xF0)
                    || (convertunsignedByte2Short(b[173 + hsize]) != 0x0c)) {
                return;
            }

            // hoffset = 174 + hsize;
            // Set product-dependent information
            setProductInfo(product, date);

            // data struct
            nowrad(hoffset, rlat1, rlon1, rlat2, rlon2, (float) nav4, (float) nav5, date);
        } else if (product.contains("USRADHF")) {
            String ot = new String(b, t1 + 2, 107, CDM.utf8Charset);

            String[] toks = StringUtil2.splitString(ot);
            double       nav1 = Math.toDegrees(Double.parseDouble(toks[1]));    // standard lat 1
            double       nav2 = Math.toDegrees(Double.parseDouble(toks[2]));    // standard lat 2
            double       nav3 = Math.toDegrees(Double.parseDouble(toks[3]));    // lat. center of proj
            double       nav4 = Math.toDegrees(Double.parseDouble(toks[4]));    // lon. center of proj
            double       nav5 = Math.toDegrees(Double.parseDouble(toks[5]));    // upper left lat
            double       nav6 = Math.toDegrees(Double.parseDouble(toks[6]));    // upper left lon

            /* List toks = StringUtil.split(ot, " ", true, true);
            String       pj   = toks.get(0);
            double       nav1 = Math.toDegrees(Double.parseDouble(toks.get(1)));    // standard lat 1
            double       nav2 = Math.toDegrees(Double.parseDouble(toks.get(2)));    // standard lat 2
            double       nav3 = Math.toDegrees(Double.parseDouble(toks.get(3)));    // lat. center of proj
            double       nav4 = Math.toDegrees(Double.parseDouble(toks.get(4)));    // lon. center of proj
            double       nav5 = Math.toDegrees(Double.parseDouble(toks.get(5)));    // upper left lat
            double       nav6 = Math.toDegrees(Double.parseDouble(toks.get(6)));    // upper left lon
            double       nav7 = Math.toDegrees(Double.parseDouble(toks.get(7)));    // lat sp
            double       nav8 = Math.toDegrees(Double.parseDouble(toks.get(8)));    // lon sp  */

            // lower left and upper right corner
            // int offh = 39;
            hoffset = t1 + 110;    // 172 + hsize+ offh;

            // start of the image sequence
            if ((convertunsignedByte2Short(b[t1 + 110]) != 0xF0) || (convertunsignedByte2Short(b[t1 + 111]) != 0x0c)) {
                return;
            }

            // Set product-dependent information
            setProductInfo(product, date);

            // data struct
            nowradL(hoffset, (float) nav1, (float) nav2, (float) nav3, (float) nav4, (float) nav5, (float) nav6, date);
        }


        ncfile.finish();
    }

    String trim(String str) {
        int          len  = str.length();
        StringBuilder ostr = new StringBuilder();

        for (int i = 0; i < len; i++) {
            char sc = str.charAt(i);

            if (Character.isDigit(sc)) {
                ostr.append(sc);
            }
        }

        return ostr.toString();
    }

    int getMonth(String m) {
        int i = 0;

        while (i < 12) {
            if (m.equalsIgnoreCase(mons[i])) {
                return i + 1;
            } else {
                i++;
            }
        }

        return 0;
    }

    ProjectionImpl  nowradL(int hoff, float lat1, float lat2, float clat, float clon, float lat, float lon, Date dd) {
        List dims = new ArrayList<>();
        Dimension dimT = new Dimension("time", 1, true, false, false);

        ncfile.addDimension(null, dimT);

        String   timeCoordName = "time";
        Variable taxis         = new Variable(ncfile, null, null, timeCoordName);

        taxis.setDataType(DataType.DOUBLE);
        taxis.setDimensions("time");
        taxis.addAttribute(new Attribute(CDM.LONG_NAME, "time since base date"));
        taxis.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));

        double[] tdata = new double[1];

        tdata[0] = dd.getTime();

        Array dataT = Array.factory(DataType.DOUBLE, new int[] { 1 }, tdata);

        taxis.setCachedData(dataT, false);

        DateFormatter formatter = new DateFormatter();

        taxis.addAttribute(new Attribute(CDM.UNITS, "msecs since " + formatter.toDateTimeStringISO(new Date(0))));
        ncfile.addVariable(null, taxis);
        dims.add(dimT);

        Dimension jDim = new Dimension("y", numY, true, false, false);
        Dimension iDim = new Dimension("x", numX, true, false, false);

        dims.add(jDim);
        dims.add(iDim);
        ncfile.addDimension(null, iDim);
        ncfile.addDimension(null, jDim);
        ncfile.addAttribute(null, new Attribute("cdm_data_type", FeatureType.GRID.toString()));

        String   coordinates = "time y x";
        Variable v           = new Variable(ncfile, null, null, cname);

        v.setDataType(DataType.BYTE);
        v.setDimensions(dims);
        ncfile.addVariable(null, v);
        v.addAttribute(new Attribute(CDM.LONG_NAME, ctitle));
        v.addAttribute(new Attribute(CDM.UNITS, cunit));
        v.addAttribute(new Attribute(CDM.SCALE_FACTOR, 5.0f));
        v.addAttribute(new Attribute(CDM.MISSING_VALUE, 0));
        v.setSPobject(new Vinfo(numX, numY, hoff));
        v.addAttribute(new Attribute(_Coordinate.Axes, coordinates));

        // create coordinate variables
        Variable xaxis = new Variable(ncfile, null, null, "x");

        xaxis.setDataType(DataType.DOUBLE);
        xaxis.setDimensions("x");
        xaxis.addAttribute(new Attribute("standard_name", "projection x coordinate"));
        xaxis.addAttribute(new Attribute(CDM.UNITS, "km"));
        xaxis.addAttribute(new Attribute(_Coordinate.AxisType, "GeoX"));

        double[]       data1      = new double[numX];
        ProjectionImpl projection = new LambertConformal(clat, clon, lat1, lat2);
        double ullat = 51.8294;
        double ullon = -135.8736;
        double lrlat = 17.2454;
        double lrlon = -70.1154;

        ProjectionPointImpl ptul = (ProjectionPointImpl) projection.latLonToProj(new LatLonPointImpl(ullat, ullon));
        ProjectionPointImpl ptlr = (ProjectionPointImpl) projection.latLonToProj(new LatLonPointImpl(lrlat, lrlon));
        double startX = ptul.getX();
        double startY = ptlr.getY();
        double dx = (ptlr.getX() - ptul.getX())/(numX-1);
        for (int i = 0; i < numX; i++) {
            data1[i] = startX + i*dx;
        }

        Array dataA = Array.factory(DataType.DOUBLE, new int[] { numX }, data1);

        xaxis.setCachedData(dataA, false);
        ncfile.addVariable(null, xaxis);

        Variable yaxis = new Variable(ncfile, null, null, "y");

        yaxis.setDataType(DataType.DOUBLE);
        yaxis.setDimensions("y");
        yaxis.addAttribute(new Attribute("standard_name", "projection y coordinate"));
        yaxis.addAttribute(new Attribute(CDM.UNITS, "km"));
        yaxis.addAttribute(new Attribute(_Coordinate.AxisType, "GeoY"));
        data1 = new double[numY];
        double dy = (ptul.getY() - ptlr.getY())/(numY-1);

        for (int i = 0; i < numY; i++) {
            data1[i] = startY + i*dy;
        }

        dataA = Array.factory(DataType.DOUBLE, new int[] { numY }, data1);
        yaxis.setCachedData(dataA, false);
        ncfile.addVariable(null, yaxis);

        // projection
        // lower left and upper right corner lat/lons
        // modified cylind. equidistant or  CED with lat/lon ration != 1
        Variable ct = new Variable(ncfile, null, null, projection.getClassName());

        ct.setDataType(DataType.CHAR);
        ct.setDimensions("");

        List params = projection.getProjectionParameters();

        for (Parameter p : params) {
            ct.addAttribute(new Attribute(p));
        }

        ct.addAttribute(new Attribute(_Coordinate.TransformType, "Projection"));
        //ct.addAttribute(new Attribute(_Coordinate.Axes, "lat lon"));
        ct.addAttribute( new Attribute(_Coordinate.Axes, "x y "));
        // fake data
        dataA = Array.factory(DataType.CHAR, new int[] {});
        dataA.setChar(dataA.getIndex(), ' ');
        ct.setCachedData(dataA, false);
        ncfile.addVariable(null, ct);

        return projection;
    }

    /**
     *  construct a raster dataset for NIDS raster products;
     *
     * @return  soff -- not used
     */
    ProjectionImpl  nowrad(int hoff, float rlat1, float rlon1, float rlat2, float rlon2, float dlat, float dlon, Date dd) {
        List dims = new ArrayList<>();
        Dimension dimT = new Dimension("time", 1, true, false, false);

        ncfile.addDimension(null, dimT);

        String   timeCoordName = "time";
        Variable taxis         = new Variable(ncfile, null, null, timeCoordName);

        taxis.setDataType(DataType.DOUBLE);
        taxis.setDimensions("time");
        taxis.addAttribute(new Attribute(CDM.LONG_NAME, "time since base date"));
        taxis.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));

        double[] tdata = new double[1];

        tdata[0] = dd.getTime();

        Array dataT = Array.factory(DataType.DOUBLE, new int[] { 1 }, tdata);

        taxis.setCachedData(dataT, false);

        DateFormatter formatter = new DateFormatter();

        taxis.addAttribute(new Attribute(CDM.UNITS, "msecs since " + formatter.toDateTimeStringISO(new Date(0))));
        ncfile.addVariable(null, taxis);
        dims.add(dimT);

        Dimension jDim = new Dimension("lat", numY, true, false, false);
        Dimension iDim = new Dimension("lon", numX, true, false, false);

        dims.add(jDim);
        dims.add(iDim);
        ncfile.addDimension(null, iDim);
        ncfile.addDimension(null, jDim);
        ncfile.addAttribute(null, new Attribute("cdm_data_type", FeatureType.GRID.toString()));

        String   coordinates = "time lat lon";
        Variable v           = new Variable(ncfile, null, null, cname);

        v.setDataType(DataType.BYTE);
        v.setDimensions(dims);
        ncfile.addVariable(null, v);
        v.addAttribute(new Attribute(CDM.LONG_NAME, ctitle));
        v.addAttribute(new Attribute(CDM.SCALE_FACTOR, 5.0f));
        v.addAttribute(new Attribute(CDM.MISSING_VALUE, 0));
        v.addAttribute(new Attribute(CDM.UNITS, cunit));
        v.setSPobject(new Vinfo(numX, numY, hoff));
        v.addAttribute(new Attribute(_Coordinate.Axes, coordinates));

        // create coordinate variables
        Variable xaxis = new Variable(ncfile, null, null, "lon");
        xaxis.setDataType(DataType.DOUBLE);
        xaxis.setDimensions("lon");
        xaxis.addAttribute(new Attribute(CDM.LONG_NAME, "longitude"));
        xaxis.addAttribute(new Attribute(CDM.UNITS, "degree"));
        xaxis.addAttribute(new Attribute(_Coordinate.AxisType, "Lon"));

        double[] data1 = new double[numX];

        for (int i = 0; i < numX; i++) {
            data1[i] = (double) (rlon1 + i * dlon);
        }

        Array dataA = Array.factory(DataType.DOUBLE, new int[] { numX }, data1);

        xaxis.setCachedData(dataA, false);
        ncfile.addVariable(null, xaxis);

        Variable yaxis = new Variable(ncfile, null, null, "lat");
        yaxis.setDataType(DataType.DOUBLE);
        yaxis.setDimensions("lat");
        yaxis.addAttribute(new Attribute(CDM.LONG_NAME, "latitude"));
        yaxis.addAttribute(new Attribute(CDM.UNITS, "degree"));
        yaxis.addAttribute(new Attribute(_Coordinate.AxisType, "Lat"));
        data1 = new double[numY];

        for (int i = 0; i < numY; i++) {
            data1[i] = rlat1 + i * dlat;
        }

        dataA = Array.factory(DataType.DOUBLE, new int[] { numY }, data1);
        yaxis.setCachedData(dataA, false);
        ncfile.addVariable(null, yaxis);

        // projection
        // lower left and upper right corner lat/lons
        // modified cylind. equidistant or  CED with lat/lon ration != 1
    /*    LatLonProjection llproj = new LatLonProjection("LatitudeLongitudeProjection",
                                  new ProjectionRect(rlat1, rlon1, rlat2, rlon2));
        Variable ct = new Variable(ncfile, null, null, llproj.getClassName());

        ct.setDataType(DataType.CHAR);
        ct.setDimensions("");

        List params = llproj.getProjectionParameters();

        for (int i = 0; i < params.size(); i++) {
            Parameter p = (Parameter) params.get(i);

            ct.addAttribute(new Attribute(p));
        }

        ct.addAttribute(new Attribute(_Coordinate.TransformType, "Projection"));
        ct.addAttribute(new Attribute(_Coordinate.Axes, "lat lon"));

        // fake data
        dataA = Array.factory(DataType.CHAR, new int[] {});
        dataA.setChar(dataA.getIndex(), ' ');
        ct.setCachedData(dataA, false);
        ncfile.addVariable(null, ct);
      */
        return null;
    }



    /**
     *  parsing the product information into netcdf dataset
     */
    void setProductInfo(String prod, Date dd) {
        String summary = null;

        if (prod.contains("NOWRADHF")) {
            cmemo   = "NOWRAD  Base Reflectivity at Tilt 1";
            ctitle  = "BREF: Base Reflectivity [dBZ]";
            cunit   = "dBZ";
            cname   = "Reflectivity";
            summary = "NOWRAD Product";
        } else if (prod.contains("USRADHF")) {
            cmemo   = "NOWRAD  Base Reflectivity at Tilt 1";
            ctitle  = "BREF: Base Reflectivity [dBZ]";
            cunit   = "dBZ";
            cname   = "Reflectivity";
            summary = "NOWRAD Product";
        } else if (prod.contains("NEXET")) {
            cmemo   = "NOWRAD Echo Tops";
            ctitle  = "Echo Tops Composite";
            cunit   = "K FT";
            cname   = "EchoTopsComposite";
            summary = "NOWRAD Product";
        } else if (prod.contains("NEXLL")) {
            cmemo   = "NOWRAD Layer Comp. Reflectivity - Low";
            ctitle  = "LayerReflectivityLow";
            cunit   = "dBZ";
            cname   = "Reflectivity";
            summary = "NOWRAD Product";
        } else if (prod.contains("NEXLM")) {
            cmemo   = "NOWRAD Layer Comp. Reflectivity - Mid";
            ctitle  = "LayerReflectivityMid";
            cunit   = "dBZ";
            cname   = "Reflectivity";
            summary = "NOWRAD Product";
        } else if (prod.contains("NEXLH")) {
            cmemo   = "NOWRAD Layer Comp. Reflectivity - High";
            ctitle  = "LayerReflectivityHigh";
            cunit   = "dBZ";
            cname   = "ReflectivityHigh";
            summary = "NOWRAD Product";
        } else if (prod.contains("NEXVI")) {
            cmemo   = "NOWRAD ";
            ctitle  = "Vert. Integrated Liquid Water";
            cunit   = "Knots";
            cname   = "VILwater";
            summary = "NOWRAD ";
        } else {
            ctilt  = "error";
            ctitle = "error";
            cunit  = "error";
            cname  = "error";
        }

        /* add geo global att */
        ncfile.addAttribute(null, new Attribute("summary", "NOWRAD radar composite products." + summary));
        ncfile.addAttribute(null, new Attribute("title", "NOWRAD"));
        ncfile.addAttribute(null, new Attribute("keywords", "NOWRAD"));
        ncfile.addAttribute(null, new Attribute("creator_name", "NOAA/NWS"));
        ncfile.addAttribute(null, new Attribute("creator_url", "http://www.ncdc.noaa.gov/oa/radar/radarproducts.html"));
        ncfile.addAttribute(null, new Attribute("naming_authority", "NOAA/NCDC"));
        ncfile.addAttribute(null, new Attribute("base_date", formatter.toDateOnlyString(dd)));
        ncfile.addAttribute(null, new Attribute("conventions", _Coordinate.Convention));
        ncfile.addAttribute(null, new Attribute("cdm_data_type", FeatureType.GRID.toString()));

    }

    /* thredds global att */

    /**
     * convert two short into a integer
     * @param s1            short one
     * @param s2            short two
     * @param swapBytes      if swap bytes
     * @return    integer
     */
    public static int shortsToInt(short s1, short s2, boolean swapBytes) {
        byte[] b = new byte[4];

        b[0] = (byte) (s1 >>> 8);
        b[1] = (byte) (s1 >>> 0);
        b[2] = (byte) (s2 >>> 8);
        b[3] = (byte) (s2 >>> 0);

        return bytesToInt(b, false);
    }

    /**
     * convert bytes into integer
     * @param bytes           bytes array
     * @param swapBytes       if need to swap
     * @return   integer
     */
    public static int bytesToInt(byte[] bytes, boolean swapBytes) {
        byte a = bytes[0];
        byte b = bytes[1];
        byte c = bytes[2];
        byte d = bytes[3];

        if (swapBytes) {
            return ((a & 0xff)) + ((b & 0xff) << 8) + ((c & 0xff) << 16) + ((d & 0xff) << 24);
        } else {
            return ((a & 0xff) << 24) + ((b & 0xff) << 16) + ((c & 0xff) << 8) + ((d & 0xff));
        }
    }

    /**
     * Concatenate two bytes to a 32-bit int value.  a is the high order
     * byte in the resulting int representation, unless swapBytes is true, in
     * which b is the high order byte.
     * @param a high order byte
     * @param b low order byte
     * @param swapBytes byte order swap flag
     * @return 32-bit integer
     */
    public static int bytesToInt(byte a, byte b, boolean swapBytes) {

        // again, high order bit is expressed left into 32-bit form
        if (swapBytes) {
            return (a & 0xff) + ((int) b << 8);
        } else {
            return ((int) a << 8) + (b & 0xff);
        }
    }

    /**
     * convert unsigned byte to short
     * @param b convert this unsigned byte
     * @return unsigned short
     */
    public short convertunsignedByte2Short(byte b) {
        return (short) ((b < 0)
                        ? (short) b + 256
                        : (short) b);
    }

    /**
     *  convert short to unsigned integer
     * @param b  convert this short
     * @return   unsigned integer
     */
    public int convertShort2unsignedInt(short b) {
        return (b < 0)
               ? (-1) * b + 32768
               : b;
    }

    /**
     * get jave date
     * @param julianDays
     * @param msecs
     * @return   java date
     */
    static public java.util.Date getDate(int julianDays, int msecs) {
        long total = ((long) (julianDays - 1)) * 24 * 3600 * 1000 + msecs;

        return new Date(total);
    }

    /**
     * Flush all data buffers to disk.
     * @throws IOException
     */
    public void flush() throws IOException {
        raf.flush();
    }

    /**
     *  Close the file.
     * @throws IOException
     */
    public void close() throws IOException {
        if (raf != null) {
            raf.close();
        }
    }

    // variable info for reading/writing
    static class Vinfo {
        long    hoff;        // header offset
        int     xt;
        int     yt;

        Vinfo(int xt, int yt, long hoff) {
            this.xt       = xt;
            this.yt       = yt;
            this.hoff     = hoff;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy