Package ucar.nc2.iosp.grib.tables

Source Code of ucar.nc2.iosp.grib.tables.GribTemplate$Field

/*
* 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<GribTemplate> {
  static Map<String, String> convertMap = new HashMap<String, String>();
  static Map<String, GribCodeTable> 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("Type of ensemble forecast", "4.6");
    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<Field> flds = new ArrayList<Field>();

  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<Field> {
    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);
       }
     }
  }


  ////////////////////////////////////////////////////////////////////////

  /*
<ForExport_Templates_E>
    <No>444</No>
    <TemplateName_E>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
    </TemplateName_E>
    <OctetNo>61-64</OctetNo>
    <Contents_E>Scaled value of distance of the cluster from ensemble mean</Contents_E>
    <Status>Operational</Status>
  </ForExport_Templates_E>
  */

  static public List<GribTemplate> 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<String, GribTemplate> map = new HashMap<String, GribTemplate>();

    Element root = doc.getRootElement();

    List<Element> 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<GribTemplate> tlist = new ArrayList<GribTemplate>(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<String, GribTemplate> 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<GribTemplate> tlist = readXml(in);

    Map<String, GribTemplate> map = new HashMap<String, GribTemplate>(100);
    for (GribTemplate t : tlist) {
        map.put(t.m1+"."+t.m2, t);
    }
    return map;
  }

  public static List<GribTemplate> 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<GribTemplate> 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);
    }

  }
}
TOP

Related Classes of ucar.nc2.iosp.grib.tables.GribTemplate$Field

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.