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

ucar.nc2.iosp.nowrad.NOWRadiosp 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.*;
import ucar.nc2.Variable;
import ucar.nc2.iosp.AbstractIOServiceProvider;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: yuanho
 * Date: Feb 10, 2010
 * Time: 11:22:03 AM
 * To change this template use File | Settings | File Templates.
 */
public class NOWRadiosp extends AbstractIOServiceProvider {
  final static int DEF_WBITS = 15;
  final static int Z_DEFLATED = 8;

  // used for writing
  protected int fileUsed = 0;    // how much of the file is written to ?
  protected int recStart = 0;    // where the record data starts
  protected boolean debug = false,
          debugSize = false,
          debugSPIO = false;
  protected boolean showHeaderBytes = false;
  protected HashMap dimHash = new HashMap(50);
  protected boolean fill;

  // private Nidsheader.Vinfo myInfo;
  protected NOWRadheader headerParser;
  private int pcode;
  protected boolean readonly;

  /**
   * checking the file
   *
   * @param raf
   * @return the valid of file checking
   */
  public boolean isValidFile(ucar.unidata.io.RandomAccessFile raf) {
    NOWRadheader localHeader = new NOWRadheader();

    return (localHeader.isValidFile(raf));
  }

  public String getFileTypeId() {
    return "NOWRAD";
  }

  public String getFileTypeDescription() {
    return "NOWRAD Products";
  }

  /**
   * Open the file and read the header part
   *
   * @param raf
   * @param file
   * @param cancelTask
   * @throws java.io.IOException
   */
  public void open(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile file,
                   ucar.nc2.util.CancelTask cancelTask)
          throws IOException {
    super.open(raf, ncfile, cancelTask);
    headerParser = new NOWRadheader();

    try {
      headerParser.read(this.raf, ncfile);
    } catch (Exception e) {
    }

    // myInfo = headerParser.getVarInfo();
    pcode = 0;
    ncfile.finish();
  }

  /**
   * Read the data for each variable passed in
   *
   * @param v2
   * @param section
   * @return output data
   * @throws IOException
   * @throws ucar.ma2.InvalidRangeException
   */
  public Array readData(Variable v2, Section section) throws IOException, InvalidRangeException {

    // subset
    Object data;
    Array outputData;
    byte[] vdata = null;
    NOWRadheader.Vinfo vinfo;
    ByteBuffer bos;
    List ranges = section.getRanges();

    vinfo = (NOWRadheader.Vinfo) v2.getSPobject();
    vdata = headerParser.getData((int) vinfo.hoff);

    bos = ByteBuffer.wrap(vdata);
    data = readOneScanData(bos, vinfo, v2.getShortName());
    outputData = Array.factory(v2.getDataType(), v2.getShape(), data);
    outputData = outputData.flip(1);

    // outputData = outputData.flip(2);
    return (outputData.sectionNoReduce(ranges).copy());

    // return outputData;
  }

  /**
   * Read one scan radar data
   *
   * @param bos   Data buffer
   * @param vinfo variable info
   * @return the data object of scan data
   */

