diff --git a/data/input/fishTryRealBV_CC.xml b/data/input/fishTryRealBV_CC.xml index 9e1ffcaf77053eff286901d2269cb0712daf5343..7a35b75a17e157dcf9d1964e9aef8066bcae2bcf 100644 --- a/data/input/fishTryRealBV_CC.xml +++ b/data/input/fishTryRealBV_CC.xml @@ -152,34 +152,6 @@ </hashtable> </entry> </compoCarcassPreSpawning> - <compoCarcassPostSpawning class="hashtable"> - <entry> - <species.DiadromousFish_-Gender>MALE</species.DiadromousFish_-Gender> - <hashtable> - <entry> - <string>P</string> - <double>0.00961</double> - </entry> - <entry> - <string>N</string> - <double>0.0279</double> - </entry> - </hashtable> - </entry> - <entry> - <species.DiadromousFish_-Gender>FEMALE</species.DiadromousFish_-Gender> - <hashtable> - <entry> - <string>P</string> - <double>0.00997</double> - </entry> - <entry> - <string>N</string> - <double>0.03216</double> - </entry> - </hashtable> - </entry> - </compoCarcassPostSpawning> <compoGametes class="hashtable"> <entry> <species.DiadromousFish_-Gender>MALE</species.DiadromousFish_-Gender> @@ -300,18 +272,17 @@ <mortalityRateInOffshore>0.4</mortalityRateInOffshore> </species.Survive> - <species.ExportFluxes> + <species.WriteEffectiveFluxes> <synchronisationMode>ASYNCHRONOUS</synchronisationMode> <exportSeason>SPRING</exportSeason> - <fileNameOutput>EffectiveFluxes</fileNameOutput> - </species.ExportFluxes> + <fileNameOutput>effectiveFluxes</fileNameOutput> + </species.WriteEffectiveFluxes> - <species.ExportBiomass> + <species.WriteBiomassFluxes> <synchronisationMode>ASYNCHRONOUS</synchronisationMode> - <survivalRateAfterReproduction>0.1</survivalRateAfterReproduction> <exportSeason>SPRING</exportSeason> - <fileNameOutput>BiomassFluxes</fileNameOutput> - </species.ExportBiomass> + <fileNameOutput>BiomassFluxessBeforeReproduction</fileNameOutput> + </species.WriteBiomassFluxes> <species.ReproduceAndSurviveAfterReproductionWithDiagnose> <synchronisationMode>ASYNCHRONOUS</synchronisationMode> @@ -348,6 +319,11 @@ </processesEachStep> <processesAtEnd> + <species.WriteImportNutrientFluxes> + <synchronisationMode>ASYNCHRONOUS</synchronisationMode> + <fileName>fluxes</fileName> + </species.WriteImportNutrientFluxes> + <species.IdentifyPopulation> <synchronisationMode>ASYNCHRONOUS</synchronisationMode> <consoleDisplay>false</consoleDisplay> @@ -358,6 +334,7 @@ </years> <fileNameOutput>JeuParam100_2100RCP85_A_essai</fileNameOutput> </species.IdentifyPopulation> + <species.TypeTrajectoryCV> <synchronisationMode>ASYNCHRONOUS</synchronisationMode> <fileNameOutput>JeuParam100_2100RCP85_A_essai</fileNameOutput> diff --git a/src/main/java/species/DiadromousFish.java b/src/main/java/species/DiadromousFish.java index 002042070fdc641407aa8fe205edd719416906b3..b6a45941dfb15b288b4c0b2ec43e5ddc6a616309 100644 --- a/src/main/java/species/DiadromousFish.java +++ b/src/main/java/species/DiadromousFish.java @@ -12,6 +12,8 @@ public class DiadromousFish extends AquaNism<Basin, BasinNetwork> { //TODO replace UNDIFFERENCIED by UNDETERMINED public static enum Gender {UNDIFFERENCIED, FEMALE, MALE}; + public enum SpawnerOrigin {AUTOCHTONOUS, ALLOCHTONOUS}; + private long amount; /** * age of the fish diff --git a/src/main/java/species/DiadromousFishGroup.java b/src/main/java/species/DiadromousFishGroup.java index b8df6fdd6d393ac769966b8c9226bbe59e7a37ba..df5f980f13246d1f7bf132b44b1d11437f94ce54 100644 --- a/src/main/java/species/DiadromousFishGroup.java +++ b/src/main/java/species/DiadromousFishGroup.java @@ -93,8 +93,9 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe */ private String basinsToUpdateFile = "data/input/reality/basinsToUpdate.csv"; - private String outputPath = "data/output/"; + private String outputPath = "data/output/" ; + //TODO:remove fileNameFluxes private String fileNameFluxes = "fluxes"; private transient BufferedWriter bWForFluxes; @@ -176,7 +177,7 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe // ================================================= // calibration // ================================================= - + private Double targetedAgeForFemaleSpawnerForFirstTime = 5.5; private Double targetedAgeForMaleSpawnerForFirstTime = 4.5; @@ -318,7 +319,7 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe nutrientsOfInterest.add("P"); - diadromousFishGroup.nutrientRoutine = new NutrientRoutine(nutrientsOfInterest,aResidenceTime, anExcretionRate, aFeaturePreSpawning, aFeaturePostSpawning, aCompoCarcassPreSpawning, aCompoCarcassPostSpawning, + diadromousFishGroup.nutrientRoutine = new NutrientRoutine(nutrientsOfInterest,aResidenceTime, anExcretionRate, aFeaturePreSpawning, aFeaturePostSpawning, aCompoCarcassPreSpawning, aCompoGametes, aJuvenileFeatures, aCompoJuveniles); @@ -498,12 +499,14 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe } catch (IOException ex) { Logger.getLogger(DiadromousFishGroup.class.getName()).log(Level.SEVERE, null, ex); } - + // defaut values if (targetedAgeForFemaleSpawnerForFirstTime == null) targetedAgeForFemaleSpawnerForFirstTime = 5.5; if (targetedAgeForMaleSpawnerForFirstTime == null) targetedAgeForMaleSpawnerForFirstTime = 4.5; + + this.nutrientRoutine.getNutrientFluxesCollection().setBasinNames(this.getEnvironment().getRiverBasinNames()); } @@ -709,8 +712,8 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe } return sum/nb; } - - + + public double computeMaleSpawnerForFirstTimeSummaryStatisticWithTarget(double TARGET ) { double sum = 0; for (RiverBasin riverBasin : getEnvironment().getRiverBasins()) { @@ -727,7 +730,7 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe public double computeMaleSpawnerForFirstTimeSummaryStatistic() { return computeMaleSpawnerForFirstTimeSummaryStatisticWithTarget(targetedAgeForFemaleSpawnerForFirstTime); } - + @Observable(description="mean age of first reprodution for male") public double getMeanAgeOfFirstReprodutionForMale() { double sum = 0; @@ -753,8 +756,8 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe } return sum/nb; } - - + + @Observable(description = "Likelihood Summary stat") public double computeLikelihood() { int obsVal; @@ -932,7 +935,7 @@ public class DiadromousFishGroup extends AquaNismsGroup< DiadromousFish, BasinNe } return eff; } - + /** * @return sum of male spawner effectives in all the river basins */ diff --git a/src/main/java/species/NutrientRoutine.java b/src/main/java/species/NutrientRoutine.java index 8aebf82ace1ddc7801312e89e87c636f5883865f..ead53e70dca149a6050e670502d0981f8fc72859 100644 --- a/src/main/java/species/NutrientRoutine.java +++ b/src/main/java/species/NutrientRoutine.java @@ -24,7 +24,10 @@ import fr.cemagref.simaqualife.pilot.Pilot; import species.DiadromousFish.Gender; import species.DiadromousFish.Stage; import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; import java.util.Hashtable; +import java.util.List; import java.util.Map; import com.thoughtworks.xstream.XStream; @@ -91,7 +94,7 @@ public class NutrientRoutine { * <key> chemical element * <value> value */ - private Map<DiadromousFish.Gender, Map<String, Double>> compoCarcassPostSpawning; + //private Map<DiadromousFish.Gender, Map<String, Double>> compoCarcassPostSpawning; /** * chemical composition of gametes estimated from the MIGADO dataset (BDalosesBruch) @@ -112,9 +115,11 @@ public class NutrientRoutine { private Map<String,Double> compoJuvenile; + private transient NutrientFluxesCollection nutrientFluxesCollection; - public NutrientRoutine() { + public NutrientRoutine() { + this.nutrientFluxesCollection = new NutrientFluxesCollection(); } /** @@ -132,7 +137,7 @@ public class NutrientRoutine { Map<DiadromousFish.Gender, Map<String, Double>> fishFeaturesPreSpawning, Map<DiadromousFish.Gender, Map<String, Double>> fishFeaturesPostSpawning, Map<DiadromousFish.Gender, Map<String, Double>> compoCarcassPreSpawning, - Map<DiadromousFish.Gender, Map<String, Double>> compoCarcassPostSpawning, + //Map<DiadromousFish.Gender, Map<String, Double>> compoCarcassPostSpawning, Map<DiadromousFish.Gender, Map<String, Double>> compoGametes, Map<String, Double> juvenileFeatures, Map<String, Double> compoJuvenile) @@ -144,11 +149,19 @@ public class NutrientRoutine { this.fishFeaturesPreSpawning = fishFeaturesPreSpawning; this.fishFeaturesPostSpawning = fishFeaturesPostSpawning; this.compoCarcassPreSpawning = compoCarcassPreSpawning; - this.compoCarcassPostSpawning = compoCarcassPostSpawning; + //this.compoCarcassPostSpawning = compoCarcassPostSpawning; this.compoGametes = compoGametes; this.juvenileFeatures = juvenileFeatures; this.compoJuvenile = compoJuvenile; + this.nutrientFluxesCollection = new NutrientFluxesCollection(); + + } + + + + public NutrientFluxesCollection getNutrientFluxesCollection() { + return nutrientFluxesCollection; } /** @@ -176,8 +189,6 @@ public class NutrientRoutine { nutrientsInput.put(nutrient, 0.); } } - - //TODO Multiply by fish amount return nutrientsInput; } @@ -200,16 +211,16 @@ public class NutrientRoutine { if (fish.getStage()== Stage.MATURE) { - double totalWeightPost = this.getWeight(fish, SpawningPosition.POST); + double totalWeightPost = this.getWeight(fish, SpawningPosition.PRE); double carcass = totalWeightPost - * compoCarcassPostSpawning.get(fish.getGender()).get(nutrient); + * compoCarcassPreSpawning.get(fish.getGender()).get(nutrient); //double gametes = (totalWeightPre - totalWeightPost) FAUX car perte de poids somatique due a la reproduction - double gametes = this.getGonadWeight(fish, SpawningPosition.PRE) - this.getGonadWeight(fish, SpawningPosition.POST) - *compoGametes.get(fish.getGender()).get(nutrient); + //double gametes = (this.getGonadWeight(fish, SpawningPosition.PRE) - this.getGonadWeight(fish, SpawningPosition.POST)) + //*compoGametes.get(fish.getGender()).get(nutrient); double excretion = totalWeightPost * residenceTime * excretionRate.get(nutrient); - double nutrientImport = carcass + gametes + excretion; + double nutrientImport = carcass + excretion; nutrientsInput.put(nutrient,nutrientImport); } @@ -220,6 +231,8 @@ public class NutrientRoutine { return nutrientsInput; } + + public Map<String, Double> computeNutrientsInputForDeathAfterSpawning(DiadromousFish fish){ return computeNutrientsInputForDeathAfterSpawning(fish, this.nutrientsOfInterest); @@ -237,10 +250,9 @@ public class NutrientRoutine { if (fish.getStage()==Stage.MATURE) { //TODO Fix with new data - double totalWeightPost = this.getWeight(fish, SpawningPosition.POST); + double totalWeightPost = this.getWeight(fish, SpawningPosition.PRE); //Gamete compositions depends on sex. - - double gametes = this.getGonadWeight(fish, SpawningPosition.PRE) - this.getGonadWeight(fish, SpawningPosition.POST) + double gametes = (this.getGonadWeight(fish, SpawningPosition.PRE) - this.getGonadWeight(fish, SpawningPosition.POST)) * compoGametes.get(fish.getGender()).get(nutrient); double excretion = totalWeightPost * residenceTime @@ -294,8 +306,8 @@ public class NutrientRoutine { if (spawningPosition == SpawningPosition.PRE) weight = fishFeaturesPreSpawning.get(fish.getGender()).get("aLW") * Math.pow(fish.getLength(), fishFeaturesPreSpawning.get(fish.getGender()).get("bLW") ); else - weight = fishFeaturesPostSpawning.get(fish.getGender()).get("aLW") * Math.pow(fish.getLength(), fishFeaturesPostSpawning.get(fish.getGender()).get("bLW")); - + //weight = fishFeaturesPostSpawning.get(fish.getGender()).get("aLW") * Math.pow(fish.getLength(), fishFeaturesPostSpawning.get(fish.getGender()).get("bLW")); + weight = fishFeaturesPreSpawning.get(fish.getGender()).get("aLW") * Math.pow(fish.getLength(), fishFeaturesPreSpawning.get(fish.getGender()).get("bLW") ); return weight; } @@ -380,7 +392,7 @@ public class NutrientRoutine { aFeature.put("aLW", 1.2102E-6 * Math.pow(10., aFeature.get("bLW"))); //weight size relationship -- Conversion des g/mm en g.cm (from Taverny, 1991) aFeature.put("bLW_Gonad", 2.6729); // issu de la relation taille - poids des gonades Bruch aFeature.put("aLW_Gonad", -5.2425); // issu de la relation taille - poids des gonades Bruch - + aFeaturePreSpawning.put(Gender.FEMALE, aFeature); /* @@ -444,18 +456,18 @@ public class NutrientRoutine { System.out.println("aCompoCarcassPreSpawning: " + aCompoCarcassPreSpawning.toString()); // // carcass composition for fish after spawning - Map<Gender, Map<String, Double>> aCompoCarcassPostSpawning = new Hashtable<DiadromousFish.Gender,Map<String,Double>>(); - aCompo = new Hashtable<String,Double>(); - aCompo.put("N", 3.216 / 100.); //On remplit une collection avec un put. - aCompo.put("P", 0.997 / 100.); - aCompoCarcassPostSpawning.put(Gender.FEMALE,aCompo); + //Map<Gender, Map<String, Double>> aCompoCarcassPostSpawning = new Hashtable<DiadromousFish.Gender,Map<String,Double>>(); + //aCompo = new Hashtable<String,Double>(); + //aCompo.put("N", 3.216 / 100.); //On remplit une collection avec un put. + //aCompo.put("P", 0.997 / 100.); + //aCompoCarcassPostSpawning.put(Gender.FEMALE,aCompo); - aCompo = new Hashtable<String,Double>(); - aCompo.put("N", 2.790 / 100.); // From Haskel et al, 2017 - aCompo.put("P", 0.961 / 100.); - aCompoCarcassPostSpawning.put(Gender.MALE,aCompo); + //aCompo = new Hashtable<String,Double>(); + //aCompo.put("N", 2.790 / 100.); // From Haskel et al, 2017 + //aCompo.put("P", 0.961 / 100.); + //aCompoCarcassPostSpawning.put(Gender.MALE,aCompo); - System.out.println("aCompoCarcassPostSpawning: " + aCompoCarcassPostSpawning.toString()); // + //System.out.println("aCompoCarcassPostSpawning: " + aCompoCarcassPostSpawning.toString()); // // Gametes composition approximated by the difference between gonads weight before and after spawning. Map<Gender, Map<String, Double>> aCompoGametes = new Hashtable<DiadromousFish.Gender,Map<String,Double>>(); @@ -494,7 +506,7 @@ public class NutrientRoutine { NutrientRoutine fn = new NutrientRoutine(nutrientsOfInterest,aResidenceTime, anExcretionRate, aFeaturePreSpawning, aFeaturePostSpawning, - aCompoCarcassPreSpawning, aCompoCarcassPostSpawning, aCompoGametes, + aCompoCarcassPreSpawning, aCompoGametes, aJuvenileFeatures, aCompoJuveniles); SeaBasin basin = new SeaBasin(0,"Bidon",10.,12., 14.,12.); //il faut aller dans "SeaBasin" dans "environement et regarder comment est construit le constructeur. Il lui faut ici un rang, un nom de bassin versant, et des temp�rature pour chaque saison @@ -529,6 +541,70 @@ public class NutrientRoutine { System.out.println((new XStream(new DomDriver())).toXML(fn)); } + + public class NutrientFluxesCollection { + + /* + * <key> Year + * <value> + * <key> Nutrient + * <value> + * <key> origin basin name + * <value> + * <key> destination basin name + * <value> flux + */ + // + private Map<Long, Map <String, Map<String, Map<String, Double>>>> fluxesCollection ; + private transient String[] basinNames; + + NutrientFluxesCollection() { + + fluxesCollection = new HashMap <Long, Map <String, Map<String, Map<String, Double>>>> (); + } + + + public Map<Long, Map<String, Map<String, Map<String, Double>>>> getFluxesCollection() { + return fluxesCollection; + } + + + public void setBasinNames(String[] basinNames) { + this.basinNames = basinNames; + } + + + public void put(Long year,String nutrient, String originBasinName, String destinationBasinName, Double flux ) { + + if(!fluxesCollection.containsKey(year)) { + + Map <String, Map <String, Map <String, Double>>> nutrientsMap = new HashMap <String, Map <String, Map <String, Double>>>(); + + for (String nutrientOfInterest : nutrientsOfInterest) { + + Map <String, Map <String, Double>> originsMap = new HashMap <String, Map <String, Double>>(); + for (String originName : basinNames) { + + Map <String, Double> destinationsMap = new HashMap <String, Double>(); + for (String destinationName : basinNames) { + destinationsMap.put(destinationName, 0.); + } + + originsMap.put(originName, destinationsMap); + } + + nutrientsMap.put(nutrientOfInterest, originsMap); + } + + fluxesCollection.put(year,nutrientsMap); + } + + double previousFlux = fluxesCollection.get(year).get(nutrient).get(originBasinName).get(destinationBasinName); + fluxesCollection.get(year).get(nutrient).get(originBasinName).put(destinationBasinName, previousFlux + flux); + + } + } + } diff --git a/src/main/java/species/NutrientRoutineEssay.java b/src/main/java/species/NutrientRoutineEssay.java index 1fc44ab3ede1b9cbba21a81ed705b1214f9941ae..193513c0a387b3801bcc405f7038295e370cb0fb 100644 --- a/src/main/java/species/NutrientRoutineEssay.java +++ b/src/main/java/species/NutrientRoutineEssay.java @@ -20,7 +20,7 @@ import com.thoughtworks.xstream.io.xml.DomDriver; public class NutrientRoutineEssay { - private static enum SpawningPosition {PRE,POST}; // on créer un static pour réserver une même classe mémoire pour toutes les instances + private static enum SpawningPosition {PRE,POST}; // on cr�er un static pour r�server une m�me classe m�moire pour toutes les instances //private static enum Gender {UNDIFFERENCIED, FEMALE, MALE}; @@ -32,7 +32,7 @@ public class NutrientRoutineEssay { /** * Main feature for weight (g) computation before spawning i.e. gametes expelling according to gender, for a given length (cm) - * //Voir pour un retour à la ligne lors du commentaire + * //Voir pour un retour � la ligne lors du commentaire * key gender * value * key feature @@ -63,9 +63,9 @@ public class NutrientRoutineEssay { */ private Map<DiadromousFish.Gender,Map<String,Double>> compoCarcassPreSpawning; - //package permettant la création d'une table de hachage ie fonctionnant en clé -valeur. Clé unique, mais valeur peut être associée à plusieurs clés; - //La class d'objet Map a pour point faible la taille des données à stocker. Plus on a de valeur dans la table, plus c'est lourd et lent! Donc, trouver un compromis entre temps de calcul et espace. - //N'accepte pas la valeur nulle et thread safe i.e. utilisable simultanément par plusieurs éléments du programme. + //package permettant la cr�ation d'une table de hachage ie fonctionnant en cl� -valeur. Cl� unique, mais valeur peut �tre associ�e � plusieurs cl�s; + //La class d'objet Map a pour point faible la taille des donn�es � stocker. Plus on a de valeur dans la table, plus c'est lourd et lent! Donc, trouver un compromis entre temps de calcul et espace. + //N'accepte pas la valeur nulle et thread safe i.e. utilisable simultan�ment par plusieurs �l�ments du programme. /** @@ -128,7 +128,7 @@ public class NutrientRoutineEssay { */ public Map<String,Double> computeNutrientsInputForDeadFish(DiadromousFish fish, ArrayList<String> nutrientsOfInterest) { - Map<String,Double> nutrientsInput = new Hashtable<String, Double>(); // On créer ici une Map, classe mère des hashtable (Homme = classe mere ie Map//Jules = hashtable) + Map<String,Double> nutrientsInput = new Hashtable<String, Double>(); // On cr�er ici une Map, classe m�re des hashtable (Homme = classe mere ie Map//Jules = hashtable) for (String nutrient : nutrientsOfInterest) { if (fish.getStage()== Stage.MATURE) { @@ -168,7 +168,7 @@ public class NutrientRoutineEssay { for (String nutrient: nutrientsOfInterest) { if (fish.getStage()==Stage.MATURE) { double totalWeightPre = this.getWeight(fish,SpawningPosition.PRE); - double gametes = this.getGonadWeight(fish, SpawningPosition.PRE) - this.getGonadWeight(fish, SpawningPosition.POST) + double gametes = (this.getGonadWeight(fish, SpawningPosition.PRE) - this.getGonadWeight(fish, SpawningPosition.POST)) * compoGametes.get(fish.getGender()).get(nutrient); double excretion = totalWeightPre * residenceTime @@ -373,7 +373,7 @@ public class NutrientRoutineEssay { aCompoGametes.put(Gender.FEMALE,aCompo); aCompo = new Hashtable<String,Double>(); - aCompo.put("N", 3.250 / 100.); // Approximée par la compo des gonades + aCompo.put("N", 3.250 / 100.); // Approxim�e par la compo des gonades aCompo.put("P", 0.724 / 100.); aCompoGametes.put(Gender.MALE,aCompo); @@ -404,7 +404,7 @@ public class NutrientRoutineEssay { NutrientRoutineEssay fn = new NutrientRoutineEssay(nutrientsOfInterest,aResidenceTime, anExcretionRate, aFeaturePreSpawning, aFeaturePostSpawning, aCompoCarcassPreSpawning, aCompoGametes, aJuvenileFeatures, aCompoJuveniles); - SeaBasin basin = new SeaBasin(0,"Bidon",10.,12., 14.,12.); //il faut aller dans "SeaBasin" dans "environement et regarder comment est construit le constructeur. Il lui faut ici un rang, un nom de bassin versant, et des température pour chaque saison + SeaBasin basin = new SeaBasin(0,"Bidon",10.,12., 14.,12.); //il faut aller dans "SeaBasin" dans "environement et regarder comment est construit le constructeur. Il lui faut ici un rang, un nom de bassin versant, et des temp�rature pour chaque saison Pilot pilot = new Pilot (); DiadromousFish fishFemale = new DiadromousFish (pilot, basin, 52., 1L, Gender.FEMALE); //Idem ici, on regarde comment est construit DiadromousFih et on lui donne les valeur de ce qu'il nous demande. fishFemale.setStage(Stage.MATURE); diff --git a/src/main/java/species/ReproduceAndSurviveAfterReproductionWithDiagnose.java b/src/main/java/species/ReproduceAndSurviveAfterReproductionWithDiagnose.java index 5b8a901658bea433a8f2a795580fd57ab8561821..5cf7faa02cd6bf6135514a674393d14f003f1ea7 100644 --- a/src/main/java/species/ReproduceAndSurviveAfterReproductionWithDiagnose.java +++ b/src/main/java/species/ReproduceAndSurviveAfterReproductionWithDiagnose.java @@ -17,6 +17,7 @@ import miscellaneous.Duo; import miscellaneous.Miscellaneous; import miscellaneous.Trio; import species.DiadromousFish.Gender; +import species.DiadromousFish.SpawnerOrigin; import org.apache.commons.math3.analysis.UnivariateFunction; import org.apache.commons.math3.optim.MaxEval; @@ -68,7 +69,7 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG private transient NormalGen genNormal; private transient MortalityFunction mortalityFunction; - private enum fluxOrigin {AUTOCHTONOUS, ALLOCHTONOUS}; + /** * relationship between * recruitment in number of juvenile on spawning grounds @@ -111,9 +112,9 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG basinList.add("Somme"); basinList.add("Meuse"); basinList. add("Rhine"); - + System.out.print(group.getPilot().getCurrentTime() + " - "); - + for(RiverBasin riverBasin : group.getEnvironment().getRiverBasins()){ // before the party !!!! @@ -145,10 +146,10 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG if (fishInBasin != null){ //Initiate the total fluxes for this basin - Map<fluxOrigin, Map<String, Double>> totalInputFluxes = new Hashtable<fluxOrigin, Map <String, Double>>(); //On cr�er la Map pour stocker les flux - totalInputFluxes.put(fluxOrigin.AUTOCHTONOUS, new Hashtable < String, Double>()); - totalInputFluxes.put(fluxOrigin.ALLOCHTONOUS, new Hashtable < String, Double>()); - for (fluxOrigin origin: totalInputFluxes.keySet()) { + Map<SpawnerOrigin, Map<String, Double>> totalInputFluxes = new Hashtable<SpawnerOrigin, Map <String, Double>>(); //On cr�er la Map pour stocker les flux + totalInputFluxes.put(SpawnerOrigin.AUTOCHTONOUS, new Hashtable < String, Double>()); + totalInputFluxes.put(SpawnerOrigin.ALLOCHTONOUS, new Hashtable < String, Double>()); + for (SpawnerOrigin origin: totalInputFluxes.keySet()) { for (String nutrient : group.getNutrientRoutine().getNutrientsOfInterest()) { totalInputFluxes.get(origin).put(nutrient, 0.); // ON MET A JOUR NOTRE map } @@ -243,11 +244,11 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG fish.incNumberOfReproduction(); // origin of the spwaner - fluxOrigin spawnerOrigin; + SpawnerOrigin spawnerOrigin; if (fish.getBirthBasin() == riverBasin) - spawnerOrigin = fluxOrigin.AUTOCHTONOUS; + spawnerOrigin = SpawnerOrigin.AUTOCHTONOUS; else - spawnerOrigin = fluxOrigin.ALLOCHTONOUS; + spawnerOrigin = SpawnerOrigin.ALLOCHTONOUS; // survival after reproduction (semelparity or iteroparity) of SI (change the amount of the SI) double biomass = 0.; @@ -258,17 +259,27 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG // compute nutrient fluxes if (survivalAmount > 0) {// SUperindividu est encore vivant mais il perd des effectifs - //Export for fishes survived after spawning (survivalAmount) : excretion + gametes + //Export for one fish survived after spawning (survivalAmount) : excretion + gametes Map <String, Double> aFluxAfterSurvival = group.getNutrientRoutine().computeNutrientsInputForSurvivalAfterSpawning(fish); - //Export for fishes that dies after spawning (fish.getAmount - survivalAmount): excretion + gametes + carcasse + //Export for one fish that dies after spawning (fish.getAmount - survivalAmount): excretion + gametes + carcasse Map<String, Double> aFluxForDeadFish = group.getNutrientRoutine().computeNutrientsInputForDeathAfterSpawning(fish); for (String nutrient: aFluxAfterSurvival.keySet()) { - //For survival fish + //For all survival fish + group.getNutrientRoutine().getNutrientFluxesCollection(). + put(Time.getYear(group.getPilot()), nutrient, fish.getBirthBasin().getName(), riverBasin.getName(), aFluxAfterSurvival.get(nutrient) * survivalAmount); + + //For all dead fish + group.getNutrientRoutine().getNutrientFluxesCollection(). + put(Time.getYear(group.getPilot()), nutrient, fish.getBirthBasin().getName(), riverBasin.getName(), aFluxForDeadFish.get(nutrient) * (fish.getAmount() - survivalAmount)); + + } + for (String nutrient: aFluxAfterSurvival.keySet()) { + //For all survival fish totalInputFluxes.get(spawnerOrigin).put(nutrient,totalInputFluxes.get(spawnerOrigin).get(nutrient) + aFluxAfterSurvival.get(nutrient) * survivalAmount); - //For dead fish + //For all dead fish totalInputFluxes.get(spawnerOrigin).put(nutrient,totalInputFluxes.get(spawnerOrigin).get(nutrient) + aFluxForDeadFish.get(nutrient) * (fish.getAmount() - survivalAmount)); } @@ -283,11 +294,12 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG //Le superindividu est mort !!! deadFish.add(fish); - //Export for fished died before spawning (fish.getAmount): carcasses + excretion + gametes - Map<String, Double> aFlux = group.getNutrientRoutine().computeNutrientsInputForDeathAfterSpawning(fish); // + //Export for fished died after spawning (fish.getAmount): carcasses + excretion + gametes + Map<String, Double> aFluxForDeadFish = group.getNutrientRoutine().computeNutrientsInputForDeathAfterSpawning(fish); // - for (String nutrient: aFlux.keySet()) { - totalInputFluxes.get(spawnerOrigin).put(nutrient,totalInputFluxes.get(spawnerOrigin).get(nutrient) + aFlux.get(nutrient) * fish.getAmount()); //Fish.getAmount - survivalAmount = total fishes died. + for (String nutrient: aFluxForDeadFish.keySet()) { + group.getNutrientRoutine().getNutrientFluxesCollection(). + put(Time.getYear(group.getPilot()), nutrient, fish.getBirthBasin().getName(), riverBasin.getName(), aFluxForDeadFish.get(nutrient) * (fish.getAmount() - survivalAmount)); } biomass = group.getNutrientRoutine().getWeight(fish) * (fish.getAmount()); totalInputFluxes.get(spawnerOrigin).put("biomass", totalInputFluxes.get(spawnerOrigin).get("biomass") + biomass); @@ -514,7 +526,7 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG BufferedWriter bW = group.getbWForFluxes(); if ( bW != null) { try { - for (fluxOrigin origin : totalInputFluxes.keySet()) { + for (SpawnerOrigin origin : totalInputFluxes.keySet()) { bW.write(group.getPilot().getCurrentTime() + "; " + Time.getYear(group.getPilot()) + ";" + Time.getSeason(group.getPilot()) +";"+ riverBasin.getName() + ";" + fluxBefore + ";" + "IMPORT"+ ";" + origin); bW.write(";" + totalInputFluxes.get(origin).get("biomass")); @@ -540,7 +552,7 @@ public class ReproduceAndSurviveAfterReproductionWithDiagnose extends AquaNismsG riverBasin.getSpawnerOrigins().push(spawnerOriginsDuringReproduction); //System.out.println(" AFTER " +riverBasin.getSpawnerOrigins().keySet()); } - System.out.println(); + System.out.println(); // -------------------------------------------------------------------------------------------------- // update the observers diff --git a/src/main/java/species/Survive.java b/src/main/java/species/Survive.java index 2c693731cb7ece42ceea2867305383133d5a3f58..fe3c127d66a8b91f88ad703b4175e9f9238785b0 100644 --- a/src/main/java/species/Survive.java +++ b/src/main/java/species/Survive.java @@ -1,8 +1,12 @@ package species; +import java.io.BufferedWriter; +import java.io.IOException; import java.util.ArrayList; +import java.util.Hashtable; import java.util.List; +import java.util.Map; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; @@ -13,6 +17,7 @@ import environment.Time; import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess; import miscellaneous.Miscellaneous; +import species.DiadromousFish.SpawnerOrigin; import org.openide.util.lookup.ServiceProvider; @@ -28,53 +33,101 @@ public class Survive extends AquaNismsGroupProcess<DiadromousFish, DiadromousFis public double mortalityRateInSea = 0.4; public double mortalityRateInOffshore = 0.4; + + public static void main(String[] args) { System.out.println((new XStream(new DomDriver())) .toXML(new Survive())); } @Override public void doProcess(DiadromousFishGroup group) { - + double survivalProbability=1.; List<DiadromousFish> deadFish = new ArrayList<DiadromousFish>(); - long survivalAmount; + long survivalAmount; + long deathAmount; + + Map<SpawnerOrigin, Map<String, Double>> totalInputFluxes = new Hashtable<SpawnerOrigin, Map <String, Double>>(); //On cr�er la Map pour stocker les flux + totalInputFluxes.put(SpawnerOrigin.AUTOCHTONOUS, new Hashtable < String, Double>()); + totalInputFluxes.put(SpawnerOrigin.ALLOCHTONOUS, new Hashtable < String, Double>()); + + for (SpawnerOrigin origin: totalInputFluxes.keySet()) { + for (String nutrient : group.getNutrientRoutine().getNutrientsOfInterest()) { + totalInputFluxes.get(origin).put(nutrient, 0.); // ON MET A JOUR NOTRE map + } + totalInputFluxes.get(origin).put("biomass",0.); + } for(Basin basin : group.getEnvironment().getBasins()){ - if (basin.getFishs(group)!=null) for(DiadromousFish fish : basin.getFishs(group)){ - survivalProbability = 1.; - //Survive - if(fish.getPosition().getType() == TypeBassin.RIVER && fish.isMature()){ - //double tempEffectSurv = Miscellaneous.temperatureEffect(fish.getPosition().getCurrentTemperature(group.getPilot()), tempMinSurvivalSpawnerInRiv, tempOptSurvivalSpawnerInRiv, tempMaxSurvivalSpawnerInRiv); - double tempEffectSurv = Miscellaneous.rectangularTemperatureEffect(fish.getPosition().getCurrentTemperature(group.getPilot()), tempMinSurvivalSpawnerInRiv, tempMaxSurvivalSpawnerInRiv); - if (tempEffectSurv == 0.){ - survivalProbability = 0.; - //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() +" a un coeff de mortalit� de " + fish.getMortalityRateInRiver() + " mais � cause de la temp�rature une prob de survie de " + survivalProbability); - }else{ - survivalProbability = survivalProbOptSpawnerInRiv * tempEffectSurv; - //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() + " a un coeff de mortalit� de " + fish.getMortalityRateInRiver() + " et donc une prob de survie de " + survivalProbability); - } - }else if (fish.getPosition().getType() == TypeBassin.SEA){ - survivalProbability = Math.exp(-mortalityRateInSea * Time.getSeasonDuration()); - //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() + " a un coeff de mortalit� de " + fish.getMortalityRateInSea() + " et donc une prob de survie de " + survivalProbability); - }else if (fish.getPosition().getType() == TypeBassin.OFFSHORE){ - survivalProbability = Math.exp(-mortalityRateInOffshore * Time.getSeasonDuration()); - //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() + " a un coeff de mortalit� de " + fish.getMortalityRateInOffshore() + " et donc une prob de survie de " + survivalProbability); - }else{ + + if (basin.getFishs(group)!=null) { + for(DiadromousFish fish : basin.getFishs(group)){ + survivalProbability = 1.; - } + //Compute the survival probability according to the fish position + if(fish.getPosition().getType() == TypeBassin.RIVER && fish.isMature()){ //Survive in river before spawning + - if (survivalProbability<1.){ - survivalAmount = Miscellaneous.binomialForSuperIndividual(group.getPilot(), fish.getAmount(), survivalProbability); + //double tempEffectSurv = Miscellaneous.temperatureEffect(fish.getPosition().getCurrentTemperature(group.getPilot()), tempMinSurvivalSpawnerInRiv, tempOptSurvivalSpawnerInRiv, tempMaxSurvivalSpawnerInRiv); + double tempEffectSurv = Miscellaneous.rectangularTemperatureEffect(fish.getPosition().getCurrentTemperature(group.getPilot()), tempMinSurvivalSpawnerInRiv, tempMaxSurvivalSpawnerInRiv); + if (tempEffectSurv == 0.){ + survivalProbability = 0.; + //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() +" a un coeff de mortalit� de " + fish.getMortalityRateInRiver() + " mais � cause de la temp�rature une prob de survie de " + survivalProbability); + }else{ + survivalProbability = survivalProbOptSpawnerInRiv * tempEffectSurv; + //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() + " a un coeff de mortalit� de " + fish.getMortalityRateInRiver() + " et donc une prob de survie de " + survivalProbability); + } + //TODO:add nutrientFluxesRoutine - if (survivalAmount > 0) - fish.setAmount(survivalAmount); - else - deadFish.add(fish); - } + }else if (fish.getPosition().getType() == TypeBassin.SEA){ //Survive at sea + survivalProbability = Math.exp(-mortalityRateInSea * Time.getSeasonDuration()); + //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() + " a un coeff de mortalit� de " + fish.getMortalityRateInSea() + " et donc une prob de survie de " + survivalProbability); + + }else if (fish.getPosition().getType() == TypeBassin.OFFSHORE){ //Survive offshore + survivalProbability = Math.exp(-mortalityRateInOffshore * Time.getSeasonDuration()); + //System.out.println("le poisson situ� dans le bassin " + fish.getPosition().getName() + " en " + Time.getSeason() + " a un coeff de mortalit� de " + fish.getMortalityRateInOffshore() + " et donc une prob de survie de " + survivalProbability); + + }else{ + survivalProbability = 1.; + } + //Compute survival amount in the SI for one fish whatever its position + deathAmount = 0L; + if (survivalProbability<1.){ + survivalAmount = Miscellaneous.binomialForSuperIndividual(group.getPilot(), fish.getAmount(), survivalProbability); + deathAmount = fish.getAmount() - survivalAmount; + + if (survivalAmount > 0) + fish.setAmount(survivalAmount); + else + deadFish.add(fish); + + if (deathAmount > 0L && fish.getPosition().getType() == TypeBassin.RIVER) { //Compute the fluxes for dead fish in river in the SI. + + SpawnerOrigin spawnerOrigin; + if (fish.getBirthBasin() == basin) + spawnerOrigin = SpawnerOrigin.AUTOCHTONOUS; + else + spawnerOrigin = SpawnerOrigin.ALLOCHTONOUS; + + Map<String, Double> aFluxForDeadFishBeforeSpawning = group.getNutrientRoutine().computeNutrientsInputForDeathBeforeSpawning(fish); // + + for (String nutrient: aFluxForDeadFishBeforeSpawning.keySet()) { + group.getNutrientRoutine().getNutrientFluxesCollection(). + put(Time.getYear(group.getPilot()), nutrient, fish.getBirthBasin().getName(), basin.getName(), aFluxForDeadFishBeforeSpawning.get(nutrient) * deathAmount); + } + } + } + }//end on loop of fish } - } - for (DiadromousFish fish : deadFish){ - group.removeAquaNism(fish); - } - } -} + for (DiadromousFish fish : deadFish){ + group.removeAquaNism(fish); + } + + } //end loop on basin + + + }//end of doprocess +}//end of class + + + diff --git a/src/main/java/species/ExportBiomass.java b/src/main/java/species/WriteBiomassFluxes.java similarity index 76% rename from src/main/java/species/ExportBiomass.java rename to src/main/java/species/WriteBiomassFluxes.java index c4b8318a180da0e674088e2db3542df62726cfb3..f7418b931b9f8cad4a395dab16e307f597caaebf 100644 --- a/src/main/java/species/ExportBiomass.java +++ b/src/main/java/species/WriteBiomassFluxes.java @@ -24,12 +24,12 @@ import species.ReproduceAndSurviveAfterReproductionWithDiagnose; /** * */ -public class ExportBiomass extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> { +public class WriteBiomassFluxes extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> { + - private double survivalRateAfterReproduction = 0.1; private Season exportSeason = Season.SPRING; - private String fileNameOutput = "BiomassFluxes"; + private String fileNameOutput = "biomassFluxes"; private transient BufferedWriter bW; private transient String sep=";"; @@ -37,7 +37,7 @@ public class ExportBiomass extends AquaNismsGroupProcess<DiadromousFish, Diadrom public static void main(String[] args) { System.out.println((new XStream(new DomDriver())) - .toXML(new ExportBiomass())); + .toXML(new WriteBiomassFluxes())); } /* (non-Javadoc) @@ -66,7 +66,7 @@ public class ExportBiomass extends AquaNismsGroupProcess<DiadromousFish, Diadrom } bW.write("\n"); - + } catch (IOException e) { e.printStackTrace(); } @@ -79,26 +79,21 @@ public class ExportBiomass extends AquaNismsGroupProcess<DiadromousFish, Diadrom for (RiverBasin migrationBasin : group.getEnvironment().getRiverBasins()) { //Create the map to get the biomass in each birth basin - Map<String, Double> spawnerOriginsBeforeReproduction = new HashMap<String, Double>(group.getEnvironment().getRiverBasinNames().length); + Map<String, Double> spawnerAbundancesPerOrigin = new HashMap<String, Double>(group.getEnvironment().getRiverBasinNames().length); for (String basinName : group.getEnvironment().getRiverBasinNames()){ - spawnerOriginsBeforeReproduction.put(basinName, 0.); + spawnerAbundancesPerOrigin.put(basinName, 0.); } double biomass=0.; //compute the cumulative effective per birth basin if (migrationBasin.getFishs(group) != null) { - + for (DiadromousFish fish : migrationBasin.getFishs(group)) { - - double survivalAmount = Miscellaneous.binomialForSuperIndividual(group.getPilot(), fish.getAmount(), survivalRateAfterReproduction); - biomass = group.getNutrientRoutine().getWeight(fish) * (fish.getAmount() - survivalAmount); - + if (fish.getStage() == Stage.MATURE) { + biomass = group.getNutrientRoutine().getWeight(fish) * fish.getAmount(); String birthBasinName = fish.getBirthBasin().getName(); - spawnerOriginsBeforeReproduction.put(birthBasinName, spawnerOriginsBeforeReproduction.get(birthBasinName) + biomass); - - + spawnerAbundancesPerOrigin.put(birthBasinName, spawnerAbundancesPerOrigin.get(birthBasinName) + biomass); } - } } @@ -107,7 +102,7 @@ public class ExportBiomass extends AquaNismsGroupProcess<DiadromousFish, Diadrom //write the cumulative effective from birth basin for (String birthBasinName : group.getEnvironment().getRiverBasinNames()) { - bW.write(sep+spawnerOriginsBeforeReproduction.get(birthBasinName)); + bW.write(sep+spawnerAbundancesPerOrigin.get(birthBasinName)); } //write an end-of(line bW.write("\n"); diff --git a/src/main/java/species/ExportFluxes.java b/src/main/java/species/WriteEffectivesFluxes.java similarity index 96% rename from src/main/java/species/ExportFluxes.java rename to src/main/java/species/WriteEffectivesFluxes.java index a258ba0c0775d044b248dca5979c316d4846e18a..7732c8038119a17dcfbe12e796c2bab4a6990a92 100644 --- a/src/main/java/species/ExportFluxes.java +++ b/src/main/java/species/WriteEffectivesFluxes.java @@ -39,7 +39,7 @@ import species.DiadromousFish.Stage; /** * */ -public class ExportFluxes extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> { +public class WriteEffectivesFluxes extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> { private Season exportSeason = Season.SPRING; @@ -50,7 +50,7 @@ public class ExportFluxes extends AquaNismsGroupProcess<DiadromousFish, Diadromo public static void main(String[] args) { System.out.println((new XStream(new DomDriver())) - .toXML(new ExportFluxes())); + .toXML(new WriteEffectivesFluxes())); } /* (non-Javadoc) @@ -88,7 +88,6 @@ public class ExportFluxes extends AquaNismsGroupProcess<DiadromousFish, Diadromo try { if (Time.getSeason(pilot) == exportSeason & Time.getYear(pilot)>1900) { - for (RiverBasin migrationBasin : group.getEnvironment().getRiverBasins()) { //Create the map to get the abundance in each birth basin Map<String, Long> spawnerOriginsBeforeReproduction = new HashMap<String, Long>(group.getEnvironment().getRiverBasinNames().length); diff --git a/src/main/java/species/WriteImportNutrientFluxes.java b/src/main/java/species/WriteImportNutrientFluxes.java new file mode 100644 index 0000000000000000000000000000000000000000..8a09e9fd39665f2f1638413a3f79925d48beeb0a --- /dev/null +++ b/src/main/java/species/WriteImportNutrientFluxes.java @@ -0,0 +1,78 @@ +package species; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.DomDriver; + +import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess; + +public class WriteImportNutrientFluxes extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> { + + private String fileName= "fluxes"; + + + + public static void main(String[] args) { + System.out.println((new XStream(new DomDriver())) + .toXML(new WriteImportNutrientFluxes())); + + } + + @Override + public void doProcess(DiadromousFishGroup group) { + + BufferedWriter bW; + + String outputPath = "data/output/" ; + String sep = ";"; + new File(outputPath + fileName).getParentFile().mkdirs(); + try { + bW = new BufferedWriter(new FileWriter(new File(outputPath+ + fileName + group.getSimulationId() + ".csv"))); + + bW.write("year"+sep+"nutrient" + sep + "originBasin"); + + for (String birthBasinName : group.getEnvironment().getRiverBasinNames()) { + bW.write(sep + birthBasinName); // write each basin name in the file + } + + bW.write("\n"); + + Map<Long, Map <String, Map<String, Map<String, Double>>>> fluxesCollection = group.getNutrientRoutine().getNutrientFluxesCollection().getFluxesCollection(); + + for (long year : fluxesCollection.keySet()) { + + Map <String, Map<String, Map<String, Double>>> yearsMap = fluxesCollection.get(year); + + for (String nutrient : yearsMap.keySet()) { + + Map<String, Map<String, Double>> originsMap = yearsMap.get(nutrient); + + for (String originBasinName : originsMap.keySet()) { + + Map<String, Double> destinationsMap = originsMap.get(originBasinName); + + for (String destinationBasinName : destinationsMap.keySet()) { + + Double aFlux = destinationsMap.get(destinationBasinName); + + bW.write(year + sep+ nutrient + sep + originBasinName + sep + aFlux + "\n"); + } + } + } + } + bW.flush(); + bW.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + +}