From 270faa2bbc7556d81a50a7c0104069d2b5b30cc3 Mon Sep 17 00:00:00 2001
From: Lambert Patrick <patrick.lambert@irstea.fr>
Date: Wed, 28 Aug 2019 16:48:10 +0200
Subject: [PATCH] with groth different between male and female

---
 data/input/fishTryRealBV_CC.xml               |  6 +-
 .../java/species/DiadromousFishGroup.java     | 98 ++++++++++++-------
 .../species/DisperseAndMigrateToRiver.java    | 16 +--
 ...perseAndMigrateToRiverStandardization.java | 18 ++--
 src/main/java/species/Grow.java               | 12 +--
 .../ReproduceAndSurviveAfterReproduction.java |  3 +-
 6 files changed, 90 insertions(+), 63 deletions(-)

diff --git a/data/input/fishTryRealBV_CC.xml b/data/input/fishTryRealBV_CC.xml
index 604bc07..097a228 100644
--- a/data/input/fishTryRealBV_CC.xml
+++ b/data/input/fishTryRealBV_CC.xml
@@ -7,10 +7,12 @@
 			<blue>0</blue>
 			<alpha>255</alpha>
 		</color>
-		<linfVonBert>70.0</linfVonBert>
 		<dMaxDisp>300.0</dMaxDisp>
+		<linfVonBertForFemale>70.0</linfVonBertForFemale>
+		<linfVonBertForMale>70.0</linfVonBertForMale>
 		<lFirstMaturityForFemale>55.0</lFirstMaturityForFemale>
 		<lFirstMaturityForMale>40.0</lFirstMaturityForMale>
+		<lengthAtHatching>2</lengthAtHatching>
 		<nutrientRoutine>
 			<nutrientsOfInterest>
 				<string>N</string>
@@ -233,7 +235,7 @@
 				<species.PopulateBasinNetworkWithANorthLimit>
 					<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
 					<nbSIPerBasin>200</nbSIPerBasin>
-					<initialLength>2.0</initialLength>
+					<initialLength>20.0</initialLength>
 					<nbFishPerSI>2500</nbFishPerSI>
 					<northLimitLatitude>43.54</northLimitLatitude>
 				</species.PopulateBasinNetworkWithANorthLimit>
diff --git a/src/main/java/species/DiadromousFishGroup.java b/src/main/java/species/DiadromousFishGroup.java
index 497bf91..e07e8d3 100644
--- a/src/main/java/species/DiadromousFishGroup.java
+++ b/src/main/java/species/DiadromousFishGroup.java
@@ -36,39 +36,21 @@ import species.DiadromousFish.Gender;
 
 import org.openide.util.lookup.ServiceProvider;
 
+/**
+ *
+ */
 @ServiceProvider(service = AquaNismsGroup.class)
 public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNetwork> implements Comparable<DiadromousFishGroup> {
 
 	public String name = "species A";
 	public Color color = Color.RED;
 
-	/**
-	 * L infinity of the van Bertalanffy growth curve
-	 * L = Linf *(1-exp(-K*(t-t0))
-	 * @unit cm
-	 */
-	public double linfVonBert = 60.;
-
 	/**
 	 *  ????
 	 * @unit
 	 */
 	public double dMaxDisp = 300.;
 	
-	/**
-	 *  length at first maturity. At that length the female become Stage.MATURE
-	 * @unit cm
-	 */
-	public double lFirstMaturityForFemale = 55.;
-
-
-	/**
-	 *  length at first maturity. At that length the female become Stage.MATURE
-	 * @unit cm
-	 */
-	public double lFirstMaturityForMale = 40.;
-
-
 	/**
 	 * Routine to compute nutrient fluxes operated by a single individual (TODO by a single super individual). 
 	 * 
@@ -127,6 +109,28 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe
 	 */
 	private transient Map<String, Duo<Double, Double>> basinsToUpdate;
 
+	/**
+	 *  length when fish hatchs ( when the diadromousFish is created after reproduction)
+	 *  no diffrence between gender
+	 * @unit cm
+	 */
+	private double lengthAtHatching = 2.;
+	
+	/**
+	 * L infinity of the van Bertalanffy growth curve for  female
+	 * L = Linf *(1-exp(-K*(t-t0))
+	 * @unit cm
+	 */
+	public double linfVonBertForFemale = 60.;
+	
+	/**
+	 * L infinity of the van Bertalanffy growth curve for  male
+	 * L = Linf *(1-exp(-K*(t-t0))
+	 * @unit cm
+	 */
+	public double linfVonBertForMale = 60.;
+	
+	
 	/**
 	 * Brody growth coefficient of the von Bertalanffy growth curve for female (calculated from the parameterset file)
 	 *  	 * L = Linf *(1-exp(-K*(t-t0))
@@ -140,6 +144,20 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe
 	 * @unit year-1
 	 */
 	private transient double kOptForMale; 
+	
+	/**
+	 *  length at first maturity. At that length the female become Stage.MATURE
+	 * @unit cm
+	 */
+	public double lFirstMaturityForFemale = 55.;
+
+
+	/**
+	 *  length at first maturity. At that length the female become Stage.MATURE
+	 * @unit cm
+	 */
+	public double lFirstMaturityForMale = 40.;
+	
 
 	/**
 	 * minimum temperature for the reproduction (from the parameterset file)
@@ -560,28 +578,38 @@ public BufferedWriter getbWForFluxes() {
 		return color;
 	}
 
-	public double getLinfVonBert() {
-		return linfVonBert;
+	public double getLinfVonBert(DiadromousFish fish) {
+		if ( fish.getGender() == Gender.FEMALE)
+			return linfVonBertForFemale;
+		else if (fish.getGender() == Gender.MALE)
+			return linfVonBertForMale;
+		else
+			return (linfVonBertForFemale+linfVonBertForMale)/2.;
 	}
 
-	public void setLinfVonBert(double linfVonBert) {
-		this.linfVonBert = linfVonBert;
-	}
 
-	public double getdMaxDisp() {
-		return dMaxDisp;
+	public double getlFirstMaturity(DiadromousFish fish) {
+		if ( fish.getGender() == Gender.FEMALE)
+			return lFirstMaturityForFemale;
+		else if (fish.getGender() == Gender.MALE)
+			return lFirstMaturityForMale;
+		else
+			return (lFirstMaturityForFemale+lFirstMaturityForFemale)/2.;
 	}
+	
 
-	public double getlFirstMaturityForFemale() {
-		return lFirstMaturityForFemale;
+	/**
+	 * @return the lengthAtHatching
+	 */
+	public double getLengthAtHatching() {
+		return lengthAtHatching;
 	}
 
-
-	public double getlFirstMaturityForMale() {
-		return lFirstMaturityForMale;
+	
+	public double getdMaxDisp() {
+		return dMaxDisp;
 	}
-
-
+	
 public  NutrientRoutine getNutrientRoutine() {
 		return nutrientRoutine; 
 	}
diff --git a/src/main/java/species/DisperseAndMigrateToRiver.java b/src/main/java/species/DisperseAndMigrateToRiver.java
index fe7c1ff..db6d184 100644
--- a/src/main/java/species/DisperseAndMigrateToRiver.java
+++ b/src/main/java/species/DisperseAndMigrateToRiver.java
@@ -49,26 +49,26 @@ public class DisperseAndMigrateToRiver extends DisperseAndMigrateToRiverBasic {
 		
 				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 
 					strayedAmount = fish.getAmount() - amountWithHoming;					
 					
 					if (strayedAmount != 0) {
-						// On récupère les info du poids des bassin par rapport à la position du poisson
+						// On r�cup�re les info du poids des bassin par rapport � la position du poisson
 						Map<Basin,Double> accBasOfFish= new TreeMap<Basin, Double>(accessibleBasinsPerBasin.get(fish.getPosition()));
 						//accBasOfFish = accessibleBasinsPerBasin.get(fish.getPosition());						
 
-						// On retire certains bassins si on considère une distance max de dispersion
+						// On retire certains bassins si on consid�re une distance max de dispersion
 						distBasOfFish = distanceBasinsPerBasin.get(fish.getPosition());
 						if (group.getdMaxDisp() != 0){
-							// TODO pourquoi distbasoffish peut être nul ?
+							// TODO pourquoi distbasoffish peut �tre nul ?
 							if (distBasOfFish != null){
-								dMaxDispFish = (group.getdMaxDisp()/group.getLinfVonBert())*fish.getLength();
+								dMaxDispFish = (group.getdMaxDisp()/group.getLinfVonBert(fish))*fish.getLength();
 								// load accessible basins
 								for (Basin surroundingBasin : distBasOfFish.keySet()){
 									Double distance = distBasOfFish.get(surroundingBasin);
-									//System.out.println("pour le poisson " + fish.hashCode() + " situé dans le bassin " + basin.getName() + " et né dans le bassin " + fish.getBirthBasin().getName());
+									//System.out.println("pour le poisson " + fish.hashCode() + " situ� dans le bassin " + basin.getName() + " et n� dans le bassin " + fish.getBirthBasin().getName());
 									//System.out.println("la distance vaut " + distance + " pour le bassin " + surroundingBasin.getName());
 									if (distance >= dMaxDispFish) {
 										accBasOfFish.remove(surroundingBasin);
@@ -81,7 +81,7 @@ public class DisperseAndMigrateToRiver extends DisperseAndMigrateToRiverBasic {
 						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 Qu'est ce qui se passe si AccBasOfFish est vide... �a beug pas mais c'est pas tr�s clair... donc � v�rifier
 						for (Basin accBasin : accBasOfFish.keySet()){
 							double accBasinWeightLogit = accBasOfFish.get(accBasin) + alpha2Rep * fish.getLength();
 							double accBasinWeight = 1 / (1 + Math.exp(- accBasinWeightLogit));
@@ -107,7 +107,7 @@ public class DisperseAndMigrateToRiver extends DisperseAndMigrateToRiverBasic {
 					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
 						fish.moveTo(group.getPilot(), bn.getAssociatedRiverBasin(fish.getPosition()), group);
 					} else {
 						deadFish.add(fish);
diff --git a/src/main/java/species/DisperseAndMigrateToRiverStandardization.java b/src/main/java/species/DisperseAndMigrateToRiverStandardization.java
index 9aa8357..d810e41 100644
--- a/src/main/java/species/DisperseAndMigrateToRiverStandardization.java
+++ b/src/main/java/species/DisperseAndMigrateToRiverStandardization.java
@@ -41,7 +41,7 @@ public class DisperseAndMigrateToRiverStandardization extends AquaNismsGroupProc
 	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>>();
@@ -107,26 +107,26 @@ public class DisperseAndMigrateToRiverStandardization extends AquaNismsGroupProc
 		
 				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 
 					strayedAmount = fish.getAmount() - amountWithHoming;					
 					
 					if (strayedAmount != 0) {
-						// On récupère les info du poids des bassin par rapport à la position du poisson
+						// On r�cup�re les info du poids des bassin par rapport � la position du poisson
 						Map<Basin,Double> accBasOfFish= new TreeMap<Basin, Double>(accessibleBasinsPerBasin.get(fish.getPosition()));
 						//accBasOfFish = accessibleBasinsPerBasin.get(fish.getPosition());						
 
-						// On retire certains bassins si on considère une distance max de dispersion
+						// On retire certains bassins si on consid�re une distance max de dispersion
 						distBasOfFish = distanceBasinsPerBasin.get(fish.getPosition());
 						if (group.getdMaxDisp() != 0){
-							// TODO pourquoi distbasoffish peut être nul ?
+							// TODO pourquoi distbasoffish peut �tre nul ?
 							if (distBasOfFish != null){
-								dMaxDispFish = (group.getdMaxDisp()/group.getLinfVonBert())*fish.getLength();
+								dMaxDispFish = (group.getdMaxDisp()/group.getLinfVonBert(fish))*fish.getLength();
 								// load accessible basins
 								for (Basin surroundingBasin : distBasOfFish.keySet()){
 									Double distance = distBasOfFish.get(surroundingBasin);
-									//System.out.println("pour le poisson " + fish.hashCode() + " situé dans le bassin " + basin.getName() + " et né dans le bassin " + fish.getBirthBasin().getName());
+									//System.out.println("pour le poisson " + fish.hashCode() + " situ� dans le bassin " + basin.getName() + " et n� dans le bassin " + fish.getBirthBasin().getName());
 									//System.out.println("la distance vaut " + distance + " pour le bassin " + surroundingBasin.getName());
 									if (distance >= dMaxDispFish) {
 										accBasOfFish.remove(surroundingBasin);
@@ -139,7 +139,7 @@ public class DisperseAndMigrateToRiverStandardization extends AquaNismsGroupProc
 						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 Qu'est ce qui se passe si AccBasOfFish est vide... �a beug pas mais c'est pas tr�s clair... donc � v�rifier
 						for (Basin accBasin : accBasOfFish.keySet()){
 							double accBasinWeightLogit = accBasOfFish.get(accBasin) + alpha2Rep*((fish.getLength() - meanLengthOfMatureFishes) / standardDeviationOfMatureFishesLength);
 							double accBasinWeight = 1 / (1 + Math.exp(- accBasinWeightLogit));
@@ -165,7 +165,7 @@ public class DisperseAndMigrateToRiverStandardization extends AquaNismsGroupProc
 					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
 						fish.moveTo(group.getPilot(), bn.getAssociatedRiverBasin(fish.getPosition()), group);
 					} else {
 						deadFish.add(fish);
diff --git a/src/main/java/species/Grow.java b/src/main/java/species/Grow.java
index 8a7638b..902d3ca 100644
--- a/src/main/java/species/Grow.java
+++ b/src/main/java/species/Grow.java
@@ -94,22 +94,20 @@ public class Grow extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGr
 
 					// 2) Update the fish length with a lognormal normal draw  of increment
 					// limit the fish length to Linf
-					if (fish.getLength() < group.getLinfVonBert()){
-						muDeltaLVonBert = Math.log((group.getLinfVonBert() - fish.getLength()) * (1 - Math.exp(-kVonBert * Time.getSeasonDuration()))) - (sigmaDeltaLVonBert*sigmaDeltaLVonBert)/2;
+					if (fish.getLength() < group.getLinfVonBert(fish)){
+						muDeltaLVonBert = Math.log((group.getLinfVonBert(fish) - 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));											
+						fish.setLength(Math.min(group.getLinfVonBert(fish), fish.getLength() + growthIncrement));											
 					}
 					else {
-						fish.setLength(group.getLinfVonBert());
+						fish.setLength(group.getLinfVonBert(fish));
 					}
 					//System.out.println(fish.getAge() + " -> "+ fish.getLength() + " ("+fish.getStage()+"): "+ growthIncrement);
 					// test if fish become mature
-					if (fish.getStage() == Stage.IMMATURE){
-						if (fish.getLength() > group.getlFirstMaturityForFemale()){
+					if (fish.getStage() == Stage.IMMATURE && fish.getLength() > group.getlFirstMaturity(fish)){
 							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());
 				}
diff --git a/src/main/java/species/ReproduceAndSurviveAfterReproduction.java b/src/main/java/species/ReproduceAndSurviveAfterReproduction.java
index 21007cc..11755b4 100644
--- a/src/main/java/species/ReproduceAndSurviveAfterReproduction.java
+++ b/src/main/java/species/ReproduceAndSurviveAfterReproduction.java
@@ -44,7 +44,6 @@ public class ReproduceAndSurviveAfterReproduction extends AquaNismsGroupProcess<
 	private double delta_t=0.33; // duration of the mortality considered in the reproduction process (ex.: from eggs to juvenile in estuary for alosa alosa = 0.33)
 	private double survOptRep = 0.0017;
 	private double lambda = 0.00041;
-	private double initialLength = 2.;
 	private double sigmaRecruitment = 0.3;
 	private double survivalRateAfterReproduction = 0.1;
 	private double maxNumberOfSuperIndividualPerReproduction = 50.;
@@ -237,7 +236,7 @@ public class ReproduceAndSurviveAfterReproduction extends AquaNismsGroupProcess<
 							long effectiveAmount =  numberOfRecruit / numberOfsuperIndividual;
 						
 							for (int i=0; i<numberOfsuperIndividual; i++){
-								group.addAquaNism(new DiadromousFish(group.getPilot(), riverBasin, initialLength, effectiveAmount, Gender.UNDIFFERENCIED));
+								group.addAquaNism(new DiadromousFish(group.getPilot(), riverBasin, group.getLengthAtHatching(), effectiveAmount, Gender.UNDIFFERENCIED));
 							}
 							
 							// stock the first year when recruitment is non nul
-- 
GitLab