Commit 44552ff8 authored by patrick.lambert's avatar patrick.lambert
Browse files

move observers from DiadromousFishGroup to AnalyseFishDistribution

parent 5ffb84c5
<hashtable>
<entry>
<!--
<java-class>fr.cemagref.simaqualife.kernel.AquaticWorld</java-class>-->
<!-- <java-class>fr.cemagref.simaqualife.kernel.AquaticWorld</java-class> -->
<java-class>environment.RIOBasinNetworkWithContinent</java-class>
<fr.cemagref.observation.kernel.ObservablesHandler>
<observers>
<environment.RIOBasinNetworkObserverWithContinent>
......@@ -27,29 +25,20 @@
<observers>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Number of colonized
basins
</title>
<title>Number of populated basins</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>number of basins</yAxisLabel>
<variableName>getNbColonizedBasins</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Total Abundance</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>number of fishes</yAxisLabel>
<variableName>getFishEffective</variableName>
<yAxisLabel>Number of basins</yAxisLabel>
<variableName>getNbPopulatedBasins</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Abundance of spawners</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>number
of fishes
</yAxisLabel>
<yAxisLabel>Number of fish</yAxisLabel>
<variableName>getSpawnerEffective</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Abundance of male spawners</title>
......@@ -57,69 +46,68 @@
<yAxisLabel>number of fishes</yAxisLabel>
<variableName>getMaleSpawnerEffective</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Abundance of female spawners</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>number
of fishes
</yAxisLabel>
<yAxisLabel>number of fishes </yAxisLabel>
<variableName>getFemaleSpawnerEffective</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<observer.TemporalRangeSerieChart>
<title>Range distribution</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>latitude</yAxisLabel>
<variableName>getRangeDistributionWithLat</variableName>
<variableName>getRangeSpawnerDistributionWithLat</variableName>
</observer.TemporalRangeSerieChart>
</observers>
</fr.cemagref.observation.kernel.ObservablesHandler>
</entry>
<entry>
<java-class>analysis.AnalyseFishDistribution</java-class>
<fr.cemagref.observation.kernel.ObservablesHandler>
<observers>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Mean age at first reproduction for female</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>age (year)</yAxisLabel>
<variableName>getMeanAgeOfFirstReprodutionForFemale</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Mean age at first reproduction
for male
</title>
<title>Number of colonized basins</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>age (year)</yAxisLabel>
<variableName>getMeanAgeOfFirstReprodutionForMale</variableName>
<yAxisLabel>Number of basins</yAxisLabel>
<variableName>getNbColonizedBasins</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Statistic for male spawners age</title>
<title>Abundance of spawners</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel></yAxisLabel>
<variableName>computeMaleSpawnerForFirstTimeSummaryStatistic</variableName>
<yAxisLabel>Number of fishes</yAxisLabel>
<variableName>getSpawnerEffective</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Statistic for female
spawners age
</title>
<title>Abundance of male spawners</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel></yAxisLabel>
<variableName>computeFemaleSpawnerForFirstTimeSummaryStatistic</variableName>
<yAxisLabel>number of fishes</yAxisLabel>
<variableName>getMaleSpawnerEffective</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Mean length at first reproduction for female</title>
<title>Abundance of female spawners</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>length (cm)</yAxisLabel>
<variableName>getMeanLengthOfFirstReprodutionForFemale</variableName>
<yAxisLabel>number of fishes </yAxisLabel>
<variableName>getFemaleSpawnerEffective</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<graphType>LINE</graphType>
<title>Mean length at first
reproduction for male
</title>
<observer.TemporalRangeSerieChart>
<title>Range distribution</title>
<xAxisLabel>Time (season)</xAxisLabel>
<yAxisLabel>length (cm)</yAxisLabel>
<variableName>getMeanLengthOfFirstReprodutionForMale</variableName>
</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
<yAxisLabel>latitude</yAxisLabel>
<variableName>getRangeDistributionWithLat</variableName>
</observer.TemporalRangeSerieChart>
</observers>
</fr.cemagref.observation.kernel.ObservablesHandler>
</entry>
......@@ -136,6 +124,7 @@
<yAxisLabel>number of juveniles</yAxisLabel>
<variableName>getJuvenileNumber</variableName>
</observer.TemporalSerieChartForBasin>
<observer.TemporalSerieChartForBasin>
<graphType>LINE</graphType>
<title>% Autochtone</title>
......
......@@ -20,7 +20,52 @@
</fr.cemagref.observation.kernel.ObservablesHandler>
</entry>
<entry>
<java-class>species.AnalyseSpawnerRun</java-class>
<java-class>analysis.AnalyseFishDistribution</java-class>
<fr.cemagref.observation.kernel.ObservablesHandler>
<observers>
<!-- <fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <graphType>LINE</graphType> -->
<!-- <title>Number of populated basins</title> -->
<!-- <xAxisLabel>Time (season)</xAxisLabel> -->
<!-- <yAxisLabel>Number of basins</yAxisLabel> -->
<!-- <variableName>getNbPopulatedBasins</variableName> -->
<!-- </fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <graphType>LINE</graphType> -->
<!-- <title>Abundance of spawners</title> -->
<!-- <xAxisLabel>Time (season)</xAxisLabel> -->
<!-- <yAxisLabel>Number of fish</yAxisLabel> -->
<!-- <variableName>getSpawnerEffective</variableName> -->
<!-- </fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <graphType>LINE</graphType> -->
<!-- <title>Abundance of male spawners</title> -->
<!-- <xAxisLabel>Time (season)</xAxisLabel> -->
<!-- <yAxisLabel>number of fishes</yAxisLabel> -->
<!-- <variableName>getMaleSpawnerEffective</variableName> -->
<!-- </fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <graphType>LINE</graphType> -->
<!-- <title>Abundance of female spawners</title> -->
<!-- <xAxisLabel>Time (season)</xAxisLabel> -->
<!-- <yAxisLabel>number of fishes </yAxisLabel> -->
<!-- <variableName>getFemaleSpawnerEffective</variableName> -->
<!-- </fr.cemagref.observation.observers.jfreechart.TemporalSerieChart> -->
<!-- <observer.TemporalRangeSerieChart> -->
<!-- <title>Range distribution</title> -->
<!-- <xAxisLabel>Time (season)</xAxisLabel> -->
<!-- <yAxisLabel>latitude</yAxisLabel> -->
<!-- <variableName>getRangeSpawnerDistributionWithLat</variableName> -->
<!-- </observer.TemporalRangeSerieChart> -->
</observers>
</fr.cemagref.observation.kernel.ObservablesHandler>
</entry>
<entry>
<java-class>analysis.AnalyseSpawnerRun</java-class>
<fr.cemagref.observation.kernel.ObservablesHandler>
<observers>
<observer.RecordDuoChart>
......@@ -41,6 +86,5 @@
</observers>
</fr.cemagref.observation.kernel.ObservablesHandler>
</entry>
</hashtable>
\ No newline at end of file
......@@ -251,7 +251,7 @@
</species.MigrateFromOffshoreToInshore>
<species.DisperseAndMigrateToRiverWithMultiNomDistriAndDeathBasin>
<riverMigrationSeason>SPRING</riverMigrationSeason>
<riverMigrationSeason>SPRING</riverMigrationSeason>
<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
<alpha0Rep>-40.8</alpha0Rep>
<alpha1Rep>35.8</alpha1Rep>
......@@ -291,8 +291,7 @@
<analysis.AnalyseFishDistribution>
<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
<analysisSeason>SPRING</analysisSeason>
<memorySize>30</memorySize>
<centileForRange>0.95</centileForRange>
<minimumRecruitsForPopulatedBasin>50</minimumRecruitsForPopulatedBasin>
</analysis.AnalyseFishDistribution>
......@@ -322,11 +321,12 @@
<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
<afterReproductionSeason>SUMMER</afterReproductionSeason>
<maximalSurvivalRate>0.1</maximalSurvivalRate>
<!-- <temperatureEffectSurvivalAfterReproduction class="temperatureEffect.LogitEffect"> -->
<!-- <Tref>19.9</Tref> -->
<!-- <alpha>-.1</alpha> -->
<!-- </temperatureEffectSurvivalAfterReproduction> -->
<temperatureEffectSurvivalAfterReproduction class="temperatureEffect.NoEffect">
<!-- <temperatureEffectSurvivalAfterReproduction class="temperatureEffect.LogitEffect"> -->
<!-- <Tref>19.9</Tref> -->
<!-- <alpha>-.1</alpha> -->
<!-- </temperatureEffectSurvivalAfterReproduction> -->
<temperatureEffectSurvivalAfterReproduction
class="temperatureEffect.NoEffect">
</temperatureEffectSurvivalAfterReproduction>
</species.SurviveAfterReproduction>
......
......@@ -19,19 +19,16 @@
*/
package analysis;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import environment.RIOBasinNetwork;
import environment.RiverBasin;
import environment.Time.Season;
import fr.cemagref.observation.kernel.Observable;
import fr.cemagref.observation.kernel.ObservablesHandler;
import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
import fr.cemagref.simaqualife.pilot.Pilot;
import miscellaneous.QueueMemory;
import miscellaneous.TreeMapForCentile;
import observer.ObservableRecord;
import species.DiadromousFish;
......@@ -42,9 +39,12 @@ import species.DiadromousFishGroup;
*/
public class AnalyseFishDistribution extends AquaNismsGroupProcess<DiadromousFish, DiadromousFishGroup> {
private Season analysisSeason = Season.SPRING;
private int memorySize = 30;
/**
* centile to calculate the nothernmost range of species distribution
*
* @unit
*/
public double centileForRange = 0.95;
/**
* The minimum number of recruits to consider a basin as populated
......@@ -59,48 +59,187 @@ public class AnalyseFishDistribution extends AquaNismsGroupProcess<DiadromousFis
private transient double northernLimit;
private transient Map<RiverBasin, QueueMemory<Double>> lastSpawnerNumbersMemory;
private transient RiverBasin[] riverBasins;
protected static transient ObservablesHandler cobservable;
@Override
public void initTransientParameters(Pilot pilot) {
super.initTransientParameters(pilot);
// records = new ArrayList<FishDistributionRecord>();
// keep the river basins
riverBasins = ((RIOBasinNetwork) pilot.getAquaticWorld().getEnvironment()).getRiverBasins();
// define the latitude range of basin network
southernLimit = 90.;
northernLimit = -90.;
for (RiverBasin riverBasin : ((RIOBasinNetwork) pilot.getAquaticWorld().getEnvironment()).getRiverBasins()) {
for (RiverBasin riverBasin : riverBasins) {
southernLimit = Math.min(southernLimit, riverBasin.getLatitude());
northernLimit = Math.max(northernLimit, riverBasin.getLatitude());
}
// add this class to observable list
cobservable = pilot.addObservable(this.getClass());
}
@Override
public void doProcess(DiadromousFishGroup group) {
// first passage
if (lastSpawnerNumbersMemory == null) {
lastSpawnerNumbersMemory = new HashMap<RiverBasin, QueueMemory<Double>>();
for (RiverBasin riverBasin : group.getEnvironment().getRiverBasins()) {
lastSpawnerNumbersMemory.put(riverBasin, new QueueMemory<>(memorySize));
// update observer once a year in automn
if (group.getEnvironment().getTime().getSeason(group.getPilot()) == Season.AUTOMN)
cobservable.fireChanges(this, group.getPilot().getCurrentTime());
}
// ========================================================
// observer to explore fish abundance
// ========================================================
/**
* @return sum of spawner effectives on spawning grounds in all river basins
*/
@Observable(description = "Number of spawners on spawning grounds")
public double getSpawnerEffective() {
double eff = 0;
for (RiverBasin riverBasin : riverBasins) {
eff += riverBasin.getLastFemaleSpawnerNumber() + riverBasin.getLastMaleSpawnerNumber();
}
return eff;
}
/**
* @return sum of female spawner effectives on spawning grounds in all river basins
*/
@Observable(description = "Number of spawners on spawning grounds")
public double getFemaleSpawnerEffective() {
double eff = 0;
for (RiverBasin riverBasin : riverBasins) {
eff += riverBasin.getLastFemaleSpawnerNumber();
}
return eff;
}
/**
* @return sum of male spawner effectives on spawning grounds in all river basins
*/
@Observable(description = "Number of spawners on spawning grounds")
public double getMaleSpawnerEffective() {
double eff = 0;
for (RiverBasin riverBasin : riverBasins) {
eff += riverBasin.getLastMaleSpawnerNumber();
}
return eff;
}
// ========================================================
// observer to explore fish distribution
// ========================================================
@Observable(description = "Number of colonized basins")
public double getNbPopulatedBasins() {
int nb = 0;
for (RiverBasin riverBasin : riverBasins) {
if (riverBasin.getLastRecruitments().getMean() >= minimumRecruitsForPopulatedBasin)
nb++;
}
return nb;
}
@Observable(description = "Northernmost populated latitude")
public double getNorthernmostPopulatedLatitude() {
double latitude = southernLimit;
for (RiverBasin riverBasin : riverBasins) {
double meanLastRecruitment = riverBasin.getLastRecruitments().getMean();
if (meanLastRecruitment >= minimumRecruitsForPopulatedBasin) {
// the river basin is considered populated
// northern edge
if (riverBasin.getLatitude() > latitude) {
// the basin is the new northern edge
latitude = riverBasin.getLatitude();
}
}
}
return latitude;
}
@Observable(description = "Southernmost populated latitude")
public double getSouthernmostPopulatedLatitude() {
double latitude = northernLimit;
for (RiverBasin riverBasin : riverBasins) {
double meanLastRecruitment = riverBasin.getLastRecruitments().getMean();
if (meanLastRecruitment >= minimumRecruitsForPopulatedBasin) {
// the river basin is considered populated
// northern edge
if (riverBasin.getLatitude() < latitude) {
// the basin is the new southern edge
latitude = riverBasin.getLatitude();
}
}
}
return latitude;
}
// if (records == null)
// initTransientParameters(group.getPilot());
if (group.getEnvironment().getTime().getSeason(group.getPilot()) == analysisSeason) {
for (RiverBasin riverBasin : group.getEnvironment().getRiverBasins()) {
double fluxBefore = riverBasin.getSpawnerNumberPerGroup(group);
@Observable(description = "latitude range of spawner distribution")
public Double[] getRangeSpawnerDistributionWithLat() {
lastSpawnerNumbersMemory.get(riverBasin).push(fluxBefore);
TreeMapForCentile latitudeEffective = new TreeMapForCentile();
double southernLatitude = northernLimit;
double northernLatitude = southernLimit;
// loop over riverBasin
for (RiverBasin riverBasin : riverBasins) {
long effective = (long) (riverBasin.getLastFemaleSpawnerNumber() + riverBasin.getLastMaleSpawnerNumber());
if (effective > 0) {
latitudeEffective.putWithAdding(riverBasin.getLatitude(), effective);
if (riverBasin.getLatitude() < southernLatitude)
southernLatitude = riverBasin.getLatitude();
if (riverBasin.getLatitude() > northernLatitude)
northernLatitude = riverBasin.getLatitude();
}
}
// compute result
// (y, y-low, y-high) data item
Double[] rangeDistribution = new Double[4];
if (!latitudeEffective.isEmpty()) {
// median
rangeDistribution[0] = latitudeEffective.calculateMedian();
// southern
rangeDistribution[1] = southernLatitude;
// northern
rangeDistribution[2] = northernLatitude;
// centile
rangeDistribution[3] = latitudeEffective.calculateCentile(centileForRange);
} else {
// median
rangeDistribution[0] = (southernLatitude + northernLatitude) / 2.;
// southern
rangeDistribution[1] = rangeDistribution[0];
// northern
rangeDistribution[2] = rangeDistribution[0];
// centile
rangeDistribution[3] = rangeDistribution[0];
}
return rangeDistribution;
}
// ======================================
// export to R
// ============================================
public String[][] exportToR() {
// initialise the distribution range
......@@ -117,35 +256,35 @@ public class AnalyseFishDistribution extends AquaNismsGroupProcess<DiadromousFis
TreeMapForCentile latitudePresence = new TreeMapForCentile();
String[][] export = new String[2][6];
int i = 0;
for (Entry<RiverBasin, QueueMemory<Double>> entry : lastSpawnerNumbersMemory.entrySet()) {
if (entry.getValue().getMean() > minimumRecruitsForPopulatedBasin) {
for (RiverBasin riverBasin : riverBasins) {
double meanLastRecruitment = riverBasin.getLastRecruitments().getMean();
if (meanLastRecruitment >= minimumRecruitsForPopulatedBasin) {
// the river basin is considered populated
// NOTE : recruiit number is calulated after thermal tolerance impact
// (which is intreaged in the stock-recruitment relationship)
// southern edge
if (entry.getKey().getLatitude() < southernEdge) {
if (riverBasin.getLatitude() < southernEdge) {
// the basin is the new southern edge
southernEdge = entry.getKey().getLatitude();
southernId = entry.getKey().getBasin_id();
southernName = entry.getKey().getName();
southernEdge = riverBasin.getLatitude();
southernId = riverBasin.getBasin_id();
southernName = riverBasin.getName();
}
// northern edge
if (entry.getKey().getLatitude() > northernEdge) {
if (riverBasin.getLatitude() > northernEdge) {
// the basin is the new northern edge
northernEdge = entry.getKey().getLatitude();
northernId = entry.getKey().getBasin_id();
northernName = entry.getKey().getName();
northernEdge = riverBasin.getLatitude();
northernId = riverBasin.getBasin_id();
northernName = riverBasin.getName();
}
// for distribution centroide computation
latitudePresence.putWithAdding(entry.getKey().getLatitude(), 1L);
long effective = ((Double) entry.getValue().getMean()).longValue();
latitudeEffective.putWithAdding(entry.getKey().getLatitude(), effective);
latitudePresence.putWithAdding(riverBasin.getLatitude(), 1L);
long effective = ((Double) meanLastRecruitment).longValue();
latitudeEffective.putWithAdding(riverBasin.getLatitude(), effective);
}
}
......@@ -175,6 +314,7 @@ public class AnalyseFishDistribution extends AquaNismsGroupProcess<DiadromousFis
return export;
}
@Deprecated
private class FishDistributionRecord implements ObservableRecord {
@Information(unit = "-")
......
......@@ -826,13 +826,11 @@ public class DiadromousFishGroup extends AquaNismsGroup<DiadromousFish, RIOBasin
if ((finalStates[i] == 1) && (basins[i].getLatitude() > latitude)) {
latitude = basins[i].getLatitude();
}
}
return latitude;
}
@Deprecated
@Observable(description = "Number of colonized basins")
public double getNbColonizedBasins() {
int nb = 0;
......@@ -949,7 +947,7 @@ public class DiadromousFishGroup extends AquaNismsGroup<DiadromousFish, RIOBasin
// observer to explore fish abundance
// ========================================================
/**
* @return sum of effectives in all the river basins
* @return sum of effectives in all river basins
*/
@Observable(description = "Number of fishes in river basin")
public double getFishEffective() {
......@@ -969,6 +967,7 @@ public class DiadromousFishGroup extends AquaNismsGroup<DiadromousFish, RIOBasin
* @return sum of spawner effectives in all the river basins
*/
@Observable(description = "Number of spawners in river basins")
@Deprecated
public double getSpawnerEffective() {
long eff = 0;
for (RiverBasin basin : this.getEnvironment().getRiverBasins()) {
......@@ -984,9 +983,10 @@ public class DiadromousFishGroup extends AquaNismsGroup<DiadromousFish, RIOBasin
/**
* @return sum of male spawner effectives in all the river basins
* @return sum of male spawner effectives in all basins
*/
@Observable(description = "Number of male spawners in all basins")
@Deprecated
public double getMaleSpawnerEffective() {
long eff = 0;
for (Basin basin : this.getEnvironment().getBasins()) {
......@@ -1002,9 +1002,10 @@ public class DiadromousFishGroup extends AquaNismsGroup<DiadromousFish, RIOBasin
/**
* @return sum of female spawner effectives in all the river basins
* @return sum of female spawner effectives in all basins
*/
@Observable(description = "Number of female spawners in all basins")
@Deprecated
public double getFemaleSpawnerEffective() {
long eff = 0;
for (Basin basin : this.getEnvironment().getBasins()) {
......
Markdown is supporte