ucar.nc2.iosp.grib.tables.GribCodeTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.iosp.grib.tables;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import ucar.grib.grib2.ParameterTable;
import ucar.grid.GridParameter;
import ucar.nc2.iosp.netcdf3.N3iosp;
import ucar.unidata.util.StringUtil;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* Read and process WMO grib code tables.
*
* @author caron
* @since Jul 31, 2010
*/
public class GribCodeTable implements Comparable {
private static Map tables;
public static GribCodeTable.TableEntry getEntry(int discipline, int category, int number) {
GribCodeTable table = tables.get( getId(discipline, category)) ;
if (table == null) return null;
return table.get(number);
}
private static String getId(int discipline, int category) {
return discipline+"."+ category;
}
public String name;
public int m1, m2;
public boolean isParameter;
public int discipline = -1;
public int category = -1;
public List entries = new ArrayList();
GribCodeTable(String name) {
this.name = name;
String[] s = name.split(" ");
String id = s[2];
String[] slist2 = id.split("\\.");
if (slist2.length == 2) {
m1 = Integer.parseInt(slist2[0]);
m2 = Integer.parseInt(slist2[1]);
} else
System.out.println("HEY bad= %s%n" + name);
}
GribCodeTable(String tableName, String subtableName) {
String[] s = tableName.split(" ");
String id = s[2];
String[] slist2 = id.split("\\.");
if (slist2.length == 2) {
m1 = Integer.parseInt(slist2[0]);
m2 = Integer.parseInt(slist2[1]);
} else
System.out.println("HEY bad= %s%n" + name);
this.name = subtableName;
String[] slist = name.split("[ :]+");
try {
for (int i = 0; i < slist.length; i++) {
if (slist[i].equalsIgnoreCase("discipline"))
discipline = Integer.parseInt(slist[i + 1]);
if (slist[i].equalsIgnoreCase("category"))
category = Integer.parseInt(slist[i + 1]);
}
} catch (Exception e) {
}
isParameter = (discipline >= 0) && (category >= 0);
}
void add(String line, String code, String meaning, String unit, String status) {
entries.add(new TableEntry(line, code, meaning, unit, status));
}
TableEntry get(int value) {
for (TableEntry p : entries) {
if (p.start == value) return p;
}
return null;
}
@Override
public int compareTo(GribCodeTable o) {
if (m1 != o.m1) return m1 - o.m1;
if (m2 != o.m2) return m2 - o.m2;
if (discipline != o.discipline) return discipline - o.discipline;
return category - o.category;
}
@Override
public String toString() {
return "GribCodeTable{" +
"name='" + name + '\'' +
", m1=" + m1 +
", m2=" + m2 +
", isParameter=" + isParameter +
", discipline=" + discipline +
", category=" + category +
'}';
}
// remove () for the following:
private static int[] badones = new int[] {
0, 1, 51,
0, 6, 25,
0, 19, 22,
0, 191, 0,
1, 0, 0,
1, 0, 1,
1, 1, 0,
1, 1, 1,
1, 1, 2,
2, 0, 0,
10, 191, 0};
private boolean remove(TableEntry entry) {
for (int i=0; i < badones.length; i+=3) {
if (discipline == badones[i] && category == badones[i+1] && entry.number == badones[i+2]) return true;
}
return false;
}
public class TableEntry implements Comparable {
public int start, stop, line;
public int number = -1;
public String code, meaning, name, unit, status;
TableEntry(String line, String code, String meaning, String unit, String status) {
this.line = Integer.parseInt(line);
this.code = code;
this.meaning = meaning;
this.status = status;
try {
int pos = code.indexOf('-');
if (pos > 0) {
start = Integer.parseInt(code.substring(0, pos));
String stops = code.substring(pos + 1);
stop = Integer.parseInt(stops);
} else {
start = Integer.parseInt(code);
stop = start;
number = start;
}
} catch (Exception e) {
start = -1;
stop = 0;
}
if (isParameter) {
// some need the () comment removed - must be hand specified (!)
if (remove(this)) {
int pos1 = meaning.indexOf('(');
int pos2 = meaning.indexOf(')');
if ((pos1 > 0) && (pos2 > 0))
meaning = meaning.substring(0, pos1).trim(); // assume () is at the end od string
}
// meaning = StringUtil.replace(meaning, '-', "_");
meaning = StringUtil.replace(meaning, '/', "-");
meaning = StringUtil.replace(meaning, '.', "p");
meaning = StringUtil.remove(meaning, '(');
meaning = StringUtil.remove(meaning, ')');
this.name = N3iosp.createValidNetcdf3ObjectName(meaning);
// massage units
if (unit != null) {
if (unit.equalsIgnoreCase("Proportion")) unit = "";
if (unit.equalsIgnoreCase("Numeric")) unit = "";
}
this.unit = unit;
}
}
@Override
public int compareTo(TableEntry o) {
return start - o.start;
}
@Override
public String toString() {
return "TableEntry{" +
", discipline=" + discipline +
", category=" + category +
", number=" + number +
", org='" + meaning + '\'' +
", name='" + name + '\'' +
", unit='" + unit + '\'' +
", status='" + status + '\'' +
'}';
}
}
//////////////////////////////////////////////////////////////////////
/*
645
Code table 4.2 - Parameter number by product discipline and parameter category
Product discipline 0 - Meteorological products, parameter category 19: physical atmospheric
properties
13
Contrail intensity
(Code table 4.210)
Operational
*/
static private List readGribCodes(InputStream ios) throws IOException {
org.jdom.Document doc;
try {
SAXBuilder builder = new SAXBuilder();
doc = builder.build(ios);
} catch (JDOMException e) {
throw new IOException(e.getMessage());
}
Element root = doc.getRootElement();
Map map = new HashMap();
tables = new HashMap();
List featList = root.getChildren("ForExport_CodeFlag_E");
for (Element elem : featList) {
String line = elem.getChildTextNormalize("No");
String tableName = elem.getChildTextNormalize("TableTitle_E");
String code = elem.getChildTextNormalize("CodeFlag");
String meaning = elem.getChildTextNormalize("Meaning_E");
GribCodeTable ct = map.get(tableName);
if (ct == null) {
ct = new GribCodeTable(tableName);
map.put(tableName, ct);
}
Element unitElem = elem.getChild("AsciiUnit_x002F_Description_E");
String unit = (unitElem == null) ? null : unitElem.getTextNormalize();
Element statusElem = elem.getChild("Status");
String status = (statusElem == null) ? null : statusElem.getTextNormalize();
Element subtableElem = elem.getChild("TableSubTitle_E");
if (subtableElem != null) {
String subTableName = subtableElem.getTextNormalize();
GribCodeTable cst = map.get(subTableName);
if (cst == null) {
cst = new GribCodeTable(tableName, subTableName);
map.put(subTableName, cst);
tables.put(getId(cst.discipline, cst.category), cst);
}
cst.add(line, code, meaning, unit, status);
} else {
ct.add(line, code, meaning, unit, status);
}
}
ios.close();
List tlist = new ArrayList(map.values());
Collections.sort(tlist);
for (GribCodeTable gt : tlist)
Collections.sort(gt.entries);
return tlist;
}
static public Map readGribCodes() throws IOException {
Class c = GribCodeTable.class;
InputStream in = c.getResourceAsStream(resourceName);
if (in == null) {
System.out.printf("cant open %s%n", resourceName);
return null;
}
List tlist = readGribCodes(in);
Map map = new HashMap( 2* tlist.size());
for (GribCodeTable ct : tlist) {
String id = ct.m1+"."+ct.m2;
if (ct.isParameter)
id += "."+ct.discipline+"."+ct.category;
map.put(id, ct);
}
return map;
}
public static List getWmoStandard() throws IOException {
Class c = GribCodeTable.class;
InputStream in = c.getResourceAsStream(resourceName);
if (in == null) {
System.out.printf("cant open %s%n", resourceName);
return null;
}
try {
return readGribCodes(in);
} finally {
in.close();
}
}
static String resourceName = "/resources/grib/wmo/GRIB2_5_2_0_CodeFlag_E.xml";
static boolean showDiff = true;
public static void main(String arg[]) throws IOException {
//String filename = "C:\\docs\\dataFormats\\grib\\GRIB2_5_2_0_xml\\wmoGribCodes.xml";
//List tlist = readGribCodes(new FileInputStream(filename));
Class c = GribCodeTable.class;
InputStream in = c.getResourceAsStream(resourceName);
if (in == null) {
System.out.printf("cant open %s%n", resourceName);
return;
}
List tlist = readGribCodes(in);
for (GribCodeTable gt : tlist) {
System.out.printf("%d.%d (%d,%d) %s %n", gt.m1, gt.m2, gt.discipline, gt.category, gt.name);
for (TableEntry p : gt.entries) {
System.out.printf(" %s (%d-%d) = %s %n", p.code, p.start, p.stop, p.meaning);
}
}
if (showDiff) {
int total = 0;
int nsame = 0;
int nsameIgn = 0;
int ndiff = 0;
int unknown = 0;
System.out.printf("DIFFERENCES with current parameter table");
for (GribCodeTable gt : tlist) {
if (!gt.isParameter) continue;
for (TableEntry p : gt.entries) {
if (p.meaning.equalsIgnoreCase("Missing")) continue;
if (p.start != p.stop) continue;
GridParameter gp = ParameterTable.getParameter(gt.discipline, gt.category, p.start);
String paramDesc = gp.getDescription();
if (paramDesc.startsWith("Unknown")) unknown++;
boolean same = paramDesc.equals(p.meaning);
if (same) nsame++;
boolean sameIgnore = paramDesc.equalsIgnoreCase(p.meaning);
if (sameIgnore) nsameIgn++;
else ndiff++;
total++;
String state = same ? " " : (sameIgnore ? "* " : "**");
System.out.printf("%s%d %d %d%n %s%n %s%n", state, gt.discipline, gt.category, p.start, p.meaning, paramDesc);
}
}
System.out.printf("Total=%d same=%d sameIgn=%d dif=%d unknown=%d%n", total, nsame, nsameIgn, ndiff, unknown);
}
}
}