diff --git a/src/main/java/pikelake/Marnage.java b/src/main/java/pikelake/Marnage.java
index 3831836fbe335e3074295f908edf033694e23b3e..9d785961355d7609b76dcbfa0d29f3138ee05279 100644
--- a/src/main/java/pikelake/Marnage.java
+++ b/src/main/java/pikelake/Marnage.java
@@ -1,74 +1,78 @@
-package pikelake;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Scanner;
-import java.util.StringTokenizer;
-
-import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
-import pikelake.environment.FichierMarnage;
-import pikelake.environment.Time;
-import pikelake.pikes.Pike;
-import pikelake.pikes.PikesGroup;
-
-public class Marnage extends AquaNismsGroupProcess<Pike,PikesGroup> {
-
-	public static String marnageOld = null, marnageNew = null;
-	public static String saison = "";
-	
-	@Override
-	public void doProcess(PikesGroup object) {
-		Grid grid = (Grid) pilot.getAquaticWorld().getEnvironment();
-		grid = grid.getGrid();
-		marnageNew = FichierMarnage.dateMarnage[Time.jourMois][Time.mois][Time.heure];
-		if (!marnageNew.equals(marnageOld) | !saison.equals(Time.getSeason()))
-			majCote(grid);			
-	}
-
-    public void majCote (Grid grid) {
-		
-    	StringTokenizer sLigne;
-	    @SuppressWarnings("unused")
-		double hsiStd = 0, hsiMoy = 0;
-		int idCell = 0, yPike = 0, xPike = 0;
-		marnageOld = marnageNew;
-		saison = Time.getSeason();
-		
-	    // Initialisation de toute la grille avec hsi = -1
-	    for (int cptCell = 0; cptCell < (grid.getGridWidth() * grid.getGridHeight() - 1); cptCell++)
-	    	grid.setCell(cptCell, -1);
-	    // Lecture fichier contenant les HSI de toutes les mailles
-	    String filePath = "data/input/HSI/hsi_BRO" + Time.getSeason() + marnageNew + ".txt";
-	    Scanner scanner;
-		try {
-			scanner = new Scanner(new File(filePath));
-			String line = scanner.nextLine();
-		   	// On boucle sur chaque ligne detectée
-		   	while (scanner.hasNextLine()) {
-		   		line = scanner.nextLine();	
-		   		// Decoupage ligne : id, hsiStd, hsiMoy
-		   		sLigne = new StringTokenizer (line);
-		   		if (sLigne.hasMoreTokens())
-		   			idCell = Integer.parseInt(sLigne.nextToken())-1;
-		   		if (sLigne.hasMoreTokens())
-		    	   	hsiStd = Double.parseDouble(sLigne.nextToken());
-		   		if (sLigne.hasMoreTokens())
-		    	   	hsiMoy = Double.parseDouble(sLigne.nextToken());
-		   		// Conversion idCell en coordonnees (x, y) 
-		   		// (x, y) avec les id de cellules de 0 à n-1
-		   		yPike = (int) Math.floor(idCell / grid.getGridWidth());
-		       	xPike = (int) idCell - (yPike * grid.getGridWidth());
-		       	// Inversion des coordonnees en Y (place l'origine en bas à gauche)
-		       	yPike = (grid.getGridHeight()-1) - yPike ;
-		       	// Conversion des coordonnees (x, y) en idCell 
-		       	idCell = xPike + yPike * grid.getGridWidth();
-		       	// Initialisation du hsi de la cellule(idCell)
-		       	grid.setCell(idCell, hsiMoy);
-		   	}
-		   	scanner.close();
-		} catch (FileNotFoundException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
-}
+package pikelake;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+import java.util.StringTokenizer;
+
+import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
+import pikelake.environment.FichierMarnage;
+import pikelake.environment.Time;
+import pikelake.pikes.Pike;
+import pikelake.pikes.PikesGroup;
+
+public class Marnage extends AquaNismsGroupProcess<Pike,PikesGroup> {
+
+	public static String marnageOld = null, marnageNew = null;
+	public static String saison = "";
+	
+	@Override
+	public void doProcess(PikesGroup object) {
+		Grid grid = (Grid) pilot.getAquaticWorld().getEnvironment();
+		grid = grid.getGrid();
+		marnageNew = FichierMarnage.dateMarnage[Time.jourMois][Time.mois][Time.heure];
+		
+		if (!marnageNew.equals(marnageOld)) {
+                    synchronized (grid) { // synchronization to be sure that graphical observer read synchronized values
+                        majCote(grid);
+                    }
+                }
+	}
+
+    public void majCote (Grid grid) {
+		
+    	StringTokenizer sLigne;
+	    @SuppressWarnings("unused")
+		double hsiStd = 0, hsiMoy = 0;
+		int idCell = 0, yPike = 0, xPike = 0;
+		marnageOld = marnageNew;
+		saison = Time.getSeason();
+		
+	    // Initialisation de toute la grille avec hsi = -1
+	    for (int cptCell = 0; cptCell < (grid.getGridWidth() * grid.getGridHeight() - 1); cptCell++)
+	    	grid.setCell(cptCell, -1);
+	    // Lecture fichier contenant les HSI de toutes les mailles
+	    String filePath = "data/input/HSI/hsi_BRO" + Time.getSeason() + marnageNew + ".txt";
+	    Scanner scanner;
+		try {
+			scanner = new Scanner(new File(filePath));
+			String line = scanner.nextLine();
+		   	// On boucle sur chaque ligne detectée
+		   	while (scanner.hasNextLine()) {
+		   		line = scanner.nextLine();	
+		   		// Decoupage ligne : id, hsiStd, hsiMoy
+		   		sLigne = new StringTokenizer (line);
+		   		if (sLigne.hasMoreTokens())
+		   			idCell = Integer.parseInt(sLigne.nextToken())-1;
+		   		if (sLigne.hasMoreTokens())
+		    	   	hsiStd = Double.parseDouble(sLigne.nextToken());
+		   		if (sLigne.hasMoreTokens())
+		    	   	hsiMoy = Double.parseDouble(sLigne.nextToken());
+		   		// Conversion idCell en coordonnees (x, y) 
+		   		// (x, y) avec les id de cellules de 0 à n-1
+		   		yPike = (int) Math.floor(idCell / grid.getGridWidth());
+		       	xPike = (int) idCell - (yPike * grid.getGridWidth());
+		       	// Inversion des coordonnees en Y (place l'origine en bas à gauche)
+		       	yPike = (grid.getGridHeight()-1) - yPike ;
+		       	// Conversion des coordonnees (x, y) en idCell 
+		       	idCell = xPike + yPike * grid.getGridWidth();
+		       	// Initialisation du hsi de la cellule(idCell)
+		       	grid.setCell(idCell, hsiMoy);
+		   	}
+		   	scanner.close();
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java b/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java
index ceda3bc5481b0eabde7d0979088526741d284bfc..edc034e5de76699628ebc36efbb73f22f6985c4c 100644
--- a/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java
+++ b/src/main/java/pikelake/environment/Movement2DWithinShapeObserver.java
@@ -35,6 +35,11 @@ import org.geotools.data.simple.SimpleFeatureSource;
 
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.MultiPolygon;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Arrays;
+import javax.swing.Timer;
+import pikelake.Cell;
 
 import pikelake.Grid;
 import pikelake.Marnage;
@@ -44,8 +49,6 @@ import pikelake.pikes.PikesGroup;
 
 public class Movement2DWithinShapeObserver extends ObserverListener implements Configurable, Drawable {
 
-	private transient Grid grid;
-	
     private transient JComponent display;
 
     private transient GeneralPath generalPath;
@@ -159,8 +162,17 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C
         groupsColors.add(Color.YELLOW);
         groupsColors.add(Color.CYAN);
         groupsColors.add(Color.GRAY);
-        display.repaint();
         display.setVisible(true);
+        // auto-repaint 20 times / second
+        Timer timer = new Timer(50, new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                display.repaint();
+            }
+
+        });
+        timer.start();
 
     }
 
@@ -177,7 +189,6 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C
         if (groups.isEmpty() && instance != null) {
            	groups.add((PikesGroup) instance);
         }
-        display.repaint();      
         display.setVisible(true);     
     }
     
@@ -226,11 +237,7 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C
                 // rescale the generalPath
                 generalPath.transform (AffineTransform.getScaleInstance (rescaleFactor, rescaleFactor));
             }           
-            // Draw Background
-            g.setColor(bgColor);
-            g.fillRect(0, 0, getWidth(), getHeight());
             Iterator<Color> colorsIterator = groupsColors.iterator();
-            
             // Draw aquanisms
             g.setColor(pikeColor);
             double widthMax = 0, heightMax = 0;
@@ -238,29 +245,29 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C
             widthMax = generalPath.getBounds().getWidth();
             heightMax = generalPath.getBounds().getHeight();
             
-            
             boolean oneShot = false;
             for (PikesGroup group : groups) {
-            	
-            	if (oneShot == false) {
-	            	grid = group.getEnvironment();
-	
+            	final Grid grid = group.getEnvironment();
+                if (oneShot == false) {
+	            	Cell[] cells;
+                        // synchronization to be sure that graphical observer read synchronized values (without interference of marnage update process)
+                        synchronized (grid) {
+                           cells = Arrays.copyOf(grid.getCells(), grid.getCells().length);
+                        }
 	            	int xHSI = 0, yHSI = 0, xHSI2 = 0, yHSI2 = 0;
 	            	int xx[] = new int [(grid.getGridHeight() * grid.getGridWidth())-1], yy[] = new int [(grid.getGridHeight() * grid.getGridWidth())-1];
 	            	g.setColor(hsiColor);
 	            	for (int cptCell = 0; cptCell < (grid.getGridHeight() * grid.getGridWidth())-1; cptCell++) {
 	            		
-		            	if (grid.getCell(cptCell).getHabitatQuality() > 0) {
+		            	if (cells[cptCell].getHabitatQuality() > 0) {
 		            		yHSI = (int) Math.floor(cptCell / grid.getGridWidth());
 		            		xHSI = (int) cptCell - (yHSI * grid.getGridWidth());
 		            		
 		            		xHSI2 = (int) (xHSI * (widthMax / grid.getGridWidth()));
 		            		yHSI2 = (int) (yHSI * (heightMax / grid.getGridHeight()));
-		            		
-		                	g.setColor(new Color(0.43f, (float) (Math.min(1,grid.getCell(cptCell).getHabitatQuality()/hsiMaxValueThreshold)), 0.13f));
+		            		g.setColor(new Color(0.43f, (float) (Math.max(0, Math.min(1,grid.getCell(cptCell).getHabitatQuality()/hsiMaxValueThreshold))), 0.13f));
                                         g2d.fillRect((int) xHSI2, (int) yHSI2, 3, 3);
-		                	
-		                	xx[cptCell] = xHSI2;
+                                        xx[cptCell] = xHSI2;
 		                	yy[cptCell] = yHSI2;
 		            	}
 	            	}            		
@@ -282,7 +289,6 @@ public class Movement2DWithinShapeObserver extends ObserverListener implements C
                 }     
             }
             
-            
             // Annotations
             DecimalFormat df = new DecimalFormat("00");
             g.setColor(textColor);