use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class TestTagUniversalFileFormatOneLocOneOb method testMatchup.
@Test
public void testMatchup() throws IOException {
// for this date and ob:
// "2005-04-16 00:00:00",6,21.50,"temperature","Celsius"
// there is a lat/lon matchup
CalendarDate findTimeCd = CalendarDate.parseISOformat("gregorian", "2005-04-16 00:00:00");
long findTime = findTimeCd.toDate().getTime() / 1000;
Variable time = ncd.findVariable("time");
Array timeVals = time.read();
int foundIndex = 0;
boolean found = false;
for (int i = 0; i < timeVals.getSize(); i++) {
long checkTime = timeVals.getLong(i);
if (checkTime == findTime) {
found = true;
foundIndex = i;
}
}
assertTrue(found);
// check that temperature value is as expected
Variable temp = ncd.findVariable("temperature");
Array tempVals = temp.read();
assertEquals(21.50, tempVals.getFloat(foundIndex), 0.001);
}
use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class NetcdfFileManager method calculateCoordVarAttrs.
/**
* Get the auto-computed attributes for a given coordinate VariableInfo object
*
* @param variableInfo The coordinate variable for which attributes should be computed
* @return A list of computed attributes
*/
List<Attribute> calculateCoordVarAttrs(VariableInfo variableInfo) {
List<Attribute> calculatedCoordVarAttrs = new ArrayList<>();
// CoordinateVariable axis
String type = VariableInfoUtils.getCoordVarType(variableInfo);
if (type.equalsIgnoreCase(VariableInfoUtils.longitude)) {
calculatedCoordVarAttrs.add(new Attribute("axis", "X"));
} else if (type.equalsIgnoreCase(VariableInfoUtils.latitude)) {
calculatedCoordVarAttrs.add(new Attribute("axis", "Y"));
} else if (type.equalsIgnoreCase(VariableInfoUtils.vertical)) {
calculatedCoordVarAttrs.add(new Attribute("axis", "Z"));
RosettaAttribute positive = VariableInfoUtils.findAttributeByName(VariableInfoUtils.positiveAttrName, variableInfo);
if (positive != null) {
calculatedCoordVarAttrs.add(new Attribute(positive.getName(), positive.getValue()));
}
}
// CoordinateVariable coverage_content_type
// no good way to guess this - will need to come from the template
int colId = variableInfo.getColumnId();
calculatedCoordVarAttrs.add(new Attribute(colIdAttrName, variableInfo.getColumnId()));
// only for coordinate variables defined in columnar data block (i.e. non-attribute based)
if (colId > 0) {
// CoordinateVariable valid_min, valid_max*
Array data = arrayData.get(variableInfo.getColumnId());
Optional<Double> missingValue = VariableInfoUtils.findMissingValue(variableInfo);
calculatedCoordVarAttrs.addAll(getMaxMinAttrs(data, missingValue));
}
return calculatedCoordVarAttrs;
}
use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class TagUniversalFileFormat method convert.
public String convert(String ncfileFinal, Template template) throws InvalidRangeException, IOException {
Path ncPath = PathUtils.replaceExtension(Paths.get(ncfileFinal), "temp");
String ncfile = ncPath.toString();
// metadata extracted from the eTuff file
if (template != null) {
Template metadataFromFileTemplate = new Template();
// make a template object containing just the global metadata from the eTuff file
metadataFromFileTemplate.setGlobalMetadata(rosettaGlobalAttributes);
// update the file metadata with template metadata
metadataFromFileTemplate.update(template);
// pull out the updated globalmetata list from the updated template
rosettaGlobalAttributes = metadataFromFileTemplate.getGlobalMetadata();
}
rootGroup = null;
if (useNetcdf4) {
ncfw = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf4, ncfile);
rootGroup = ncfw.addGroup(null, null);
} else {
ncfw = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf3, ncfile);
}
// create time dimension
int numTimeRecords = matchupOneLocOneOb ? data.get(latDimName).size() : getMaxNumRecords();
Dimension timeDimension = ncfw.addDimension(rootGroup, timeDimName, numTimeRecords);
// add global attributes
if (useNetcdf4) {
// netCDF-4 installed - write global attributes in rootGroup
makeMetadataGroups();
} else {
for (RosettaGlobalAttribute rga : rosettaGlobalAttributes) {
Attribute ga = RosettaGlobalAttributeUtils.getAttributeFromGlobalAttr(rga);
ncfw.addGroupAttribute(rootGroup, ga);
}
}
// add the needed CF traj attributes
ncfw.addGroupAttribute(rootGroup, new Attribute("Conventions", "CF-1.6"));
ncfw.addGroupAttribute(rootGroup, new Attribute("featureType", "trajectory"));
String trajectoryId = getTrajId();
ncfw.addDimension(null, "str_len", trajectoryId.length());
Variable trajId = ncfw.addVariable(rootGroup, trajectoryIdName, DataType.CHAR, "str_len");
trajId.addAttribute(new Attribute("cf_role", "trajectory_id"));
// create time coordinate variable (special since it's not part of the data object
Variable theNewVar = ncfw.addVariable(rootGroup, timeDimName, DataType.INT, timeDimName);
theNewVar.addAttribute(new Attribute("standard_name", timeDimName));
theNewVar.addAttribute(new Attribute("long_name", timeDimName));
theNewVar.addAttribute(new Attribute("axis", "T"));
String timeUnit = "seconds since 1970-01-01T00:00:00 UTC";
theNewVar.addAttribute(new Attribute("units", timeUnit));
if (!matchupOneLocOneOb) {
// create freshness time coordinate variable
// because we are matching one location with more than one ob, it's important to know
// how "fresh" the location data are compared to the individual data point
theNewVar = ncfw.addVariable(rootGroup, freshnessVarName, DataType.FLOAT, timeDimName);
theNewVar.addAttribute(new Attribute("long_name", freshnessVarName));
theNewVar.addAttribute(new Attribute("units", "seconds"));
theNewVar.addAttribute(new Attribute("description", "time since last latitude and longitude observation were obtained."));
}
// create variables:
List<String> sortedKeys = new ArrayList<>(data.keySet());
Collections.sort(sortedKeys);
List<String> trajVarNames = new ArrayList<>();
for (Object name : sortedKeys) {
String strName = name.toString();
// todo: grab obs to find max/min, add to attributes
if (trajCoordVarNames.contains(name.toString())) {
List<String> strData = data.get(strName).values().stream().map(Ob::getValue).collect(Collectors.toList());
makeCoordinateVariables(name, strData);
} else {
int numVarRecords = data.get(strName).size();
// only add variables which have time series available (i.e. not histogram)
// add a small fudge factor in identifying possible time series variables
// from which we want matchup with lat/lon values.
// one loc many obs check
int expectedTimeseriesLength = matchupOneLocOneOb ? getMaxNumRecords() : timeDimension.getLength();
boolean isVar = Math.abs(numVarRecords - expectedTimeseriesLength) <= 10;
if (isVar) {
if (!name.equals("datetime")) {
List<String> strData = data.get(strName).values().stream().map(Ob::getValue).collect(Collectors.toList());
// compute max/min
List<Attribute> maxMinAttrs = getMaxMinAttrs(Array.makeArray(DataType.FLOAT, strData));
theNewVar = ncfw.addVariable(rootGroup, name.toString(), DataType.FLOAT, timeDimName);
trajVarNames.add(name.toString());
String unit = data.get(strName).firstEntry().getValue().getUnit();
if (!unit.isEmpty()) {
theNewVar.addAttribute(new Attribute("units", unit));
}
theNewVar.addAttribute(new Attribute("coordinates", trajCoordVarNames));
theNewVar.addAll(maxMinAttrs);
}
} else {
logger.warn("Skipping non time series variable " + name.toString());
}
}
}
trajVarNames.add(latDimName);
trajVarNames.add(lonDimName);
trajVarNames.add(depthDimName);
// create the file - writes medata and basic structure
ncfw.create();
// write the data, yo!
// since this is a trajectory file, only write out data when we have lat, lon, and depth obs
// for a given date
// get latitude variable
TreeMap<Long, Ob> dateTimeVar = data.get(maxTimeVar);
TreeMap<Long, Ob> latVar = data.get("latitude");
// because we use a TreeMap, the iterator of the Set returned by keySet() are sorted
// in ascending order.
Set<Long> times = matchupOneLocOneOb ? latVar.keySet() : dateTimeVar.keySet();
List<String> varValues;
List<String> freshnessValues = new ArrayList<>();
// the netCDF file
for (Object name : trajVarNames) {
String strName = name.toString();
varValues = new ArrayList<>();
// find a matching ob for the given trajectory time
if (matchupOneLocOneOb) {
// we are matching one location to a single ob
for (Long time : times) {
TreeMap<Long, Ob> varTM = data.get(strName);
// ob time closest to before the trajectory time
Long before = varTM.floorKey(time);
// ob time closest to after the trajectory time
Long after = varTM.ceilingKey(time);
Ob value = null;
// find which is actually closest
if ((before != null) && (after != null)) {
if ((time - before) < (after - time)) {
value = varTM.get(before);
} else {
value = varTM.get(after);
}
} else if (before != null) {
value = varTM.get(before);
} else if (after != null) {
value = varTM.get(after);
} else {
logger.error("no time match found!");
}
varValues.add(value.getValue());
}
} else {
// we are matching one location to many obs
for (Long time : times) {
TreeMap<Long, Ob> varTM = data.get(strName);
// ob time closest to before the datetime time
Long before = varTM.floorKey(time);
Ob value = null;
// find which is actually closest
if (before != null) {
value = varTM.get(before);
} else {
logger.error("no time match found!");
}
varValues.add(value.getValue());
if (name.equals(latDimName)) {
freshnessValues.add(String.valueOf(time - before));
}
}
}
Array thisData = ArrayFloat.makeArray(DataType.FLOAT, varValues);
Variable thisVar = ncfw.findVariable(name.toString());
ncfw.write(thisVar, thisData);
}
// write out the values for the time variable
varValues = new ArrayList<>();
for (Long time : times) {
varValues.add(time.toString());
}
Array thisData = ArrayInt.makeArray(DataType.INT, varValues);
Variable thisVar = ncfw.findVariable(timeDimName);
ncfw.write(thisVar, thisData);
thisData = ArrayChar.makeFromString(trajectoryId, trajectoryId.length());
thisVar = ncfw.findVariable(trajId.getFullName());
ncfw.write(thisVar, thisData);
if (!matchupOneLocOneOb) {
// write out "freshness" of the location data
thisData = Array.makeArray(DataType.FLOAT, freshnessValues);
thisVar = ncfw.findVariable(freshnessVarName);
ncfw.write(thisVar, thisData);
}
// close up
ncfw.close();
// we don't know all of the data values for all variables at the time we are writing
// metadata, so we must re-write the file with the max/min metadata here.
NetcdfFile ncf = NetcdfFile.open(ncfile);
Variable theVar = ncf.findVariable(timeDimName);
List<Attribute> theAttrs = getMaxMinAttrs(theVar.read());
theVar.addAll(theAttrs);
if (!matchupOneLocOneOb) {
theVar = ncf.findVariable(freshnessVarName);
theAttrs = getMaxMinAttrs(theVar.read());
theVar.addAll(theAttrs);
}
if (useNetcdf4) {
FileWriter2 fw2 = new FileWriter2(ncf, ncfileFinal, NetcdfFileWriter.Version.netcdf4, null);
NetcdfFile ncfw2 = fw2.write();
ncfw2.close();
} else {
FileWriter2 fw2 = new FileWriter2(ncf, ncfileFinal, NetcdfFileWriter.Version.netcdf3, null);
NetcdfFile ncfw2 = fw2.write();
ncfw2.close();
}
ncf.close();
Files.delete(ncPath);
return ncfileFinal;
}
use of org.openmuc.openiec61850.Array in project Protocol-Adapter-IEC61850 by OSGP.
the class NodeContainer method writeFloatArray.
public void writeFloatArray(final SubDataAttribute child, final Float[] values) throws NodeWriteException {
final Array array = (Array) this.parent.getChild(child.getDescription());
if (array.size() != values.length) {
throw new NodeWriteException(String.format("Invalid array size %d. Size on device is %d", values.length, array.size()));
}
for (int i = 0; i < values.length; i++) {
final BdaFloat32 bdaFloat = (BdaFloat32) array.getChild(i);
bdaFloat.setFloat(values[i]);
this.writeNode(bdaFloat);
}
// Unfortunately writing an array using "this.writeNode(array);"
// doesn't seem to work...
// Therefore the items are written in individual calls...
}
use of org.openmuc.openiec61850.Array in project Protocol-Adapter-IEC61850 by OSGP.
the class NodeContainer method writeDateArray.
public void writeDateArray(final SubDataAttribute child, final Date[] values) throws NodeWriteException {
final Array array = (Array) this.parent.getChild(child.getDescription());
if (array.size() != values.length) {
throw new NodeWriteException(String.format("Invalid array size %d. Size on device is %d", values.length, array.size()));
}
for (int i = 0; i < values.length; i++) {
final BdaTimestamp bdaTimestamp = (BdaTimestamp) array.getChild(i);
bdaTimestamp.setDate(values[i]);
this.writeNode(bdaTimestamp);
}
// Unfortunately writing an array using "this.writeNode(array);"
// doesn't seem to work...
// Therefore the items are written in individual calls...
}
Aggregations