/* * #%L * IsisFish data * %% * Copyright (C) 2006 - 2011 Ifremer, CodeLutin * %% * 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 2 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 * . * #L% */ package rules; import static org.nuiton.i18n.I18n._; import java.util.HashSet; import java.util.Set; import java.util.List; import java.util.ArrayList; import java.util.Iterator; 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.EffortDescription; import fr.ifremer.isisfish.entities.Metier; import fr.ifremer.isisfish.entities.Population; import fr.ifremer.isisfish.entities.Species; import fr.ifremer.isisfish.entities.Strategy; import fr.ifremer.isisfish.entities.StrategyMonthInfo; import fr.ifremer.isisfish.entities.TargetSpecies; import fr.ifremer.isisfish.entities.MetierSeasonInfo; import fr.ifremer.isisfish.entities.PopulationGroup; import fr.ifremer.isisfish.entities.*; import fr.ifremer.isisfish.rule.AbstractRule; import fr.ifremer.isisfish.simulator.MetierMonitor; import fr.ifremer.isisfish.simulator.PopulationMonitor; import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.types.TimeStep; import fr.ifremer.isisfish.types.Month; import fr.ifremer.isisfish.util.Doc; /** * TAC peut-etre utilise pour les differents TAC, en proportion des effectifs * et/ou avec survie ou non. * *
  • Pour utiliser le tac proportionnel, il faut mettre dans le parametre * propTac une valeur > 0, le TAC sera alors recalcule a chaque mois de janvier. *
  • Pour utiliser la survie il faut mettre dans le parametre propSurvie une * valeur > 0, automatiquement les suvie seront ajoute aux effectifs * * Created: 7 septembre 2006 * * @author anonymous * @version $Revision: 1.3 $ * * Last update: $Date: 30 aout 2012 $ * by : $Author: Stephanie Mahevas$ */ public class TACpoids20012011OgiveTriMerlu extends AbstractRule { /** to use log facility, just put in your code: log.info("..."); */ static private Log log = LogFactory.getLog(TACpoids20012011OgiveTriMerlu.class); @Doc("Affected species") public Species param_species = null; @Doc("Proportion de survie") public double param_propSurvie = 0.45; @Doc(value = "param_Retention_L50") public double param_Retention_L50 = 29.4307; @Doc(value = "param_Retention_slope") public double param_Retention_slope = 2.02485; @Doc(value = "param_TailleMin") public double param_TailleMin = 27.0; /** TAC in tonnes */ @Doc("TAC in tons 2001") public double param_tacInTons2001 =8452; @Doc("TAC in tons 2002") public double param_tacInTons2002 = 10098; @Doc("TAC in tons 2003") public double param_tacInTons2003 = 11220; @Doc("TAC in tons 2004") public double param_tacInTons2004 = 14623; @Doc("TAC in tons 2005") public double param_tacInTons2005 = 15932; @Doc("TAC in tons 2006") public double param_tacInTons2006 = 16412; @Doc("TAC in tons 2007") public double param_tacInTons2007 = 19701; @Doc("TAC in tons 2008") public double param_tacInTons2008 = 20196; @Doc("TAC in tons 2009") public double param_tacInTons2009 = 19261; @Doc("TAC in tons 2010") public double param_tacInTons2010 = 20609; @Doc("TAC in tons 2011") public double param_tacInTons2011 = 20609; boolean affectation = true; // pour ne passer qu'une seule fois dans afterSimulation (pour le premier metier) boolean tacAtteint = false; // pour ne passer dans beforeSimulation que si le tac est atteint protected String[] necessaryResult = { // put here all necessary result for this rule // example: // ResultName.MATRIX_BIOMASS, // ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET, }; /** * @return the necessaryResult */ @Override 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 */ @Override public String getDescription() { return _("Combinaison de la regle tac poids sur 2001-2011 avec ogive de tri + prop de survie des rejets."); } /** * Appele au demarrage de la simulation, cette methode permet d'initialiser * des valeurs * * @param context La simulation pour lequel on utilise cette regle */ @Override public void init(SimulationContext context) throws Exception { } /** * 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 concern * @return vrai si on souhaite que les actions soit faites */ @Override public boolean condition(SimulationContext context, TimeStep step, Metier metier) throws Exception { log.info("test si TAC atteint"); // read species in current session : plus necessaire bug resolu //param_species = (Species) context.getDB().findByTopiaId( // param_species.getTopiaId()); TargetSpecies ts = metier.getMetierSeasonInfo(step.getMonth()) .getSpeciesTargetSpecies(param_species); boolean result = false; if (ts != null) { // on n'applique la regle que si espece captur�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������e par ce metier double param_tacInTons = 0; if (step.getYear()>10) { //si on est apres 2011 result = false; } else { result = true; // au moins ogive tri s'applique if (step.getYear()==0) { param_tacInTons = param_tacInTons2001; } else if (step.getYear()==1) { param_tacInTons = param_tacInTons2002; } else if (step.getYear()==2) { param_tacInTons = param_tacInTons2003; } else if (step.getYear()==3) { param_tacInTons = param_tacInTons2004; } else if (step.getYear()==4) { param_tacInTons = param_tacInTons2005; } else if (step.getYear()==5) { param_tacInTons = param_tacInTons2006; } else if (step.getYear()==6) { param_tacInTons = param_tacInTons2007; } else if (step.getYear()==7) { param_tacInTons = param_tacInTons2008; } else if (step.getYear()==8) { param_tacInTons = param_tacInTons2009; } else if (step.getYear()==9) { param_tacInTons = param_tacInTons2010; } else if (step.getYear()==10) { param_tacInTons = param_tacInTons2011; } // test si Tac atteint double catchTons = RuleUtil.getTotalCatchTons(context, param_species, step); log.info("[TAC] catchTons = " + catchTons + " >= param_tacInTons:" + param_tacInTons); if (catchTons >= param_tacInTons) { tacAtteint = 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 { // la preaction ne tourne que si le TAC est atteint affectation = true; if (tacAtteint) { log.info("[TAC] preAction for: " + metier); log.info(" TAC atteint [TAC] preAction for: " + metier); TargetSpecies ts = metier.getMetierSeasonInfo(step.getMonth()) .getSpeciesTargetSpecies(param_species); if (ts != null && ts.getPrimaryCatch()) { // recupere tous les metiers qui ont l'espece en capture principale =>metiers vises // aimedMetiers ne fonctionne pas je ne sais pas pourquoi ! mais au final forbiddenMetier aura le meme effet context.getMetierMonitor().addforbiddenMetier(metier); //recupere toutes les strategies pratiquant le metier et pour lesquelles la proportion !=0 SiMatrix siMatrix = SiMatrix.getSiMatrix(context); Set strs = new HashSet(); for (Strategy str : siMatrix.getStrategies(step)) { double prop = str.getStrategyMonthInfo(step.getMonth()) .getProportionMetier(metier); if (prop != 0) { strs.add(str); } } for (Strategy str : strs) { StrategyMonthInfo smi = str.getStrategyMonthInfo(step .getMonth()); // 1er cas de figure: l'effort est reporte sur un metier de la // meme strategie, n'ayant pas l'espece comme capture principale // et pechant avec le meme engin Set possibleMetierCase1 = new HashSet(); // second cas de figure: on cherche un metier de substitution // sans condition sur les engins, mais qui soit pratique Set possibleMetierCase2 = new HashSet(); // 3 eme cas de figure: on cherche des metiers non vises, // sans consideration sur les engins, et pour lesquels la // proportion peut etre nulle Set possibleMetierCase3 = new HashSet(); for (EffortDescription effort : str.getSetOfVessels() .getPossibleMetiers()) { Metier newMetier = effort.getPossibleMetiers(); if ( /*!aimedMetiers.contains(newMetier) &&*/!metier.getName().equalsIgnoreCase("nonActiviy") && !metier.getName().equalsIgnoreCase("nonActivie") && !metier.getName().equalsIgnoreCase( "non Activite") && !context.getMetierMonitor().getForbiddenMetier() .contains(newMetier)) { possibleMetierCase3.add(newMetier); if (smi.getProportionMetier(newMetier) != 0) { possibleMetierCase2.add(newMetier); if (metier.getGear().equals(newMetier.getGear())) { possibleMetierCase1.add(newMetier); } } } } Set possibleMetier = null; if (possibleMetierCase1.size() != 0) { log.info("[TAC] Use case 1"); possibleMetier = possibleMetierCase1; } else if (possibleMetierCase2.size() != 0) { log.info("[TAC] Use case 2"); possibleMetier = possibleMetierCase2; } else if (possibleMetierCase3.size() != 0) { log.info("[TAC] Use case 3"); possibleMetier = possibleMetierCase3; } if (possibleMetier != null) { // on repartit maintenant l'effort entre les differents metiers // possibles dans la meme strategie si un metier possible existe // bien la repartion est proportionnelle a l'effort deja alloue // dans la strategie double somme = 0; for (Metier met : possibleMetier) { somme += smi.getProportionMetier(met); } for (Metier met : possibleMetier) { double newProportion = smi.getProportionMetier(met) + (smi.getProportionMetier(metier) * smi.getProportionMetier(met) / somme); smi.setProportionMetier(met, newProportion); } smi.setProportionMetier(metier, 0); //le metier vise a alors une proportion nulle log.info("[TAC] il y a des metiers possibles"); } else { log.info("[TAC] Use no activity"); // sinon on met tout dans le metier nonActivite MetierMonitor metierMon = context.getMetierMonitor(); MatrixND mat = metierMon.getOrCreateNoActivity(step, ResultName.MATRIX_NO_ACTIVITY, siMatrix .getStrategies(step), siMatrix .getMetiers(step)); mat.setValue(str, metier, smi.getProportionMetier(metier)); smi.getProportionMetier().setValue(metier, 0); } } } } } /** * Si la condition est vrai alors cette action est execute 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 { if (affectation) { // Application des rejets si Tac atteint et tailleMin sinon sur les captures // la matrice de captures a une dimension metier - donc a cette etape, toutes // les captures de tous les metiers sont connues // Ne doit pas s'appliquer pour chaque metier de la boucle mais une seule fois! // affectation est mis ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� true ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� la fin de la boucle sur les pop // la preaction ne tourne que si le TAC est atteint if (tacAtteint) { //postAction de la regle TAC dans ce cas TailleMin ne s'applique pas log.info("[TAC] postAction for: " + metier); PopulationMonitor popMon = context.getPopulationMonitor(); log.info("popMon biomass" + popMon.getBiomass(param_species)); for (Population pop : param_species.getPopulation()) { log.info("pop : " + pop.getName()); // si on a deja une matrice rejet on le vide (elle vient // forcement de la regle taille minimale or si le tac est // atteint, tout va dorenavent dans les rejets et on mais // TOUTES les captures dans les rejets MatrixND discard = popMon.getDiscard(step, pop); //log.info("discard : " + discard); if (discard != null) { discard.mults(0); } log.info("catch = " + popMon.getCatch(pop)); MatrixND discardRegle = popMon.getCatch(pop).copy(); //nouvelle instance pour le calcul dans la regle // ca ne doit pas pouvoir marcher car MATRIX_DISCARDS_PER_STR_MET est de dimension pop groupe str met - et discard n'a plus la dimension pop discardRegle.setName(ResultName.MATRIX_DISCARDS_PER_STR_MET_PER_ZONE_POP); popMon.addDiscard(step, pop, discardRegle); log.info("[TAC] add discard for " + pop + ": " + discardRegle); if (param_propSurvie > 0) { MatrixND eff = popMon.getN(pop); //on r��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ajoute les survivants aux effectifs for (MatrixIterator i = discardRegle.iterator(); i .next();) { Object[] coord = i.getSemanticsCoordinates(); eff.setValue(coord[2], coord[3], eff.getValue( coord[2], coord[3]) + i.getValue() * param_propSurvie); } } } } else { log.info("deb de affecterCaptureRejetSelonOgive"); PopulationMonitor popMon = context.getPopulationMonitor(); for (Population pop : param_species.getPopulation()) { MatrixND discard = popMon.getCatch(pop).copy(); MatrixND eff = popMon.getN(pop); for (MatrixIterator i = discard.iterator(); i.next();) { Object[] coordonnees = i.getSemanticsCoordinates(); PopulationGroup group = (PopulationGroup) coordonnees[2]; // Metier met = (Metier) coordonnees[1]; if (metier.getName().equals("metier lang simp Sud")||metier.getName().equals("metier lang simp Nord")||metier.getName().equals("metier lang simple")||metier.getName().equals("metier lang jum Nord")||metier.getName().equals("metier lang jum Sud")||metier.getName().equals("metier lang jum")) { double propTrie = 1 / (1 + Math.exp(-(group.getLength() - param_Retention_L50)/ param_Retention_slope)); double propRejet = 1 - propTrie; log.info("REJETS" + propRejet); double value = i.getValue() * propRejet; log.info("VALUE" + value); i.setValue(value); if (param_propSurvie >0) { //ajout de la survie aux effectifs eff.setValue(coordonnees[2], coordonnees[3], eff.getValue(coordonnees[2], coordonnees[3]) + i.getValue() * param_propSurvie); } }else if (group.getLength() >= param_TailleMin) { i.setValue(0); // initialise discard si pas de rejet (ie taille>=TailleMin et pas metierLangoustine) } else { //si group.getLength() < param_TailleMin if (param_propSurvie >0) { //ajout de la survie aux effectifs eff.setValue(coordonnees[2], coordonnees[3], eff.getValue(coordonnees[2], coordonnees[3]) + i.getValue() *param_propSurvie); } } } discard.setName(ResultName.MATRIX_DISCARDS_PER_STR_MET_PER_ZONE_POP); popMon.addDiscard(step, pop, discard); } } // on a affecte une fois cette meta pop au rejet il ne faut pas // le refaire affectation = false; } } }