diff --git a/data/input/northeastamerica/fishRIOBasin_Sapidissima_Rjava.xml b/data/input/northeastamerica/fishRIOBasin_Sapidissima_Rjava.xml
index 177e4b4fd382c5953d1e1f31ba78c3474ed47433..2678c280162c0308b89d371e7ea114427ca5eacf 100644
--- a/data/input/northeastamerica/fishRIOBasin_Sapidissima_Rjava.xml
+++ b/data/input/northeastamerica/fishRIOBasin_Sapidissima_Rjava.xml
@@ -288,7 +288,14 @@
 					<analysisSeason>SPRING</analysisSeason>
 					<memorySize>30</memorySize>
 				</species.AnalyseSpawnerFeatures>
-					
+
+				<species.AnalyseFishDistribution>
+					<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
+					<analysisSeason>SPRING</analysisSeason>
+					<memorySize>30</memorySize>
+					<minimumRecruitsForPopulatedBasin>50</minimumRecruitsForPopulatedBasin>
+				</species.AnalyseFishDistribution>
+
 				<species.ReproduceAndSurviveAfterReproductionWithDiagnose>
 					<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
 					<reproductionSeason>SPRING</reproductionSeason>
@@ -311,11 +318,6 @@
 					<displayFluxesOnConsole>false</displayFluxesOnConsole>
 				</species.ReproduceAndSurviveAfterReproductionWithDiagnose>
 
-				<species.AnalyseFishDistribution>
-					<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
-					<analysisSeason>SPRING</analysisSeason>
-					<minimumRecruitsForPopulatedBasin>50</minimumRecruitsForPopulatedBasin>
-				</species.AnalyseFishDistribution>
 
 				<species.MigrateFromRiverToInshore>
 					<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
@@ -340,11 +342,13 @@
 			</processesEachStep>
 
 			<processesAtEnd>
-				<species.WriteBiomassFluxes>
+				<species.AnalyseLikelihoodOfPresence>
 					<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
-					<exportSeason>SPRING</exportSeason>
-					<fileNameOutput>biomassFluxes</fileNameOutput>
-				</species.WriteBiomassFluxes>
+					<presenceFileName>data/input/northeastamerica/nea_presence.csv</presenceFileName>
+					<period>obs_1900_1950</period>
+					<minimumRecruitsForPopulatedBasin>50</minimumRecruitsForPopulatedBasin>
+					<epsilon>0.001</epsilon>
+				</species.AnalyseLikelihoodOfPresence>
 
 				<species.IdentifyPopulation>
 					<synchronisationMode>ASYNCHRONOUS</synchronisationMode>
diff --git a/src/main/java/miscellaneous/EasyRun.java b/src/main/java/miscellaneous/EasyRun.java
index 2993abe42980a0ab5807bf23603179f67000d4fc..72bc04ca5fcd4b341cca391256bd7421eafda5b4 100644
--- a/src/main/java/miscellaneous/EasyRun.java
+++ b/src/main/java/miscellaneous/EasyRun.java
@@ -16,7 +16,6 @@
  */
 package miscellaneous;
 
-import java.util.Arrays;
 import java.util.List;
 
 import fr.cemagref.simaqualife.extensions.pilot.BatchRunner;
@@ -37,8 +36,8 @@ public class EasyRun {
 			pilot.load();
 
 			// update the simulation parameters
-			ReflectUtils.setFieldValueFromPath(pilot.getAquaticWorld().getAquaNismsGroupsList().get(0),
-					"processes.processesAtEnd.0.fileNameOutput", outputfilename);
+			// ReflectUtils.setFieldValueFromPath(pilot.getAquaticWorld().getAquaNismsGroupsList().get(0),
+			// "processes.processesAtEnd.0.fileNameOutput", outputfilename);
 			for (int i = 0; i < paramNames.length; i++) {
 				ReflectUtils.setFieldValueFromPath(pilot.getAquaticWorld().getAquaNismsGroupsList().get(0), paramNames[i],
 						paramValues[i]);
@@ -75,36 +74,49 @@ public class EasyRun {
 	}
 
 
+	public static double getSingleValueFromAquanismGroupProcess(String targetPath) throws Exception {
+		return (double) ReflectUtils.getValueFromPath(pilot.getAquaticWorld().getAquaNismsGroupsList().get(0), targetPath);
+	}
+
+
 	public static void main(String[] args) throws Exception {
-		String[] batchArguments = ("-simDuration 100 -simBegin 1 -timeStepDuration 1 -RNGStatusIndex 1 "
+		String[] batchArguments = ("-simDuration 150 -simBegin 1 -timeStepDuration 1 -RNGStatusIndex 1 "
 				+ "-groups data/input/northeastamerica/fishRIOBasin_Sapidissima_Rjava.xml "
 				+ "-env data/input/northeastamerica/RIOBNneaBasins_Rjava.xml "
 				+ "-observers data/input/northeastamerica/RIO_obs_empty.xml").split("\\ ");
 
-		String[] parameterNames = new String[] { "processes.processesEachStep.9.tempMinRep",
-				"processes.processesEachStep.9.ratioS95_S50", "processes.processesEachStep.6.pHomingAfterEquil" };
+		String[] parameterNames = new String[] { "processes.processesEachStep.10.tempMinRep",
+				"processes.processesEachStep.10.ratioS95_S50", "processes.processesEachStep.6.pHomingAfterEquil" };
 
 		double[] parameterValues = new double[] { 10, 2, 0.7 };
 
 		runSimulation(batchArguments, "tsointsoin", parameterNames, parameterValues);
 
-		double[][] spawnerRunResults = getValuesFromAquanismGroupProcess("processes.processesEachStep.8.exportToR");
-		for (double[] result : spawnerRunResults) {
-			System.out.println(Arrays.toString(result));
-		}
-
-		double[][] distributionResults = getValuesFromAquanismGroupProcess("processes.processesEachStep.10.exportToR");
-		for (double[] result : distributionResults) {
-			System.out.println(Arrays.toString(result));
-		}
-
-		// List truc = getAListFromAquanismGroupProcess("processes.processesAtEnd.1.getRecords");
+		// System.out.println("\nAnalyseSpawnerFeatures");
+		// System.out.println("basin_id, female_mean_age, male_mean_age, percent_primiparous");
+		// double[][] spawnerRunResults = getValuesFromAquanismGroupProcess("processes.processesEachStep.8.exportToR");
+		// for (double[] result : spawnerRunResults) {
+		// System.out.println(Arrays.toString(result));
+		// }
+		//
+		// System.out.println("\nAnalyseFishDistribution");
+		// System.out.println("southern_basin_id, northern_basin_id, basin_centroid_latitude,
+		// effective_centroid_latitude");
+		// double[][] distributionResults =
+		// getValuesFromAquanismGroupProcess("processes.processesEachStep.9.exportToR");
+		// for (double[] result : distributionResults) {
+		// System.out.println(Arrays.toString(result));
+		// }
+
+		System.out.println("\nAnalyseLikelihoodOfPresence");
+		System.out.println(getSingleValueFromAquanismGroupProcess("processes.processesAtEnd.0.getLogLikelihood"));
+
+		// List truc = getAListFromAquanismGroupProcess("processes.processesAtEnd.0.getRecords");
 		// System.out.println(truc.get(0).toString());
 		// System.out.println(getAListFromAquanismGroupProcess("processes.processesAtEnd.1.getRecords"));
 
-		System.out.println(Arrays.toString(getValuesFromEnvironment("getMeanLastPercOfAut")));
-
-		System.out.println(Arrays.toString(getValuesFromAquanismGroup("getRangeDistribution")));
+		// System.out.println("\ngetMeanLastPercOfAut");
+		// System.out.println(Arrays.toString(getValuesFromEnvironment("getMeanLastPercOfAut")));
 
 	}
 }
diff --git a/src/main/java/species/AnalyseFishDistribution.java b/src/main/java/species/AnalyseFishDistribution.java
index 4d8d337cda5889b0202a582d58fdb48444f2b9fb..70681aba2ecffae4529ab246df98cd419388db7b 100644
--- a/src/main/java/species/AnalyseFishDistribution.java
+++ b/src/main/java/species/AnalyseFishDistribution.java
@@ -19,8 +19,9 @@
  */
 package species;
 
-import java.util.ArrayList;
-import java.util.List;
+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;
@@ -30,6 +31,7 @@ import environment.RiverBasin;
 import environment.Time.Season;
 import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
 import fr.cemagref.simaqualife.pilot.Pilot;
+import miscellaneous.QueueMemory;
 import miscellaneous.TreeMapForCentile;
 import observer.ObservableRecord;
 
@@ -40,6 +42,8 @@ public class AnalyseFishDistribution extends AquaNismsGroupProcess<DiadromousFis
 
 	private Season analysisSeason = Season.SPRING;
 
+	private int memorySize = 30;
+
 	/**
 	 * The minimum number of recruits to consider a basin as populated
 	 * 
@@ -47,16 +51,18 @@ public class AnalyseFishDistribution extends AquaNismsGroupProcess<DiadromousFis
 	 */
 	private int minimumRecruitsForPopulatedBasin = 50;
 
-	private transient List<FishDistributionRecord> records;
+	// private transient List<FishDistributionRecord> records;
 
 	private transient double southernLimit;
 
 	private transient double northernLimit;
 
+	private transient Map<RiverBasin, QueueMemory<Double>> lastSpawnerNumbersMemory;
+
 	@Override
 	public void initTransientParameters(Pilot pilot) {
 		super.initTransientParameters(pilot);
-		records = new ArrayList<FishDistributionRecord>();
+		// records = new ArrayList<FishDistributionRecord>();
 
 		// define the latitude range of basin network
 		southernLimit = 90.;
@@ -71,78 +77,88 @@ public class AnalyseFishDistribution extends AquaNismsGroupProcess<DiadromousFis
 	@Override
 	public void doProcess(DiadromousFishGroup group) {
 
-		if (records == null)
-			initTransientParameters(group.getPilot());
+		// first passage
+		if (lastSpawnerNumbersMemory == null) {
+			lastSpawnerNumbersMemory = new HashMap<RiverBasin, QueueMemory<Double>>();
+			for (RiverBasin riverBasin : group.getEnvironment().getRiverBasins()) {
+				lastSpawnerNumbersMemory.put(riverBasin, new QueueMemory<>(memorySize));
+			}
+		}
 
-		if (group.getEnvironment().getTime().getSeason(group.getPilot()) == analysisSeason) {
-			// initialise the distribution range
-			double southernEdge = northernLimit;
-			double northernEdge = southernLimit;
-			int southernId = -1;
-			int northernId = -1;
-			String southernName = "";
-			String northernName = "";
-			// initialise for centroid
-			TreeMapForCentile latitudeEffective = new TreeMapForCentile();
-			TreeMapForCentile latitudePresence = new TreeMapForCentile();
+		// 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);
 
-				if (riverBasin.getLastRecruitments().getMean() > minimumRecruitsForPopulatedBasin) {
-					// the river basin is consdered populated
-
-					// NOTE : recruiit number is calulated after thermal tolerance impact
-					// (which is intreaged in the stock-recruitment relationship)
-
-					// southern edge
-					if (riverBasin.getLatitude() < southernEdge) {
-						// the basin is the new southern edge
-						southernEdge = riverBasin.getLatitude();
-						southernId = riverBasin.getBasin_id();
-						southernName = riverBasin.getName();
-					}
-
-					// northern edge
-					if (riverBasin.getLatitude() > southernEdge) {
-						// the basin is the new northern edge
-						northernEdge = riverBasin.getLatitude();
-						northernId = riverBasin.getBasin_id();
-						northernName = riverBasin.getName();
-					}
-
-					// for distribution centroide computation
-					latitudePresence.putWithAdding(riverBasin.getLatitude(), 1L);
-					long effective = ((Double) riverBasin.getLastSpawnerNumbersBeforeReproduction().getMean()).longValue();
-					latitudeEffective.putWithAdding(riverBasin.getLatitude(), effective);
-				}
-			}
-			// if the universe is empty
-			if (southernEdge == northernLimit & northernEdge == southernLimit) {
-				southernEdge = (northernLimit + southernLimit) / 2.;
-				northernEdge = southernEdge;
+				lastSpawnerNumbersMemory.get(riverBasin).push(fluxBefore);
 			}
 
-			// distribution centroids computation
-			double basinCentroid = latitudePresence.calculateMedian();
-			double effectiveCentroid = latitudeEffective.calculateMedian();
-
-			// add a record
-			FishDistributionRecord record = new FishDistributionRecord(southernId, southernName, southernEdge, northernId,
-					northernName, northernEdge, basinCentroid, effectiveCentroid);
-
-			records.add(record);
 		}
 	}
 
 
 	public double[][] exportToR() {
-		double[][] export = new double[records.size()][4];
-		for (int i = 0; i < records.size(); i++) {
-			export[i][0] = records.get(i).southern_basin_id;
-			export[i][1] = records.get(i).northern_basin_id;
-			export[i][2] = records.get(i).basinCentroid_latitude;
-			export[i][3] = records.get(i).effectiveCentroid_latitude;
+
+		// initialise the distribution range
+		double southernEdge = northernLimit;
+		double northernEdge = southernLimit;
+		int southernId = -1;
+		int northernId = -1;
+		// String southernName = "";
+		// String northernName = "";
+		// initialise for centroid
+		TreeMapForCentile latitudeEffective = new TreeMapForCentile();
+		TreeMapForCentile latitudePresence = new TreeMapForCentile();
+
+		double[][] export = new double[1][4];
+		int i = 0;
+		for (Entry<RiverBasin, QueueMemory<Double>> entry : lastSpawnerNumbersMemory.entrySet()) {
+
+			if (entry.getValue().getMean() > 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) {
+					// the basin is the new southern edge
+					southernEdge = entry.getKey().getLatitude();
+					southernId = entry.getKey().getBasin_id();
+					// southernName = entry.getKey().getName();
+				}
+
+				// northern edge
+				if (entry.getKey().getLatitude() > northernEdge) {
+					// the basin is the new northern edge
+					northernEdge = entry.getKey().getLatitude();
+					northernId = entry.getKey().getBasin_id();
+					// northernName = entry.getKey().getName();
+				}
+
+				// for distribution centroide computation
+				latitudePresence.putWithAdding(entry.getKey().getLatitude(), 1L);
+				long effective = ((Double) entry.getValue().getMean()).longValue();
+				latitudeEffective.putWithAdding(entry.getKey().getLatitude(), effective);
+			}
+		}
+
+		// if the universe is empty (none of basins is populated)
+		if (southernEdge == northernLimit & northernEdge == southernLimit) {
+			southernEdge = (northernLimit + southernLimit) / 2.;
+			northernEdge = southernEdge;
 		}
+
+		// distribution centroids computation
+		double basinCentroid = latitudePresence.calculateMedian();
+		double effectiveCentroid = latitudeEffective.calculateMedian();
+
+		export[0][0] = southernId;
+		export[0][1] = northernId;
+		export[0][2] = basinCentroid;
+		export[0][3] = effectiveCentroid;
 		return export;
 	}
 
diff --git a/src/main/java/species/AnalyseLikelihoodOfPresence.java b/src/main/java/species/AnalyseLikelihoodOfPresence.java
index fa663d89d0331e6be1ec357736dc7d57f9587c99..ca4a12344da3d34812486036a6b46d445f774415 100644
--- a/src/main/java/species/AnalyseLikelihoodOfPresence.java
+++ b/src/main/java/species/AnalyseLikelihoodOfPresence.java
@@ -47,6 +47,11 @@ public class AnalyseLikelihoodOfPresence extends AquaNismsGroupProcess<Diadromou
 	 */
 	private int minimumRecruitsForPopulatedBasin = 50;
 
+	/**
+	 * to avoid log(0) in log-lokelihood
+	 * 
+	 * @unit
+	 */
 	private double epsilon = 1e-3;
 
 	// map with presence
@@ -62,6 +67,7 @@ public class AnalyseLikelihoodOfPresence extends AquaNismsGroupProcess<Diadromou
 		if (Double.isNaN(epsilon))
 			epsilon = 1e-3;
 
+		// read the file of presence in river basin
 		try {
 			// open the file
 			FileReader reader = new FileReader(presenceFileName);
@@ -74,10 +80,16 @@ public class AnalyseLikelihoodOfPresence extends AquaNismsGroupProcess<Diadromou
 			// read the headers
 			String[] headers = scanner.nextLine().split(",");
 			presences = new TreeMap<String, Map<String, Integer>>();
+			boolean periodTest = false;
 			for (int i = 2; i < headers.length; i++) {
+				if (period.equals(headers[i]))
+					periodTest = true;
 				presences.put(headers[i], new TreeMap<String, Integer>());
 			}
 
+			// TODO send the error
+			if (periodTest == false)
+				System.out.println("The period " + period + "  is not present in the file " + presenceFileName);
 			// read the lines
 			while (scanner.hasNextLine()) {
 				String[] fields = scanner.nextLine().split(",");
@@ -94,8 +106,8 @@ public class AnalyseLikelihoodOfPresence extends AquaNismsGroupProcess<Diadromou
 					}
 				}
 			}
-			// reader.close();
-			// scanner.close();
+			reader.close();
+			scanner.close();
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
@@ -104,18 +116,24 @@ public class AnalyseLikelihoodOfPresence extends AquaNismsGroupProcess<Diadromou
 
 	@Override
 	public void doProcess(DiadromousFishGroup group) {
+
+		// first passage for processesAtEnd
+		if (presences == null)
+			initTransientParameters(group.getPilot());
+
 		logLikelihood = 0.;
 		for (RiverBasin riverBasin : group.getEnvironment().getRiverBasins()) {
 			double p_predit = (double) riverBasin.getLastRecruitments()
 					.getNumberOfStriclyHigherValue(minimumRecruitsForPopulatedBasin)
 					/ (double) riverBasin.getLastRecruitments().size();
 
-			int presence = presences.get(riverBasin.getName()).get(period);
+			int presence = presences.get(period).get(riverBasin.getName());
+			// System.out.println(riverBasin.getName() + " " + presence + " " + p_predit);
 
 			if (presence == 1)
-				logLikelihood += Math.log(p_predit) + epsilon;
+				logLikelihood += Math.log(p_predit + epsilon);
 			else
-				logLikelihood += 1 - Math.log(p_predit) + epsilon;
+				logLikelihood += 1 - Math.log(p_predit + epsilon);
 		}
 	}
 
diff --git a/src/main/java/species/AnalyseSpawnerFeatures.java b/src/main/java/species/AnalyseSpawnerFeatures.java
index 8640ceda8845d830ca624ca0d260782bc40a4483..d3ddb75f99f6ba9184caead4df3dec284ace3277 100644
--- a/src/main/java/species/AnalyseSpawnerFeatures.java
+++ b/src/main/java/species/AnalyseSpawnerFeatures.java
@@ -130,6 +130,8 @@ public class AnalyseSpawnerFeatures extends AquaNismsGroupProcess<DiadromousFish
 			result[i][1] = entry.getValue().getMean();
 			result[i][2] = maleAgeMemories.get(entry.getKey()).getMean();
 			result[i][3] = primiparousMemories.get(entry.getKey()).getMean();
+
+			i++;
 		}
 
 		return result;