org.jgrasstools.hortonmachine.modules.networktools.trento_p.OmsTrentoP.java Source code

Java tutorial

Introduction

Here is the source code for org.jgrasstools.hortonmachine.modules.networktools.trento_p.OmsTrentoP.java

Source

/*
 * 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 <http://www.gnu.org/licenses/>.
 */
package org.jgrasstools.hortonmachine.modules.networktools.trento_p;

import static java.lang.Math.pow;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_AUTHORCONTACTS;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_AUTHORNAMES;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_KEYWORDS;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_LABEL;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_LICENSE;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_NAME;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_STATUS;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_dt_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_inDiameters_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_inPipes_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_inRain_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_outDischarge_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_outFillDegree_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_outPipes_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_outTpMax_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pA_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pAccuracy_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pAlign_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pC_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pCelerityFactor_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pEpsilon_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pEspInflux_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pExponent_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pFranco_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pG_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pGamma_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pJMax_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pMaxJunction_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pMaxTheta_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pMinDischarge_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pMinG_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pMinimumDepth_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pMode_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pN_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pOutPipe_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pTau_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_pTolerance_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_tDTp_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_tMax_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_tpMaxCalibration_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_tpMax_DESCRIPTION;
import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSTRENTOP_tpMin_DESCRIPTION;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_ACCURACY;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_CELERITY_FACTOR;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_EPSILON;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_ESP1;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_EXPONENT;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_FRANCO;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_GAMMA;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_J_MAX;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_MAX_JUNCTION;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_MAX_THETA;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_MING;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_MINIMUM_DEPTH;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_MIN_DISCHARGE;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_TDTP;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_TMAX;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_TOLERANCE;
import static org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants.DEFAULT_TPMIN;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import oms3.annotations.Author;
import oms3.annotations.Description;
import oms3.annotations.Execute;
import oms3.annotations.In;
import oms3.annotations.Keywords;
import oms3.annotations.Label;
import oms3.annotations.License;
import oms3.annotations.Name;
import oms3.annotations.Out;
import oms3.annotations.Range;
import oms3.annotations.Status;
import oms3.annotations.UI;
import oms3.annotations.Unit;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.jgrasstools.gears.libs.modules.JGTModel;
import org.jgrasstools.gears.libs.modules.ModelsEngine;
import org.jgrasstools.gears.libs.monitor.IJGTProgressMonitor;
import org.jgrasstools.gears.utils.sorting.QuickSortAlgorithm;
import org.jgrasstools.hortonmachine.i18n.HortonMessageHandler;
import org.jgrasstools.hortonmachine.modules.networktools.trento_p.net.Network;
import org.jgrasstools.hortonmachine.modules.networktools.trento_p.net.NetworkBuilder;
import org.jgrasstools.hortonmachine.modules.networktools.trento_p.net.NetworkCalibration;
import org.jgrasstools.hortonmachine.modules.networktools.trento_p.net.Pipe;
import org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Constants;
import org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.TrentoPFeatureType;
import org.jgrasstools.hortonmachine.modules.networktools.trento_p.utils.Utility;
import org.joda.time.DateTime;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import com.vividsolutions.jts.geom.Coordinate;

@Description(OMSTRENTOP_DESCRIPTION)
@Author(name = OMSTRENTOP_AUTHORNAMES, contact = OMSTRENTOP_AUTHORCONTACTS)
@Keywords(OMSTRENTOP_KEYWORDS)
@Label(OMSTRENTOP_LABEL)
@Name(OMSTRENTOP_NAME)
@Status(OMSTRENTOP_STATUS)
@License(OMSTRENTOP_LICENSE)
public class OmsTrentoP extends JGTModel {

    @Description(OMSTRENTOP_pMode_DESCRIPTION)
    @In
    public int pMode;

    @Description(OMSTRENTOP_pMinimumDepth_DESCRIPTION)
    @Unit("m")
    @In
    public double pMinimumDepth = DEFAULT_MINIMUM_DEPTH;

    @Description(OMSTRENTOP_pMaxJunction_DESCRIPTION)
    @Unit("-")
    @Range(max = 6, min = 0)
    @In
    public int pMaxJunction = DEFAULT_MAX_JUNCTION;

