All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.nc2.iosp.grib.tables.GribTemplate Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

There is a newer version: 4.3.22
Show newest version
/*
 * 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);
    }

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy