Package ucar.nc2.iosp.sigmet

Source Code of ucar.nc2.iosp.sigmet.SigmetIOServiceProvider

package ucar.nc2.iosp.sigmet;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import ucar.ma2.Range;
import ucar.ma2.Array;
import ucar.ma2.ArrayFloat;
import ucar.ma2.ArrayInt;
import ucar.ma2.DataType;
import ucar.ma2.Index;
import ucar.ma2.IndexIterator;
import ucar.ma2.InvalidRangeException;
import ucar.ma2.Section;
import ucar.nc2.Attribute;
import ucar.nc2.Dimension;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import ucar.nc2.constants.AxisType;
import ucar.nc2.constants._Coordinate;
import ucar.nc2.iosp.AbstractIOServiceProvider;
import ucar.nc2.iosp.Layout;
import ucar.nc2.iosp.LayoutRegular;
import ucar.unidata.io.RandomAccessFile;

/** Implementation of the ServerProvider pattern provides input/output
* of the SIGMET-IRIS dataset. IOSP are managed by the NetcdfFile class.
* When the SigmetDataset is requested by calling NetcdfFile.open(), the file
* is opened as a ucar.unidata.io.RandomAccessFile.
* The SIGMET-IRIS data format are described in "IRIS Programmer's Manual" ch.3
* The SIGMET-IRIS file consists of records with fixed length=6144 bytes. Data is written in
* little-endian format. The organization of raw product SIGMET-IRIS file is:
*      Record #1   { <product_hdr> 0,0,0,...}
*      Record #2   { <ingest_header> 0,0,0,... }
*       ---if there are several sweeps (usually 24) and one type of data:
*      Record #3   { <raw_prod_bhdr><ingest_data_header>...Data for sweep 1.. }
*      Record #4   { <raw_prod_bhdr>...Data for sweep 1...  }
*             .............................................
*      Record #n   { <raw_prod_bhdr>...Data for sweep 1... 0.... }
*      Record #n+1 { <raw_prod_bhdr><ingest_data_header>...Data for sweep 2.. }
*      Record #n+2 { <raw_prod_bhdr>...Data for sweep 2...  }
*             .............................................
*      Record #m   { <raw_prod_bhdr>...Data for sweep 2... 0...  }
*      Record #m+1 { <raw_prod_bhdr><ingest_data_header>...Data for sweep 3.. }
*             .............................................
*             Structure of "Data for sweep" is:  <ray_header><ray_data>...<ray_header><ray_data>...
*             <ray_header> and <ray_data> are encoded with the compression algorithm
*             ("IRIS Programmer's Manual" 3.5.4.1)
*       ---if there are "n" types of data (usually 4 or 5) and one sweep:
*      Record #3   { <raw_prod_bhdr><ingest_data_header(data_type_1)><ingest_data_header(data_type_2)>...
*                    <ingest_data_header(data_type_n)>...Data...}
*      Record #4   { <raw_prod_bhdr>...Data...  }
*             .............................................
*      Record #n   { <raw_prod_bhdr>...Data...  }
*             Structure of "Data" is:  <ray_header(data_type_1)><ray_data(data_type_1)><ray_header(data_type_2)><ray_data(data_type_2)>...
*             <ray_header(data_type_n)><ray_data(data_type_n)><ray_header(data_type_1)><ray_data(data_type_1)>
*         <ray_header(data_type_2)><ray_data(data_type_2)>... <ray_header(data_type_n)><ray_data(data_type_n)>...
*             <ray_header> and <ray_data> are encoded with the compression algorithm
*             ("IRIS Programmer's Manual" 3.5.4.1)
*
*/
public class SigmetIOServiceProvider  extends AbstractIOServiceProvider {
    private static final String def_datafile="SIGMET-IRIS";
    // org.slf4j.Logger logger=org.slf4j.LoggerFactory.getLogger(TestNetcdf.class);
    // ucar.unidata.io.RandomAccessFile raf=null;
    //  static String infile="C:\\netcdf\\data\\sig00.dat";
    // static String infile="testdata2\\200705162030~~CONVOL-URP-XNC-RADAR-IRIS--20070516203210";
    // static String infile="testdata2\\200705162030~~DOPVOL1_A-URP-XNC-RADAR-IRIS--20070516203241";
    private ucar.nc2.NetcdfFile ncfile = null;
    ArrayList<Variable> varList = null;
    RandomAccessFile myRaf = null;
   //Ray[][] ray=null;
    int[] tsu_sec=null;
    int[] sweep_bins=null;
    String date0;
  
    public static java.util.Map<String, Number> recHdr = new java.util.HashMap<String, Number> ();
    private SigmetVolumeScan volScan;
    public static void main(String[] args) {
        String infile=" ";
        if (args.length == 1) {
            infile=args[0];
        } else { System.out.println("Usage: java SigmetIOServiceProvider inputFile");
        System.exit(0)}
        try {
            NetcdfFile.registerIOProvider(SigmetIOServiceProvider.class);
            NetcdfFile ncfile=NetcdfFile.open(infile);
            System.out.println("ncfile = \n"+ncfile);
        } catch (Exception e) { System.out.println("MAIN!!!   "+e.toString());
        e.printStackTrace(); }
    }
    public String getFileTypeDescription() {
        return "SIGMET-IRIS";
    }
    public String getFileTypeVersion() {
        return "SIGMET-IRIS";
    }
    public String getFileTypeId() {
        return "SIGMET";
    }

    /** Check if this is a valid SIGMET-IRIS file for this IOServiceProvider. */
    public boolean isValidFile(ucar.unidata.io.RandomAccessFile raf) {
        try {
            raf.order(RandomAccessFile.LITTLE_ENDIAN);
            raf.seek(24);
            return (raf.readShort() == (short)15);
        } catch (IOException ioe) {  System.out.println("In isValidFile(): "+ioe.toString());
        return false;
        }
    }

    /** Open existing file, and populate ncfile with it.  */
    public void open(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile,
            ucar.nc2.util.CancelTask cancelTask) throws java.io.IOException  {
        this.ncfile = ncfile;
        this.myRaf = raf;
        //java.util.Map<String, Number> recHdr=new java.util.HashMap<String, Number>();
        java.util.Map<String, String> hdrNames=new java.util.HashMap<String, String>();
        volScan = new SigmetVolumeScan(raf, ncfile, varList);
        this.varList=init(raf, ncfile, hdrNames);

       // doData(raf, ncfile, varList);
       // raf.close();
       // this.ncfile.close();
    }

    /** Read some global data from SIGMET file. The SIGMET file consists of records with
     *  fixed length=6144 bytes.
     */
   static  public java.util.Map<String, Number> readRecordsHdr(ucar.unidata.io.RandomAccessFile raf) {
        java.util.Map<String, Number> recHdr1 = new java.util.HashMap<String, Number> ();
        try { int nparams=0;
        //      -- Read from <product_end> of the 1st record -- 12+320+120
        //      -- Calculate Nyquist velocity --------------------
        raf.seek(452)int prf=raf.readInt();
        raf.seek(480)int wave=raf.readInt();
        float vNyq=calcNyquist(prf, wave);
        recHdr1.put("vNyq", new Float(vNyq));

        //      -- Read from the 2nd record----------- 6144+12(strucr_hdr)+168(from ingest_config)
        raf.seek(6324)int radar_lat=raf.readInt();
        int radar_lon=raf.readInt();           //6328
        short ground_height= raf.readShort()//6332
        short radar_height= raf.readShort();   //6334
        raf.skipBytes(4);
        short num_rays= raf.readShort();      // 6340
        raf.skipBytes(2);
        int radar_alt=raf.readInt();          //6344
        raf.seek(6648);
        int time_beg=raf.readInt();
        raf.seek(6652);
        int time_end=raf.readInt();
        raf.seek(6772);
        int data_mask=raf.readInt();
        for (int j=0; j<32; j++) {  nparams+=((data_mask >> j) & (0x1))}
        raf.seek(6912);
        short multiprf=raf.readShort();
        raf.seek(7408);
        int range_first=raf.readInt();   //  cm    7408
        int range_last=raf.readInt();    //  cm  7412
        raf.skipBytes(2);
        short bins=raf.readShort();             //7418
        if (bins % 2 != 0) bins=(short)(bins+1);
        raf.skipBytes(4);
        int step=raf.readInt();          //  cm    7424
        raf.seek(7574);
        short number_sweeps= raf.readShort();    // 7574
        raf.seek(12312);
        int base_time=raf.readInt();        //<ingest_data_header> 3d rec
        raf.skipBytes(2);
        short year=raf.readShort();
        short month=raf.readShort();
        short day=raf.readShort();
        recHdr1.put("radar_lat", new Float(calcAngle(radar_lat)));
        recHdr1.put("radar_lon", new Float(calcAngle(radar_lon)));
        recHdr1.put("range_first", new Integer(range_first));
        recHdr1.put("range_last", new Integer(range_last));
        recHdr1.put("ground_height", new Short(ground_height));
        recHdr1.put("radar_height", new Short(radar_height));
        recHdr1.put("radar_alt", new Integer(radar_alt));
        recHdr1.put("step", new Integer(step));
        recHdr1.put("bins", new Short(bins));    //System.out.println("  bins="+bins);
        recHdr1.put("num_rays", new Short(num_rays)); //System.out.println("  rays="+num_rays);
        recHdr1.put("nparams", new Integer(nparams));//System.out.println("  nparams="+nparams);
        recHdr1.put("multiprf", new Short(multiprf));
        recHdr1.put("number_sweeps", new Short(number_sweeps));   //System.out.println("IN HDR:  number_sweeps="+number_sweeps);
        recHdr1.put("year", new Short(year));
        recHdr1.put("month", new Short(month));
        recHdr1.put("day", new Short(day));
        recHdr1.put("base_time", new Integer(base_time));
        } catch (Exception e) { System.out.println(e.toString());
        e.printStackTrace(); }
        return recHdr1;
    }

    /** Read StationName strings  */
    public java.util.Map<String, String> readStnNames(ucar.unidata.io.RandomAccessFile raf) {
        java.util.Map<String, String> hdrNames=new java.util.HashMap<String, String> ();
        try {
            raf.seek(6288);
            String stnName=raf.readString(16)//System.out.println(" stnName="+stnName.trim());
            raf.seek(6306);
            String stnName_util=raf.readString(16);
            hdrNames.put("StationName", stnName.trim());
            hdrNames.put("StationName_SetupUtility", stnName_util.trim());
        } catch (Exception e) { System.out.println(e.toString());
        e.printStackTrace(); }
        return hdrNames;
    }

