ClimaticResource.java

/*
 * This file is part of Indicators.
 *
 * Indicators 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.
 *
 * Indicators 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 Indicators. If not, see <https://www.gnu.org/licenses/>.
 */
package fr.inrae.agroclim.indicators.model.data.climate;

import java.util.Date;
import java.util.List;
import java.util.Set;

import fr.inrae.agroclim.indicators.model.data.Resource;
import fr.inrae.agroclim.indicators.model.data.Variable;
import fr.inrae.agroclim.indicators.util.DateUtils;

/**
 * Storage of climatic daily data.
 *
 * Last change $Date$
 *
 * @author $Author$
 * @version $Revision$
 */
public class ClimaticResource extends Resource<ClimaticDailyData> {
    /**
     * UUID for Serializable.
     */
    private static final long serialVersionUID = 4872847709393688049L;

    /**
     * Constructor.
     */
    public ClimaticResource() {
        super();
    }

    /**
     * @param dailyData
     *            a climatic daily data to add
     */
    private void addData(final ClimaticDailyData dailyData) {
        getData().add(dailyData);
        addYear(dailyData.getYear());
        fireDataLoadingAddEvent(dailyData);
    }

    @Override
    public final ClimaticResource clone() throws CloneNotSupportedException {
        final ClimaticResource clone = (ClimaticResource) super.clone();
        clone.getData().addAll(getData());
        return clone;
    }

    /**
     * Create a new resource for the period.
     *
     * @param startDate period start included
     * @param endDate period end excluded
     * @return new resource with data
     */
    public final ClimaticResource getClimaticDataByPhaseAndYear(
            final Date startDate, final Date endDate) {
        final ClimaticResource newResource = new ClimaticResource();
        newResource.setMissingVariables(getMissingVariables());

        getData().stream().filter(dailyData -> {
            final Date date = dailyData.getDate();
            if (date != null) {
                return date.equals(startDate)
                        || dailyData.getDate().after(startDate)
                        && dailyData.getDate().before(endDate);
            } else {
                return false;
            }

        }
                ).forEach(newResource::addData);
        return newResource;
    }

    /**
     * Create a new resource for the period.
     *
     * @param start
     *            period start (day of year) included
     * @param end
     *            period end (day of year) excluded
     * @param year
     *            period year
     * @return new resource with data
     */
    public final ClimaticResource getClimaticDataByPhaseAndYear(
            final int start, final int end, final int year) {
        final Date startDate = DateUtils.getDate(year, start);
        final Date endDate = DateUtils.getDate(year, end);
        return getClimaticDataByPhaseAndYear(startDate, endDate);
    }

    /**
     * @param list all climatic daily data for the resource
     */
    public final void setData(final List<ClimaticDailyData> list) {
        getData().clear();
        getYears().clear();
        list.forEach(this::addData);
        fireDataLoadingEndEvent(list.size() + " climatic data added!");
    }
    /**
     * Check if current year has complete data.
     * If at least one variable in the dataset has at least a zero value, then the year is considered incomplete.
     * @param providedVariables List of variables present in the climate file
     * @return {@code true} if the data for the year are all present or {@code false} otherwise
     */
    public boolean hasCompleteDataInYear(final Set<Variable> providedVariables) {
        boolean state = true;
        for (final ClimaticDailyData cdd : this.getData()) {    // Pour chaque ligne remontée pour la phase / année
            for (final Variable v : providedVariables) {        // Pour chaque variable du fichier climatique
                final Double value = cdd.getValue(v);

                state = !(value == null) && state;
            }
        }
        return state;
    }
}