use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class NetcdfFileManager method makeTimeVarFromFullDateTime.
/**
* Create the time variable based on a full date/time time coordinate variable
*
* @param fullDateTimeVi The full date/time coordinate variable
* @return <code>true</code> if successfully created, otherwise false
*/
private boolean makeTimeVarFromFullDateTime(Template template, VariableInfo fullDateTimeVi) {
boolean success;
Group group = null;
String dimName = TemplateUtils.findUniqueName("time", template);
try {
List<String> fullDateTime = new ArrayList<>();
DataType dataType = DataType.LONG;
if (fullDateTimeVi.getColumnId() > 0) {
fullDateTime = stringData.get(fullDateTimeVi.getColumnId());
int numTimeObs = toIntExact(fullDateTime.size());
String dateTimeFormat = VariableInfoUtils.getUnit(fullDateTimeVi);
if (useNetcdf4) {
timeCoordVarArr = createLongTimeDataFromFullDateTime(fullDateTime, dateTimeFormat);
} else {
timeCoordVarArr = createIntTimeDataFromFullDateTime(fullDateTime, dateTimeFormat);
}
// only create element dimension if time is the element dimension
if (myDsgType.equalsIgnoreCase("trajectory") | myDsgType.equalsIgnoreCase("timeseries")) {
elementDimension = ncf.addDimension(dimName, toIntExact(numTimeObs));
}
// in this case, we are creating a totally new variable, so we need to check
// if the variable "time" already exists in data and coordinate variables
timeCoordVarName = dimName;
} else {
// extract scalar value out of global attribute
for (RosettaAttribute ra : fullDateTimeVi.getRosettaControlMetadata()) {
// if not netCDF4, use INT instead of LONG
if (!useNetcdf4) {
dataType = DataType.INT;
}
String name = ra.getName();
String attrDate = "";
if (name.equalsIgnoreCase("globalattributename")) {
String attrName = ra.getValue();
// find attribute in template
Map<String, ArrayList<Attribute>> gam = TemplateUtils.getGlobalAttrsMap(template);
for (String k : gam.keySet()) {
ArrayList<Attribute> attrList = gam.get(k);
for (Attribute attr : attrList) {
if (attr.getFullName().equalsIgnoreCase(attrName)) {
attrDate = attr.getStringValue();
}
}
}
Array scalar = null;
scalar = new ArrayInt.D0(false);
CalendarDate cd = parseISOformat(null, attrDate);
scalar.setFloat(0, cd.getMillis() / 1000L);
timeCoordVarArr = scalar;
timeCoordVarName = dimName;
}
}
}
Variable timeVar = null;
if (fullDateTimeVi.getColumnId() > 0) {
timeVar = ncf.addVariable(group, timeCoordVarName, dataType, Collections.singletonList(elementDimension));
} else {
// created from globalAttr - scalar
timeVar = ncf.addVariable(group, timeCoordVarName, dataType, "");
}
List<Attribute> timeVarAttrs = getBaseTimeVarAttrs();
timeVarAttrs.addAll(getMaxMinAttrs(timeCoordVarArr));
timeVar.addAll(timeVarAttrs);
// if profile, then check if this is created from global attribute
if ((myDsgType != "profile") | (fullDateTimeVi.getColumnId() == -2)) {
coordAttrValues.add(timeCoordVarName);
}
success = true;
} catch (ArithmeticException ae) {
logger.error("Size of the dimension could not fit in an integer value");
success = false;
}
return success;
}
use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class NetcdfFileManager method calculateDataVarAttrs.
/**
* Get the auto-computed attributes for a given data VariableInfo object
*
* @param variableInfo The data variable for which attributes should be computed
* @return A list of computed attributes
*/
List<Attribute> calculateDataVarAttrs(VariableInfo variableInfo) {
List<Attribute> calculatedDataVarAttrs = new ArrayList<>();
// DataVariable _FillValue
// DataVariable coordinates
String coords = String.join(" ", coordAttrValues);
calculatedDataVarAttrs.add(new Attribute("coordinates", coords));
// DataVariable coverage_content_type
// no good way to guess this - will need to come from the template
Array data = arrayData.get(variableInfo.getColumnId());
if (data.getDataType() != DataType.CHAR && data.getDataType() != DataType.STRING) {
Optional<Double> missingValue = VariableInfoUtils.findMissingValue(variableInfo);
calculatedDataVarAttrs.addAll(getMaxMinAttrs(data, missingValue));
}
// add columnId if it was initilized in attribute
int colId = variableInfo.getColumnId();
if (colId > 0) {
calculatedDataVarAttrs.add(new Attribute(colIdAttrName, variableInfo.getColumnId()));
}
return calculatedDataVarAttrs;
}
use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class NetcdfFileManager method createNetcdfFile.
/**
* Create a netCDF file, following CF DSGs, based on the data contained within a data file and
* the metadata contained within a template
*
* @param dataFile file containing observed data
* @param template template associated with dataFile
* @param delimiter the delimiter used to parse the file.
* @return location of the created netCDF file
*/
public String createNetcdfFile(Path dataFile, Template template, String delimiter) throws IOException, RosettaDataException {
Path netcdfFile = PathUtils.replaceExtension(dataFile, ".nc");
String netcdfFilePath = netcdfFile.toString();
ParsedFile parsedFile = new ParsedFile(dataFile, template, delimiter);
arrayData = parsedFile.getArrayData();
stringData = parsedFile.getStringData();
// TODO: add check to see if netCDF-4 is enabled
// before we do anything, we need to modify the template to add variables that are constructed
// from global attributes. This way, they will be picked up as if they were defined in the
// data block of the csv file
createNonElementCoordVars(template);
ncf = NetcdfFileWriter.createNew(netcdfFilePath, false);
identifyVariables(template);
// create Element Coordinate Variable
boolean elementDimCreated = false;
if (myDsgType.equalsIgnoreCase("trajectory") | myDsgType.equalsIgnoreCase("timeseries")) {
elementDimCreated = createElementCoordVarTime(template);
} else if (myDsgType.equalsIgnoreCase("profile")) {
// create vertical coordinate coord var
elementDimCreated = createElementCoordVarVertical();
// create time coordvar from global attr
createTimeVarInfoFromGlobalAttr(template);
// create time variable (non coord var). Although it is not the element coordinate in this case, we
// will use the same functions as if it were. Inside these functions, the element dimension will
// not be created, as we will use the element dimension created during the createElementCoordVarVertical()
// call
boolean timeVarCreated = createElementCoordVarTime(template);
// for profile, create time coord var from global attribute
if (!timeVarCreated) {
// stop conversion as a time variable was not created - indicate to use that they
// need to check the log file
logger.error("time coordinate variable not created. Stopping");
}
}
if (!elementDimCreated) {
// stop conversion as a time variable was not created - indicate to use that they
// need to check the log file
logger.error("element dimension not created. Stopping");
}
// add coordinate variable info
for (VariableInfo coordVarInfo : nonElementCoordVarInfo) {
makeNonElementCoordVars(coordVarInfo);
}
// add data variable info
for (VariableInfo dataVarInfo : dataVarInfo) {
makeDataVars(dataVarInfo);
}
// add global metadata
// first, get from template
Map<String, ArrayList<Attribute>> globalAttrs = TemplateUtils.getGlobalAttrsMap(template);
// update global attribute lists obtained from template with new feature specific global attributes
List<RosettaGlobalAttribute> featureSpecificGlobalAttrs = getFeatureSpecificGlobalAttrs(template);
for (RosettaGlobalAttribute attr : featureSpecificGlobalAttrs) {
String groupName = attr.getGroup();
if (globalAttrs.containsKey(groupName)) {
ArrayList<Attribute> globalAttr = globalAttrs.get(groupName);
globalAttr.add(RosettaGlobalAttributeUtils.getAttributeFromGlobalAttr(attr));
globalAttrs.put(groupName, globalAttr);
} else {
ArrayList<Attribute> globalAttr = new ArrayList<>();
globalAttr.add(RosettaGlobalAttributeUtils.getAttributeFromGlobalAttr(attr));
globalAttrs.put(groupName, globalAttr);
}
}
// add globalAttributes to ncf
for (String groupName : globalAttrs.keySet()) {
// todo - add check for netCDF4, and use metadata groups if it is enabled
for (Attribute globalAttr : globalAttrs.get(groupName)) {
ncf.addGlobalAttribute(globalAttr);
}
}
makeOtherVariables();
// write all metadata and get ready for writing data values
ncf.create();
try {
// write variable data to netCDF File
// write time variable data
ncf.write(timeCoordVarName, timeCoordVarArr);
// if profile, detailed time might exist
if (myDsgType == "profile") {
// if profile, detailed time might exist
if (timeCoordVarDetailName != null) {
ncf.write(timeCoordVarDetailName, timeCoordVarDetailArr);
}
// write data for vertical coord variable
ncf.write(verticalCoordVarName, verticalCoordVarArr);
}
// write data to featureId variable
ncf.write(featureVarName, Array.makeFromJavaArray(featureId.toCharArray()));
// write data to all netCDF variables with an attribute containing the column id
for (Variable var : ncf.getNetcdfFile().getVariables()) {
Attribute colIdAttr = var.findAttribute(colIdAttrName);
if (colIdAttr != null) {
Number colIdNum = colIdAttr.getNumericValue();
int colId = colIdNum.intValue();
// defined in columnar data block
if (colId > 0) {
Array thisData = arrayData.get(colId);
if ((thisData.getDataType() == DataType.CHAR) || (thisData.getDataType() == DataType.STRING && !useNetcdf4)) {
// CHAR arrays are backed by a list of strings in the ParsedData object
// so need to handle special when writing
ncf.writeStringData(var, Array.makeArray(DataType.STRING, stringData.get(colId)));
} else {
ncf.write(var, thisData);
}
} else {
// write data to variables extracted from global metadata
for (VariableInfo vi : nonElementCoordVarInfo) {
if (var.getFullNameEscaped().contains(vi.getName())) {
for (RosettaAttribute ra : vi.getRosettaControlMetadata()) {
String name = ra.getName();
if (name.equalsIgnoreCase("globalattributename")) {
Attribute ga = ncf.findGlobalAttribute(ra.getValue());
DataType dt = ga.getDataType();
Number val = ga.getNumericValue();
Array scalar = null;
if (dt == DataType.FLOAT) {
scalar = new ArrayFloat.D0();
scalar.setFloat(0, val.floatValue());
} else if (dt == DataType.DOUBLE) {
scalar = new ArrayDouble.D0();
scalar.setDouble(0, val.doubleValue());
} else if ((val != null) && (dt == DataType.STRING)) {
// ok, we were able to get a non-null Number out of the attribute, but
// the datatype on the attribute is string - let's store it as a double
scalar = new ArrayDouble.D0();
scalar.setDouble(0, val.doubleValue());
}
if (scalar != null) {
ncf.write(var, scalar);
} else {
logger.error("failed to write scalar value to var " + var.getFullNameEscaped());
}
}
}
}
}
}
}
}
} catch (InvalidRangeException e) {
logger.error(e.getMessage());
logger.error(e.getStackTrace());
}
ncf.close();
return netcdfFilePath;
}
use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class NetcdfFileManager method addTuffGlobalAttrs.
/**
* If the file to be converted follows the eTuff standard, auto-compute the needed attributes
*
* @return A list of computed eTuff attributes
*/
private void addTuffGlobalAttrs() {
int end = elementDimension.getLength();
for (VariableInfo coordVar : nonElementCoordVarInfo) {
// CoordinateVariable axis
String type = VariableInfoUtils.getCoordVarType(coordVar);
Array data = arrayData.get(coordVar.getColumnId());
if (type.equalsIgnoreCase(VariableInfoUtils.longitude)) {
ncf.addGlobalAttribute(new Attribute("geospatial_lon_start", data.getDouble(0)));
ncf.addGlobalAttribute(new Attribute("geospatial_lon_end", data.getDouble(end)));
} else if (type.equalsIgnoreCase(VariableInfoUtils.latitude)) {
ncf.addGlobalAttribute(new Attribute("geospatial_lat_start", data.getDouble(0)));
ncf.addGlobalAttribute(new Attribute("geospatial_lat_end", data.getDouble(end)));
}
}
String startUdUnit = String.join(" ", String.valueOf(timeCoordVarArr.getLong(0)), timeUnits);
String stopUdUnit = String.join(" ", String.valueOf(timeCoordVarArr.getLong(end)), timeUnits);
CalendarDate start = parseUdunits(null, startUdUnit);
CalendarDate stop = parseUdunits(null, stopUdUnit);
ncf.addGlobalAttribute(new Attribute("time_coverage_start", CalendarDateFormatter.toDateTimeStringISO(start)));
ncf.addGlobalAttribute(new Attribute("time_coverage_end", CalendarDateFormatter.toDateTimeStringISO(stop)));
}
use of org.openmuc.openiec61850.Array in project rosetta by Unidata.
the class EolSoundingComp method writeNcFile.
private boolean writeNcFile(String ncFileName) {
boolean success = false;
int timeIndex = -1;
int latIndex = -1;
int lonIndex = -1;
int altIndex = -1;
String varName;
List<Attribute> attrsToAdd;
// try to find lat, lon, height, and time variableName indexes
for (int var = 0; var < variableNames.size(); var++) {
varName = variableNames.get(var);
if (varName.toLowerCase().contains("lat")) {
latIndex = var;
} else if (varName.toLowerCase().contains("lon")) {
lonIndex = var;
} else if (varName.toLowerCase().contains("time")) {
timeIndex = var;
} else if (varName.toLowerCase().contains("alt")) {
altIndex = var;
}
}
// use the index info from above to create the coordinates attribute
String coordsStr = variableNames.get(timeIndex) + " " + variableNames.get(latIndex) + " " + variableNames.get(lonIndex) + " " + variableNames.get(altIndex);
Attribute coordsAttr = new Attribute(COORDS_ATTR_NAME, coordsStr);
int numberOfTimes = data.get(variableNames.get(0)).size();
Dimension timeDim = new Dimension("time", numberOfTimes);
try (NetcdfFileWriter ncfw = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf3, ncFileName)) {
Group group = null;
// create time dimension
ncfw.addDimension(group, timeDim.getFullName(), timeDim.getLength());
// add global attribute
for (Attribute ga : globalAttrs) {
ncfw.addGroupAttribute(group, ga);
}
// add the needed CF traj attributes
ncfw.addGroupAttribute(group, new Attribute("Conventions", "CF-1.6"));
ncfw.addGroupAttribute(group, new Attribute("featureType", "trajectory"));
// create list of data variables:
for (int varInd = 0; varInd < variableNames.size(); varInd++) {
attrsToAdd = new ArrayList<>();
if (varInd == timeIndex) {
attrsToAdd.add(new Attribute(AXIS_ATTR_NAME, "T"));
attrsToAdd.add(new Attribute(STD_NAME_ATTR_NAME, "time"));
String tmpTimeUnit = variableUnits.get(varInd);
if (tmpTimeUnit.equals("s") || tmpTimeUnit.equals("sec")) {
tmpTimeUnit = "seconds";
}
attrsToAdd.add(new Attribute("units", tmpTimeUnit + " since " + launchDateIsoStr));
} else if (varInd == lonIndex) {
attrsToAdd.add(new Attribute(AXIS_ATTR_NAME, "X"));
attrsToAdd.add(new Attribute(STD_NAME_ATTR_NAME, "longitude"));
attrsToAdd.add(new Attribute("units", variableUnits.get(varInd)));
} else if (varInd == latIndex) {
attrsToAdd.add(new Attribute(AXIS_ATTR_NAME, "Y"));
attrsToAdd.add(new Attribute(STD_NAME_ATTR_NAME, "latitude"));
attrsToAdd.add(new Attribute("units", variableUnits.get(varInd)));
} else if (varInd == altIndex) {
attrsToAdd.add(new Attribute(AXIS_ATTR_NAME, "Z"));
attrsToAdd.add(new Attribute(STD_NAME_ATTR_NAME, "altitude"));
attrsToAdd.add(new Attribute(POSITIVE_ATTR_NAME, "UP"));
attrsToAdd.add(new Attribute("units", variableUnits.get(varInd)));
} else {
attrsToAdd.add(new Attribute("units", variableUnits.get(varInd)));
attrsToAdd.add(coordsAttr);
}
// create the variable and add the attributes
Variable theNewVar = ncfw.addVariable(group, variableNames.get(varInd), DataType.FLOAT, timeDim.getFullName());
for (Attribute attr : attrsToAdd) {
ncfw.addVariableAttribute(theNewVar, attr);
}
}
// add the special trajectory variable which has a cf role as "trajectory_id"
Dimension trajIdDim = new Dimension("str_len", siteId.length());
ncfw.addDimension(group, trajIdDim.getFullName(), trajIdDim.getLength());
Variable trajId = ncfw.addVariable(group, "trajectory", DataType.CHAR, trajIdDim.getFullName());
trajId.addAttribute(new Attribute("cf_role", "trajectory_id"));
// create the file - writes medata and basic structure
ncfw.create();
// write the data, yo!
for (String dataVar : data.keySet()) {
Array thisData = ArrayFloat.makeArray(DataType.FLOAT, data.get(dataVar));
Variable thisVar = ncfw.findVariable(dataVar);
ncfw.write(thisVar, thisData);
}
// write out trajectory id
Array siteIdArr = ArrayChar.makeFromString(siteId, siteId.length());
ncfw.write(trajId, siteIdArr);
// close shop
ncfw.close();
success = true;
} catch (IOException | InvalidRangeException ioe) {
logger.debug(ioe.getMessage());
}
return success;
}
Aggregations