Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cdm-radial: sigmet fixes #1295

Merged
merged 22 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 154 additions & 57 deletions cdm/radial/src/main/java/ucar/nc2/iosp/sigmet/Ray.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,48 @@

package ucar.nc2.iosp.sigmet;

import ucar.ma2.DataType;
import ucar.ma2.IndexIterator;
import ucar.ma2.Range;
import ucar.unidata.io.RandomAccessFile;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Formatter;

/**
* @author yuanho
* @since Apr 7, 2010
*/
public class Ray {
private short bins;

private short bins, bins_actual;
int dataRead;
int offset;
int offset1;
private float range, step, az, elev;
private short time;
// int because UINT2 data type (Unsigned 16-bit integer)
private int time;
// private float[] val;
String varName;
int nsweep;
short datatype;
int bytesPerBin;

public Ray(float range, float step, float az, float elev, short bins, int time, int offset, int dataRead, int offset1,
int nsweep, String name, short datatype, int bytesPerBin) {
this(range, step, az, elev, bins, bins, time, offset, dataRead, offset1, nsweep, name, datatype, 1);
}

public Ray(float range, float step, float az, float elev, short bins, short time, int offset, int dataRead,
int offset1, int nsweep, String name, short datatype) {
public Ray(float range, float step, float az, float elev, short bins, short bins_actual, int time, int offset,
int dataRead, int offset1, int nsweep, String name, short datatype, int bytesPerBin) {

// this.val = new float[bins];
setRange(range);
setStep(step);
setAz(az);
setElev(elev);
setBins(bins);
setBinsActual(bins_actual);
setTime(time);
setOffset(offset);
setDataRead(dataRead);
Expand All @@ -45,7 +55,7 @@ public Ray(float range, float step, float az, float elev, short bins, short time
setName(name);
setNsweep(nsweep);
setDataType(datatype);

setBytesPerBin(bytesPerBin);
}

public short getDataType() {
Expand All @@ -56,6 +66,14 @@ public void setDataType(short datatype) {
this.datatype = datatype;
}

public int getBytesPerBin() {
return bytesPerBin;
}

public void setBytesPerBin(int bytesPerBin) {
this.bytesPerBin = bytesPerBin;
}

public float getRange() {
return range;
}
Expand Down Expand Up @@ -108,11 +126,19 @@ public void setBins(short bins) {
this.bins = bins;
}

public short getTime() {
public short getBinsActual() {
return bins_actual;
}

public void setBinsActual(short bins_actual) {
this.bins_actual = bins_actual;
}

public int getTime() {
return time;
}

public void setTime(short time) {
public void setTime(int time) {
this.time = time;
}

Expand Down Expand Up @@ -140,15 +166,6 @@ public void setOffset1(int offset1) {
this.offset1 = offset1;
}

/*
* public float[] getVal() {
* return val;
* }
*
* public void setVal(float[] val) {
* System.arraycopy(val, 0, this.val, 0, bins);
* }
*/
public void setName(String name) {
this.varName = name;
}
Expand All @@ -163,15 +180,17 @@ public boolean equals(Object o) {
} else if (o instanceof Ray) {
Ray oo = (Ray) o;

return (range == oo.range & step == oo.step & az == oo.az & elev == oo.elev & bins == oo.bins & time == oo.time);
return (range == oo.range & step == oo.step & az == oo.az & elev == oo.elev & bins == oo.bins
& bins_actual == oo.bins_actual & time == oo.time & bytesPerBin == oo.bytesPerBin);
} else {
return false;
}
}

public int hashCode() {
return new Float(range).hashCode() + new Float(step).hashCode() + new Float(az).hashCode()
+ new Float(elev).hashCode() + new Short(bins).hashCode() + new Short(time).hashCode();
+ new Float(elev).hashCode() + new Short(bins).hashCode() + new Short(bins_actual).hashCode()
+ new Integer(time).hashCode() + new Integer(bytesPerBin).hashCode();

// val.hashCode();
}
Expand All @@ -184,7 +203,7 @@ public String toString() {
az = 360.0f + az;
}

sb.format(" Az=%f Elev=%f Bins=%d Time=%d", az, elev, bins, time);
sb.format(" Az=%f Elev=%f Bins=%d (%d) Time=%d", az, elev, bins, bins_actual, time);
// for (int i=0; i<bins; i++) { sb.append(" "+val[i]); }
return sb.toString();
}
Expand All @@ -196,84 +215,162 @@ public String toString() {
* @param raf read from this file
* @param gateRange handles the possible subset of data to return
* @param ii put the data here
* @throws java.io.IOException on read error
* @throws IOException on read error
*/
public void readData(RandomAccessFile raf, Range gateRange, IndexIterator ii) throws IOException {
int REC_SIZE = 6144;
raf.seek(offset);
byte[] data = new byte[bins];
float[] dd = new float[bins];
byte d;
// first need to read all the data (because bytesPerBin could be > 1)
Byte[] dd = new Byte[bins * bytesPerBin];
int nb = 0;
short a00;
// raf.readFully(data);

short dty = getDataType();

int posInRay_absolute = 0;

if (dataRead > 0) {
raf.seek(offset);

for (int i = 0; i < dataRead; i++) {
d = raf.readByte();
dd[i] = SigmetIOServiceProvider.calcData(SigmetIOServiceProvider.recHdr, getDataType(), d);
nb++;
dd[i] = raf.readByte();
posInRay_absolute++;
if (posInRay_absolute % bytesPerBin == 0)
nb++;
}
}
raf.seek(offset1);
int cur_len = offset1;

// this only works for 1 additional record, not for more. Only a theoretical possibility for now.
// (relevant only for data types with a lot of bytes per bin)
while (nb < (int) bins) {
// --- Check if the code=1 ("1" means an end of a ray)
a00 = raf.readShort();
cur_len = cur_len + 2;

// end of ray
if (a00 == (short) 1) {
for (int uk = 0; uk < (int) bins; uk++) {
dd[uk] = -999.99f;
}
// don't need to do anything as the rest of dd is already null
break;
}

if (a00 < 0) { // -- This is data
int nwords = a00 & 0x7fff;
int dataRead1 = nwords * 2;
int pos = 0;
if (cur_len % REC_SIZE == 0) {
boolean breakOuterLoop = false;
if (cur_len % SigmetVolumeScan.REC_SIZE == 0) {
break;
}
raf.seek(cur_len);
for (int i = 0; i < dataRead1; i++) {
d = raf.readByte();
dd[nb] = SigmetIOServiceProvider.calcData(SigmetIOServiceProvider.recHdr, getDataType(), d);
nb = nb + 1;
cur_len = cur_len + 1;
if (nb % REC_SIZE == 0) {
pos = i + 1;
for (int i = 0; i < dataRead1 && nb < bins; i++) {
dd[posInRay_absolute] = raf.readByte();
posInRay_absolute++;
if (posInRay_absolute % bytesPerBin == 0)
nb++;

cur_len++;

if (cur_len % SigmetVolumeScan.REC_SIZE == 0) {
breakOuterLoop = true;
break;
}
}

if (pos > 0) {
if (breakOuterLoop) {
break;
}

} else if (a00 > 0 & a00 != 1) {
int num_zero = a00 * 2;
int dataRead1 = num_zero;
for (int k = 0; k < dataRead1; k++) {
dd[nb + k] = SigmetIOServiceProvider.calcData(SigmetIOServiceProvider.recHdr, getDataType(), (byte) 0);
}
nb = nb + dataRead1;
if (cur_len % REC_SIZE == 0) {
break;
}
for (int k = 0; k < dataRead1 && nb < bins; k++) {
dd[posInRay_absolute] = 0;
posInRay_absolute++;
if (posInRay_absolute % bytesPerBin == 0)
nb++;

if (cur_len % SigmetVolumeScan.REC_SIZE == 0) {
break;
}
}
}

} // ------ end of while for num_bins---------------------------------

for (int gateIdx : gateRange) {
if (gateIdx >= bins)
ii.setFloatNext(Float.NaN);
else
ii.setFloatNext(dd[gateIdx]);
// only supporting float, double, byte and byte[]/Object for now
DataType dType = SigmetIOServiceProvider.calcDataType(dty, bytesPerBin);
switch (dType) {
case FLOAT:
for (int gateIdx : gateRange) {
if (gateIdx >= bins)
ii.setFloatNext(Float.NaN);
else if (gateIdx >= bins_actual)
ii.setFloatNext(SigmetVolumeScan.MISSING_VALUE_FLOAT);
else {
int offset = gateIdx * bytesPerBin;
Byte ddx = dd[offset];
if (ddx == null)
ii.setFloatNext(SigmetVolumeScan.MISSING_VALUE_FLOAT);
else
ii.setFloatNext(SigmetIOServiceProvider.calcData(SigmetIOServiceProvider.recHdr, dty, ddx));
}
}
break;
case DOUBLE:
for (int gateIdx : gateRange) {
if (gateIdx >= bins)
ii.setDoubleNext(Double.NaN);
else if (gateIdx >= bins_actual)
ii.setDoubleNext(SigmetVolumeScan.MISSING_VALUE_DOUBLE);
else {
int offset = gateIdx * bytesPerBin;
Byte ddx = dd[offset];
if (ddx == null)
ii.setDoubleNext(SigmetVolumeScan.MISSING_VALUE_DOUBLE);
else {
int ddx2 = dd[offset + 1];
int rawValue = (ddx & 0xFF) | ((ddx2 & 0xFF) << 8);
ii.setDoubleNext(SigmetIOServiceProvider.calcData(SigmetIOServiceProvider.recHdr, dty, rawValue));
}
}
}
break;
case BYTE:
for (int gateIdx : gateRange) {
if (gateIdx >= bins)
ii.setByteNext(SigmetVolumeScan.MISSING_VALUE_BYTE);
else if (gateIdx >= bins_actual)
ii.setByteNext(SigmetVolumeScan.MISSING_VALUE_BYTE);
else {
int offset = gateIdx * bytesPerBin;
Byte ddx = dd[offset];
if (ddx == null)
ii.setByteNext(SigmetVolumeScan.MISSING_VALUE_BYTE);
else
ii.setByteNext(ddx);
}
}
break;
default:
for (int gateIdx : gateRange) {
if (gateIdx >= bins)
ii.setObjectNext(SigmetVolumeScan.MISSING_VALUE_BYTE_ARRAY_BB);
else if (gateIdx >= bins_actual)
ii.setObjectNext(SigmetVolumeScan.MISSING_VALUE_BYTE_ARRAY_BB);
else {
int offset = gateIdx * bytesPerBin;
Byte ddx = dd[offset];
if (ddx == null)
ii.setObjectNext(SigmetVolumeScan.MISSING_VALUE_BYTE_ARRAY_BB);
else {
byte[] b = new byte[bytesPerBin];
for (int i = 0; i < bytesPerBin; i++) {
ddx = dd[offset + i];
b[i] = ddx == null ? SigmetVolumeScan.MISSING_VALUE_BYTE : ddx;
}
ii.setObjectNext(ByteBuffer.wrap(b));
}
}
}
}

} // end of readData
} // class Ray end------------------------------------------

Expand Down
Loading
Loading