    @Description(OMSTRENTOP_pJMax_DESCRIPTION)
    @Unit("-")
    @Range(max = 1000, min = 3)
    @In
    public int pJMax = DEFAULT_J_MAX;

    @Description(OMSTRENTOP_pAccuracy_DESCRIPTION)
    @Unit("-")
    @Range(min = 0)
    @In
    public Double pAccuracy = DEFAULT_ACCURACY;

    @Description(OMSTRENTOP_pEpsilon_DESCRIPTION)
    @Unit("-")
    @Range(max = 1, min = 0)
    @In
    public double pEpsilon = DEFAULT_EPSILON;

    @Description(OMSTRENTOP_pMinG_DESCRIPTION)
    @Unit("-")
    @Range(max = 0.1, min = 0)
    @In
    public double pMinG = DEFAULT_MING;

    @Description(OMSTRENTOP_pMinDischarge_DESCRIPTION)
    @Unit("m3/s")
    @Range(min = 0)
    @In
    public double pMinDischarge = DEFAULT_MIN_DISCHARGE;

    @Description(OMSTRENTOP_pMaxTheta_DESCRIPTION)
    @Unit("-")
    @Range(min = Math.PI)
    @In
    public double pMaxTheta = DEFAULT_MAX_THETA;

    @Description(OMSTRENTOP_pCelerityFactor_DESCRIPTION)
    @Unit("-")
    @Range(min = 1, max = 1.6)
    @In
    public double pCelerityFactor = DEFAULT_CELERITY_FACTOR;

    @Description(OMSTRENTOP_pExponent_DESCRIPTION)
    @Unit("-")
    @Range(min = 0)
    @In
    public double pExponent = DEFAULT_EXPONENT;

    @Description(OMSTRENTOP_pTolerance_DESCRIPTION)
    @Unit("-")
    @Range(min = 0)
    @In
    public double pTolerance = DEFAULT_TOLERANCE;

    @Description(OMSTRENTOP_pC_DESCRIPTION)
    @Unit("-")
    @Range(min = 0)
    @In
    public double pC = 1;

    @Description(OMSTRENTOP_pGamma_DESCRIPTION)
    @Unit("-")
    @Range(min = 0)
    @In
    public double pGamma = DEFAULT_GAMMA;

    @Description(OMSTRENTOP_pEspInflux_DESCRIPTION)
    @Unit("-")
    @Range(min = 0)
    @In
    public double pEspInflux = DEFAULT_ESP1;

    @Description(OMSTRENTOP_pFranco_DESCRIPTION)
    @Unit("m")
    @Range(min = 0)
    @In
    public double pFranco = DEFAULT_FRANCO;

    @Description(OMSTRENTOP_pA_DESCRIPTION)
    @Unit("-")
    @Range(min = 0)
    @In
    public Double pA;

    @Description(OMSTRENTOP_pN_DESCRIPTION)
    @Unit("-")
    @Range(min = 0.05, max = 0.95)
    @In
    public Double pN;

    @Description(OMSTRENTOP_pTau_DESCRIPTION)
    @Unit("N/m2")
    @Range(min = 0)
    @In
    public Double pTau;

    @Description(OMSTRENTOP_pG_DESCRIPTION)
    @Unit("-")
    @Range(min = 0, max = 0.99)
    @In
    public Double pG;

    @Description(OMSTRENTOP_pAlign_DESCRIPTION)
    @In
    public Integer pAlign;

    @Description(OMSTRENTOP_inDiameters_DESCRIPTION)
    @UI("infile")
    @In
    public List<double[]> inDiameters;

    @Description(OMSTRENTOP_pOutPipe_DESCRIPTION)
    @Unit("-")
    @In
    public Integer pOutPipe = null;

    @Description(OMSTRENTOP_tDTp_DESCRIPTION)
    @Unit("-")
    @Range(min = 0.015)
    @In
    public double tDTp = DEFAULT_TDTP;

    @Description(OMSTRENTOP_tpMin_DESCRIPTION)
    @Unit("-")
    @Range(min = 5)
    @In
    public double tpMin = DEFAULT_TPMIN;

    @Description(OMSTRENTOP_tpMax_DESCRIPTION)
    @Unit("minutes")
    @Range(min = 30)
    @In
    public double tpMax = DEFAULT_TMAX;

    @Description(OMSTRENTOP_tMax_DESCRIPTION)
    @Unit("-")
    @In
    public int tMax = (int) DEFAULT_TMAX;

    @Description(OMSTRENTOP_tpMaxCalibration_DESCRIPTION)
    @Unit("minutes")
    @In
    public Integer tpMaxCalibration = null;

    @Description(OMSTRENTOP_dt_DESCRIPTION)
    @Unit("minutes")
    @In
    public Integer dt;

    @Description(OMSTRENTOP_inRain_DESCRIPTION)
    @UI("infile")
    @In
    public HashMap<DateTime, double[]> inRain = null;

    @Description(OMSTRENTOP_inPipes_DESCRIPTION)
    @In
    public SimpleFeatureCollection inPipes = null;

    @Description(OMSTRENTOP_outPipes_DESCRIPTION)
    @Out
    public SimpleFeatureCollection outPipes = null;

    @Description(OMSTRENTOP_outDischarge_DESCRIPTION)
    @UI("outfile")
    @Out
    public HashMap<DateTime, HashMap<Integer, double[]>> outDischarge;

    @Description(OMSTRENTOP_outFillDegree_DESCRIPTION)
    @UI("outfile")
    @Out
    public HashMap<DateTime, HashMap<Integer, double[]>> outFillDegree;

    @Description(OMSTRENTOP_outTpMax_DESCRIPTION)
    @Unit("minutes")
    @Out
    public Integer outTpMax = null;

    /**
     * Message handler.
     */
    private final HortonMessageHandler msg = HortonMessageHandler.getInstance();

    /**
     * Is an array with all the pipe of the net.
     */
    private Pipe[] networkPipes;

    /*
     * string which collected all the warnings. the warnings are printed at the
     * end of the processes.
     */
    private String warnings = "warnings";

    public StringBuilder warningBuilder = new StringBuilder(warnings);
    /**
     * Used in calibration mode if use the generation of the rain.
     */
    private boolean foundTp = false;

    /**
     * 
     * Elaboration on the net.
     * 
     * <p>
     * 
     * <ol>
     * <li>Verify the net throughout the method verify.
     * <li>Call the geosewer method which calculate the pipes diameter or the
     * discharge.
     * </ol>
     * </p>
     * 
     * @throws Exception
     * 
     * 
     * @throw {@link IllegalArgumentException} this is throw to the verify
     *        methods, if some parameters isn't correct.
     * @see {@link NetworkBuilder}
     * 
     */
    @Execute
    public void process() throws Exception {
        /*
         * verify the parameter in input (these method, when the OMS annotation
         * work well, can be deleted).
         */
        // begin the process.
        pm.message(msg.message("trentoP.firstMessage"));
        /*
         * verify the parameter in input (these method, when the OMS annotation
         * work well, can be deleted) andcreate the net as an array of pipes. .
         */
        setNetworkPipes(verifyParameter());
        /*
         * create a network object. It can be a NetworkCalibration if the mode
         * (pTest==1) verify otherwise is a NetworkBuilder.
         */
        Network network = null;
        if (pMode == 1) {
            // set other common parameters for the verification.
            if (inPipes != null) {
                for (int t = 0; t < networkPipes.length; t++) {

                    networkPipes[t].setAccuracy(pAccuracy);
                    networkPipes[t].setJMax(pJMax);
                    networkPipes[t].setMaxTheta(pMaxTheta);
                    networkPipes[t].setTolerance(pTolerance);
                    networkPipes[t].setK(pEspInflux, pExponent, pGamma);

                }

            }

            outDischarge = new LinkedHashMap<DateTime, HashMap<Integer, double[]>>();
            outFillDegree = new LinkedHashMap<DateTime, HashMap<Integer, double[]>>();
            // initialize the NetworkCalibration.
            network = new NetworkCalibration.Builder(pm, networkPipes, dt, inRain, outDischarge, outFillDegree,
                    warningBuilder, tpMaxCalibration, foundTp).celerityFactor(pCelerityFactor).tMax(tMax).build();
            network.geoSewer();
            outTpMax = ((NetworkCalibration) network).getTpMax();

        } else {
            // set other common parameters for the project.

            if (inPipes != null) {
                for (int t = 0; t < networkPipes.length; t++) {
                    networkPipes[t].setAccuracy(pAccuracy);
                    networkPipes[t].setMinimumDepth(pMinimumDepth);
                    networkPipes[t].setMinG(pMinG);
                    networkPipes[t].setJMax(pJMax);
                    networkPipes[t].setMaxJunction(pMaxJunction);
                    networkPipes[t].setAlign(pAlign);
                    networkPipes[t].setC(pC);
                    networkPipes[t].setG(pG);
                    networkPipes[t].setTau(pTau);
                    networkPipes[t].setMinDischarge(pMinDischarge);

                }

            }

            pA = pA / pow(60, pN); /* [mm/hour^n] -> [mm/min^n] */
            // initialize the NetworkCalibration.

            NetworkBuilder.Builder builder = new NetworkBuilder.Builder(pm, networkPipes, pN, pA, inDiameters,
                    inPipes, warningBuilder);
            network = builder.celerityFactor(pCelerityFactor).pEpsilon(pEpsilon).pEsp1(pEspInflux)
                    .pExponent(pExponent).pGamma(pGamma).tDTp(tDTp).tpMax(tpMax).tpMin(tpMin).build();
            network.geoSewer();
            outPipes = Utility.createFeatureCollections(inPipes, networkPipes);

        }

        // elaborate.

        String w = warningBuilder.toString();
        if (!w.equals(warnings)) {
            pm.message(w);
        }

        pm.message(msg.message("trentoP.end"));

    }

    /*
     * Verifica la validit dei dati, OSSERVAZIONE con OMS non necessaria,
     * vedere dichiarazione variabili per il range.
     * 
     * @throw IllegalArgumentException se un parametro non rispetta certe
     * condizioni (in OMS3 fatto dalle annotation)
     * 
     * @return true if there is the percentage area.
     */
    private boolean verifyParameter() {
        // checkNull(inPipes,pAccuracy);
        boolean isAreaAllDry;

        if (pMode < 0 || pMode > 1) {
            pm.errorMessage(msg.message("trentoP.error.mode"));
            throw new IllegalArgumentException(msg.message("trentoP.error.mode"));

        }

        if (inPipes == null) {
            pm.errorMessage(msg.message("trentoP.error.inputMatrix") + " geometry file");
            throw new IllegalArgumentException(msg.message("trentoP.error.inputMatrix") + " geometry file");
        }

        /* Il numero di giunzioni in un nodo non puo' superiore a 7 */
        if (pMaxJunction <= 0 || pMaxJunction > 6) {
            pm.errorMessage(msg.message("trentoP.error.maxJunction"));
            throw new IllegalArgumentException();
        }

        /*
         * Il numero di iterazioni ammesso non puo' essere troppo piccolo ne'
         * eccessivamente grande
         */
        if (pJMax < 3 || pJMax > 1000) {
            pm.errorMessage(msg.message("trentoP.error.jMax"));
            throw new IllegalArgumentException(msg.message("trentoP.error.jMax"));
        }

        /*
         * La precisione con cui si cercano alcune soluzioni non puo' essere
         * negativa
         */
        if (pAccuracy == null || pAccuracy <= 0) {
            pm.errorMessage(msg.message("trentoP.error.accuracy"));
            throw new IllegalArgumentException();
        }
        /* Intervallo in cui puo variare il riempimento minimo */
        if (pMinG <= 0 || pMinG > 0.1) {
            pm.errorMessage(msg.message("trentoP.error.minG"));
            throw new IllegalArgumentException();
        }
        /* Non sono ammesse portate minime negative nei tubi */
        if (pMinDischarge <= 0) {
            pm.errorMessage(msg.message("trentoP.error.minDischarge"));
            throw new IllegalArgumentException();
        }

        /* Il fattore di celerita' deve essere compreso tra 1 e 1.6 */
        if (pCelerityFactor < 1 || pCelerityFactor > 1.6) {
            pm.errorMessage(msg.message("trentoP.error.celerity"));
            throw new IllegalArgumentException();
        }

        /* EXPONENT non puo' essere negativo */
        if (pExponent <= 0) {
            pm.errorMessage(msg.message("trentoP.error.exponent"));
            throw new IllegalArgumentException();
        }

        /* La tolleranza non puo' essere nulla tantomeno negativa */
        if (pTolerance <= 0) {
            pm.errorMessage(msg.message("trentoP.error.tolerance"));
            throw new IllegalArgumentException();
        }

        if (pGamma <= 0) {
            pm.errorMessage(msg.message("trentoP.error.gamma"));
            throw new IllegalArgumentException();
        }

        if (pEspInflux <= 0) {
            pm.errorMessage(msg.message("trentoP.error.eps1"));
            throw new IllegalArgumentException();
        }

        SimpleFeatureType schema = inPipes.getSchema();

        if (pMode == 0) {
            // checkNull(pA,pN,pTau,inDiameters);

            isAreaAllDry = Utility.verifyProjectType(schema, pm);

            if (pA == null || pA <= 0) {
                pm.errorMessage(msg.message("trentoP.error.a"));
                throw new IllegalArgumentException(msg.message("trentoP.error.a"));
            }
            if (pN == null || pN < 0.05 || pN > 0.95) {
                pm.errorMessage(msg.message("trentoP.error.n"));
                throw new IllegalArgumentException(msg.message("trentoP.error.n"));
            }
            if (pTau == null || pTau <= 0) {
                pm.errorMessage(msg.message("trentoP.error.tau"));
                throw new IllegalArgumentException(msg.message("trentoP.error.tau"));
            }

            if (pG == null || pG <= 0 || pG > 0.99) {
                pm.errorMessage(msg.message("trentoP.error.g"));

                throw new IllegalArgumentException(msg.message("trentoP.error.g"));
            }
            if (pAlign != 0 && pAlign != 1) {
                pm.errorMessage(msg.message("trentoP.error.align"));
                throw new IllegalArgumentException(msg.message("trentoP.error.align"));
            }
            /* Lo scavo minimo non puo' essere uguale o inferiore a 0 */
            if (pMinimumDepth <= 0) {
                pm.errorMessage(msg.message("trentoP.error.scavomin"));
                throw new IllegalArgumentException();

            }
            /* Pecisione con cui si ricerca la portata nelle aree non di testa. */
            if (pEpsilon <= 0 || pEpsilon > 1) {
                pm.errorMessage(msg.message("trentoP.error.epsilon"));
                throw new IllegalArgumentException();
            }
            /*
             * L'angolo di riempimento minimo non puo' essere inferiore a 3.14
             * [rad]
             */
            if (pMaxTheta < 3.14) {
                pm.errorMessage(msg.message("trentoP.error.maxtheta"));
                throw new IllegalArgumentException();
            }
            if (pC <= 0) {
                pm.errorMessage(msg.message("trentoP.error.c"));
                throw new IllegalArgumentException();
            }
            if (inDiameters == null) {

                throw new IllegalArgumentException();
            }

            /*
             * Il passo temporale con cui valutare le portate non puo' essere
             * inferiore a 0.015 [min]
             */
            if (tDTp < 0.015) {
                pm.errorMessage(msg.message("trentoP.error.dtp"));
                throw new IllegalArgumentException();
            }

            /*
             * Tempo di pioggia minimo da considerare nella massimizzazione
             * delle portate non puo' essere superiore a 5 [min]
             */
            if (tpMin > 5) {
                pm.errorMessage(msg.message("trentoP.error.tpmin"));
                throw new IllegalArgumentException();
            }

            /*
             * Tempo di pioggia massimo da adottare nella ricerca della portata
             * massima non puo' essere inferiore a 5 [min]
             */
            if (tpMax < 30) {
                pm.errorMessage(msg.message("trentoP.error.tpmax"));
                throw new IllegalArgumentException();
            }
        } else {
            // checkNull(inRain);
            isAreaAllDry = Utility.verifyCalibrationType(schema, pm);

            /*
             * If the inRain is null and the users set the a and n parameters then create the rain data.
             */
            if (pA != null && pN != null) {
                // set it to true in order to search the time at max discharge.
                if (tpMaxCalibration != null) {
                    foundTp = true;
                } else {
                    tpMaxCalibration = tMax;
                }
                if (dt == null) {
                    pm.errorMessage(msg.message("trentoP.error.dtp"));
                    throw new IllegalArgumentException();
                }
                if (tMax < tpMaxCalibration) {
                    tpMaxCalibration = tMax;
                }

                double tMaxApproximate = ModelsEngine.approximate2Multiple(tMax, dt);
                // initialize the output.
                int iMax = (int) (tMaxApproximate / dt);
                int iRainMax = (int) (Math.floor((double) tpMaxCalibration / (double) dt));
                DateTime startTime = new DateTime(System.currentTimeMillis());
                inRain = new LinkedHashMap<DateTime, double[]>();
                double tp = ((double) dt) / 2;
                DateTime newDate = startTime;
                for (int i = 0; i <= iMax; i++) {
                    newDate = newDate.plusMinutes(dt);
                    double hourTime = tp / Constants.HOUR2MIN;
                    double value;
                    if (i < iRainMax) {
                        value = pA * pow(hourTime, pN - 1) / Constants.HOUR2MIN;
                    } else {
                        value = 0.0;
                    }
                    inRain.put(newDate, new double[] { value });
                    tp = tp + dt;
                }

            } else {
                // force the time steep to null in order to read it to the file.
                dt = null;
            }
            if (inRain == null) {

                pm.errorMessage(msg.message("trentoP.error.inputRainMatrix") + " rain file");
                throw new IllegalArgumentException(msg.message("trentoP.error.inputRainMatrix") + " rain file");
            }

            // verificy if the field exist.

        }
        return isAreaAllDry;
    }

    /**
     * Initializating the array.
     * 
     * <p>
     * The array is the net. If there is a FeatureCollection extract values from
     * it. The Array is order following the ID.
     * </p>
     * oss: if the FeatureCillection is null a IllegalArgumentException is throw
     * in {@link OmsTrentoP#verifyParameter()}.
     * 
     * @param isAreaNotAllDry it is true if there is only a percentage of the input area dry.
     * @throws IllegalArgumentException
     *             if the FeatureCollection hasn't the correct parameters.
     */
    private void setNetworkPipes(boolean isAreaNotAllDry) throws Exception {

        int length = inPipes.size();
        networkPipes = new Pipe[length];
        SimpleFeatureIterator stationsIter = inPipes.features();
        boolean existOut = false;
        int tmpOutIndex = 0;
        try {
            int t = 0;
            while (stationsIter.hasNext()) {
                SimpleFeature feature = stationsIter.next();
                try {
                    /*
                     * extract the value of the ID which is the position (minus
                     * 1) in the array.
                     */

                    Number field = ((Number) feature.getAttribute(TrentoPFeatureType.ID_STR));
                    if (field == null) {
                        pm.errorMessage(msg.message("trentoP.error.number") + TrentoPFeatureType.ID_STR);
                        throw new IllegalArgumentException(
                                msg.message("trentoP.error.number") + TrentoPFeatureType.ID_STR);
                    }
                    if (field.equals(pOutPipe)) {
                        tmpOutIndex = t;
                        existOut = true;
                    }
                    networkPipes[t] = new Pipe(feature, pMode, isAreaNotAllDry, pm);
                    t++;

                } catch (NullPointerException e) {
                    pm.errorMessage(msg.message("trentop.illegalNet"));
                    throw new IllegalArgumentException(msg.message("trentop.illegalNet"));

                }
            }

        } finally {
            stationsIter.close();
        }
        if (!existOut) {

        }
        // set the id where drain of the outlet.
        networkPipes[tmpOutIndex].setIdPipeWhereDrain(0);
        networkPipes[tmpOutIndex].setIndexPipeWhereDrain(-1);

        // start to construct the net.
        int numberOfPoint = networkPipes[tmpOutIndex].point.length - 1;
        findIdThatDrainsIntoIndex(tmpOutIndex, networkPipes[tmpOutIndex].point[0]);
        findIdThatDrainsIntoIndex(tmpOutIndex, networkPipes[tmpOutIndex].point[numberOfPoint]);

        List<Integer> missingId = new ArrayList<Integer>();
        for (Pipe pipe : networkPipes) {
            if (pipe.getIdPipeWhereDrain() == null && pipe.getId() != pOutPipe) {
                missingId.add(pipe.getId());
            }
        }
        if (missingId.size() > 0) {
            String errorMsg = "One of the following pipes doesn't have a connected pipe towards the outlet: "
                    + Arrays.toString(missingId.toArray(new Integer[0]));
            pm.errorMessage(msg.message(errorMsg));
            throw new IllegalArgumentException(errorMsg);
        }

        verifyNet(networkPipes, pm);

    }

    /**
     * Find the pipes that are draining in this pipe (defined by the index parameter).
     * 
     * @param index
     *            the ID of this pipe.
     * @param cord
     *            the Coordinate of the link where drain.
     */
    private void findIdThatDrainsIntoIndex(int index, Coordinate cord) {
        int t = 0;
        double toll = 0.1;
        for (int i = 0; i < networkPipes.length; i++) {
            // if it is this pipe then go haead.
            if (index == i) {
                continue;
            }
            // there isn-t other pipe that can drain in this.
            else if (t == pMaxJunction) {
                break;
            }
            // the id is already set.
            else if (networkPipes[i].getIdPipeWhereDrain() != null) {
                continue;
            }
            // extract the coordinate of the point of the linee of the new pipe.
            Coordinate[] coords = networkPipes[i].point;
            // if one of the coordinates are near of coord then the 2 pipe are
            // linked.
            int lastIndex = coords.length - 1;
            if (cord.distance(coords[0]) < toll) {
                networkPipes[i].setIdPipeWhereDrain(networkPipes[index].getId());
                networkPipes[i].setIndexPipeWhereDrain(index);
                findIdThatDrainsIntoIndex(i, coords[lastIndex]);
                t++;
            } else if (cord.distance(coords[lastIndex]) < toll) {
                networkPipes[i].setIdPipeWhereDrain(networkPipes[index].getId());
                networkPipes[i].setIndexPipeWhereDrain(index);
                findIdThatDrainsIntoIndex(i, coords[0]);
                t++;
            }

        }

    }

