package edu.colostate.vchill.netcdf;
import edu.colostate.vchill.ChillDefines;
import edu.colostate.vchill.ControlMessage;
import edu.colostate.vchill.ScaleManager;
import edu.colostate.vchill.cache.CacheMain;
import edu.colostate.vchill.chill.*;
import edu.colostate.vchill.file.FileFunctions;
import ucar.ma2.Array;
import ucar.ma2.DataType;
import ucar.ma2.Index;
import ucar.nc2.Dimension;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Class for reading CASA NetCDF archive files
*
* @author Jochen Deyke
* @author jpont
* @version 2010-08-30
*/
public class CASANetCDFFile {
private static final ScaleManager sm = ScaleManager.getInstance();
private static final Map<String, ChillFieldInfo> infos = new HashMap<String, ChillFieldInfo>();
public static final ChillFieldInfo Z = new ChillFieldInfo("dBZ", "Reflectivity", 12, 7500000, -1000000, 0, 0);
public static final ChillFieldInfo V = new ChillFieldInfo("Vel", "Velocity", 13, 5500000, -5500000, 16, 1);
public static final ChillFieldInfo W = new ChillFieldInfo("Wid", "SpectralWidth", 14, 800000, 0, 0, 2);
public static final ChillFieldInfo NCP = new ChillFieldInfo("NCP", "NormalizedCoherentPower", 15, 100000, 0, 0, 3);
public static final ChillFieldInfo ZDR = new ChillFieldInfo("ZDR", "DifferentialReflectivity", 16, 9030899, -3010299, 0, 4);
public static final ChillFieldInfo PHIDP = new ChillFieldInfo("PHIDP", "DifferentialPhase", 19, 90000000, -90000000, 0, 6);
public static final ChillFieldInfo RHOHV = new ChillFieldInfo("RhoHV", "CrossPolCorrelation", 20, 1000000, 0, 0, 7);
public static final ChillFieldInfo KDP = new ChillFieldInfo("KDP", "SpecificPhase", 22, 3000000, -1000000, 0, 7);
public static final ChillFieldInfo CZ = new ChillFieldInfo("CdBZ", "CorrectedReflectivity", 32, 7500000, -1000000, 0, 0); //change number?
public static final ChillFieldInfo CZDR = new ChillFieldInfo("CZDR", "CorrectedDifferentialReflectivity", 36, 9030899, -3010299, 0, 4); //change number?
public static final ChillFieldInfo AZ = new ChillFieldInfo("AdBZ", "AdjustedReflectivity", 42, 7500000, -1000000, 0, 0); //change number?
public static final ChillFieldInfo AZDR = new ChillFieldInfo("AZDR", "AdjustedDifferentialReflectivity", 46, 9030899, -3010299, 0, 4); //change number?
public static final ChillFieldInfo ASDP = new ChillFieldInfo("ASDP", "AdptSpecificDifferentialPhase", 0, 25500000, 0, 0, 1); //fix scale, colors, etc
public static final ChillFieldInfo VFilt = new ChillFieldInfo("VelFilt", "FilteredVelocity", 26, 5500000, -5500000, 16, 1);
public static final ChillFieldInfo VFast = new ChillFieldInfo("VelFast", "VelocityFast", 27, 5500000, -5500000, 16, 1);
public static final ChillFieldInfo VSlow = new ChillFieldInfo("VelSlow", "VelocitySlow", 28, 5500000, -5500000, 16, 1);
private static final ChillFieldInfo[] types = new ChillFieldInfo[]{
Z, V, W, NCP, ZDR, PHIDP, RHOHV, KDP, CZ, CZDR, AZ, AZDR, ASDP, VFilt, VFast, VSlow
};
static {
for (ChillFieldInfo info : types) infos.put(info.longFieldName, info);
}
public static void load(final ControlMessage command, final CacheMain cache) throws IOException {
String path = FileFunctions.stripFileName(command.getDir()) + "/" + FileFunctions.stripFileName(command.getFile());
NetcdfFile ncFile = NetcdfFile.open(path);
Dimension radial = ncFile.hasUnlimitedDimension() ?
ncFile.getUnlimitedDimension() : ncFile.getRootGroup().findDimension("Radial");
Dimension gate = ncFile.getRootGroup().findDimension("Gate");
List<Variable> vars = new ArrayList<Variable>();
List<ChillMomentFieldScale> scales = new ArrayList<ChillMomentFieldScale>();
int fieldNum = 0;
for (Object obj : ncFile.getVariables()) {
while (sm.getScale(fieldNum) != null) ++fieldNum;
Variable var = (Variable) obj;
if (var.getDataType() == DataType.FLOAT) {
vars.add(var);
String units = var.findAttribute("Units").getStringValue().trim();
String description = var.getShortName();
//System.out.println("Found data type: " + description + " in " + units);
ChillFieldInfo info = infos.get(description);
if (info == null) { //unknown
info = new ChillFieldInfo(description.substring(0, 4) + fieldNum, description, fieldNum++, 12800000, -12800000, 0, 0);
}
ChillMomentFieldScale scale = new ChillMomentFieldScale(info, -1, units, 100000, 1, 0);
scales.add(scale);
cache.addRay(command, ChillDefines.META_TYPE, scale);
sm.putScale(scale);
}
}
Array azimuth = ncFile.findVariable("Azimuth").read();
Array elevation = ncFile.findVariable("Elevation").read();
Array gateWidth = ncFile.findVariable("GateWidth").read();
Array startRange = ncFile.findVariable("StartRange").read();
Array time = ncFile.findVariable("Time").read();
Array timenSec = null;
{
Variable tns = ncFile.findVariable("TimenSec");
if (tns != null) timenSec = tns.read();
}
Array[] data = new Array[vars.size()];
long availableData = 0;
for (int typeI = 0; typeI < vars.size(); ++typeI) {
Variable var = vars.get(typeI);
data[typeI] = var.read();
availableData |= 1l << scales.get(typeI).fieldNumber;
}
ChillHSKHeader hskH = new ChillHSKHeader();
hskH.radarLatitude = (int) (1e6 * ncFile.findGlobalAttribute("Latitude").getNumericValue().doubleValue());
hskH.radarLongitude = (int) (1e6 * ncFile.findGlobalAttribute("Longitude").getNumericValue().doubleValue());
hskH.radarId = ncFile.findGlobalAttribute("RadarName").getStringValue();
hskH.angleScale = 0x7fffffff;
cache.addRay(command, ChillDefines.META_TYPE, hskH);
for (int radialI = 0; radialI < radial.getLength(); ++radialI) {
ChillDataHeader dataH = new ChillDataHeader();
Index i1 = azimuth.getIndex().set(radialI);
dataH.availableData = availableData;
//dataH.availableData = -1;
dataH.startAz = dataH.endAz = (int) (azimuth.getDouble(i1) / 360 * hskH.angleScale);
dataH.startEl = dataH.endEl = (int) (elevation.getDouble(i1) / 360 * hskH.angleScale);
dataH.numGates = gate.getLength();
dataH.startRange = startRange.getInt(i1);
dataH.dataTime = time.getInt(i1);
dataH.fractionalSecs = timenSec == null ? 0 : timenSec.getInt(i1);
hskH.gateWidth = (int) gateWidth.getFloat(i1);
cache.addRay(command, ChillDefines.META_TYPE, dataH);
for (int typeI = 0; typeI < vars.size(); ++typeI) {
if (data[typeI] == null) continue;
Index i2 = data[typeI].getIndex().set0(radialI);
double[] typeData = new double[dataH.numGates];
for (int gateI = 0; gateI < dataH.numGates; ++gateI) {
typeData[gateI] = data[typeI].getDouble(i2.set1(gateI));
// System.out.println("Type Data"+typeData[gateI]);
}
cache.addRay(command, scales.get(typeI).fieldName, new ChillGenRay(hskH, dataH, scales.get(typeI).fieldName, typeData));
}
}
for (String type : sm.getTypes()) {
cache.setCompleteFlag(command, type);
System.out.println("marked " + type + " complete; cached " + cache.getNumberOfRays(command, type) + " rays");
}
cache.setCompleteFlag(command, ChillDefines.META_TYPE);
ncFile.close();
}
}