    /** Define Dimensions, Variables, Attributes in ncfile
     * @param raf      ucar.unidata.io.RandomAccessFile corresponds of SIGMET datafile.
     * @param ncfile   an empty NetcdfFile object which will be filled.
     * @param hdrNames java.util.Map with values for "StationName.." Attributes
     * @return ArrayList of Variables of ncfile
     */
    public ArrayList<Variable> init(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile,
            java.util.Map<String, String> hdrNames)   throws java.io.IOException  {
        // prepare attribute values
        String[] data_name={ " ", "TotalPower", "Reflectivity", "Velocity",
                "Width", "Differential_Reflectivity"};
        String[] unit={" ", "dbZ", "dbZ", "m/sec", "m/sec", "dB"};
        int[] type={1, 2, 3, 4, 5};
        String def_datafile="SIGMET-IRIS";
        String tim="";
        int ngates=0;

        recHdr=readRecordsHdr(raf);
        hdrNames=readStnNames(raf);

        String stnName=hdrNames.get("StationName");
        String stnName_util=hdrNames.get("StationName_SetupUtility");
        float radar_lat=((Float)recHdr.get("radar_lat")).floatValue(); //System.out.println("rad_lat="+radar_lat);
        float radar_lon=((Float)recHdr.get("radar_lon")).floatValue(); //System.out.println("rad_lon="+radar_lon);
        short ground_height=((Short)recHdr.get("ground_height")).shortValue(); //System.out.println("ground_H="+ground_height);
        short radar_height=((Short)recHdr.get("radar_height")).shortValue(); //System.out.println("radar_H="+radar_height);
        int radar_alt=(((Integer)recHdr.get("radar_alt")).intValue())/100; //System.out.println("rad_alt="+radar_alt);
        short num_rays=((Short)recHdr.get("num_rays")).shortValue(); //System.out.println("num_rays="+num_rays);
        short bins=((Short)recHdr.get("bins")).shortValue(); //System.out.println("bins="+bins);
        float range_first=(((Integer)recHdr.get("range_first")).intValue())*0.01f; //System.out.println("range_1st="+range_first);
        float range_last=(((Integer)recHdr.get("range_last")).intValue())*0.01f; //System.out.println("step="+step);
        short number_sweeps=((Short)recHdr.get("number_sweeps")).shortValue();
        //System.out.println("number_sweeps="+number_sweeps);
        int nparams=(((Integer)recHdr.get("nparams")).intValue()); //System.out.println("nparams="+nparams);
        short year=((Short)recHdr.get("year")).shortValue(); //System.out.println("year="+year);
        short month=((Short)recHdr.get("month")).shortValue();
        short day=((Short)recHdr.get("day")).shortValue();
        int base_time=(((Integer)recHdr.get("base_time")).intValue());

        // define number of gates for every sweep
        sweep_bins=new int[nparams*number_sweeps];
        if (number_sweeps > 1) { sweep_bins=volScan.getNumberGates();
        } else {
            for (int kk=0; kk < nparams; kk++) {  sweep_bins[kk]=bins;  }
        }

        // add Dimensions
        Dimension scanR=new Dimension("scanR", number_sweeps, true);
        Dimension radial=new Dimension("radial", num_rays, true);
        Dimension[] gateR=new Dimension[number_sweeps];
        String dim_name="gateR";
        for (int j=0; j<number_sweeps; j++) {
            if (number_sweeps > 1) { dim_name="gateR_sweep_"+(j+1); }
            gateR[j]=new Dimension(dim_name, sweep_bins[j], true);
        }
        ncfile.addDimension(null, scanR);
        ncfile.addDimension(null, radial);
        for (int j=0; j<number_sweeps; j++) {
            ncfile.addDimension(null, gateR[j]);
        }
        ArrayList<Dimension> dims0=new ArrayList<Dimension>();
        ArrayList<Dimension> dims1=new ArrayList<Dimension>();
        ArrayList<Dimension> dims2=new ArrayList<Dimension>();
        ArrayList<Dimension> dims3=new ArrayList<Dimension>();

        ArrayList<Variable> varList=new ArrayList<Variable>();

        Variable[][] v=new Variable[nparams][number_sweeps];
        String var_name="";
        for (int j=0; j<nparams; j++) {
            int tp=type[j];
            var_name=data_name[tp];
            for (int jj=0; jj<number_sweeps; jj++) {
                if (number_sweeps > 1) {  var_name=data_name[tp]+"_sweep_"+(jj+1); }
                v[j][jj]=new Variable(ncfile, null, null, var_name);
                v[j][jj].setDataType(DataType.FLOAT);
                dims2.add(radial);
                dims2.add(gateR[jj]);
                v[j][jj].setDimensions(dims2);
                v[j][jj].addAttribute(new Attribute( "long_name", var_name));
                v[j][jj].addAttribute(new Attribute( "units", unit[tp]));
                String coordinates="time elevationR azimuthR distanceR";
                v[j][jj].addAttribute(new Attribute(_Coordinate.Axes, coordinates));
                v[j][jj].addAttribute(new Attribute("missing_value", -999.99f));
                ncfile.addVariable(null, v[j][jj]);
                varList.add(v[j][jj]);
                dims2.clear();
            }
        }
        tsu_sec=new int[number_sweeps];
        String[] tsu=new String[number_sweeps];
        String[] time_units=new String[number_sweeps];
        tsu_sec=volScan.getStartSweep();
        for (int i=0; i< number_sweeps; i++) {
            String st1=Short.toString(month);
            if (st1.length() < 2) st1="0"+st1;
            String st2=Short.toString(day);
            if (st2.length() < 2) st2="0"+st2;
            date0=String.valueOf(year)+"-"+st1+"-"+st2;
            tsu[i]=date0+"T"+calcTime(tsu_sec[i],0)+"Z";
        }
        for (int j=0; j<number_sweeps; j++) { time_units[j]="secs since "+tsu[j]; }

        dims0.add(radial);
        // add "time" variable
        Variable[] time=new Variable[number_sweeps];
        String tm="time";   String tm_name="";
        for (int j=0; j<number_sweeps; j++) {  tm_name=tm;
        if (number_sweeps > 1) { tm_name=tm+"_sweep_"+(j+1)}
        time[j]=new Variable(ncfile, null, null, tm_name);
        time[j].setDataType(DataType.INT);
        time[j].setDimensions(dims0);
        time[j].addAttribute(new Attribute("long_name", "time from start of sweep"));
        time[j].addAttribute(new Attribute("units", time_units[j]));
        time[j].addAttribute( new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));
        time[j].addAttribute(new Attribute("missing_value", -99));
        ncfile.addVariable(null, time[j]);
        varList.add(time[j]);
        }

