ucar.nc2.iosp.uf.UFheader 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.uf;
import ucar.unidata.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: yuanho
* Date: Sep 24, 2008
* Time: 3:53:18 PM
* To change this template use File | Settings | File Templates.
*/
public class UFheader {
static final boolean littleEndianData = true;
String dataFormat = "UNIVERSALFORMAT"; // temp setting
Ray firstRay = null;
Date endDate = null;
Map>> variableGroup; // key = data type, value = List by sweep number
private int max_radials = 0;
private int min_radials = Integer.MAX_VALUE;
public boolean isValidFile(ucar.unidata.io.RandomAccessFile raf) {
try {
raf.order(RandomAccessFile.BIG_ENDIAN);
raf.seek(4);
String ufStr = raf.readString(2);
if (!ufStr.equals("UF"))
return false;
//if ufStr is UF, then a further checking apply
raf.seek(0);
int rsize = raf.readInt();
byte[] buffer = new byte[rsize];
long offset = raf.getFilePointer();
int readBytes = raf.read(buffer, 0, rsize);
if (readBytes != rsize) {
return false;
}
int endPoint = raf.readInt();
if (endPoint != rsize) {
return false;
}
ByteBuffer bos = ByteBuffer.wrap(buffer);
firstRay = new Ray(bos, rsize, offset);
} catch (IOException e) {
return (false);
}
return true;
}
void read(ucar.unidata.io.RandomAccessFile raf) throws IOException {
Map> rayListMap = new HashMap<>(600); // all the rays for a variable
raf.seek(0);
raf.order(RandomAccessFile.BIG_ENDIAN);
while (!raf.isAtEndOfFile()) {
byte[] b4 = new byte[4];
int bytesRead = raf.read(b4);
if (bytesRead != 4) break; // done
int rsize = bytesToInt(b4, false);
byte[] buffer = new byte[rsize];
long offset = raf.getFilePointer();
raf.readFully(buffer);
raf.readFully(b4);
int endPoint = bytesToInt(b4, false);
if (endPoint != rsize || rsize == 0) {
// System.out.println("Herr " +velocityList.size());
continue;
}
ByteBuffer bos = ByteBuffer.wrap(buffer);
Ray r = new Ray(bos, rsize, offset);
if (firstRay == null)
{
firstRay = r;
endDate = r.getDate();
} else if (r.getTitleMsecs() > firstRay.getTitleMsecs())
endDate = r.getDate();
Map rayMap = r.field_header_map; // each ray has a list of variables
for (Map.Entry entry : rayMap.entrySet()) {
String ab = entry.getKey(); // variable name
List group = rayListMap.get(ab); // all the rays for this variable
if (null == group) {
group = new ArrayList<>();
rayListMap.put(ab, group);
}
group.add(r);
}
}
// now sort the rays by sweep number
variableGroup = new HashMap<>();
for (Map.Entry> entry : rayListMap.entrySet()) {
String key = entry.getKey();
List group = entry.getValue();
List> sortedGroup = sortScans(key, group);
variableGroup.put(key, sortedGroup);
}
//System.out.println("Herr " +velocityList.size());
//return;
}
private List> sortScans(String name, List rays) {
// now group by sweepNumber
Map> sweepMap = new HashMap<>(2*rays.size());
for ( Ray r : rays) {
Integer groupNo = (int) r.uf_header2.sweepNumber; //.elevation);
List group = sweepMap.get(groupNo);
if (null == group) {
group = new ArrayList<>();
sweepMap.put(groupNo, group);
}
group.add(r);
}
// sort the groups by elevation
List> groups = new ArrayList<>(sweepMap.values());
Collections.sort(groups, new GroupComparator());
// count rays in each group
for (List group : groups) {
max_radials = Math.max(max_radials, group.size());
min_radials = Math.min(min_radials, group.size());
}
return groups;
}
/* public float getMeanElevation(String key, int eNum) {
List gp = getGroup(key);
return getMeanElevation(gp);
}
public float getMeanElevation(List gList) {
float sum = 0;
int size = 0;
for (Ray r : gList) {
sum += r.getElevation();
size++;
}
return sum / size;
}
public List getGroup(String key) {
return variableGroup.get(key);
} */
public int getMaxRadials() {
return max_radials;
}
public String getDataFormat() {
return dataFormat;
}
public Date getStartDate() {
return firstRay.getDate();
}
public Date getEndDate() {
return endDate;
}
public float getHorizontalBeamWidth(String ab) {
return firstRay.getHorizontalBeamWidth(ab);
}
public String getStationId() {
return getSiteName();
}
public String getSiteName() {
return firstRay.uf_header2.siteName;
}
String getRadarName() {
return firstRay.uf_header2.radarName;
}
public Short getSweepMode() {
return firstRay.uf_header2.sweepMode;
}
public float getStationLatitude() {
return firstRay.getLatitude();
}
public float getStationLongitude() {
return firstRay.getLongtitude();
}
public short getStationElevation() {
return firstRay.uf_header2.height;
}
public short getMissingData() {
return firstRay.getMissingData();
}
private static class GroupComparator implements Comparator> {
public int compare(List group1, List group2) {
Ray ray1 = group1.get(0);
Ray ray2 = group2.get(0);
//if (record1.elevation_num != record2.elevation_num)
return (ray1.uf_header2.elevation - ray2.uf_header2.elevation < 13 ? 0 : 1);
//return record1.cut - record2.cut;
}
}
protected short getShort(byte[] bytes, int offset) {
int ndx0 = offset + (littleEndianData ? 1 : 0);
int ndx1 = offset + (littleEndianData ? 0 : 1);
// careful that we only allow sign extension on the highest order byte
return (short) (bytes[ndx0] << 8 | (bytes[ndx1] & 0xff));
}
public static int bytesToShort(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);
}
}
public static int bytesToInt(byte[] bytes, boolean swapBytes) {
byte a = bytes[0];
byte b = bytes[1];
byte c = bytes[2];
byte d = bytes[3];
if (swapBytes) {
return ((a & 0xff)) +
((b & 0xff) << 8) +
((c & 0xff) << 16) +
((d & 0xff) << 24);
} else {
return ((a & 0xff) << 24) +
((b & 0xff) << 16) +
((c & 0xff) << 8) +
((d & 0xff));
}
}
}