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

org.jgrasstools.gears.io.timedependent.OmsTimeSeriesIteratorReader Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of JGrasstools (http://www.jgrasstools.org)
 * (C) HydroloGIS - www.hydrologis.com 
 * 
 * JGrasstools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.jgrasstools.gears.io.timedependent;

import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_AUTHORCONTACTS;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_AUTHORNAMES;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_KEYWORDS;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_LABEL;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_LICENSE;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_NAME;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_STATUS;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_FILE_NOVALUE_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_FILE_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_ID_FIELD_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_NOVALUE_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_OUT_DATA_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_P_AGGREGATION_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_P_NUM_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_T_CURRENT_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_T_END_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_T_PREVIOUS_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_T_START_DESCRIPTION;
import static org.jgrasstools.gears.i18n.GearsMessages.OMSTIMESERIESITERATORREADER_T_TIMESTEP_DESCRIPTION;
import static org.jgrasstools.gears.libs.modules.JGTConstants.doubleNovalue;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import oms3.annotations.Author;
import oms3.annotations.Description;
import oms3.annotations.Execute;
import oms3.annotations.Finalize;
import oms3.annotations.In;
import oms3.annotations.Initialize;
import oms3.annotations.Keywords;
import oms3.annotations.Label;
import oms3.annotations.License;
import oms3.annotations.Name;
import oms3.annotations.Out;
import oms3.annotations.Status;
import oms3.annotations.UI;
import oms3.io.CSTable;
import oms3.io.DataIO;
import oms3.io.TableIterator;

import org.jgrasstools.gears.libs.exceptions.ModelsIllegalargumentException;
import org.jgrasstools.gears.libs.modules.JGTConstants;
import org.jgrasstools.gears.libs.modules.JGTModel;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;

@Description(OMSTIMESERIESITERATORREADER_DESCRIPTION)
@Author(name = OMSTIMESERIESITERATORREADER_AUTHORNAMES, contact = OMSTIMESERIESITERATORREADER_AUTHORCONTACTS)
@Keywords(OMSTIMESERIESITERATORREADER_KEYWORDS)
@Label(OMSTIMESERIESITERATORREADER_LABEL)
@Name(OMSTIMESERIESITERATORREADER_NAME)
@Status(OMSTIMESERIESITERATORREADER_STATUS)
@License(OMSTIMESERIESITERATORREADER_LICENSE)
public class OmsTimeSeriesIteratorReader extends JGTModel {

    @Description(OMSTIMESERIESITERATORREADER_FILE_DESCRIPTION)
    @UI(JGTConstants.FILEIN_UI_HINT)
    @In
    public String file = null;

    @Description(OMSTIMESERIESITERATORREADER_ID_FIELD_DESCRIPTION)
    @In
    public String idfield = "ID";

    @Description(OMSTIMESERIESITERATORREADER_FILE_NOVALUE_DESCRIPTION)
    @In
    public String fileNovalue = "-9999.0";

    @Description(OMSTIMESERIESITERATORREADER_NOVALUE_DESCRIPTION)
    @In
    public double novalue = JGTConstants.doubleNovalue;

    @Description(OMSTIMESERIESITERATORREADER_P_NUM_DESCRIPTION)
    @In
    public int pNum = 1;

    @Description(OMSTIMESERIESITERATORREADER_P_AGGREGATION_DESCRIPTION)
    @In
    public int pAggregation = 0;

    @Description(OMSTIMESERIESITERATORREADER_T_START_DESCRIPTION)
    @In
    @Out
    public String tStart;

    @Description(OMSTIMESERIESITERATORREADER_T_END_DESCRIPTION)
    @In
    @Out
    public String tEnd;

    @Description(OMSTIMESERIESITERATORREADER_T_TIMESTEP_DESCRIPTION)
    @In
    @Out
    public int tTimestep;

    @Description(OMSTIMESERIESITERATORREADER_T_CURRENT_DESCRIPTION)
    @Out
    public String tCurrent;

    @Description(OMSTIMESERIESITERATORREADER_T_PREVIOUS_DESCRIPTION)
    @Out
    public String tPrevious;

    @Description(OMSTIMESERIESITERATORREADER_OUT_DATA_DESCRIPTION)
    @Out
    public HashMap outData;

    private TableIterator rowsIterator;

    private CSTable table;

    private DateTimeFormatter formatter = JGTConstants.utcDateFormatterYYYYMMDDHHMM;

    private DateTime expectedTimestamp = null;

    @Initialize
    public void initProcess() {
        // activate time
        doProcess = true;

    }
    private void ensureOpen() throws IOException {
        if (table == null) {
            table = DataIO.table(new File(file), null);
            rowsIterator = (TableIterator) table.rows().iterator();
            /*
             * If tStart is null then the reader try to read all the value in the file, nb time step constant.
             */
            if (tStart == null) {
                String secondTime = null;
                // get the first time in the file.
                if (rowsIterator.hasNext()) {
                    String[] row = rowsIterator.next();
                    tStart = row[1];
                }
                // get the time of the second row in the file.
                if (rowsIterator.hasNext()) {
                    String[] row = rowsIterator.next();
                    secondTime = row[1];
                }
                // the dt is equal to the fifference of the time of 2 rows.
                tTimestep = formatter.parseDateTime(secondTime).getMinuteOfDay()
                        - formatter.parseDateTime(tStart).getMinuteOfDay();
                // close and reopen to read the row.
                rowsIterator.close();
                rowsIterator = (TableIterator) table.rows().iterator();
            }

        }
    }

    @Execute
    public void nextRecord() throws IOException {
        ensureOpen();
        if (tCurrent == null) {
            tPrevious = null;
            tCurrent = tStart.trim();
            expectedTimestamp = formatter.parseDateTime(tCurrent);
        } else {

            tPrevious = tCurrent;
            expectedTimestamp = expectedTimestamp.plusMinutes(tTimestep);
            tCurrent = expectedTimestamp.toString(formatter);
        }
        outData = new HashMap();

        int columnCount = table.getColumnCount();
        List idList = new ArrayList();
        List idCountList = new ArrayList();
        int count = 0;
        Integer previousIdInteger = null;
        for( int i = 2; i <= columnCount; i++ ) {
            String id = table.getColumnInfo(i).get(idfield);
            try {
                Integer idInteger = Integer.valueOf(id);
                idList.add(idInteger);
                if (previousIdInteger == null) {
                    count++;
                } else {
                    if (idInteger.intValue() == previousIdInteger.intValue()) {
                        count++;
                    } else {
                        idCountList.add(count);
                        count = 1;
                    }
                }
                if (i == columnCount) {
                    idCountList.add(count);
                }
                previousIdInteger = idInteger;
            } catch (Exception e) {
                throw new ModelsIllegalargumentException("The id value doesn't seem to be an integer.", this.getClass()
                        .getSimpleName(), pm);
            }
        }

        if (rowsIterator.hasNext()) {
            String[] row = getExpectedRow(rowsIterator, expectedTimestamp);

            int idCountIndex = 0;
            for( int i = 2; i < row.length; i++ ) {
                Integer id = idList.get(i - 2);
                Integer idCount = idCountList.get(idCountIndex);
                double[] values = outData.get(id);
                if (values == null) {
                    values = new double[idCount];
                    outData.put(id, values);
                }
                for( int j = 0; j < idCount; j++, i++ ) {
                    if (row[i] == null || row[i].length() == 0) {
                        values[j] = novalue;
                    } else {
                        String valueStr = row[i].trim();
                        if (valueStr.equals(fileNovalue)) {
                            values[j] = novalue;
                        } else {
                            values[j] = Double.parseDouble(valueStr);
                        }
                    }
                }
                idCountIndex++;
                i--;
            }
        } else {
            outData = null;
        }

        // time ran out
        if (tEnd != null && tCurrent.equals(tEnd)) {
            doProcess = false;
        }
        // data ran out
        if (!rowsIterator.hasNext()) {
            doProcess = false;
        }
    }

    /**
     * Get the needed datarow from the table.
     * 
     * @param tableRowIterator
     * @return the row that is aligned with the expected timestep.
     * @throws IOException if the expected timestep is < than the current.
     */
    private String[] getExpectedRow( TableIterator tableRowIterator, DateTime expectedDT ) throws IOException {
        while( tableRowIterator.hasNext() ) {
            String[] row = tableRowIterator.next();
            DateTime currentTimestamp = formatter.parseDateTime(row[1]);
            if (currentTimestamp.equals(expectedDT)) {
                if (pNum == 1) {
                    return row;
                } else {
                    String[][] allRows = new String[pNum][];
                    allRows[0] = row;
                    int rowNum = 1;
                    for( int i = 1; i < pNum; i++ ) {
                        if (tableRowIterator.hasNext()) {
                            String[] nextRow = tableRowIterator.next();
                            allRows[i] = nextRow;
                            rowNum++;
                        }
                    }
                    // now aggregate
                    String[] aggregatedRow = new String[row.length];
                    // date is the one of the first instant
                    aggregatedRow[0] = allRows[0][0];
                    aggregatedRow[1] = allRows[0][1];
                    for( int col = 2; col < allRows[0].length; col++ ) {

                        boolean hasOne = false;
                        switch( pAggregation ) {
                        case 0:
                            double sum = 0;
                            for( int j = 0; j < rowNum; j++ ) {
                                String valueStr = allRows[j][col];
                                if (!valueStr.equals(fileNovalue)) {
                                    double value = Double.parseDouble(valueStr);
                                    sum = sum + value;
                                    hasOne = true;
                                }
                            }
                            if (!hasOne) {
                                sum = doubleNovalue;
                            }
                            aggregatedRow[col] = String.valueOf(sum);
                            break;
                        case 1:
                            double avg = 0;
                            for( int j = 0; j < rowNum; j++ ) {
                                String valueStr = allRows[j][col];
                                if (!valueStr.equals(fileNovalue)) {
                                    double value = Double.parseDouble(valueStr);
                                    avg = avg + value;
                                    hasOne = true;
                                }
                            }
                            if (!hasOne) {
                                avg = doubleNovalue;
                            } else {
                                avg = avg / pNum;
                            }
                            aggregatedRow[col] = String.valueOf(avg);
                            break;

                        default:
                            break;
                        }

                    }
                    return aggregatedRow;
                }
            } else if (currentTimestamp.isBefore(expectedDT)) {
                // browse until the instant is found
                continue;
            } else if (currentTimestamp.isAfter(expectedDT)) {
                /*
                 * lost the moment, for now throw exception.
                 * Could be enhanced in future.
                 */
                String message = "The data are not aligned with the simulation interval (" + currentTimestamp + "/" + expectedDT
                        + "). Check your data file: " + file;
                throw new IOException(message);
            }

        }
        return null;
    }

    @Finalize
    public void close() throws IOException {
        rowsIterator.close();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy