/* * #%L * IsisFish data * %% * Copyright (C) 2006 - 2016 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 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 fr.ifremer.isisfish.annotations.Doc; import fr.ifremer.isisfish.entities.*; import fr.ifremer.isisfish.rule.AbstractRule; import fr.ifremer.isisfish.simulator.MetierMonitor; import fr.ifremer.isisfish.simulator.SimulationContext; import fr.ifremer.isisfish.types.Month; import fr.ifremer.isisfish.types.TimeStep; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.math.matrix.MatrixND; import resultinfos.MatrixNoActivity; import scripts.SiMatrix; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * ZPF.java * * It's a Cantonnment rules adapted for ZPF (high protected area). * It's a cantonnment working every months for every metiers. * The metiers report their effort to the rest of their fishing areas, * and if they are entirely in the ZPF then they can report their efforts to other metiers if report==True. * * Created: 19/02/2026 * * @author LW * @version $Revision: $ * * Last update * by : $Author: $ */ public class Cantonnement_ZPF extends AbstractRule { /** to use log facility, just put in your code: log.info("..."); */ static private Log log = LogFactory.getLog(Cantonnement_ZPF.class); @Doc(value="Zone de fermeture") public Zone param_zone = null; @Doc(value="Begin step") public TimeStep param_beginStep = new TimeStep(0); @Doc(value="End step") public TimeStep param_endStep = new TimeStep(119); public Boolean param_report = false; protected String [] necessaryResult = { // put here all necessary result for this rule // example: // MatrixBiomass.NAME, // MatrixNetValueOfLandingsPerStrategyMet.NAME MatrixNoActivity.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 { // fermeture annuelle de zone pour tous les engins // et a certaines années de la simulation return "ZPF: a cantonnement that's active the entire year for every gears"; } /** * Appelé au démarrage de la simulation, cette méthode 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 { if (step.before(param_beginStep)) { return false; } else if (step.after(param_endStep)) { return false; } List cellMetiers = metier.getMetierSeasonInfo(step.getMonth()).getCells(); List cells = param_zone.getCell(); cellMetiers.retainAll(cells); boolean result = !Collections.disjoint(cellMetiers, cells); if (result && log.isInfoEnabled()) { log.info("Cantonnement condition 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 { MetierMonitor metierMon = context.getMetierMonitor(); MetierSeasonInfo infoMetier = metier.getMetierSeasonInfo(step.getMonth()); SiMatrix siMatrix = SiMatrix.getSiMatrix(context); List strategies = siMatrix.getStrategies(step); List cellMetiers = infoMetier.getCells(); List cells = param_zone.getCell(); cellMetiers.removeAll(cells); if (cellMetiers.size() != 0) { ZoneDAO dao = context.getZoneDAO(); // // Create new empty zone for cantonnement // String name = "ZoneCantonnement-" + metier.getName()+ "-" + step.getStep(); Zone zoneCantonnement = dao.findByName(name); int cpt=0; while (zoneCantonnement != null) { cpt++; zoneCantonnement = dao.findByName(name + "-" + cpt); } zoneCantonnement = dao.create(); if (cpt > 0) { name += "-" + cpt; } zoneCantonnement.setName(name); // // Remove prohibited zone and add not prohibited cell to zoneCantonnement // Collection zoneMetiers = infoMetier.getZone(); for (Iterator i = zoneMetiers.iterator(); i.hasNext();) { Zone zone = i.next(); // copy list cell to not modify original zone List tmpCells = new ArrayList<>(zone.getCell()); tmpCells.removeAll(param_zone.getCell()); zoneCantonnement.addAllCell(tmpCells); i.remove(); } List newZone = new ArrayList<>(); newZone.add(zoneCantonnement); infoMetier.setZone(newZone); } else if(!param_report) { // sinon toute la zone de pratique du metier est incluse dans zone Cantonnement // alors metier devient metier-nonactivite System.out.println("pas de report pour " +metier.getName()); MatrixND noActivity = metierMon.getOrCreateNoActivity(step, MatrixNoActivity.NAME, siMatrix.getStrategies(step), siMatrix.getMetiers(step)); metierMon.addforbiddenMetier(metier); for (Strategy str : strategies) { StrategyMonthInfo info = str.getStrategyMonthInfo(step.getMonth()); double prop = info.getProportionMetier(metier); System.out.println("proportion metier " +metier.getName() + " :" + prop); if (prop != 0) { noActivity.setValue(str , metier, prop); info.setProportionMetier(metier, 0); System.out.println("MODIFICATION DE PROP ET NOACTIVITY OK "); } } }else { // report == true System.out.println("recherche de report pour le Metier " +metier.getName()); metierMon.addforbiddenMetier(metier); for (Strategy Strat : strategies) { SetOfVessels vessels = Strat.getSetOfVessels(); StrategyMonthInfo StratMonthInfo = Strat.getStrategyMonthInfo(step.getMonth()); if (vessels.getPossibleMetiers(metier) != null && StratMonthInfo.getProportionMetier(metier) != 0 ) { // si le metier est pratiqué dans la strategie System.out.println("on entre dans strategie " +Strat.getName()); double PropAReallouer = StratMonthInfo.getProportionMetier(metier); System.out.println("proportion a reallouer " +PropAReallouer); // liste des métiers de la strategie List MetiersPossibles = new ArrayList<>(Strat.getSetOfVessels().getPossibleMetiers()); // on verifie que les metiers sont bien pratiques au mois courant, // qu'ils n'ont pas le meme ont le meme engin et qu'ils ne sont // pas interdits par ailleurs double propSumStr = 0; // sum des prop d'effort encore autorisé List reallocMet = MetiersPossibles; // liste des metiers encore autorisés for (Iterator effort = reallocMet.iterator(); effort.hasNext(); ) { Metier met = effort.next().getPossibleMetiers(); System.out.println("boucle met de la strat " + met.getName()); if (StratMonthInfo.getProportionMetier(met) == 0 || met.getName().equalsIgnoreCase("nonActivite") || metierMon.isForbidden(met, step.getMonth())) { effort.remove(); //System.out.println("pas possible"); } else { propSumStr += StratMonthInfo.getProportionMetier(met); //System.out.println("possible " + propSumStr); } } System.out.println("proportion a reallouer :" + PropAReallouer + " a " + reallocMet.size() + " metiers"); //on repartit maintenant l'effort entre les differents metiers possibles dans la meme strategie // si un metier possible existe bien if (reallocMet.size() != 0) { for (EffortDescription effort : reallocMet) { Metier met = effort.getPossibleMetiers(); double NouvelleProportion = StratMonthInfo.getProportionMetier(met) + (PropAReallouer * StratMonthInfo.getProportionMetier(met) / propSumStr); StratMonthInfo.setProportionMetier(met, NouvelleProportion); System.out.println("realloc Metier " + met.getName() + "ancienne " + StratMonthInfo.getProportionMetier(met) + " nouvelle " + NouvelleProportion); } StratMonthInfo.setProportionMetier(metier, 0); } else { //Il n'y a aucun métier à qui réallouer l'effort System.out.println("on entre dans la transition de " + metier.getName() + " en Noactivity qui recevra " + PropAReallouer+ " comme proportion "); MatrixND noActivity = metierMon.getOrCreateNoActivity(step, MatrixNoActivity.NAME, siMatrix.getStrategies(step), siMatrix.getMetiers(step)); System.out.println("AVANT :" + noActivity); noActivity.setValue(Strat , metier, PropAReallouer); System.out.println("PENDANT :" + noActivity); metierMon.setNoActivity(step, noActivity); System.out.println("APRES :" + noActivity); StratMonthInfo.setProportionMetier(metier, 0); } } } } // fin de preAction } /** * 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 { MetierMonitor metierMon = context.getMetierMonitor(); SiMatrix siMatrix = SiMatrix.getSiMatrix(context); MatrixND noActivity = metierMon.getOrCreateNoActivity(step, MatrixNoActivity.NAME, siMatrix.getStrategies(step), siMatrix.getMetiers(step)); System.out.println("POSTACTION :" + noActivity); // nothing } }