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