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

ucar.nc2.iosp.gempak.AbstractGempakStationFileReader 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.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 dateTimeKeys;

    /** station keys */
    private List stationKeys;

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

    /** unique list of dates as Dates */
    private List dates;

    /** list of stations */
    private List stations;

    /** list of parameters */
    private List params;

    /** list of parameters */
    private Map> partParamMap =
        new HashMap>();

    /** 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 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 getDateTimeKeys() {
        Key date = findKey(DATE);
        Key time = findKey(TIME);
        if ((date == null) || (time == null)
                || !date.type.equals(time.type)) {
            return null;
        }
        List dt = new ArrayList(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 makeDateList(boolean unique) {
        Key         date = dateTimeKeys.get(0);
        Key         time = dateTimeKeys.get(1);
        List toCheck;
        if (date.type.equals(ROW)) {
            toCheck = headers.rowHeaders;
        } else {
            toCheck = headers.colHeaders;
        }
        List fileDates = new ArrayList();
        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 uniqueTimes =
                Collections.synchronizedSortedSet(new TreeSet());
            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 makeParams(DMPart part) {
        List gemparms =
            new ArrayList(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 getParameters(String partName) {
        return partParamMap.get(partName);
    }

    /**
     * Get the station list
     *
     * @return the list of stations
     */
    private List getStationList() {
        Key slat = findKey(GempakStation.SLAT);
        if (slat == null) {
            return null;
        }
        List toCheck;
        if (slat.type.equals(ROW)) {
            toCheck = headers.rowHeaders;
        } else {
            toCheck = headers.colHeaders;
        }
        List fileStations = new ArrayList();
        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 getStationKeyNames() {
        List keys = new ArrayList();
        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 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 stKeys = new ArrayList();
        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 getStations() {
        return stations;
    }

    /**
     * Get the list of dates in this file.
     * @return list of dates.
     */
    public List getDates() {
        if ((dates == null || dates.isEmpty()) && !dateList.isEmpty()) {
            dates = new ArrayList(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;
    }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy