Package ucar.nc2.iosp.gempak

Source Code of ucar.nc2.iosp.gempak.AbstractGempakStationFileReader

/*
* 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.gempak;


import visad.util.Trace;

import java.io.*;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeSet;


/**
* Class to hold common methods for reading surface and sounding files
*
* @author IDV Development Team
*/
public abstract class AbstractGempakStationFileReader extends GempakFileReader {

    /** date key identifier */
    public static final String DATE = "DATE";

    /** time key identifier */
    public static final String TIME = "TIME";

    /** obs date format */
    private static final String DATE_FORMAT = "yyMMdd'/'HHmm";

    /** date/time keys */
    private List<Key> dateTimeKeys;

    /** station keys */
    private List<Key> stationKeys;

    /** unique list of dates as Strings */
    private List<String> dateList;

    /** unique list of dates as Dates */
    private List<Date> dates;

    /** list of stations */
    private List<GempakStation> stations;

    /** list of parameters */
    private List<GempakParameter> params;

    /** list of parameters */
    private Map<String, List<GempakParameter>> partParamMap =
        new HashMap<String, List<GempakParameter>>();

    /** data formatter */
    private SimpleDateFormat dateFmt = new SimpleDateFormat(DATE_FORMAT);

    /** The file subtype */
    protected String subType = "";

    /**
     * Default ctor
     */
    AbstractGempakStationFileReader() {}

    /**
     * Initialize this reader.  Read all the metadata
     *
     * @return true if successful
     *
     * @throws IOException  problem reading the data
     */
    protected boolean init() throws IOException {
        return init(true);
    }

    /**
     * Initialize this reader.  Get the Grid specific info
     *
     * @param fullCheck  check to make sure there are grids we can handle
     * @return true if successful
     *
     * @throws IOException  problem reading the data
     */
    protected boolean init(boolean fullCheck) throws IOException {
        //Trace.startTrace();

        if ( !super.init(fullCheck)) {
            return false;
        }

        if ((dmLabel.kftype != MFSN) && (dmLabel.kftype != MFSF)) {
            logError("not a point data file ");
            return false;
        }
        return true;

    }

    /**
     * Read in the stations and times.  Subclasses should
     * call this during init()
     * @param uniqueTimes  make a set of unique times
     * @return true if stations and times were read okay.
     */
    protected boolean readStationsAndTimes(boolean uniqueTimes) {

        Trace.call1("GEMPAK: making params");
        for (DMPart apart : parts) {
            List<GempakParameter> params = makeParams(apart);
            partParamMap.put(apart.kprtnm, params);
        }
        Trace.call2("GEMPAK: making params");

        // get the date/time keys
        dateTimeKeys = getDateTimeKeys();
        if ((dateTimeKeys == null) || dateTimeKeys.isEmpty()) {
            return false;
        }

        // get the station info
        stationKeys = findStationKeys();
        if ((stationKeys == null) || stationKeys.isEmpty()) {
            return false;
        }
        Trace.call1("GEMPAK: get station list");
        stations = getStationList();
        Trace.call2("GEMPAK: get station list");
        makeFileSubType();

        Trace.call1("GEMPAK: get date list");
        // null out the old cached list
        dates = null;
        dateList = makeDateList(uniqueTimes);
        Trace.call2("GEMPAK: get date list");

        return true;

    }

    /**
     * Get the date/time information
     *
     * @return the list of date/time keys
     */
    private List<Key> getDateTimeKeys() {
        Key date = findKey(DATE);
        Key time = findKey(TIME);
        if ((date == null) || (time == null)
                || !date.type.equals(time.type)) {
            return null;
        }
        List<Key> dt = new ArrayList<Key>(2);
        dt.add(date);
        dt.add(time);
        return dt;
    }

    /**
     * Get the list of dates
     *
     * @param unique true for unique list
     *
     * @return the list of dates
     */
    protected List<String> makeDateList(boolean unique) {
        Key         date = dateTimeKeys.get(0);
        Key         time = dateTimeKeys.get(1);
        List<int[]> toCheck;
        if (date.type.equals(ROW)) {
            toCheck = headers.rowHeaders;
        } else {
            toCheck = headers.colHeaders;
        }
        List<String> fileDates = new ArrayList<String>();
        for (int[] header : toCheck) {
            if (header[0] != IMISSD) {
                // convert to GEMPAK date/time
                int idate = header[date.loc + 1];
                int itime = header[time.loc + 1];
                // TODO: Add in the century
                String dateTime = GempakUtil.TI_CDTM(idate, itime);
                fileDates.add(dateTime);
            }
        }
        if (unique && !fileDates.isEmpty()) {
            SortedSet<String> uniqueTimes =
                Collections.synchronizedSortedSet(new TreeSet<String>());
            uniqueTimes.addAll(fileDates);
            fileDates.clear();
            fileDates.addAll(uniqueTimes);
        }

        return fileDates;
    }

    /**
     * Make GempakParameters from the list of
     *
     * @param part  the part to use
     *
     * @return  parameters from the info in that part.
     */
    private List<GempakParameter> makeParams(DMPart part) {
        List<GempakParameter> gemparms =
            new ArrayList<GempakParameter>(part.kparms);
        for (DMParam param : part.params) {
            String          name = param.kprmnm;
            GempakParameter parm = GempakParameters.getParameter(name);
            if (parm == null) {
                //System.out.println("couldn't find " + name
                //                   + " in params table");
                parm = new GempakParameter(1, name, name, "", 0);
            }
            gemparms.add(parm);
        }
        return gemparms;
    }

    /**
     * Get the list of parameters for the part
     *
     * @param partName name of the part
     * @return  list of parameters
     */
    public List<GempakParameter> getParameters(String partName) {
        return partParamMap.get(partName);
    }

    /**
     * Get the station list
     *
     * @return the list of stations
     */
    private List<GempakStation> getStationList() {
        Key slat = findKey(GempakStation.SLAT);
        if (slat == null) {
            return null;
        }
        List<int[]> toCheck;
        if (slat.type.equals(ROW)) {
            toCheck = headers.rowHeaders;
        } else {
            toCheck = headers.colHeaders;
        }
        List<GempakStation> fileStations = new ArrayList<GempakStation>();
        int                 i            = 0;
        for (int[] header : toCheck) {
            if (header[0] != IMISSD) {
                GempakStation station = makeStation(header);
                if (station != null) {
                    station.setIndex(i + 1);
                    fileStations.add(station);
                }
            }
            i++;
        }
        return fileStations;
    }

    /**
     * Make a station from the header info
     *
     * @param header  the station header
     *
     * @return  the corresponding station
     */
    private GempakStation makeStation(int[] header) {
        if ((stationKeys == null) || stationKeys.isEmpty()) {
            return null;
        }
        GempakStation newStation = new GempakStation();
        for (Key key : stationKeys) {
            int loc = key.loc + 1;
            if (key.name.equals(GempakStation.STID)) {
                newStation.setSTID(GempakUtil.ST_ITOC(header[loc]).trim());
            } else if (key.name.equals(GempakStation.STNM)) {
                newStation.setSTNM(header[loc]);
            } else if (key.name.equals(GempakStation.SLAT)) {
                newStation.setSLAT(header[loc]);
            } else if (key.name.equals(GempakStation.SLON)) {
                newStation.setSLON(header[loc]);
            } else if (key.name.equals(GempakStation.SELV)) {
                newStation.setSELV(header[loc]);
            } else if (key.name.equals(GempakStation.SPRI)) {
                newStation.setSPRI(header[loc]);
            } else if (key.name.equals(GempakStation.STAT)) {
                newStation.setSTAT(GempakUtil.ST_ITOC(header[loc]).trim());
            } else if (key.name.equals(GempakStation.COUN)) {
                newStation.setCOUN(GempakUtil.ST_ITOC(header[loc]).trim());
            } else if (key.name.equals(GempakStation.SWFO)) {
                newStation.setSWFO(GempakUtil.ST_ITOC(header[loc]).trim());
            } else if (key.name.equals(GempakStation.WFO2)) {
                newStation.setWFO2(GempakUtil.ST_ITOC(header[loc]).trim());
            } else if (key.name.equals(GempakStation.STD2)) {
                newStation.setSTD2(GempakUtil.ST_ITOC(header[loc]).trim());
            }
        }
        return newStation;
    }

    /**
     * Get the station key names
     *
     * @return the list of station key names
     */
    public List<String> getStationKeyNames() {
        List<String> keys = new ArrayList<String>();
        if ((stationKeys != null) && !stationKeys.isEmpty()) {
            for (Key key : stationKeys) {
                keys.add(key.name);
            }
        }
        return keys;
    }

    /**
     * Get the station keys
     *
     * @return the list of station keys
     */
    private List<Key> findStationKeys() {
        Key stid = findKey(GempakStation.STID);
        Key stnm = findKey(GempakStation.STNM);
        Key slat = findKey(GempakStation.SLAT);
        Key slon = findKey(GempakStation.SLON);
        Key selv = findKey(GempakStation.SELV);
        Key stat = findKey(GempakStation.STAT);
        Key coun = findKey(GempakStation.COUN);
        Key std2 = findKey(GempakStation.STD2);
        Key spri = findKey(GempakStation.SPRI);
        Key swfo = findKey(GempakStation.SWFO);
        Key wfo2 = findKey(GempakStation.WFO2);
        if ((slat == null) || (slon == null)
                || !slat.type.equals(slon.type)) {
            return null;
        }
        String tslat = slat.type;
        // check to make sure they are all in the same set of keys
        List<Key> stKeys = new ArrayList<Key>();
        stKeys.add(slat);
        stKeys.add(slon);
        if ((stid != null) && !stid.type.equals(tslat)) {
            return null;
        } else if ((stnm != null) && !stnm.type.equals(tslat)) {
            return null;
        } else if ((selv != null) && !selv.type.equals(tslat)) {
            return null;
        } else if ((stat != null) && !stat.type.equals(tslat)) {
            return null;
        } else if ((coun != null) && !coun.type.equals(tslat)) {
            return null;
        } else if ((std2 != null) && !std2.type.equals(tslat)) {
            return null;
        } else if ((spri != null) && !spri.type.equals(tslat)) {
            return null;
        } else if ((swfo != null) && !swfo.type.equals(tslat)) {
            return null;
        } else if ((wfo2 != null) && !wfo2.type.equals(tslat)) {
            return null;
        }
        if (stid != null) {
            stKeys.add(stid);
        }
        if (stnm != null) {
            stKeys.add(stnm);
        }
        if (selv != null) {
            stKeys.add(selv);
        }
        if (stat != null) {
            stKeys.add(stat);
        }
        if (coun != null) {
            stKeys.add(coun);
        }
        if (std2 != null) {
            stKeys.add(std2);
        }
        if (spri != null) {
            stKeys.add(spri);
        }
        if (swfo != null) {
            stKeys.add(swfo);
        }
        if (wfo2 != null) {
            stKeys.add(wfo2);
        }
        return stKeys;
    }

    /**
     * Get the list of stations in this file.
     * @return list of stations.
     */
    public List<GempakStation> getStations() {
        return stations;
    }

    /**
     * Get the list of dates in this file.
     * @return list of dates.
     */
    public List<Date> getDates() {
        if ((dates == null || dates.isEmpty()) && !dateList.isEmpty()) {
            dates = new ArrayList<Date>(dateList.size());
            dateFmt.setTimeZone(TimeZone.getTimeZone("GMT"));
            for (String dateString : dateList) {
                Date d = dateFmt.parse(dateString, new ParsePosition(0));
                //DateFromString.getDateUsingSimpleDateFormat(dateString,
                //    DATE_FORMAT);
                dates.add(d);
            }
        }
        return dates;
    }

    /**
     * Get the date string at the index
     *
     * @param index index (row or column)
     *
     * @return the date at that index
     */
    protected String getDateString(int index) {
        return dateList.get(index);
    }

    /**
     * Print the list of dates in the file
     */
    public void printDates() {
        StringBuilder builder = new StringBuilder();
        builder.append("\nDates:\n");
        for (String date : dateList) {
            builder.append("\t");
            builder.append(date);
            builder.append("\n");
        }
        System.out.println(builder.toString());
    }

    /**
     * Print the list of dates in the file
     * @param list  true to list each station, false to list summary
     */
    public void printStations(boolean list) {
        StringBuilder builder = new StringBuilder();
        builder.append("\nStations:\n");
        if (list) {
            for (GempakStation station : getStations()) {
                builder.append(station);
                builder.append("\n");
            }
        } else {
            builder.append("\t");
            builder.append(getStations().size());
        }
        System.out.println(builder.toString());
    }

    /**
     * Find the station index for the specified station id.
     * @param id station id (case sensitive)
     * @return index or -1 if not found.
     */
    public int findStationIndex(String id) {
        for (GempakStation station : getStations()) {
            if (station.getSTID().equals(id)) {
                return station.getIndex();
            }
        }
        return -1;
    }

    /**
     * Get the type for this file
     * @return file type
     */
    public String getFileType() {
        String type = "Unknown";
        switch (dmLabel.kftype) {

          case MFSN :
              type = "Sounding";
              break;

          case MFSF :
              type = "Surface";
              break;

          default :
        }
        if ( !subType.equals("")) {
            type = type + " (" + subType + ")";
        }
        return type;
    }

    /**
     * Subclasses need to set the subtype. This is an abstract
     * method so users will implement something to set the type.
     */
    protected abstract void makeFileSubType();

    /**
     * Get the file sub type
     * @return the subtype.
     */
    protected String getFileSubType() {
        return subType;
    }

}
TOP

Related Classes of ucar.nc2.iosp.gempak.AbstractGempakStationFileReader

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.