  // all the work is here, so can be called recursively
  public Object readOneScanData(ByteBuffer bos, NOWRadheader.Vinfo vinfo, String vName)
          throws IOException, InvalidRangeException {
    int doff = (int) vinfo.hoff;
    int npixel = vinfo.yt * vinfo.xt;
    byte[] rdata = null;
    byte[] ldata = new byte[vinfo.xt];
    byte[] pdata = new byte[npixel];
    byte[] b2 = new byte[2];

    bos.position(doff);

    // begining of image data
    if ((DataType.unsignedByteToShort(bos.get()) != 0xF0) || (bos.get() != 0x0C)) {
      return null;
    }

    int ecode;
    int color;
    int datapos;
    int offset = 0;
    int roffset = 0;
    boolean newline = true;
    int linenum = 0;

    while (true) {

      // line number
      if (newline) {
        bos.get(b2);
        linenum = (DataType.unsignedByteToShort(b2[1]) << 8) + DataType.unsignedByteToShort(b2[0]);

        // System.out.println("Line Number = " + linenum);
      }

      // int linenum = bytesToInt(b2[0], b2[1], true);
      // System.out.println("Line Number = " + linenum);
      // if(linenum == 1225)
      //   System.out.println(" HHHHH");
      short b = DataType.unsignedByteToShort(bos.get());

      color = b & 0xF;
      ecode = b >> 4;
      datapos = bos.position();

      int datarun;

      if (ecode == 0xF) {
        byte bb1 = bos.get(datapos - 2);
        byte bb2 = bos.get(datapos);

        if ((color == 0x0) && (bb1 == 0x00) && (bb2 == 0x00)) {
          datapos += 1;
        }

        bos.position(datapos);
        datarun = 0;
      } else if (ecode == 0xE) {
        byte b0 = bos.get(datapos);

        datarun = DataType.unsignedByteToShort(b0) + 1;
        datapos += 1;
        bos.position(datapos);
      } else if (ecode == 0xD) {
        b2[0] = bos.get(datapos);
        b2[1] = bos.get(datapos + 1);
        datarun = (DataType.unsignedByteToShort(b2[1]) << 8) + DataType.unsignedByteToShort(b2[0]) + 1;
        datapos += 2;
        bos.position(datapos);
      } else {
        datarun = ecode + 1;
      }

      // move the unpacked data in the data line
      rdata = new byte[datarun];

      for (int i = 0; i < datarun; i++) {
        rdata[i] = (byte) color;
      }

      System.arraycopy(rdata, 0, ldata, roffset, datarun);
      roffset = roffset + datarun;

      // System.out.println("run ecode = " + ecode + " and data run " + datarun + " and totalrun " + roffset);
      // check to see if the beginning of the next line or at the end of the file
      short c0 = DataType.unsignedByteToShort(bos.get());

      if (c0 == 0x00) {
        short c1 = DataType.unsignedByteToShort(bos.get());
        short c2 = DataType.unsignedByteToShort(bos.get());

        // System.out.println("c1 and c2 " + c1 + " " + c2);

        if ((c0 == 0x00) && (c1 == 0xF0) && (c2 == 0x0C)) {
          // beginning of next line
          //  System.out.println("linenum   " + linenum + "   and this line total " + roffset);
          //  if (roffset != 3661) {
          //      System.out.println("ERROR missing data, this line total only " + roffset);
          //  }
          System.arraycopy(ldata, 0, pdata, offset, roffset);
          offset = offset + vinfo.xt;
          roffset = 0;
          newline = true;
          ldata = new byte[vinfo.xt];
        } else if ((c1 == 0xF0) && (c2 == 0x02)) {
          // end of the file
          break;
        } else {
          datapos = bos.position() - 3;
          bos.position(datapos);
          newline = false;
        }
      } else {
        newline = false;
        datapos = bos.position();
        bos.position(datapos - 1);
      }
    }

    return pdata;
  }

  int getUInt(byte[] b, int num) {
    int base = 1;
    int i;
    int word = 0;
    int bv[] = new int[num];

    for (i = 0; i < num; i++) {
      bv[i] = DataType.unsignedByteToShort(b[i]);
    }

    /*
    * Calculate the integer value of the byte sequence
    */
    for (i = num - 1; i >= 0; i--) {
      word += base * bv[i];
      base *= 256;
    }

    return word;
  }

  public static int bytesToInt(short a, short 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);
    }
  }

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


  /**
   * Read data from encoded values and run len into regular data array
   *
   * @param ddata is encoded data values
   * @return the data array of row data
   */
  public byte[] readOneRowData(byte[] ddata, int rLen, int xt) throws IOException, InvalidRangeException {
    int run;
    byte[] bdata = new byte[xt];
    int nbin = 0;
    int total = 0;

    for (run = 0; run < rLen; run++) {
      int drun = DataType.unsignedByteToShort(ddata[run]) >> 4;
      byte dcode1 = (byte) (DataType.unsignedByteToShort(ddata[run]) & 0Xf);

      for (int i = 0; i < drun; i++) {
        bdata[nbin++] = dcode1;
        total++;
      }
    }

    if (total < xt) {
      for (run = total; run < xt; run++) {
        bdata[run] = 0;
      }
    }

    return bdata;
  }


  int getUInt(byte[] b, int offset, int num) {
    int base = 1;
    int i;
    int word = 0;
    int bv[] = new int[num];

    for (i = 0; i < num; i++) {
      bv[i] = DataType.unsignedByteToShort(b[offset + i]);
    }

    /*
    * Calculate the integer value of the byte sequence
    */
    for (i = num - 1; i >= 0; i--) {
      word += base * bv[i];
      base *= 256;
    }

    return word;
  }

  int getInt(byte[] b, int offset, int num) {
    int base = 1;
    int i;
    int word = 0;
    int bv[] = new int[num];

    for (i = 0; i < num; i++) {
      bv[i] = DataType.unsignedByteToShort(b[offset + i]);
    }

    if (bv[0] > 127) {
      bv[0] -= 128;
      base = -1;
    }

    /*
    * Calculate the integer value of the byte sequence
    */

    for (i = num - 1; i >= 0; i--) {
      word += base * bv[i];
      base *= 256;
    }

    return word;
  }

  @Override
  public void reacquire() throws IOException {
    super.reacquire();
    headerParser.raf = this.raf;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy