ucar.nc2.iosp.grib.tables.GribTemplate 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.GribNumbers;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* Read and process WMO GRIB templates.
*
* @author caron
* @since Jul 31, 2010
*/
public class GribTemplate implements Comparable {
static Map convertMap = new HashMap();
static Map gribCodes;
static {
convertMap.put("Type of generating process", "4.3");
convertMap.put("Indicator of unit of time range", "4.4");
convertMap.put("Indicator of unit of time for time range over which statistical processing is done", "4.4");
convertMap.put("Indicator of unit of time for the increment between the successive fields used", "4.4");
convertMap.put("Type of first fixed surface", "4.5");
convertMap.put("Type of second fixed surface", "4.5");
convertMap.put("Derived forecast", "4.7");
convertMap.put("Probability type", "4.9");
convertMap.put("Statistical process used to calculate the processed field from the field at each time increment during the time range", "4.10");
convertMap.put("Type of time increment between successive fields used in the statistical processing", "4.11");
}
static String convert(String table, int value) {
if (gribCodes == null) {
try {
gribCodes = GribCodeTable.readGribCodes();
} catch (IOException e) {
return "Read GridCodes failed";
}
}
GribCodeTable gct = gribCodes.get(table);
if (gct == null) return table+" not found";
GribCodeTable.TableEntry entry = gct.get(value);
if (entry != null) return entry.meaning;
return "Table "+table+" code "+ value+ " not found";
}
///////////////////////////////////////
public String name, desc;
public int m1, m2;
public List flds = new ArrayList();
GribTemplate(String desc) {
this.desc = desc;
String[] slist = desc.split(" ");
for (int i = 0; i < slist.length; i++) {
if (slist[i].equalsIgnoreCase("template")) {
name = slist[i + 1];
String[] slist2 = name.split("\\.");
if (slist2.length == 2) {
m1 = Integer.parseInt(slist2[0]);
m2 = Integer.parseInt(slist2[1]);
} else
System.out.println("HEY bad= %s%n" + name);
break;
}
}
}
void add(String octet, String content) {
flds.add(new Field(octet, content));
}
void add(int start, int nbytes, String content) {
flds.add(new Field(start, nbytes, content));
}
@Override
public int compareTo(GribTemplate o) {
if (m1 == o.m1) return m2 - o.m2;
else return m1 - o.m1;
}
public class Field implements Comparable {
public String octet, content;
public int start, nbytes;
Field(String octet, String content) {
this.octet = octet;
this.content = content;
try {
int pos = octet.indexOf('-');
if (pos > 0) {
start = Integer.parseInt(octet.substring(0, pos));
String stops = octet.substring(pos+1);
int stop = -1;
try {
stop = Integer.parseInt(stops);
nbytes = stop - start + 1;
} catch (Exception e) {
}
} else {
start = Integer.parseInt(octet);
nbytes = 1;
}
} catch (Exception e) {
start = -1;
nbytes = 0;
}
}
Field(int start, int nbytes, String content) {
this.start = start;
this.nbytes = nbytes;
this.content = content;
this.octet = start+"-"+(start+nbytes-1);
}
@Override
public int compareTo(Field o) {
return start - o.start;
}
int value(byte[] pds) {
switch (nbytes) {
case 1 : return get(pds, start);
case 2 : return GribNumbers.int2( get(pds, start), get(pds, start+1));
case 4 : return GribNumbers.int4( get(pds, start), get(pds, start+1), get(pds, start+2), get(pds, start+3));
default : return -9999;
}
}
int get(byte[] pds, int offset) {
return pds[offset-1] & 0xff;
}
}
public void showInfo(byte[] pds, Formatter f) {
f.format("%n(%s) %s %n", name, desc);
for (Field fld : flds) {
if (fld.start < 0) continue;
String info = convertMap.get(fld.content);
if (info == null)
f.format("%3d: %90s == %d %n", fld.start, fld.content, fld.value(pds));
else {
String desc = convert(info, fld.value(pds));
if (desc == null)
f.format("%3d: %90s == %d (%s) %n", fld.start, fld.content, fld.value(pds), convert(info, fld.value(pds)));
else
f.format("%3d: %90s == %d (table %s: %s) %n", fld.start, fld.content, fld.value(pds), info, desc);
}
}
}
////////////////////////////////////////////////////////////////////////
/*
444
Product definition template 4.4 - derived forecasts based on a cluster of ensemble members over a
circular area at a horizontal level or in a horizontal layer at a point in time
61-64
Scaled value of distance of the cluster from ensemble mean
Operational
*/
static public List readXml(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());
}
Map map = new HashMap();
Element root = doc.getRootElement();
List featList = root.getChildren("ForExport_Templates_E");
for (Element elem : featList) {
String desc = elem.getChildTextNormalize("TemplateName_E");
String octet = elem.getChildTextNormalize("OctetNo");
String content = elem.getChildTextNormalize("Contents_E");
GribTemplate t = map.get(desc);
if (t == null) {
t = new GribTemplate(desc);
map.put(desc, t);
}
t.add(octet, content);
}
ios.close();
List tlist = new ArrayList(map.values());
Collections.sort(tlist);
for (GribTemplate t : tlist) {
if (t.m1 == 3) {
t.add( 1, 4, "GDS length");
t.add( 5, 1, "Section");
t.add( 6, 1, "Source of Grid Definition (see code table 3.0)");
t.add( 7, 4, "Number of data points");
t.add( 11, 1, "Number of octects for optional list of numbers");
t.add( 12, 1, "Interpretation of list of numbers");
t.add( 13, 2, "Grid Definition Template Number");
} else if (t.m1 == 4) {
t.add( 1, 4, "PDS length");
t.add( 5, 1, "Section");
t.add( 6, 2, "Number of coordinates values after Template");
t.add( 8, 2, "Product Definition Template Number");
}
Collections.sort(t.flds);
}
return tlist;
}
static String resourceName = "/resources/grib/wmo/GRIB2_5_2_0_Templates_E.xml";
static public Map getParameterTemplates() 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 = readXml(in);
Map map = new HashMap(100);
for (GribTemplate t : tlist) {
map.put(t.m1+"."+t.m2, t);
}
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 readXml(in);
} finally {
in.close();
}
}
public static void main(String arg[]) throws IOException {
Class c = GribCodeTable.class;
InputStream in = c.getResourceAsStream(resourceName);
if (in == null) {
System.out.printf("cant open %s%n", resourceName);
return;
}
List tlist = readXml(in);
for (GribTemplate t : tlist) {
System.out.printf("%n(%s) %s %n", t.name, t.desc);
for (GribTemplate.Field f : t.flds) {
System.out.printf(" (%d,%d) %10s : %s %n", f.start, f.nbytes, f.octet, f.content);
}
}
for (GribTemplate t : tlist) {
System.out.printf("%n(%s) %s %n", t.name, t.desc);
int start = -1;
int next = 0;
for (GribTemplate.Field f : t.flds) {
if (f.start < 0) continue;
if (start < 0) {
start = f.start;
next = start + f.nbytes;
} else {
if (f.start != next) System.out.printf(" missing %d to %d %n", next, start);
next = f.start + f.nbytes;
}
}
System.out.printf(" range %d-%d %n", start, next);
}
}
}