/* * #%L * IsisFish data * %% * Copyright (C) 2006 - 2015 Ifremer, CodeLutin, Stéphanie Mahevas, Chatellier Eric * %% * 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 * . * #L% */ 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 fr.ifremer.isisfish.entities.Metier; import fr.ifremer.isisfish.entities.MetierSeasonInfo; import fr.ifremer.isisfish.entities.Population; import fr.ifremer.isisfish.entities.PopulationGroup; import fr.ifremer.isisfish.entities.Species; import fr.ifremer.isisfish.entities.TargetSpecies; import fr.ifremer.isisfish.entities.Zone; import fr.ifremer.isisfish.rule.AbstractRule; import fr.ifremer.isisfish.simulator.PopulationMonitor; import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.types.TimeStep; import fr.ifremer.isisfish.annotations.Doc; import resultinfos.MatrixDiscardsPerStrMetPerZonePop; import java.util.List; /** * Cette regles tient compte de la taille minimum des poissons capturable. * * Les captures ne sont pas impactées, mais des rejets sont générés si la * taille des poissons est inférieures à TailleMin. * * En cas de propSurvie positif, la matrice d'effectif est modifié * pour tenir compte de la partie de poisson rejeté qui survi. * * Created: 30 novembre 2006 * * @author smahevas * @version $Revision: 1.1 $ * * Last update: $Date: 2007-01-24 18:25:34 $ by : $Author: bpoussin $ */ public class TailleMin extends AbstractRule { /** to use log facility, just put in your code: log.info("..."); */ static private Log log = LogFactory.getLog(TailleMin.class); @Doc(value = "Begin step") public TimeStep param_beginStep = new TimeStep(0); @Doc(value = "End date") public TimeStep param_endStep = new TimeStep(119); @Doc(value = "Affected species") public Species param_species = null; @Doc(value = "Taille minimale") public double param_TailleMin = 20; //valeur par defaut (scenario_1, reference) @Doc(value = "Proportion de survie") public double param_propSurvie = 0.5; //valeur par defaut (scenario_1, reference) protected boolean affectation = true; protected String[] necessaryResult = { // put here all necessary result for this rule // example: // MatrixBiomass.NAME, // MatrixNetValueOfLandingsPerStrategyMet.NAME }; @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() throws Exception { return "Tous les poissons dont la taille est inférieure à TailleMin" + " ne seront pas capturés. Ils sont placés en rejets et rejetés" + " suivant la proportion de survie."; } /** * Appele au demarrage de la simulation, cette methode permet * d'initialiser des valeurs de la règle. * * @param context La simulation pour laquelle on utilise cette regle */ @Override public void init(SimulationContext context) throws Exception { } private boolean isCaptureDate(TimeStep step, Species species, Metier metier) { MetierSeasonInfo info = metier.getMetierSeasonInfo(step.getMonth()); TargetSpecies target = info.getSpeciesTargetSpecies(species); boolean result; if (target != null) { result = true; } else { result = false; } return result; } /** * 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 { log.info("Recherche si la taille Minimale s'applique"); boolean result = true; if (step.before(param_beginStep)) { result = false; } else if (step.after(param_endStep)) { result = false; } else if (isCaptureDate(step, param_species, metier) != true) { result = false; } log.info("fin de condition TailleMin:" + result); 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 concerne */ @Override public void preAction(SimulationContext context, TimeStep step, Metier metier) throws Exception { affectation = true; // pour que affectation soit vraie au debut de // chaque pas de temps pour rentrer au moins une // fois dans postaction } /** * Si la condition est vrai alors cette action est executee 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 concerne */ @Override public void postAction(SimulationContext context, TimeStep step, Metier metier) throws Exception { //log.info("*$*$*$* TailleMin.actionApres:" + step + " metapop:" // + param_species + " metier:" + metier); if (affectation) { log.info("*$*$*$* ok affecte capture inferieure a TailleMin au rejet"); // ATTENTION // les captures pour cette metapop ne sont plus du qu'au metier pour // qui l'espece est secondaire: elles sont affectees aux rejets // pb : ne se fait pas par metier // il faut une matrice pour chaques pas de temps qui stocke les // rejets par metier, par metapop et par classes d'age (comme pour // les captures) //log.info("deb de affecterCaptureREJETTailleMin"); PopulationMonitor popMon = context.getPopulationMonitor(); int groupDim = 2; int zoneDim = 3; for (Population pop : param_species.getPopulation()) { MatrixND discard = popMon.getCatch(pop).copy(); discard.setName(MatrixDiscardsPerStrMetPerZonePop.NAME); MatrixND eff = popMon.getN(pop); // collect les tailles des groupes pour eviter de multiples appels a la methode // getLength dans la boucle List groups = (List)discard.getSemantic(2); double[] length = new double[groups.size()]; int cpt = 0; for (PopulationGroup group : groups) { length[cpt++] = group.getLength(); } // on iter que sur les valeurs != 0, car si deja zero, ca ne // sert a rien de le mettre a 0 for (MatrixIterator i = discard.iteratorNotZero(); i.next();) { int[] pos = i.getCoordinates(); int groupIndex = pos[groupDim]; if (length[groupIndex] >= param_TailleMin) { i.setValue(0); } else if (param_propSurvie > 0) { Object[] coordonnees = i.getSemanticsCoordinates(); PopulationGroup group = (PopulationGroup) coordonnees[groupDim]; Zone zone = (Zone)coordonnees[zoneDim]; eff.setValue(group, zone, eff.getValue(group, zone) + i.getValue() * param_propSurvie); } } popMon.addDiscard(step, pop, discard); } //log.info("fin de affecterCaptureRejetTailleMin"); // on a affecte une fois cette meta pop au rejet il ne faut pas le // refaire pour ce pas de temps affectation = false; } } }