        // add "elevationR" variable
        Variable[] elevationR=new Variable[number_sweeps];
        String ele="elevationR";   String ele_name="";
        for (int j=0; j<number_sweeps; j++) {  ele_name=ele;
        if (number_sweeps > 1) { ele_name=ele+"_sweep_"+(j+1)}
        elevationR[j]=new Variable(ncfile, null, null, ele_name);
        elevationR[j].setDataType(DataType.FLOAT);
        elevationR[j].setDimensions(dims0);
        elevationR[j].addAttribute(new Attribute("long_name", "elevation angle"));
        elevationR[j].addAttribute(new Attribute("units", "degrees"));
        elevationR[j].addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString()));
        elevationR[j].addAttribute(new Attribute("missing_value", -999.99f));
        ncfile.addVariable(null, elevationR[j]);
        varList.add(elevationR[j]);
        }

        // add "azimuthR" variable
        Variable[] azimuthR=new Variable[number_sweeps];
        String azim="azimuthR";   String azim_name="";
        for (int j=0; j<number_sweeps; j++) {  azim_name=azim;
        if (number_sweeps > 1) { azim_name=azim+"_sweep_"+(j+1)}
        azimuthR[j]=new Variable(ncfile, null, null, azim_name);
        azimuthR[j].setDataType(DataType.FLOAT);
        azimuthR[j].setDimensions(dims0);
        azimuthR[j].addAttribute(new Attribute("long_name", "azimuth angle"));
        azimuthR[j].addAttribute(new Attribute("units", "degrees"));
        azimuthR[j].addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialAzimuth.toString()));
        azimuthR[j].addAttribute(new Attribute("missing_value", -999.99f));
        ncfile.addVariable(null, azimuthR[j]);
        varList.add(azimuthR[j]);
        }

        // add "distanceR" variable
        Variable[] distanceR=new Variable[number_sweeps];
        String dName="distanceR";
        String dist_name="";
        for (int j=0; j<number_sweeps; j++) {  dist_name=dName;
        if (number_sweeps > 1) { dist_name=dName+"_sweep_"+(j+1)}
        distanceR[j]=new Variable(ncfile, null, null, dist_name);
        distanceR[j].setDataType(DataType.FLOAT);
        dims1.add(gateR[j]);
        distanceR[j].setDimensions(dims1);
        distanceR[j].addAttribute(new Attribute("long_name", "radial distance"));
        distanceR[j].addAttribute(new Attribute("units", "m"));
        distanceR[j].addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialDistance.toString()));
        ncfile.addVariable(null, distanceR[j]);
        varList.add(distanceR[j]);
        dims1.clear();
        }
        // add "numGates" variable
        dims3.add(scanR);
        Variable numGates=new Variable(ncfile, null, null, "numGates");
        numGates.setDataType(DataType.INT);
        numGates.setDimensions(dims3);
        numGates.addAttribute(new Attribute("long_name", "number of gates in the sweep"));
        ncfile.addVariable(null, numGates);
        varList.add(numGates);

        // add global attributes
        ncfile.addAttribute(null, new Attribute("definition", "SIGMET-IRIS RAW"));
        ncfile.addAttribute(null, new Attribute("description", "SIGMET-IRIS data are reading by Netcdf IOSP"));
        ncfile.addAttribute(null, new Attribute("StationName", stnName));
        ncfile.addAttribute(null, new Attribute("StationName_SetupUtility", stnName_util));
        ncfile.addAttribute(null, new Attribute("radar_lat", new Float(radar_lat)));
        ncfile.addAttribute(null, new Attribute("radar_lon", new Float(radar_lon)));
        ncfile.addAttribute(null, new Attribute("ground_height", new Short(ground_height)));
        ncfile.addAttribute(null, new Attribute("radar_height", new Short(radar_height)));
        ncfile.addAttribute(null, new Attribute("radar_alt", new Integer(radar_alt)));
        ncfile.addAttribute(null, new Attribute("num_data_types", new Integer(nparams)));
        ncfile.addAttribute(null, new Attribute("number_sweeps", new Short(number_sweeps)));
        String sn="start_sweep";  String snn="";
        for (int j=0; j<number_sweeps; j++) { snn=sn;
        if (number_sweeps > 1) { snn=sn+"_"+(j+1)}
        ncfile.addAttribute(null, new Attribute(snn, tsu[j]));
        }
        ncfile.addAttribute(null, new Attribute("num_rays", new Short(num_rays)));
        ncfile.addAttribute(null, new Attribute("max_number_gates", new Short(bins)));
        ncfile.addAttribute(null, new Attribute("range_first", new Float(range_first)));
        ncfile.addAttribute(null, new Attribute("range_last", new Float(range_last)));
        ncfile.addAttribute(null, new Attribute("DataType", "Radial"));
        ncfile.addAttribute(null, new Attribute("Conventions", _Coordinate.Convention));

        // --------- fill all of values in the ncfile ------
        doNetcdfFileCoordinate(ncfile, volScan.base_time, volScan.year, volScan.month, volScan.day, varList, recHdr);

        ncfile.finish();

        return varList;
    }

     /** Fill all of the variables/attributes in the ncfile
     * @param ncfile   NetcdfFile object which will be filled.

     * @param bst      number of seconds since midnight for start of sweep
     * @param yr       year of start of each sweep
     * @param m        month of start of each sweep
     * @param dda      day of start of each sweep
     * @param varList  ArrayList of Variables of ncfile
     * @param recHdr   java.util.Map with values for Attributes
     */
    public void doNetcdfFileCoordinate(ucar.nc2.NetcdfFile ncfile,  int[] bst,
            short[] yr, short[] m,  short[] dda,
            ArrayList<Variable> varList, java.util.Map<String, Number> recHdr)  {
        // prepare attribute values

        String[] unit={" ", "dbZ", "dbZ", "m/sec", "m/sec", "dB"};
        String def_datafile="SIGMET-IRIS";
        Short header_length=80;
        Short ray_header_length=6;
        int ngates=0;

        float radar_lat=((Float)recHdr.get("radar_lat")).floatValue(); //System.out.println("rad_lat="+radar_lat);
        float radar_lon=((Float)recHdr.get("radar_lon")).floatValue(); //System.out.println("rad_lon="+radar_lon);
        short ground_height=((Short)recHdr.get("ground_height")).shortValue(); //System.out.println("ground_H="+ground_height);
        short radar_height=((Short)recHdr.get("radar_height")).shortValue(); //System.out.println("radar_H="+radar_height);
        int radar_alt=(((Integer)recHdr.get("radar_alt")).intValue())/100; //System.out.println("rad_alt="+radar_alt);
        short num_rays=((Short)recHdr.get("num_rays")).shortValue(); //System.out.println("HERE!! num_rays="+num_rays);
        float range_first=(((Integer)recHdr.get("range_first")).intValue())*0.01f; //System.out.println("range_1st="+range_first);
        float range_last=(((Integer)recHdr.get("range_last")).intValue())*0.01f; //System.out.println("step="+step);
        short number_sweeps=((Short)recHdr.get("number_sweeps")).shortValue();
        int nparams=(((Integer)recHdr.get("nparams")).intValue()); //System.out.println("nparams="+nparams);
        // define date/time
        //int last_t=(int)(ray[nparams*number_sweeps-1][num_rays-1].getTime());
        int last_t = volScan.lastRay.getTime();
        String sss1=Short.toString(m[0]);
        if (sss1.length() < 2) sss1="0"+sss1;
        String sss2=Short.toString(dda[0]);
        if (sss2.length() < 2) sss2="0"+sss2;
        String base_date0=String.valueOf(yr[0])+"-"+sss1+"-"+sss2;
        String sss11=Short.toString(m[number_sweeps-1]);
        if (sss11.length() < 2) sss11="0"+sss11;
        String sss22=Short.toString(dda[number_sweeps-1]);
        if (sss22.length() < 2) sss22="0"+sss22;
        String base_date1=String.valueOf(yr[number_sweeps-1])+"-"+sss11+"-"+sss22;
        String start_time=base_date0+"T"+calcTime(bst[0], 0)+"Z";
        String end_time=base_date1+"T"+calcTime(bst[number_sweeps-1], last_t)+"Z";
        ncfile.addAttribute(null, new Attribute("time_coverage_start", start_time));
        ncfile.addAttribute(null, new Attribute("time_coverage_end", end_time));

        // set all of Variables
        try {
            int sz=varList.size();

            ArrayFloat.D2[] dataArr=new ArrayFloat.D2[nparams*number_sweeps];
            Index[] dataIndex=new Index[nparams*number_sweeps];

           // Variable[][] vv=new Variable[nparams][number_sweeps];
            Variable var=null;
            String var_name="";

            Ray[] rtemp=new Ray[(int)num_rays];

            // NCdump.printArray(dataArr[0], "Total_Power", System.out, null);

            Variable[] distanceR=new Variable[number_sweeps];
            ArrayFloat.D1[] distArr=new ArrayFloat.D1[number_sweeps];
            Index[] distIndex=new Index[number_sweeps];
            String distName="distanceR";
            for (int i=0; i<number_sweeps; i++) {
                if (number_sweeps > 1) {  distName="distanceR_sweep_"+(i+1); }
                for  (int ix=0; ix<sz; ix++)  {
                    var=varList.get(ix);
                    if ((var.getShortName()).equals(distName.trim())) { distanceR[i]= var; break; }
                }
                distArr[i]=(ArrayFloat.D1) Array.factory(DataType.FLOAT, distanceR[i].getShape());
                distIndex[i]=distArr[i].getIndex();

               // for (int jj=0; jj<num_rays; jj++) { rtemp[jj]=ray[i][jj]; }
                ngates=sweep_bins[i];
                float stp=calcStep(range_first, range_last,(short)ngates);
                for (int ii=0; ii<ngates; ii++)  {
                    distArr[i].setFloat(distIndex[i].set(ii), (range_first+ii*stp));
                }
            }
            // NCdump.printArray(distArr[0], "distanceR", System.out, null);
            List rgp =  volScan.getTotalPowerGroups();
            if(rgp.size() == 0) rgp = volScan.getReflectivityGroups();
            List [] sgp = new ArrayList[number_sweeps];
            for (int i=0; i<number_sweeps; i++) {
                sgp[i] = (List)rgp.get((short)i);
            }


            Variable[] time=new Variable[number_sweeps];
            ArrayInt.D1[] timeArr=new ArrayInt.D1[number_sweeps];
            Index[] timeIndex=new Index[number_sweeps];
            String t_n="time";
            for (int i=0; i<number_sweeps; i++) {
                if (number_sweeps > 1) { t_n="time_sweep_"+(i+1); }
                for  (int ix=0; ix<sz; ix++)  {
                    var=varList.get(ix);
                    if ((var.getShortName()).equals(t_n.trim())) { time[i]=var;  break; }
                }

                //                if (time[i].getShape().length == 0) {
                //                    continue;
                //                }
                timeArr[i]=(ArrayInt.D1) Array.factory(DataType.INT, time[i].getShape());
                timeIndex[i]=timeArr[i].getIndex();
                List rlist = sgp[i];

                for (int jj=0; jj<num_rays; jj++) { rtemp[jj]=(Ray)rlist.get(jj); }    //ray[i][jj]; }
                for (int jj=0; jj<num_rays; jj++) {
                    timeArr[i].setInt(timeIndex[i].set(jj), rtemp[jj].getTime());
                }
            }

            // NCdump.printArray(timeArr[0], "time", System.out, null);

            Variable[] azimuthR=new Variable[number_sweeps];
            ArrayFloat.D1[] azimArr=new ArrayFloat.D1[number_sweeps];
            Index[] azimIndex=new Index[number_sweeps];
            String azimName="azimuthR";
            for (int i=0; i<number_sweeps; i++) {
                if (number_sweeps > 1) {  azimName="azimuthR_sweep_"+(i+1); }
                for  (int ix=0; ix<sz; ix++)  {
                    var=varList.get(ix);
                    if ((var.getShortName()).equals(azimName.trim())) { azimuthR[i]=var; break}
                }
                azimArr[i]=(ArrayFloat.D1) Array.factory(DataType.FLOAT, azimuthR[i].getShape());
                azimIndex[i]=azimArr[i].getIndex();
                List rlist = sgp[i];

                for (int jj=0; jj<num_rays; jj++) { rtemp[jj]=(Ray)rlist.get(jj); } //ray[i][jj]; }
                for (int jj=0; jj<num_rays; jj++) {
                    azimArr[i].setFloat(azimIndex[i].set(jj), rtemp[jj].getAz());
                }
            }
            //NCdump.printArray(azimArr[0], "azimuthR", System.out, null);

            Variable[] elevationR=new Variable[number_sweeps];
            ArrayFloat.D1[] elevArr=new ArrayFloat.D1[number_sweeps];
            Index[] elevIndex=new Index[number_sweeps];
            String elevName="elevationR";
            for (int i=0; i<number_sweeps; i++) {
                if (number_sweeps > 1) {  elevName="elevationR_sweep_"+(i+1); }
                for  (int ix=0; ix<sz; ix++)  {
                    var=varList.get(ix);
                    if ((var.getShortName()).equals(elevName.trim())) { elevationR[i]=var; break}
                }
                elevArr[i]=(ArrayFloat.D1) Array.factory(DataType.FLOAT, elevationR[i].getShape());
                elevIndex[i]=elevArr[i].getIndex();
                List rlist = sgp[i];

                for (int jj=0; jj<num_rays; jj++) { rtemp[jj]=(Ray)rlist.get(jj); } //ray[i][jj]; }
                for (int jj=0; jj<num_rays; jj++) {
                    elevArr[i].setFloat(elevIndex[i].set(jj), rtemp[jj].getElev());
                }
            }
            // NCdump.printArray(elevArr[0], "elevationR", System.out, null);

            Variable numGates=null;
            for (int i=0; i<number_sweeps; i++) {
                for  (int ix=0; ix<sz; ix++)  {
                    var=varList.get(ix);
                    if ((var.getShortName()).equals("numGates")) { numGates=var; break}
                }
            }
            ArrayInt.D1 gatesArr=(ArrayInt.D1) Array.factory(DataType.INT, numGates.getShape());
            Index gatesIndex=gatesArr.getIndex();
           
            for (int i=0; i<number_sweeps; i++) {
                List rlist = sgp[i];
                for (int jj=0; jj<num_rays; jj++) { rtemp[jj]=(Ray)rlist.get(jj); } //ray[i][jj]; }
                ngates=rtemp[0].getBins();
                gatesArr.setInt(gatesIndex.set(i), ngates);
            }

            for (int i=0; i<number_sweeps; i++) {
                distanceR[i].setCachedData(distArr[i], false);
                time[i].setCachedData(timeArr[i], false);
                azimuthR[i].setCachedData(azimArr[i], false);
                elevationR[i].setCachedData(elevArr[i], false);
            }
            numGates.setCachedData(gatesArr, false);
            // startSweep.setCachedData(sweepArr, false);

            //          -------------------------------------------------
           // int b=(int)ray[0][0].getBins();

            // -- Test of readData() and readToByteChannel() -----------------
            /*
  Range r1=new Range(356, 359);
  Range r2=new Range(0, 15);
  java.util.List arlist=new ArrayList();
  arlist.add(r1);
  arlist.add(r2);
       Array testArr=readData(v[0], new Section(arlist));
       NCdump.printArray(testArr, "Total_Power_sweep_1", System.out, null);
   WritableByteChannel channel=new FileOutputStream(new File("C:\\netcdf\\tt.dat")).getChannel();
   long ikk=readToByteChannel(v[0], new Section(arlist), channel);
   System.out.println("IKK="+ikk);
   channel.close();
             */
            //---------------------------------------------------

        } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); }
    }   //----------- end of doNetcdf ----------------------------------

    /** Read data from a top level Variable and return a memory resident Array.
     * @param v2  Variable. It may have FLOAT/INTEGER data type.
     * @param section  wanted section of data of Variable. The section list is a list
     *                 of ucar.ma2.Range which define the requested data subset.
     * @return  Array of data which will be read from Variable through this call.
     */
    public Array readData1(ucar.nc2.Variable v2, Section section)
    throws IOException, InvalidRangeException {
        //doData(raf, ncfile, varList);
        int[] sh=section.getShape();
        Array temp=Array.factory(v2.getDataType(), sh);
        long pos0=0;
        // Suppose that the data has LayoutRegular
        LayoutRegular index=new LayoutRegular(pos0, v2.getElementSize(), v2.getShape(), section);
        if (v2.getShortName().startsWith("time") | v2.getShortName().startsWith("numGates")) {
            temp=readIntData(index, v2);
        } else {   temp=readFloatData(index, v2);    }
        return temp;
    }

    public Array readData(Variable v2, Section section) throws IOException, InvalidRangeException {
     // Vgroup vgroup = (Vgroup) v2.getSPobject();
     // Range scanRange = section.getRange(0);
     // Range radialRange = section.getRange(1);
     // Range gateRange = section.getRange(2);

      Array data = Array.factory(v2.getDataType().getPrimitiveClassType(), section.getShape());
      IndexIterator ii = data.getIndexIterator();

      List groups = null;
      String shortName = v2.getShortName();
      if( shortName.startsWith("Reflectivity"))
        groups = volScan.getReflectivityGroups();
      else if( shortName.startsWith("Velocity"))
        groups = volScan.getVelocityGroups();
      else if( shortName.startsWith("TotalPower"))
        groups = volScan.getTotalPowerGroups();
      else if( shortName.startsWith("Width"))
        groups = volScan.getWidthGroups();
      else if( shortName.startsWith("DiffReflectivity"))
        groups = volScan.getDifferentialReflectivityGroups();

      if(section.getRank() == 2) {
          Range radialRange = section.getRange(0);
          Range gateRange = section.getRange(1);
          List lli = (List)groups.get(0);
          readOneScan(lli, radialRange, gateRange, ii);
      } else {
          Range scanRange = section.getRange(0);
          Range radialRange = section.getRange(1);
          Range gateRange = section.getRange(2);
          for (int i=scanRange.first(); i<=scanRange.last(); i+= scanRange.stride()) {
            readOneScan((List)groups.get(i), radialRange, gateRange, ii);
          }
      }
      return data;
    }


  private void readOneScan(List mapScan, Range radialRange, Range gateRange, IndexIterator ii) throws IOException {
    int siz = mapScan.size();
    for (int i=radialRange.first(); i<=radialRange.last(); i+= radialRange.stride()) {
      if(i >= siz)
           readOneRadial(null, gateRange, ii);
      else {
          Ray r = (Ray)mapScan.get(i);
          readOneRadial(r, gateRange, ii);
      }
    }
  }

  private void readOneRadial(Ray r, Range gateRange, IndexIterator ii) throws IOException {
    if (r == null) {
      for (int i=gateRange.first(); i<=gateRange.last(); i+= gateRange.stride())
        ii.setFloatNext( Float.NaN);
      return;
    }
    r.readData(volScan.raf, gateRange, ii);
  }
    /** Read data from a top level Variable of INTEGER data type and return a memory resident Array.
     * @param index  LayoutRegular object
     * @param v2     Variable has INTEGER data type.
     * @return  Array of data which will be read from Variable through this call.
     */
    public Array readIntData(LayoutRegular index, Variable v2)
    throws IOException  {
        int[] var=(int[])(v2.read().get1DJavaArray(v2.getDataType().getPrimitiveClassType()));
        int[] data = new int[(int)index.getTotalNelems()];
        while (index.hasNext()) {
            Layout.Chunk chunk=index.next();
            System.arraycopy(var, (int)chunk.getSrcPos()/4, data,
                    (int)chunk.getDestElem(), chunk.getNelems());
        }
        return Array.factory(data);
    }
    /** Read data from a top level Variable of FLOAT data type and return a memory resident Array.
     * @param index  LayoutRegular object
     * @param v2     Variable has FLOAT data type.
     * @return  Array of data which will be read from Variable through this call.
     */
    public Array readFloatData(LayoutRegular index, Variable v2)
    throws IOException  {
        float[] var=(float[])(v2.read().get1DJavaArray(v2.getDataType().getPrimitiveClassType()));
        float[] data = new float[(int)index.getTotalNelems()];
        while (index.hasNext()) {
            Layout.Chunk chunk=index.next();
            System.arraycopy(var, (int)chunk.getSrcPos()/4, data,
                    (int)chunk.getDestElem(), chunk.getNelems());
        }
        return Array.factory(data);
    }
    //----------------------------------------------------------------------------------

    /** Read data from a top level Variable and send data to a WritableByteChannel.
     * @param v2  Variable
     * @param section  wanted section of data of Variable. The section list is a list
     *                 of ucar.ma2.Range which define the requested data subset.
     * @param channel  WritableByteChannel object - channel that can write bytes.
     * @return the number of bytes written, possibly zero.
     */
    public long readToByteChannel11(ucar.nc2.Variable v2, Section section, WritableByteChannel channel)
    throws java.io.IOException, ucar.ma2.InvalidRangeException {
        Array data = readData(v2, section);
        float[] ftdata=new float[(int)data.getSize()];
        byte[] bytedata=new byte[(int)data.getSize()*4];
        IndexIterator iter=data.getIndexIterator();
        int i=0;
        ByteBuffer buffer=ByteBuffer.allocateDirect(bytedata.length);
        while (iter.hasNext()) { ftdata[i]=iter.getFloatNext();
        bytedata[i]=new Float(ftdata[i]).byteValue();
        buffer.put(bytedata[i]);
        i++;
        }
        buffer=ByteBuffer.wrap(bytedata);
        // write the bytes to the channel
        int count=channel.write(buffer);  System.out.println("COUNT="+count);
        // check if all bytes where written
        if (buffer.hasRemaining()) {
            // if not all bytes were written, move the unwritten bytes to the beginning and
            // set position just after the last unwritten byte
            buffer.compact();
        } else { buffer.clear()}
        return (long)count;
    }


    //  -----------------------------------------------------------------------
    /** Convert 2 bytes binary angle to float
     * @param angle   two bytes binary angle
     * @return float value of angle in degrees with precision of two decimal
     */
    static float calcAngle(short angle) {
        final double maxval=65536.0;
        double ang=(double)angle;
        if (ang < 0.0) { ang=maxval+ang; }
        double temp=(ang/maxval)*360.0;
        BigDecimal bd=new BigDecimal(temp);
        BigDecimal result=bd.setScale(2, RoundingMode.HALF_DOWN);
        return result.floatValue();
    }

    /** Convert 4 bytes binary angle to float
     * @param ang   four bytes binary angle
     * @return float value of angle with precision of two decimal in degrees
     */
    static float calcAngle(int ang) {
        final double maxval=4294967296.0;
        double temp=(ang/maxval)*360.0;
        BigDecimal bd=new BigDecimal(temp);
        BigDecimal result=bd.setScale(3, RoundingMode.HALF_DOWN);
        return result.floatValue();
    }

    /** Calculate radial elevation of each ray
     * @param angle  two bytes binary angle
     * @return float value of elevation in degrees with precision of two decimal
     */
    static float calcElev(short angle) {
        final double maxval=65536.0;
        double ang=(double)angle;
        if (angle < 0) ang=(~angle)+1;
        double temp=(ang/maxval)*360.0;
        BigDecimal bd=new BigDecimal(temp);
        BigDecimal result=bd.setScale(2, RoundingMode.HALF_DOWN);
        return result.floatValue();
    }

    /** Calculate distance between sequential bins in a ray
     * @param range_first  range of first bin in centimeters
     * @param range_last   range of last bin in centimeters
     * @param num_bins     number of bins
     * @return float distance in centimeters with precision of two decimal
     */
    static float calcStep(float range_first, float range_last, short num_bins) {
        float step=(range_last-range_first)/(num_bins-1);
        BigDecimal bd=new BigDecimal(step);
        BigDecimal result=bd.setScale(2, RoundingMode.HALF_DOWN);
        return result.floatValue();
    }

    /** Calculate azimuth of a ray
     * @param az0  azimuth at beginning of ray (binary angle)
     * @param az1  azimuth at end of ray (binary angle)
     * @return float azimuth in degrees with precision of two decimal
     */
    static float calcAz(short az0, short az1) {
        // output in deg
        float azim0=calcAngle(az0);
        float azim1=calcAngle(az1);
        float d=0.0f;
        d=Math.abs(azim0-azim1);
        if ((az0 < 0)&(az1 > 0)) { d=Math.abs(360.0f-azim0)+Math.abs(azim1)}
        double temp=azim0+d*0.5;
        if (temp>360.0) { temp-=360.0; }
        BigDecimal bd=new BigDecimal(temp);
        BigDecimal result=bd.setScale(2, RoundingMode.HALF_DOWN);
        return result.floatValue();
    }

    /** Calculate data values from raw ingest data
     * @param recHdr  java.util.Map object with values for calculation
     * @param dty     type of data ( "Total_Power", "Reflectivity", "Velocity",
     *                "Width", "Differential_Reflectivity")
     * @param data    1-byte input value
     * @return float value with precision of two decimal
     */
    static float calcData(Map<String, Number> recHdr, short dty, byte data) {
        short[] coef={1, 2, 3, 4}; // MultiPRF modes
        short multiprf=((Short)recHdr.get("multiprf")).shortValue();
        float vNyq=((Float)recHdr.get("vNyq")).floatValue();
        double temp=-999.99;
        switch (dty) {
        default:        // dty=1,2 -total_power, reflectivity (dBZ)
            if (data != 0) { temp=(((int)data & 0xFF)-64)*0.5; }
            break;
        case 3:        // dty=3 - mean velocity (m/sec)
            if (data != 0) {
                temp=((((int)data & 0xFF)-128)/127.0)*vNyq*coef[multiprf]}
            break;
        case 4:        // dty=4 - spectrum width (m/sec)
            if (data != 0) {
                double v=((((int)data & 0xFF)-128)/127.0)*vNyq*coef[multiprf];
                temp=(((int)data & 0xFF)/256.0)*v;  }
            break;
        case 5:        // dty=5 - differential reflectivity (dB)
            if (data != 0) {
                temp=((((int)data & 0xFF)-128)/16.0); }
            break;
        }
        BigDecimal bd=new BigDecimal(temp);
        BigDecimal result=bd.setScale(2, RoundingMode.HALF_DOWN);
        return result.floatValue();
    }

    /** Calculate time as hh:mm:ss
     * @param t   number of seconds since midnight for start of sweep
     * @param t0  time in seconds from start of sweep
     * @return time as string "hh:mm:ss"
     */
    static String calcTime(int t, int t0) {
        StringBuilder tim=new StringBuilder();
        int[] tt=new int[3];
        int mmh=(t+t0)/60;
        tt[2]=(t+t0)%60;                  // Define SEC
        tt[0]=mmh/60;                     // Define HOUR
        tt[1]=mmh%60;                     // Define MIN
        for (int i=0; i<3; i++) {
            String s=Integer.toString(tt[i]);
            int len=s.length();
            if (len < 2) { s="0"+tt[i]; }
            if (i != 2) s+=":";
            tim.append(s);
        }
        return tim.toString();
    }
    /** Calculate of Nyquist velocity
     * @param prf   PRF in Hertz
     * @param wave  wavelength in 1/100 of centimeters
     * @return float value of Nyquist velocity in m/sec with precision of two decimal
     */
   static float calcNyquist(int prf, int wave) {
        double tmp=(prf*wave*0.01)*0.25;
        tmp=tmp*0.01;                    //Make it m/sec
        BigDecimal bd=new BigDecimal(tmp);
        BigDecimal result=bd.setScale(2, RoundingMode.HALF_DOWN);
        return result.floatValue();
    }


    // dummy implementations of other methods
    public Array readNestedData(Variable v2, List section) throws IOException, InvalidRangeException {
        return null;
    }
    public void close() throws java.io.IOException {
      myRaf.close();
    }

//   public void close() throws IOException {  }
//    public boolean syncExtend() throws IOException {
//        return false;
//    }
//    public boolean sync() throws IOException {
//        return false;
//    }
    public void setSpecial(Object special) {  }
    public String toStringDebug(Object o) {
        return null;
    }
    public String getDetailInfo() {
        return null;
    }


}
TOP

Related Classes of ucar.nc2.iosp.sigmet.SigmetIOServiceProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.