Author: echatellier Date: 2012-12-05 12:04:54 +0100 (Wed, 05 Dec 2012) New Revision: 21 Url: http://forge.codelutin.com/projects/isis-fish-community/repository/revisions... Log: Fix 0/0 when effort can't be transfered to another metier Modified: trunk/rules/TACpoids20012011OgiveTriMerlu.java trunk/rules/TACpoids20012011TailleMin.java Modified: trunk/rules/TACpoids20012011OgiveTriMerlu.java =================================================================== --- trunk/rules/TACpoids20012011OgiveTriMerlu.java 2012-10-23 13:40:08 UTC (rev 20) +++ trunk/rules/TACpoids20012011OgiveTriMerlu.java 2012-12-05 11:04:54 UTC (rev 21) @@ -1,464 +1,468 @@ -/* - * #%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 - * <http://www.gnu.org/licenses/gpl-2.0.html>. - * #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. - * - * <li>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. - * <li>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 <anonymous@labs.libre-entreprise.org> - * @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<Strategy> strs = new HashSet<Strategy>(); - 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<Metier> possibleMetierCase1 = new HashSet<Metier>(); - // second cas de figure: on cherche un metier de substitution - // sans condition sur les engins, mais qui soit pratique - Set<Metier> possibleMetierCase2 = new HashSet<Metier>(); - // 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<Metier> possibleMetierCase3 = new HashSet<Metier>(); - - 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<Metier> 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 (met.getName().equals("metier lang simp Sud")||met.getName().equals("metier lang simp Nord")||met.getName().equals("metier lang simple")||met.getName().equals("metier lang jum Nord")||met.getName().equals("metier lang jum Sud")||met.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; - } - - } - -} +/* + * #%L + * IsisFish data + * %% + * Copyright (C) 2006 - 2012 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 + * <http://www.gnu.org/licenses/gpl-2.0.html>. + * #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. + * + * <li>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. + * <li>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 <anonymous@labs.libre-entreprise.org> + * @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 + 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<Strategy> strs = new HashSet<Strategy>(); + 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<Metier> possibleMetierCase1 = new HashSet<Metier>(); + // second cas de figure: on cherche un metier de substitution + // sans condition sur les engins, mais qui soit pratique + Set<Metier> possibleMetierCase2 = new HashSet<Metier>(); + // 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<Metier> possibleMetierCase3 = new HashSet<Metier>(); + + for (EffortDescription effort : str.getSetOfVessels() + .getPossibleMetiers()) { + Metier newMetier = effort.getPossibleMetiers(); + if ( + /*!aimedMetiers.contains(newMetier) + &&*/!metier.getName().equalsIgnoreCase("nonActiviy") + && !metier.getName().equalsIgnoreCase("nonActivite") + && !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<Metier> 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; + if (somme == 0) { + // cas ou aucun autre metier n'est pratique + // on répartit quand meme l'effort equitablement + // sur tous les autres metier + newProportion = smi.getProportionMetier(metier) / possibleMetier.size(); + } else { + newProportion = smi.getProportionMetier(met) + + (smi.getProportionMetier(metier) + * smi.getProportionMetier(met) / somme); + } + smi.setProportionMetier(met, newProportion); + + log.info("[TAC] set new proportion to " + newProportion + " for " + met.getName()); + } + 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 + // 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 re + 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 (met.getName().equals("metier lang simp Sud")||met.getName().equals("metier lang simp Nord")||met.getName().equals("metier lang simple")||met.getName().equals("metier lang jum Nord")||met.getName().equals("metier lang jum Sud")||met.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; + } + + } + +} Modified: trunk/rules/TACpoids20012011TailleMin.java =================================================================== --- trunk/rules/TACpoids20012011TailleMin.java 2012-10-23 13:40:08 UTC (rev 20) +++ trunk/rules/TACpoids20012011TailleMin.java 2012-12-05 11:04:54 UTC (rev 21) @@ -1,445 +1,452 @@ -/* - * #%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 - * <http://www.gnu.org/licenses/gpl-2.0.html>. - * #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. - * - * <li>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. - * <li>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 <anonymous@labs.libre-entreprise.org> - * @version $Revision: 1.3 $ - * - * Last update: $Date: 30 aout 2012 $ - * by : $Author: Stephanie Mahevas$ - */ -public class TACpoids20012011TailleMin extends AbstractRule { - - /** to use log facility, just put in your code: log.info("..."); */ - static private Log log = LogFactory.getLog(TACpoids20012011TailleMin.class); - - @Doc("Affected species") - public Species param_species = null; - - @Doc("Proportion de survie") - public double param_propSurvie = 0.45; - - - /** TAC in tonnes */ - @Doc("TAC in tons 2001") - public double param_tacInTons2001 = 4000.0; - @Doc("TAC in tons 2002") - public double param_tacInTons2002 = 3200.0; - @Doc("TAC in tons 2003") - public double param_tacInTons2003 = 3000.0; - @Doc("TAC in tons 2004") - public double param_tacInTons2004 = 3150.0; - @Doc("TAC in tons 2005") - public double param_tacInTons2005 = 3100.0; - @Doc("TAC in tons 2006") - public double param_tacInTons2006 = 4000.0; - @Doc("TAC in tons 2007") - public double param_tacInTons2007 = 4320.0; - @Doc("TAC in tons 2008") - public double param_tacInTons2008 = 4320.0; - @Doc("TAC in tons 2009") - public double param_tacInTons2009 = 4100.0; - @Doc("TAC in tons 2010") - public double param_tacInTons2010 = 3900.0; - @Doc("TAC in tons 2011") - public double param_tacInTons2011 = 3900.0; - - @Doc(value = "param_TailleMin") - public double param_TailleMin = 85.0; - - - - 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 tailleMin + 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 tailleMin 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<Strategy> strs = new HashSet<Strategy>(); - 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<Metier> possibleMetierCase1 = new HashSet<Metier>(); - // second cas de figure: on cherche un metier de substitution - // sans condition sur les engins, mais qui soit pratique - Set<Metier> possibleMetierCase2 = new HashSet<Metier>(); - // 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<Metier> possibleMetierCase3 = new HashSet<Metier>(); - - 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<Metier> 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 { - //on applique TailleMin uniquement si tac pas atteint - log.info(" TailleMin.actionApres:" + step + " metapop:" + - param_species + " metier:" + metier); - log.info("deb de affecterCaptureREJETTailleMin"); - - PopulationMonitor popMon = context.getPopulationMonitor(); - - for (Population pop : param_species.getPopulation()) { - //if (popMon.getDiscard(step, pop) == null) { - 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]; - if (group.getLength() >= param_TailleMin) { - i.setValue(0); - } else if (param_propSurvie > 0) { - 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; - } - - } - -} +/* + * #%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 + * <http://www.gnu.org/licenses/gpl-2.0.html>. + * #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. + * + * <li>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. + * <li>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 <anonymous@labs.libre-entreprise.org> + * @version $Revision: 1.3 $ + * + * Last update: $Date: 30 aout 2012 $ + * by : $Author: Stephanie Mahevas$ + */ +public class TACpoids20012011TailleMin extends AbstractRule { + + /** to use log facility, just put in your code: log.info("..."); */ + static private Log log = LogFactory.getLog(TACpoids20012011TailleMin.class); + + @Doc("Affected species") + public Species param_species = null; + + @Doc("Proportion de survie") + public double param_propSurvie = 0.45; + + + /** TAC in tonnes */ + @Doc("TAC in tons 2001") + public double param_tacInTons2001 = 4000.0; + @Doc("TAC in tons 2002") + public double param_tacInTons2002 = 3200.0; + @Doc("TAC in tons 2003") + public double param_tacInTons2003 = 3000.0; + @Doc("TAC in tons 2004") + public double param_tacInTons2004 = 3150.0; + @Doc("TAC in tons 2005") + public double param_tacInTons2005 = 3100.0; + @Doc("TAC in tons 2006") + public double param_tacInTons2006 = 4000.0; + @Doc("TAC in tons 2007") + public double param_tacInTons2007 = 4320.0; + @Doc("TAC in tons 2008") + public double param_tacInTons2008 = 4320.0; + @Doc("TAC in tons 2009") + public double param_tacInTons2009 = 4100.0; + @Doc("TAC in tons 2010") + public double param_tacInTons2010 = 3900.0; + @Doc("TAC in tons 2011") + public double param_tacInTons2011 = 3900.0; + + @Doc(value = "param_TailleMin") + public double param_TailleMin = 85.0; + + + + 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 tailleMin + 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 tailleMin 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<Strategy> strs = new HashSet<Strategy>(); + 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<Metier> possibleMetierCase1 = new HashSet<Metier>(); + // second cas de figure: on cherche un metier de substitution + // sans condition sur les engins, mais qui soit pratique + Set<Metier> possibleMetierCase2 = new HashSet<Metier>(); + // 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<Metier> possibleMetierCase3 = new HashSet<Metier>(); + + for (EffortDescription effort : str.getSetOfVessels() + .getPossibleMetiers()) { + Metier newMetier = effort.getPossibleMetiers(); + if ( + /*!aimedMetiers.contains(newMetier) + &&*/!metier.getName().equalsIgnoreCase("nonActiviy") + && !metier.getName().equalsIgnoreCase("nonActivite") + && !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<Metier> 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; + if (somme == 0) { + // cas ou aucun autre metier n'est pratique + // on répartit quand meme l'effort equitablement + // sur tous les autres metier + newProportion = smi.getProportionMetier(metier) / possibleMetier.size(); + } else { + 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 { + //on applique TailleMin uniquement si tac pas atteint + log.info(" TailleMin.actionApres:" + step + " metapop:" + + param_species + " metier:" + metier); + log.info("deb de affecterCaptureREJETTailleMin"); + + PopulationMonitor popMon = context.getPopulationMonitor(); + + for (Population pop : param_species.getPopulation()) { + //if (popMon.getDiscard(step, pop) == null) { + 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]; + if (group.getLength() >= param_TailleMin) { + i.setValue(0); + } else if (param_propSurvie > 0) { + 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; + } + + } + +}