Salut,
On avait trouvé quelques erreurs dans la règle TACPoids, voici un code
qui fonctionne.
il y a seulement le aimedMetier (lignes 146:151 et lignes 182:183) qui
chez moi fait boguer la simulation
Si je ne m'abuse le fait de le supprimer ne change pas les resultats, je
l ai donc mis en commentaire
si qqn peut regarder si ces lignes marchent avec sa pecherie ... merci
Sigrid
rappel : les metiers interdits sont ceux qui ont l espece visee en
capture principale
l effort de ces metiers est reporte sur les metiers autorises de la
strategie au prorata de l effort deja existant sur ces metiers
ou si il n y a pas d autre metier possible l effort est mis dans non
activité
les autres metiers continuent a la capturer mais rejettent avec une
survie = prop survie
--
Sigrid LEHUTA
~ ><> ~
Ecologie et Modèles pour l'Halieutique
IFREMer, rue de l'ile d'Yeu BP 21105
44311 Nantes Cedex 03
package rules;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.codelutin.i18n.I18n._;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codelutin.math.matrix.MatrixFactory;
import org.codelutin.math.matrix.MatrixIterator;
import org.codelutin.math.matrix.MatrixND;
import scripts.ResultName;
import scripts.RuleUtil;
import scripts.SiMatrix;
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.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.Date;
import fr.ifremer.isisfish.types.Month;
/**
* TAC.java
*
* Created: 7 septembre 2006
*
* @author anonymous <anonymous(a)labs.libre-entreprise.org>
* @version $Revision: 1.3 $
*
* Last update: $Date: 290607 $
* by : $Author: sigrid $
*/
/**
* TAC peut-etre utilisé pour les différents 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 recalculé a chaque mois de janvier.
* <li>Pour utiliser la survie il faut mettre dans le paramètre propSurvie
* une valeur > 0, automatiquement les suvie seront ajouté aux effectifs
*
*/
public class TACpoids extends AbstractRule {
/** to use log facility, just put in your code: log.info("..."); */
static private Log log = LogFactory.getLog(TACpoids.class);
public Species param_species = null;
public Date param_beginDate = new Date(0);
public Date param_endDate = new Date(90);
public double param_propSurvie = 0;
public double param_propTac = 0;
/** TAC in tonnes */
public double param_tacInTons = 1000000;
boolean affectation = false;
protected String [] necessaryResult = {
// put here all necessary result for this rule
// example:
// ResultName.MATRIX_BIOMASS,
// ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET,
};
/**
* @return the necessaryResult
*/
public String[] getNecessaryResult() {
return this.necessaryResult;
}
/**
* Permet d'afficher a l'utilisateur une aide sur la regle.
* @return L'aide ou la description de la regle
*/
public String getDescription() {
return _("TAC weight in tons.\nIf you want survival discard use propSurvie other than 0.\nIf you wish TAC computed as a proportion of the biomass use propTac other than 0.");
}
/**
* Appelé au démarrage de la simulation, cette méthode permet d'initialiser
* des valeurs
* @param simulation La simulation pour lequel on utilise cette regle
*/
public void init(SimulationContext context) throws Exception {
}
/**
* La condition qui doit etre vrai pour faire les actions
* @param simulation La simulation pour lequel on utilise cette regle
* @return vrai si on souhaite que les actions soit faites
*/
public boolean condition(SimulationContext context, Date date, Metier metier) throws Exception {
// read species in current session
param_species = (Species)context.getDB().findByTopiaId(param_species.getTopiaId());
// on fait le calcul du tac si nécessaire
if (param_propTac > 0 && date.getMonth().equals(Month.JANUARY)){
PopulationMonitor popMon = context.getPopulationMonitor();
param_tacInTons = popMon.getBiomass(param_species) * param_propTac;
}
boolean result = false;
if(date.before(param_beginDate)) {
result = false;
} else if(date.after(param_endDate)) {
result = false;
} else {
TargetSpecies ts = metier.getMetierSeasonInfo(date.getMonth()).getSpeciesTargetSpecies(param_species);
if (ts != null) {
double catchTons = RuleUtil.getTotalCatchTons(context, param_species);
log.info("[TAC] catchTons = " + catchTons + " >= param_tacInTons:" + param_tacInTons );
if (catchTons >= param_tacInTons) {
result = true;
}
}
}
return result;
}
/**
* Si la condition est vrai alors cette action est executée avant le pas
* de temps de la simulation.
* @param simulation La simulation pour lequel on utilise cette regle
*/
public void preAction(SimulationContext context, Date date, Metier metier) throws Exception {
affectation = false;
log.info("[TAC] preAction for: " + metier);
TargetSpecies ts = metier.getMetierSeasonInfo(date.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
/*List<Metier> aimedMetiers = context.getDB().find("select distinct(metierSeasonInfo.metier) " +
"from fr.ifremer.isisfish.entities.TargetSpecies" +
"where species=? and primaryCatch=true", param_species);
log.info("aimed Metier: " + aimedMetiers);*/
context.getMetierMonitor().addforbiddenMetier(metier);
//récupere toutes les stratégies pratiquant le métier et pour lesquelles la proportion !=0
SiMatrix siMatrix = SiMatrix.getSiMatrix(context);
Set<Strategy> strs = new HashSet<Strategy>();
for (Strategy str : siMatrix.getStrategies(date)) {
double prop = str.getStrategyMonthInfo(date.getMonth()).getProportionMetier(metier);
if (prop != 0) {
strs.add(str);
}
}
for (Strategy str : strs){
StrategyMonthInfo smi = str.getStrategyMonthInfo(date.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 Activité")
&& !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(date,
ResultName.MATRIX_NO_ACTIVITY,
siMatrix.getStrategies(date),
siMatrix.getMetiers(date));
mat.setValue(str, metier, smi.getProportionMetier(metier));
smi.getProportionMetier().setValue(metier, 0);
}
}
}
}
/**
* Si la condition est vrai alors cette action est executée apres le pas
* de temps de la simulation.
* @param simulation La simulation pour lequel on utilise cette regle
*/
public void postAction(SimulationContext context, Date date, Metier metier) throws Exception {
log.info("[TAC] postAction for: " + metier);
TargetSpecies ts = metier.getMetierSeasonInfo(date.getMonth()).getSpeciesTargetSpecies(param_species);
if(ts != null){
if (!affectation){
// 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)
//////
PopulationMonitor popMon = context.getPopulationMonitor();
log.info("popMon biomass" + popMon.getBiomass(param_species));
for (Population pop : param_species.getPopulation()) {
if (!pop.getName().equals("Population_new")){
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(date, pop);
log.info("discard : " + discard);
if (discard != null) {
discard.mults(0);
}
log.info("catch = "+ popMon.getCatch(pop));
discard = popMon.getCatch(pop).copy();
discard.setName(ResultName.MATRIX_DISCARDS_PER_STR_MET);
popMon.addDiscard(date, pop, discard);
log.info("[TAC] add discard for " + pop + ": " + discard);
if (param_propSurvie > 0) {
MatrixND eff = popMon.getN(pop);
//on réajoute les survivants aux effectifs
for (MatrixIterator i=discard.iterator(); i.next();){
Object [] coord = i.getSemanticsCoordinates();
eff.setValue(coord[2],coord[3],
eff.getValue(coord[2],coord[3])+i.getValue()*param_propSurvie);
}
}
}
// on a affecte une fois cette meta pop au rejet il ne faut pas
// le refaire
affectation=true;
}
}
}
}
}