ucar.nc2.iosp.sigmet.SigmetIOServiceProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdm Show documentation
Show all versions of cdm Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
The newest version!
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.CDM;
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 { 0,0,0,...}
* Record #2 { 0,0,0,... }
* ---if there are several sweeps (usually 24) and one type of data:
* Record #3 { ...Data for sweep 1.. }
* Record #4 { ...Data for sweep 1... }
* .............................................
* Record #n { ...Data for sweep 1... 0.... }
* Record #n+1 { ...Data for sweep 2.. }
* Record #n+2 { ...Data for sweep 2... }
* .............................................
* Record #m { ...Data for sweep 2... 0... }
* Record #m+1 { ...Data for sweep 3.. }
* .............................................
* Structure of "Data for sweep" is: ......
* and 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 { ...
* ...Data...}
* Record #4 { ...Data... }
* .............................................
* Record #n { ...Data... }
* Structure of "Data" is: ...
*
* ... ...
* and are encoded with the compression algorithm
* ("IRIS Programmer's Manual" 3.5.4.1)
*
* @author yuanho
* @see "ftp://ftp.sigmet.com/outgoing/manuals/program/3data.pdf"
* esp section 3.5
*/
public class SigmetIOServiceProvider extends AbstractIOServiceProvider {
private ArrayList varList = null;
private int[] tsu_sec = null;
private int[] sweep_bins = null;
private String date0;
public static java.util.Map recHdr = new java.util.HashMap();
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);
// The first struct in the file is the product_hdr, which will have the
// standard structure_header, followed by other embedded structures.
// Each of these structures also have a structure header. To validate
// the file we check for a product_hdr (by looking for type 27 in the
// structure_header), then a product_configuration structure (by looking
// for type 26 in its structure_header), then checking that that
// the product_configuration does indicate a type of RAW data (type 15)
raf.seek(0);
short[] data = new short[13];
raf.readShort(data, 0, 13);
return (data[0] == (short) 27 &&
data[6] == (short) 26 &&
data[12] ==(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 {
super.open(raf, ncfile, cancelTask);
//java.util.Map recHdr=new java.util.HashMap();
java.util.Map hdrNames = new java.util.HashMap();
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 readRecordsHdr(ucar.unidata.io.RandomAccessFile raf) {
java.util.Map recHdr1 = new java.util.HashMap();
try {
int nparams = 0;
// -- Read from 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", 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(); // 3d rec
raf.skipBytes(2);
short year = raf.readShort();
short month = raf.readShort();
short day = raf.readShort();
recHdr1.put("radar_lat", calcAngle(radar_lat));
recHdr1.put("radar_lon", calcAngle(radar_lon));
recHdr1.put("range_first", range_first);
recHdr1.put("range_last", range_last);
recHdr1.put("ground_height", ground_height);
recHdr1.put("radar_height", radar_height);
recHdr1.put("radar_alt", radar_alt);
recHdr1.put("step", step);
recHdr1.put("bins", bins); //System.out.println(" bins="+bins);
recHdr1.put("num_rays", num_rays); //System.out.println(" rays="+num_rays);
recHdr1.put("nparams", nparams);//System.out.println(" nparams="+nparams);
recHdr1.put("multiprf", multiprf);
recHdr1.put("number_sweeps", number_sweeps); //System.out.println("IN HDR: number_sweeps="+number_sweeps);
recHdr1.put("year", year);
recHdr1.put("month", month);
recHdr1.put("day", day);
recHdr1.put("base_time", base_time);
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
return recHdr1;
}
/**
* Read StationName strings
*/
public java.util.Map readStnNames(ucar.unidata.io.RandomAccessFile raf) {
java.util.Map hdrNames = new java.util.HashMap();
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 init(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile,
java.util.Map 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 = recHdr.get("radar_lat").floatValue(); //System.out.println("rad_lat="+radar_lat);
float radar_lon = recHdr.get("radar_lon").floatValue(); //System.out.println("rad_lon="+radar_lon);
short ground_height = recHdr.get("ground_height").shortValue(); //System.out.println("ground_H="+ground_height);
short radar_height = recHdr.get("radar_height").shortValue(); //System.out.println("radar_H="+radar_height);
int radar_alt = (recHdr.get("radar_alt").intValue()) / 100; //System.out.println("rad_alt="+radar_alt);
short num_rays = recHdr.get("num_rays").shortValue(); //System.out.println("num_rays="+num_rays);
short bins = recHdr.get("bins").shortValue(); //System.out.println("bins="+bins);
float range_first = (recHdr.get("range_first").intValue()) * 0.01f; //System.out.println("range_1st="+range_first);
float range_last = (recHdr.get("range_last").intValue()) * 0.01f; //System.out.println("step="+step);
short number_sweeps = recHdr.get("number_sweeps").shortValue();
//System.out.println("number_sweeps="+number_sweeps);
int nparams = (recHdr.get("nparams").intValue()); //System.out.println("nparams="+nparams);
short year = recHdr.get("year").shortValue(); //System.out.println("year="+year);
short month = recHdr.get("month").shortValue();
short day = recHdr.get("day").shortValue();
int base_time = (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 dims0 = new ArrayList();
ArrayList dims1 = new ArrayList();
ArrayList dims2 = new ArrayList();
ArrayList dims3 = new ArrayList();
ArrayList varList = new ArrayList();
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(CDM.LONG_NAME, var_name));
v[j][jj].addAttribute(new Attribute(CDM.UNITS, unit[tp]));
String coordinates = "time elevationR azimuthR distanceR";
v[j][jj].addAttribute(new Attribute(_Coordinate.Axes, coordinates));
v[j][jj].addAttribute(new Attribute(CDM.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(CDM.LONG_NAME, "time from start of sweep"));
time[j].addAttribute(new Attribute(CDM.UNITS, time_units[j]));
time[j].addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));
time[j].addAttribute(new Attribute(CDM.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(CDM.LONG_NAME, "elevation angle"));
elevationR[j].addAttribute(new Attribute(CDM.UNITS, "degrees"));
elevationR[j].addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString()));
elevationR[j].addAttribute(new Attribute(CDM.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(CDM.LONG_NAME, "azimuth angle"));
azimuthR[j].addAttribute(new Attribute(CDM.UNITS, "degrees"));
azimuthR[j].addAttribute(new Attribute(_Coordinate.AxisType, AxisType.RadialAzimuth.toString()));
azimuthR[j].addAttribute(new Attribute(CDM.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(CDM.LONG_NAME, "radial distance"));
distanceR[j].addAttribute(new Attribute(CDM.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(CDM.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", radar_lat));
ncfile.addAttribute(null, new Attribute("radar_lon", radar_lon));
ncfile.addAttribute(null, new Attribute("ground_height", ground_height));
ncfile.addAttribute(null, new Attribute("radar_height", radar_height));
ncfile.addAttribute(null, new Attribute("radar_alt", radar_alt));
ncfile.addAttribute(null, new Attribute("num_data_types", nparams));
ncfile.addAttribute(null, new Attribute("number_sweeps", 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", num_rays));
ncfile.addAttribute(null, new Attribute("max_number_gates", bins));
ncfile.addAttribute(null, new Attribute("range_first", range_first));
ncfile.addAttribute(null, new Attribute("range_last", range_last));
ncfile.addAttribute(null, new Attribute("DataType", "Radial"));
ncfile.addAttribute(null, new Attribute(CDM.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 varList, java.util.Map 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 = recHdr.get("radar_lat").floatValue(); //System.out.println("rad_lat="+radar_lat);
float radar_lon = recHdr.get("radar_lon").floatValue(); //System.out.println("rad_lon="+radar_lon);
short ground_height = recHdr.get("ground_height").shortValue(); //System.out.println("ground_H="+ground_height);
short radar_height = recHdr.get("radar_height").shortValue(); //System.out.println("radar_H="+radar_height);
int radar_alt = (recHdr.get("radar_alt").intValue()) / 100; //System.out.println("rad_alt="+radar_alt);
short num_rays = recHdr.get("num_rays").shortValue(); //System.out.println("HERE!! num_rays="+num_rays);
float range_first = (recHdr.get("range_first").intValue()) * 0.01f; //System.out.println("range_1st="+range_first);
float range_last = (recHdr.get("range_last").intValue()) * 0.01f; //System.out.println("step="+step);
short number_sweeps = recHdr.get("number_sweeps").shortValue();
int nparams = (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];
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 (Variable aVarList : varList) {
if ((aVarList.getShortName()).equals(distName.trim())) {
distanceR[i] = aVarList;
break;
}
}
distArr[i] = (ArrayFloat.D1) Array.factory(DataType.FLOAT, distanceR[i].getShape());
distIndex[i] = distArr[i].getIndex();
// for (int jj=0; jj 1) {
t_n = "time_sweep_" + (i + 1);
}
for (Variable aVarList : varList) {
if ((aVarList.getShortName()).equals(t_n.trim())) {
time[i] = aVarList;
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 (Variable aVarList : varList) {
if ((aVarList.getShortName()).equals(azimName.trim())) {
azimuthR[i] = aVarList;
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 (Variable aVarList : varList) {
if ((aVarList.getShortName()).equals(elevName.trim())) {
elevationR[i] = aVarList;
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 (Variable aVarList : varList) {
if ((aVarList.getShortName()).equals("numGates")) {
numGates = aVarList;
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;
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();
else
throw new IllegalStateException("Illegal variable name = "+shortName);
if (section.getRank() == 2) {
Range radialRange = section.getRange(0);
Range gateRange = section.getRange(1);
List lli = 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( 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 = 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 recHdr, short dty, byte data) {
short[] coef = {1, 2, 3, 4}; // MultiPRF modes
short multiprf = recHdr.get("multiprf").shortValue();
float vNyq = 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();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy