/* * Copyright (C) 2014 yreecht * * This program 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 rules; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.math.matrix.MatrixIterator; import org.nuiton.math.matrix.MatrixND; import scripts.ResultName; import scripts.RuleUtil; import scripts.SiMatrix; import fr.ifremer.isisfish.datastore.ResultStorage; import fr.ifremer.isisfish.entities.Metier; import fr.ifremer.isisfish.entities.Population; import fr.ifremer.isisfish.entities.PopulationGroup; import fr.ifremer.isisfish.rule.AbstractRule; import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.types.TimeStep; import fr.ifremer.isisfish.types.Month; import fr.ifremer.isisfish.util.Doc; /** * HCR_transition_MSY_YR.java * * Created: 8 septembre 2014 * * @author yreecht * @version $Revision: 1545 $ * Last update: $Date: 8 septembre 2014 $ * by : $Author: yreecht $ */ public class HCR_transition_MSY_YR extends AbstractRule { /** to use log facility, just put in your code: log.info("..."); */ private static Log log = LogFactory.getLog(HCR_transition_MSY_YR.class); @Doc("Affected population") public Population param_populationHCR = null; @Doc("TAC en tonnes avant transition MSY") public double Tac2010 = 3400.0; @Doc("Begin date") public TimeStep param_beginStep = new TimeStep(36); @Doc("End date") public TimeStep param_endStep = new TimeStep(119); @Doc("Fmsy") public double param_fmsy = 0.29; @Doc("Fpa") public double param_fpa = 0.4; @Doc("MSY Btrigger") public double param_msyBtrigger = 8000; // Attention aux unites : kg VS t @Doc("Duration of transition period (year)") public double param_transitionDuration = 5; @Doc("Proportion de survie") public double param_propSurvieHCR = 0; @Doc("Variation annuelle max du TAC ") public double param_varTac = 0.15; boolean affectation = false; protected String[] necessaryResult = { // put here all necessary result for this rule // example: // ResultName.MATRIX_BIOMASS, // ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET, ResultName.MATRIX_BIOMASS, ResultName.MATRIX_TOTAL_FISHING_MORTALITY }; public String[] getNecessaryResult() { return this.necessaryResult; } /** * Permet d'afficher a l'utilisateur une aide sur la regle. * @return L'aide ou la description de la regle */ public String getDescription() { return "Harvest Control Rule simulatinf the transition between a precautionary approach management and a MSY management, for a given population"; } /** * Appelée au démarrage de la simulation, cette méthode permet d'initialiser * des valeurs. * * @param context la simulation pour lequel on utilise cette regle */ public void init(SimulationContext context) throws Exception { // TODO } /** * La condition qui doit etre vrai pour faire les actions. * * @param context la simulation pour lequel on utilise cette regle * @param step le pas de temps courant * @param metier le metier concerne * @return vrai si on souhaite que les actions soit faites */ @Override public boolean condition(SimulationContext context, TimeStep step, Metier metier) throws Exception { boolean result = false; if (step.after(param_beginStep) && step.before(param_endStep) && step.getMonth() == Month.FEBRUARY){ // .previous() // JANUARY ? result = true; } return result; } /** * Si la condition est vrai alors cette action est executee avant le pas * de temps de la simulation. * * @param context la simulation pour lequel on utilise cette regle * @param step le pas de temps courant * @param metier le metier concerné */ @Override public void preAction(SimulationContext context, TimeStep step, Metier metier) throws Exception { // Tac2010 = (Double) context.getValue("tacInTons_" + param_populationHCR.getName() + "_2010"); log.info("Tac2010 = " + Tac2010); affectation = false; log.info("Mise en place de l'HCR"); ResultStorage matResult = context.getSimulationStorage().getResultStorage(); // Import de la mortalite par peche de 2010 MatrixND MatF2010 = matResult.getMatrix(param_beginStep.previous(), param_populationHCR, ResultName.MATRIX_TOTAL_FISHING_MORTALITY); // Ne marche que si param_beginStep est Janvier 2011 double F2010 = MatF2010.sumAll(); log.info("F2010 = " + F2010); // Import de la biomasse de l'annee en cours MatrixND MatBiom = matResult.getMatrix(step.previous(), param_populationHCR, ResultName.MATRIX_BIOMASS); // step, MatBiom = MatBiom.reduce(); log.info("MatBiom = " + MatBiom); // Calcul de la SSB de l'annee en cours double SSBiom = 0; for (MatrixIterator i=MatBiom.iterator(); i.hasNext();) { i.next(); Object [] sems = i.getSemanticsCoordinates(); PopulationGroup group = (PopulationGroup)sems[0]; double val = i.getValue()* group.getMaturityOgive(); SSBiom = SSBiom + val; } SSBiom = SSBiom / 1000; log.info("SSBiom = " + SSBiom); // Comparaison de la SSB a MSYBtrigger et calcul de fMsyHcr double fMsyHcr = 0; log.info("param_fmsy = " + param_fmsy); if ( SSBiom < param_msyBtrigger) { double triggerMult = 1 - SSBiom / param_msyBtrigger; fMsyHcr = param_fmsy - triggerMult * param_fmsy; } else { fMsyHcr = param_fmsy; } log.info("fMsyHcr = " + fMsyHcr); // Calcul des multiplicateurs a appliquer a F2010 et fMsyHCR double multF2010 = 1 - (step.getYear() - (param_beginStep.getYear() - 1)) * (1/param_transitionDuration); if (multF2010 < 0){ multF2010 = 0; } double multFmsy = 0 + (step.getYear() - (param_beginStep.getYear() - 1)) * (1/param_transitionDuration); if (multFmsy > 1){ multFmsy = 1; } log.info("multF2010 = " + multF2010); log.info("multFmsy = " + multFmsy); // Calcul de fMsyHcrTransition double fMsyHcrTransition = multF2010 * F2010 + multFmsy * fMsyHcr; log.info("fMsyHcrTransition = " + fMsyHcrTransition); // Si fMsyHcrTransition > fpa on applique fpa double AppliedF = 0; log.info("param_fpa = " + param_fpa); if (fMsyHcrTransition < param_fpa) { AppliedF = fMsyHcrTransition; } else { AppliedF = param_fpa; } log.info("AppliedF = " + AppliedF); // Calcul du niveau de captures correspondant au F choisi double TAC = AppliedF * SSBiom; log.info("TAC = " + TAC); // Si niveau de captures inferieur de plus de 15 pcts au TAC de l'annee precedente limiter a 15 pcts double diffTac = 0; double TacReel = 0; double TacPrevYr = 0; if (step.getYear() == param_beginStep.getYear()){ diffTac = TAC / Tac2010 - 1; log.info("diffTac = " + diffTac); if (diffTac < -1 * param_varTac){ TacReel = Tac2010 - param_varTac * Tac2010; } else if (diffTac >= param_varTac){ TacReel = Tac2010 + param_varTac * Tac2010; } else { TacReel = TAC; } } else { // retrouver le niveau de TAC de l'annee precedente TacPrevYr = (Double) context.getValue("TAC_" + param_populationHCR.getName() + "_HCR"); log.info("TacPrevYr = " + TacPrevYr); diffTac = TAC / TacPrevYr - 1; log.info("diffTac = " + diffTac); if (diffTac < -1 * param_varTac){ TacReel = TacPrevYr - param_varTac * TacPrevYr; } else if (diffTac >= param_varTac){ TacReel = TacPrevYr + param_varTac * TacPrevYr; } else { TacReel = TAC; } } log.info("TacReel = " + TacReel); // Stocker le TAC dans une matrice (pour pouvoir comparer les annees entre elles) // Faire en sorte que le TAC soit utilise par la regle TACPoidsPop_PourHCR context.setValue("TAC_" + param_populationHCR.getName() + "_HCR", TacReel); //TacReel context.setValue("BeginStep_TAC_" + param_populationHCR.getName() + "_HCR", step); // Pas besoin de EndStep car on sait que c'est BeginStep+12 (mis dans regle TAC) //context.setValue("Population_TAC_HCR", param_populationHCR); context.setValue("PropSurvie_TAC_" + param_populationHCR.getName() + "_HCR", param_propSurvieHCR); } /** * Si la condition est vrai alors cette action est executée apres le pas * de temps de la simulation. * * @param context La simulation pour lequel on utilise cette regle * @param step le pas de temps courant * @param metier le metier concerné */ @Override public void postAction(SimulationContext context, TimeStep step, Metier metier) throws Exception { // Creation de la matrice de stockage de TAC //ResultStorage resultmanager = context.getSimulationStorage().getResultStorage(); // // if (!affectation){ // // // Ici les TACs sont definis au niveau de la population // public MatrixND matrixTacPop(TimeStep step, Population pop) throws TopiaException { // ResultStorage resManager ? // // List populations = Collections.singletonList(pop); // // MatrixND TacPopMatrix = MatrixFactory.getInstance().create( // ResultName.MATRIX_TAC_PER_POP, new List[] { populations }, // new String[] { n_("Populations") }); // // if (step.getMonth() == Month.JANUARY) { // Pas besoin car postAction ne s'applique que si la condition est vraie // TacPopMatrix.setValue(param_population, TacReel); // } // else { // TacPopMatrix.setValue(param_population, 0); // } // return TacPopMatrix; // } // // on a affecte une fois un TAC a une pop et il ne faut pas le refaire // affectation = true; // } //} } }