diff --git a/src/main/java/species/DisperseAndMigrateToRiverBasic.java b/src/main/java/species/DisperseAndMigrateToRiverBasic.java index 37b2d0b1013d5beda0153d410c2163e4ce0d220f..cbbae2950cdd2230ec04568b2fe1d6369d450445 100644 --- a/src/main/java/species/DisperseAndMigrateToRiverBasic.java +++ b/src/main/java/species/DisperseAndMigrateToRiverBasic.java @@ -21,31 +21,86 @@ import com.thoughtworks.xstream.io.xml.DomDriver; @ServiceProvider(service = AquaNismsGroupProcess.class) public class DisperseAndMigrateToRiverBasic extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> { + /** the coefficient independent of environmental factors in the logistic function used to calculate the probability to disperse + * @unit - + */ private double alpha0Rep = -2.2; - private double alpha1Rep = 17.3; + + /** + * the coefficient associated with the distance between catchment in the logistic function used to calculate the probability to disperse + * i.e. the relative influence of accessibility + * @unit - + */ + //TODO transform to a negative value (the larger the distance , the smaller the accessibility is) and correct in the computation of the weight + private double alpha1Rep = 17.3; + + /** + * the mean distance between catchments used to standardize the inter-catchment distance in the logistic function that calculates the probability to disperse + * @unit km + */ + private double meanInterDistance = 300.; // (from the 53 cathments among the 173 of Lassalles 2008) + + /** + * the standard deviation of distances between catchments used to standardize the inter-catchment distance in the logistic function that calculates the probability to disperse + * @unit km + */ + private double standardDeviationInterDistance = 978.; // (from the 53 cathments among the 173 of Lassalles 2008) + + /** + * the coefficient associated with the attractive surface of the catchment in the logistic function used to calculate the probability to disperse + * i.e. the relative influence of attractiveness + * should be positive : the larger the surface , the higher the attractiveness is + * @unit - + */ + //TODO check the sign in the formula private double alpha3Rep = 0.; - private double meanBvSurface = 23071., standardDeviationBvSurface = 39833.; // for standard core values... Value for the selected 54 BV of the Atlantic Coast from the 196 BV of LAssale, 2008 - private double meanInterDistance = 300., standardDeviationInterDistance = 978.; // for standard core values...Value for the selected 54 BV of the Atlantic Coast from the 196 BV of LAssale, 2008 + /** + * the mean surface used to standardize the catchment surface in the logistic function that calculates the probability to disperse + * @unit ? ha ? + */ + private double meanBvSurface = 23071.; // (from the 53 cathments among the 173 of Lassalles 2008) + + /** + * the standard deviation used to standardize the catchment surface in the logistic function that calculates the probability to disperse + * @unit ? ha ? + */ + private double standardDeviationBvSurface = 39833.; // (from the 53 cathments among the 173 of Lassalles 2008) + /** + * a map associtaing a sea bassin with the weight (accessibility and atrrtactivity) for each river bassin + * <key> SeaBasin + * <value> + * <key> RiverBasin + * <value> weight to calculate probaility to disperse + */ protected transient Map<Basin,Map<Basin,Double>> accessibleBasinsPerBasin; + + /** + * a map associtaing a sea bassin with the distance for each river bassin + * <key> SeaBasin + * <value> + * <key> RiverBasin + * <value> distance between the river Basin and the river basin associated with the sea basin + */ protected transient Map<Basin,Map<Basin,Double>> distanceBasinsPerBasin; - //private transient ObservablesHandler cObservable; + @Override @InitTransientParameters public void initTransientParameters(Pilot pilot) { super.initTransientParameters(pilot); - // calcul les poids des bassins voisins qui ne dépendent pas des poissons pour chaque SeaBassin + // calcul les poids des bassins voisins qui ne d�pendent pas des poissons pour chaque SeaBassin BasinNetwork bn = (BasinNetwork) pilot.getAquaticWorld().getEnvironment(); accessibleBasinsPerBasin = new TreeMap<Basin, Map<Basin,Double>>(); distanceBasinsPerBasin = new TreeMap<Basin, Map<Basin,Double>>(); for (Basin seaBas : bn.getSeaBasins()){ + // compoute the distance with between seaBas and all the river basins Map<Basin,Double> mapDist = bn.getNeighboursWithDistance(seaBas); distanceBasinsPerBasin.put(seaBas, mapDist); - // Compute the weight of each basin + // Compute the weight of each river basin Map<Basin,Double> accessibleBasins = bn.getNeighboursWithDistance(seaBas); for (Basin bas : accessibleBasins.keySet()){ double weight = alpha0Rep diff --git a/src/main/java/species/DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin.java b/src/main/java/species/DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin.java index b7f86e6c9a66d06a0c1100257a2d95c4506a0daa..e3949b2d192896b996f5c293eafef5cc4903af9f 100644 --- a/src/main/java/species/DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin.java +++ b/src/main/java/species/DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin.java @@ -18,17 +18,71 @@ import com.thoughtworks.xstream.io.xml.DomDriver; import miscellaneous.Duo; +/** + * + */ @ServiceProvider(service = AquaNismsGroupProcess.class) public class DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin extends DisperseAndMigrateToRiverBasic { + + /** + * the season when fish migrate to the river to reproduce + * @unit + */ + private Season riverMigrationSeason = Season.SPRING; + + /** + * the homing probalilty during the installation of new populations ( to reach kind of equilibrium) + * @unit + */ private double pHomingForReachEquil = 1.0; + + /** + * the homing probalilty after the installation of new populations ( after reaching an equilibrium) + * @unit + */ private double pHomingAfterEquil = 0.8; + + /** + * Number of year for newly created populations to be installed ( to reach an equilibrium) + * @unit + */ private long NbYearForInstallPop = 50; - private Season riverMigrationSeason = Season.SPRING; + + + /** the coefficient associated with the fish size in the logistic function used to calculate the probability to disperse + * @unit - + */ private double alpha2Rep = 0.; - private double meanSpawnersLengthAtRepro = 45., standardDeviationOfSpawnersLengthAtRepro = 2.; // for standard core values... + + /** + * the mean length used to standardize the fish length in the logistic function that calculates the probability to disperse + * @unit - + */ + private double meanSpawnersLengthAtRepro = 45.; + + /** + * the length standard deviation used to standardize the fish length in the logistic function that calculates the probability to disperse + * @unit - + */ + private double standardDeviationOfSpawnersLengthAtRepro = 2.; // for standard core values... + + /** + * the weigth of the death bassin ( for strayers that do not find a catcment) used to calculate the probability to disperse + * @unit + */ private double weightOfDeathBasin = 0.2; + + /** + * a bollean to kill of the strayers (used to determine if a catchment is a souce or a sink) the year given by yearOfTheKilling + * @unit + */ private boolean killStrayers; + + /** + * the year when the strayers are killed (used to determine if a catchment is a souce or a sink) if killStrayers is true + * @unit + */ private long yearOfTheKillings; public static void main(String[] args) { @@ -43,8 +97,9 @@ public class DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin extends Di BasinNetwork bn = group.getEnvironment(); long amountWithHoming, strayedAmount; - double pHoming; + // probability of homing + double pHoming; if (Time.getYear(group.getPilot()) < NbYearForInstallPop) { pHoming = pHomingForReachEquil; } else { @@ -54,18 +109,23 @@ public class DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin extends Di List<DiadromousFish> deadFish = new ArrayList<DiadromousFish>(); List<DiadromousFish> newFish = new ArrayList<DiadromousFish>(); + // creation of the death basin (for the lost strayers) + //TODO move as a transient field Basin deathBasin = new Basin(-1, "deathBasin", 0, 0, 0, 0); + List<Duo<DiadromousFish, Basin>> fishesToMove = new ArrayList<Duo<DiadromousFish, Basin>>(); for (Basin basin : group.getEnvironment().getSeaBasins()) { List<DiadromousFish> fishes = basin.getFishs(group); if (fishes != null) { - for (int j = 0; j < fishes.size(); j++) { - DiadromousFish fish = fishes.get(j); + for (DiadromousFish fish : fishes) { + + // verify that fish is in a sea basin assert fish.getPosition().getType() == Basin.TypeBassin.SEA; + if (fish.isMature()) { // fish with homing - amountWithHoming = Miscellaneous.binomialForSuperIndividual(group.getPilot(), fish.getAmount(), pHoming); // seuil par défaut fixé à 50 + amountWithHoming = Miscellaneous.binomialForSuperIndividual(group.getPilot(), fish.getAmount(), pHoming); // seuil par d�faut fix� � 50 // strayed fish if (killStrayers == true && Time.getYear(group.getPilot()) >= yearOfTheKillings) { @@ -75,10 +135,12 @@ public class DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin extends Di strayedAmount = fish.getAmount() - amountWithHoming; } + // influence of the fish length on the probability to disperse if (strayedAmount != 0) { - double weightFishLength = Math.exp(-(alpha2Rep * ((fish.getLength() - meanSpawnersLengthAtRepro) / standardDeviationOfSpawnersLengthAtRepro))); + // calcula the weight associated with the fish length in the probabaility to disperse + double weightFishLength = -(alpha2Rep * ((fish.getLength() - meanSpawnersLengthAtRepro) / standardDeviationOfSpawnersLengthAtRepro)); - // On récupère les info du poids des bassin par rapport à la position du poisson + // upload the weights associated with features of the catchment (accessibility and attractivity) List<Duo<Basin, Double>> accBasOfFish = new ArrayList<Duo<Basin, Double>>(); for (Map.Entry<Basin, Double> entry : accessibleBasinsPerBasin.get(fish.getPosition()).entrySet()) { Duo<Basin, Double> duo = new Duo<Basin, Double>(entry.getKey(), entry.getValue()); @@ -89,11 +151,13 @@ public class DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin extends Di double totalWeight = 0.; double probToGo = 0.; long amountToGo = 0; - // TODO Qu'est ce qui se passe si AccBasOfFish est vide... ça beug pas mais c'est pas très clair... donc à vérifier + // TODO manage the case when AccBasOfFish is empty for (Duo<Basin, Double> accBasin : accBasOfFish) { + // total weight for the basin Basin b = accBasin.getFirst(); Double weight = accBasin.getSecond(); - double accBasinWeight = 1 / (1 + Math.exp(-weight) * weightFishLength); + double accBasinWeight = 1 / (1 + Math.exp(-(weight + weightFishLength))); + // put weight to 0 for unused basins if (group.isThereBasinToUpdate()){ if (Time.getYear(group.getPilot()) >= group.getYearOfTheUpdate() @@ -104,10 +168,8 @@ public class DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin extends Di } accBasin.setSecond(accBasinWeight); totalWeight += accBasinWeight; - //} } - // add the deathBasin in the list accBasOfFish.add(new Duo<Basin, Double>(deathBasin, weightOfDeathBasin)); totalWeight = totalWeight + weightOfDeathBasin; @@ -141,7 +203,7 @@ public class DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin extends Di if (amountWithHoming > 0) { fish.setAmount(amountWithHoming); // retour soit dans le bassin de naissance pour les semelpares - // soit dans le dernier bassin de reproduction pour les itéropares + // soit dans le dernier bassin de reproduction pour les it�ropares fishesToMove.add(new Duo<DiadromousFish, Basin>(fish, bn.getAssociatedRiverBasin(fish.getPosition()))); } else { deadFish.add(fish); diff --git a/src/main/java/species/Grow.java b/src/main/java/species/Grow.java index df3bb3f5fdd502d893a9f7e752384cb7329eb9b4..f1f9e9b943d3b18ceeffe0d00dde920f467c9f4c 100644 --- a/src/main/java/species/Grow.java +++ b/src/main/java/species/Grow.java @@ -62,7 +62,7 @@ public class Grow extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGr // 2) We update the size of the fish if (fish.getLength() < group.getLinfVonBert()){ - muDeltaLVonBert = Math.log((group.getLinfVonBert() - fish.getLength()) * (1 - Math.exp(-kVonBert * Time.getSeasonDuration()))) - (Math.pow(sigmaDeltaLVonBert,2))/2; + muDeltaLVonBert = Math.log((group.getLinfVonBert() - fish.getLength()) * (1 - Math.exp(-kVonBert * Time.getSeasonDuration()))) - (sigmaDeltaLVonBert*sigmaDeltaLVonBert)/2; growthIncrement = Math.exp(genNormal.nextDouble()*sigmaDeltaLVonBert + muDeltaLVonBert); fish.setLength(Math.min(group.getLinfVonBert(), fish.getLength() + growthIncrement)); }else{ @@ -74,7 +74,7 @@ public class Grow extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGr fish.setStage(Stage.MATURE); } } - //System.out.println("la température du lieu de vie du poisson est :" + fish.getPosition().getCurrentTemperature() + ", la saison est :" + Time.getSeason() + " et sa nouvelle taille est :" + fish.getLength()); + //System.out.println("la temp�rature du lieu de vie du poisson est :" + fish.getPosition().getCurrentTemperature() + ", la saison est :" + Time.getSeason() + " et sa nouvelle taille est :" + fish.getLength()); } } }