    /**
     * Verify if the network is consistent.
     * 
     * <p>
     * <ol>
     * <li>Verify that the <i>ID</i> of a pipe is a value less than the number
     * of pipe.
     * <li>Verify that the pipe where, the current pipe drain, have an <i>ID</i>
     * less than the number of pipes.
     * <li>Verify that there is an <b>outlet<b> in the net.
     * </ol>
     * </p>
     * 
     * @param networkPipes
     *            the array which rappresent the net.
     * @param pm
     *            the progerss monitor.
     * @throws IllegalArgumentException
     *             if the net is unconsistent.
     */
    public void verifyNet(Pipe[] networkPipes, IJGTProgressMonitor pm) {
        /*
         * serve per verificare che ci sia almeno un'uscita. True= esiste
         * un'uscita
         */
        boolean isOut = false;
        if (networkPipes != null) {
            /* VERIFICA DATI GEOMETRICI DELLA RETE */
            // Per ogni stato
            int length = networkPipes.length;

            int kj;

            for (int i = 0; i < length; i++)

            {
                // verifica che la rete abbia almeno un-uscita.
                if (networkPipes[i].getIdPipeWhereDrain() == 0) {
                    isOut = true;
                }
                /*
                 * Controlla che non ci siano errori nei dati geometrici della
                 * rete, numero ID pipe in cui drena i >del numero consentito
                 * (la numerazione va da 1 a length
                 */
                if (networkPipes[i].getIndexPipeWhereDrain() > length) {
                    pm.errorMessage(msg.message("trentoP.error.pipe"));
                    throw new IllegalArgumentException(msg.message("trentoP.error.pipe"));
                }
                /*
                 * Da quanto si puo leggere nel file di input fossolo.geo in
                 * Fluide Turtle, ogni stato o sottobacino e contraddistinto da
                 * un numero crescente che va da 1 a n=numero di stati; n e
                 * anche pari a data->nrh. Inoltre si apprende che la prima
                 * colonna della matrice in fossolo.geo riporta l'elenco degli
                 * stati, mentre la seconda colonna ci dice dove ciascun stato
                 * va a drenare.(NON E AMMESSO CHE LO STESSO STATO DRENI SU PIU
                 * DI UNO!!) Questa if serve per verificare che non siano
                 * presenti condotte non dichiarate, ovvero piu realisticamente
                 * che non ci sia un'errore di numerazione o battitura. In altri
                 * termini lo stato analizzato non puo drenare in uno stato al
                 * di fuori di quelli esplicitamente dichiarati o dell'uscita,
                 * contradistinta con ID 0
                 */
                kj = i;
                /*
                 * Terra conto degli stati attraversati dall'acqua che inizia a
                 * scorrere a partire dallo stato analizzato
                 */

                int count = 0;
                /*
                 * Seguo il percorso dell'acqua a partire dallo stato corrente
                 */
                while (networkPipes[kj].getIdPipeWhereDrain() != 0) {
                    kj = networkPipes[kj].getIndexPipeWhereDrain();
                    /*
                     * L'acqua non puo finire in uno stato che con sia tra
                     * quelli esplicitamente definiti, in altre parole il
                     * percorso dell'acqua non puo essere al di fuori
                     * dell'inseme dei dercorsi possibili
                     */
                    if (kj > length) {
                        pm.errorMessage(msg.message("trentoP.error.drainPipe") + kj);
                        throw new IllegalArgumentException(msg.message("trentoP.error.drainPipe") + kj);
                    }

                    count++;
                    if (count > length) {
                        pm.errorMessage(msg.message("trentoP.error.pipe"));
                        throw new IllegalArgumentException(msg.message("trentoP.error.pipe"));
                    }
                    /*
                     * La variabile count mi consente di uscire dal ciclo while,
                     * nel caso non ci fosse [kj][2]=0, ossia un'uscita. Infatti
                     * partendo da uno stato qualsiasi il numero degli stati
                     * attraversati prima di raggiungere l'uscita non puo essere
                     * superiore al numero degli stati effettivamente presenti.
                     * Quando questo accade vuol dire che l'acqua e in un loop
                     * chiuso
                     */
                }

            }
            /*
             * Non si e trovato neanche un uscita, quindi Trento_p da errore di
             * esecuzione, perch almeno una colonna deve essere l'uscita
             */
            if (isOut == false) {
                pm.errorMessage(msg.message("trentoP.error.noout"));
                throw new IllegalArgumentException(msg.message("trentoP.error.noout"));
            }

        } else {
            throw new IllegalArgumentException(msg.message("trentoP.error.incorrectmatrix"));
        }

    }

    /**
     * Temporaneo per i test, ritorna i dati sotto forma di matrice.
     * 
     * @return
     */
    public double[][] getResults() {
        double[][] results = new double[networkPipes.length][28];
        double[] one = new double[networkPipes.length];
        double[] two = new double[networkPipes.length];
        for (int i = 0; i < networkPipes.length; i++) {
            one[i] = i;
            two[i] = networkPipes[i].getId();

        }
        QuickSortAlgorithm t = new QuickSortAlgorithm(pm);
        t.sort(two, one);

        for (int i = 0; i < networkPipes.length; i++) {
            int index = (int) one[i];
            results[i][0] = networkPipes[index].getId();
            results[i][1] = networkPipes[index].getIdPipeWhereDrain();
            results[i][2] = networkPipes[index].getDrainArea();
            results[i][3] = networkPipes[index].getLenght();
            results[i][4] = networkPipes[index].getInitialElevation();
            results[i][5] = networkPipes[index].getFinalElevation();
            results[i][6] = networkPipes[index].getRunoffCoefficient();
            results[i][7] = networkPipes[index].getAverageResidenceTime();
            results[i][8] = networkPipes[index].getKs();
            results[i][9] = networkPipes[index].getMinimumPipeSlope();
            results[i][10] = networkPipes[index].getPipeSectionType();
            results[i][11] = networkPipes[index].getAverageSlope();
            results[i][12] = networkPipes[index].discharge;
            results[i][13] = networkPipes[index].coeffUdometrico;
            results[i][14] = networkPipes[index].residenceTime;
            results[i][15] = networkPipes[index].tP;
            results[i][16] = networkPipes[index].tQmax;
            results[i][17] = networkPipes[index].meanSpeed;
            results[i][18] = networkPipes[index].pipeSlope;
            results[i][19] = networkPipes[index].diameter;
            results[i][20] = networkPipes[index].emptyDegree;
            results[i][21] = networkPipes[index].depthInitialPipe;
            results[i][22] = networkPipes[index].depthFinalPipe;
            results[i][23] = networkPipes[index].initialFreesurface;
            results[i][24] = networkPipes[index].finalFreesurface;
            results[i][25] = networkPipes[index].totalSubNetArea;
            results[i][26] = networkPipes[index].meanLengthSubNet;
            results[i][27] = networkPipes[index].varianceLengthSubNet;

        }

        return results;
    }
}