diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
index 3dcf0b26da4c44fd830602897f1509e9bbef7181..006e5935fb20b3803a3c9d1c907dc5f42e84346d 100644
--- a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
+++ b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
@@ -37,12 +37,6 @@ public class MinMaxTreeTile extends SimpleTile {
     /** Start indices of tree levels. */
     private int[] start;
 
-    /** Number of rows of tree levels. */
-    private int[] rows;
-
-    /** Number of columns of tree levels. */
-    private int[] columns;
-
     /** Simple constructor.
      * <p>
      * Creates an empty tile.
@@ -55,16 +49,19 @@ public class MinMaxTreeTile extends SimpleTile {
     @Override
     protected void processUpdatedElevation(final double[] elevations) {
 
+        final int nbRows = getLatitudeRows();
+        final int nbCols = getLongitudeColumns();
+
         // set up the levels
-        final int size = setLevels(0, getLatitudeRows(), getLongitudeColumns());
+        final int size = setLevels(0, nbRows, nbCols);
         minTree = new double[size];
         maxTree = new double[size];
 
         // compute min/max trees
-        applyRecursively(minTree, 0, getLatitudeRows(), getLongitudeColumns(),
-                         new Min(), elevations, 0);
-        applyRecursively(maxTree, 0, getLatitudeRows(), getLongitudeColumns(),
-                         new Max(), elevations, 0);
+        if (start.length > 0) {
+            applyRecursively(minTree, start.length - 1, nbRows, nbCols, new Min(), elevations, 0);
+            applyRecursively(maxTree, start.length - 1, nbRows, nbCols, new Max(), elevations, 0);
+        }
 
     }
 
@@ -87,11 +84,15 @@ public class MinMaxTreeTile extends SimpleTile {
      */
     public double getMinElevation(final int i, final int j, final int level) {
 
-        // compute row index in level merged array
-        final int levelI = i >> ((level + 1) / 2);
-        final int levelJ = j >> ((level + 2) / 2);
+        // compute indices in level merged array
+        final int k        = start.length - level;
+        final int rowShift = k / 2;
+        final int colShift = (k + 1) / 2;
+        final int levelI   = i >> rowShift;
+        final int levelJ   = j >> colShift;
+        final int levelC   = 1 + ((getLongitudeColumns() - 1) >> colShift);
 
-        return minTree[start[level] + levelI * columns[level] + levelJ];
+        return minTree[start[level] + levelI * levelC + levelJ];
 
     }
 
@@ -105,11 +106,15 @@ public class MinMaxTreeTile extends SimpleTile {
      */
     public double getMaxElevation(final int i, final int j, final int level) {
 
-        // compute row index in level merged array
-        final int levelI = i >> ((level + 1) / 2);
-        final int levelJ = j >> (level / 2);
+        // compute indices in level merged array
+        final int k        = start.length - level;
+        final int rowShift = k / 2;
+        final int colShift = (k + 1) / 2;
+        final int levelI   = i >> rowShift;
+        final int levelJ   = j >> colShift;
+        final int levelC   = 1 + ((getLongitudeColumns() - 1) >> colShift);
 
-        return maxTree[start[level] + levelI * columns[level] + levelJ];
+        return maxTree[start[level] + levelI * levelC + levelJ];
 
     }
 
@@ -125,53 +130,49 @@ public class MinMaxTreeTile extends SimpleTile {
      * <table border="0">
      * <tr BGCOLOR="#EEEEFF"><font size="+1">
      *     <td>Level</td>   <td>Dimension</td>  <td>Start index</td>  <td>End index</td></font></tr>
-     * <tr>   <td>8</td>     <td>  7 ⨉  1</td>       <td>   0</td>        <td>  6</td> </tr>
-     * <tr>   <td>7</td>     <td>  7 ⨉  2</td>       <td>   7</td>        <td> 20</td> </tr>
-     * <tr>   <td>6</td>     <td> 14 ⨉  2</td>       <td>  21</td>        <td> 48</td> </tr>
-     * <tr>   <td>5</td>     <td> 14 ⨉  3</td>       <td>  49</td>        <td> 90</td> </tr>
+     * <tr>   <td>0</td>     <td>  7 ⨉  1</td>       <td>   0</td>        <td>  6</td> </tr>
+     * <tr>   <td>1</td>     <td>  7 ⨉  2</td>       <td>   7</td>        <td> 20</td> </tr>
+     * <tr>   <td>2</td>     <td> 14 ⨉  2</td>       <td>  21</td>        <td> 48</td> </tr>
+     * <tr>   <td>3</td>     <td> 14 ⨉  3</td>       <td>  49</td>        <td> 90</td> </tr>
      * <tr>   <td>4</td>     <td> 27 ⨉  3</td>       <td>  91</td>        <td>171</td> </tr>
-     * <tr>   <td>3</td>     <td> 27 ⨉  5</td>       <td> 172</td>        <td>306</td> </tr>
-     * <tr>   <td>2</td>     <td> 54 ⨉  5</td>       <td> 307</td>        <td>576</td> </tr>
-     * <tr>   <td>1</td>     <td> 54 ⨉ 10</td>      <td> 577</td>        <td>1116</td> </tr>
-     * <tr>   <td>0</td>     <td>107 ⨉ 10</td>      <td>1117</td>        <td>2186</td> </tr>
+     * <tr>   <td>5</td>     <td> 27 ⨉  5</td>       <td> 172</td>        <td>306</td> </tr>
+     * <tr>   <td>6</td>     <td> 54 ⨉  5</td>       <td> 307</td>        <td>576</td> </tr>
+     * <tr>   <td>7</td>     <td> 54 ⨉ 10</td>      <td> 577</td>        <td>1116</td> </tr>
+     * <tr>   <td>8</td>     <td>107 ⨉ 10</td>      <td>1117</td>        <td>2186</td> </tr>
      * </table>
      * </p>
-     * @param level current level (counting from leafs to root)
-     * @param levelRows number of rows at current level
-     * @param levelColumns number of columns at current level
-     * @return size cumulative size from current level to root
+     * @param stage number of merging stages
+     * @param stageRows number of rows at current stage
+     * @param stageColumns number of columns at current stage
+     * @return size cumulative size from root to current level
      */
-    private int setLevels(final int level, final int levelRows, final int levelColumns) {
+    private int setLevels(final int stage, final int stageRows, final int stageColumns) {
 
-        if (levelRows == 1 || levelColumns == 1) {
+        if (stageRows == 1 || stageColumns == 1) {
             // we have found root, stop recursion
-            start              = new int[level];
-            rows               = new int[level];
-            columns            = new int[level];
-            start[level - 1]   = 0;
-            rows[level - 1]    = levelRows;
-            columns[level - 1] = levelColumns;
-            return levelRows * levelColumns;
+            start   = new int[stage];
+            if (stage > 0) {
+                start[0]   = 0;
+            }
+            return stageRows * stageColumns;
         }
 
         final int size;
-        if ((level & 0x1) == 0) {
+        if ((stage & 0x1) == 0) {
             // columns merging
-            size = setLevels(level + 1, levelRows, (levelColumns + 1) / 2);
+            size = setLevels(stage + 1, stageRows, (stageColumns + 1) / 2);
         } else {
             // rows merging
-            size = setLevels(level + 1, (levelRows + 1) / 2, levelColumns);
+            size = setLevels(stage + 1, (stageRows + 1) / 2, stageColumns);
         }
 
-        if (level > 0) {
+        if (stage > 0) {
             // store current level characteristics
-            start[level - 1]   = size;
-            rows[level - 1]    = levelRows;
-            columns[level - 1] = levelColumns;
-            return size + levelRows * levelColumns;
+            start[start.length     - stage] = size;
+            return size + stageRows * stageColumns;
         } else {
-            // we don't count the elements at leaf as they are not stored
-            // in the min/max trees
+            // we don't count the elements at stage 0 as they are not stored in the
+            // min/max trees (they correspond to the raw elevation, without merging)
             return size;
         }
 
@@ -197,10 +198,10 @@ public class MinMaxTreeTile extends SimpleTile {
             int           iBase       = first;
             final int     nextColumns = (levelColumns + 1) / 2;
             final boolean odd         = (levelColumns & 0x1) != 0;
+            int           jEnd        = odd ? nextColumns - 1 : nextColumns;
             for (int i = 0; i < levelRows; ++i) {
 
                 // regular pairs
-                int jEnd = odd ? nextColumns - 1 : nextColumns;
                 for (int j = 0; j < jEnd; ++j) {
                     tree[iTree++] = f.value(base[iBase], base[iBase + 1]);
                     iBase += 2;
@@ -214,8 +215,8 @@ public class MinMaxTreeTile extends SimpleTile {
 
             }
 
-            if (level < start.length - 1) {
-                applyRecursively(tree, level + 1, levelRows, nextColumns, f, tree, start[level]);
+            if (level > 0) {
+                applyRecursively(tree, level - 1, levelRows, nextColumns, f, tree, start[level]);
             }
 
         } else {
@@ -225,9 +226,9 @@ public class MinMaxTreeTile extends SimpleTile {
             int           iBase    = first;
             final int     nextRows = (levelRows + 1) / 2;
             final boolean odd      = (levelRows & 0x1) != 0;
+            int           iEnd     = odd ? nextRows - 1 : nextRows;
 
             // regular pairs
-            int iEnd = odd ? nextRows - 1 : nextRows;
             for (int i = 0; i < iEnd; ++i) {
 
                 for (int j = 0; j < levelColumns; ++j) {
@@ -243,8 +244,8 @@ public class MinMaxTreeTile extends SimpleTile {
                 System.arraycopy(base, iBase, tree, iTree, levelColumns);
             }
 
-            if (level < start.length - 1) {
-                applyRecursively(tree, level + 1, nextRows, levelColumns, f, tree, start[level]);
+            if (level > 0) {
+                applyRecursively(tree, level - 1, nextRows, levelColumns, f, tree, start[level]);
             }
 
         }
diff --git a/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java b/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
index 68295ff633cd16a6f3e0c0aba4ea892f372fb9bf..7b69d6f6c74940f4ab789b84af705589963de60e 100644
--- a/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
+++ b/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
@@ -18,8 +18,6 @@ package orekit.rugged.core.duvenhage;
 
 import java.lang.reflect.Field;
 
-import org.apache.commons.math3.random.RandomGenerator;
-import org.apache.commons.math3.random.Well19937a;
 import org.apache.commons.math3.util.FastMath;
 import org.junit.Assert;
 import org.junit.Test;
@@ -41,47 +39,23 @@ public class MinMaxTreeTileTest {
         Field startField = MinMaxTreeTile.class.getDeclaredField("start");
         startField.setAccessible(true);
         int[] start = (int[]) startField.get(tile);
-        Assert.assertEquals(   0, start[ 8]);
-        Assert.assertEquals(   7, start[ 7]);
-        Assert.assertEquals(  21, start[ 6]);
-        Assert.assertEquals(  49, start[ 5]);
+        Assert.assertEquals(   0, start[ 0]);
+        Assert.assertEquals(   7, start[ 1]);
+        Assert.assertEquals(  21, start[ 2]);
+        Assert.assertEquals(  49, start[ 3]);
         Assert.assertEquals(  91, start[ 4]);
-        Assert.assertEquals( 172, start[ 3]);
-        Assert.assertEquals( 307, start[ 2]);
-        Assert.assertEquals( 577, start[ 1]);
-        Assert.assertEquals(1117, start[ 0]);
-
-        Field rowsField = MinMaxTreeTile.class.getDeclaredField("rows");
-        rowsField.setAccessible(true);
-        int[] rows = (int[]) rowsField.get(tile);
-        Assert.assertEquals(   7, rows[ 8]);
-        Assert.assertEquals(   7, rows[ 7]);
-        Assert.assertEquals(  14, rows[ 6]);
-        Assert.assertEquals(  14, rows[ 5]);
-        Assert.assertEquals(  27, rows[ 4]);
-        Assert.assertEquals(  27, rows[ 3]);
-        Assert.assertEquals(  54, rows[ 2]);
-        Assert.assertEquals(  54, rows[ 1]);
-        Assert.assertEquals( 107, rows[ 0]);
-
-        Field columnsField = MinMaxTreeTile.class.getDeclaredField("columns");
-        columnsField.setAccessible(true);
-        int[] columns = (int[]) columnsField.get(tile);
-        Assert.assertEquals(  1, columns[ 8]);
-        Assert.assertEquals(  2, columns[ 7]);
-        Assert.assertEquals(  2, columns[ 6]);
-        Assert.assertEquals(  3, columns[ 5]);
-        Assert.assertEquals(  3, columns[ 4]);
-        Assert.assertEquals(  5, columns[ 3]);
-        Assert.assertEquals(  5, columns[ 2]);
-        Assert.assertEquals( 10, columns[ 1]);
-        Assert.assertEquals( 10, columns[ 0]);
+        Assert.assertEquals( 172, start[ 5]);
+        Assert.assertEquals( 307, start[ 6]);
+        Assert.assertEquals( 577, start[ 7]);
+        Assert.assertEquals(1117, start[ 8]);
+
         Field minTreeField = MinMaxTreeTile.class.getDeclaredField("minTree");
         minTreeField.setAccessible(true);
         Assert.assertEquals(2187, ((double[]) minTreeField.get(tile)).length);
         Field maxTreeField = MinMaxTreeTile.class.getDeclaredField("maxTree");
         maxTreeField.setAccessible(true);
         Assert.assertEquals(2187, ((double[]) maxTreeField.get(tile)).length);
+
     }
 
     @Test
@@ -96,26 +70,10 @@ public class MinMaxTreeTileTest {
         Field startField = MinMaxTreeTile.class.getDeclaredField("start");
         startField.setAccessible(true);
         int[] start = (int[]) startField.get(tile);
-        Assert.assertEquals( 0, start[ 3]);
-        Assert.assertEquals( 2, start[ 2]);
-        Assert.assertEquals( 6, start[ 1]);
-        Assert.assertEquals(14, start[ 0]);
-
-        Field rowsField = MinMaxTreeTile.class.getDeclaredField("rows");
-        rowsField.setAccessible(true);
-        int[] rows = (int[]) rowsField.get(tile);
-        Assert.assertEquals( 1, rows[ 3]);
-        Assert.assertEquals( 2, rows[ 2]);
-        Assert.assertEquals( 2, rows[ 1]);
-        Assert.assertEquals( 4, rows[ 0]);
-
-        Field columnsField = MinMaxTreeTile.class.getDeclaredField("columns");
-        columnsField.setAccessible(true);
-        int[] columns = (int[]) columnsField.get(tile);
-        Assert.assertEquals( 2, columns[ 3]);
-        Assert.assertEquals( 2, columns[ 2]);
-        Assert.assertEquals( 4, columns[ 1]);
-        Assert.assertEquals( 4, columns[ 0]);
+        Assert.assertEquals( 0, start[ 0]);
+        Assert.assertEquals( 2, start[ 1]);
+        Assert.assertEquals( 6, start[ 2]);
+        Assert.assertEquals(14, start[ 3]);
 
         Field minTreeField = MinMaxTreeTile.class.getDeclaredField("minTree");
         minTreeField.setAccessible(true);
@@ -123,84 +81,91 @@ public class MinMaxTreeTileTest {
         Field maxTreeField = MinMaxTreeTile.class.getDeclaredField("maxTree");
         maxTreeField.setAccessible(true);
         Assert.assertEquals(30, ((double[]) maxTreeField.get(tile)).length);
+
+    }
+
+    @Test
+    public void testSinglePixel() throws RuggedException {
+        MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
+        tile.setGeometry(1.0, 2.0, 0.1, 0.2, 1, 1);
+        tile.setElevation(0, 0, 2.5);
+        tile.tileUpdateCompleted();
+        Assert.assertEquals(0, tile.getLevels());
     }
 
     @Test
     public void testMinMax() throws RuggedException {
-        RandomGenerator random = new Well19937a(0xfbbc1d1739b23555l);
-        checkMinMax(4, 7, 100, random);
+        for (int nbRows = 1; nbRows < 25; nbRows++) {
+            for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
+                checkMinMax(nbRows, nbColumns);
+            }
+        }
     }
 
-    private void checkMinMax(int nbRows, int nbColumns, int nbChecks, RandomGenerator random)
+    private void checkMinMax(int nbRows, int nbColumns)
         throws RuggedException {
 
         MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
         tile.setGeometry(1.0, 2.0, 0.1, 0.2, nbRows, nbColumns);
         for (int i = 0; i < nbRows; ++i) {
             for (int j = 0; j < nbColumns; ++j) {
-                tile.setElevation(i, j, 1000 * random.nextDouble());
+                tile.setElevation(i, j, i + 0.01 * j);
             }
         }
         tile.tileUpdateCompleted();
 
-        for (int k = 0; k < nbChecks; ++k) {
-            int row    = random.nextInt(nbRows);
-            int column = random.nextInt(nbColumns);
-            int level  = random.nextInt(tile.getLevels());
-
-            // reference min and max
-            int[] neighbors = neighbors(row, column, nbRows, nbColumns, level);
-            System.out.println(row + " " + column + " (" + level + "): [" +
-                               neighbors[0] + ", " + neighbors[1] + "] [" +
-                               neighbors[2] + ", " + neighbors[3] + "]");
-            double min = Double.POSITIVE_INFINITY;
-            double max = Double.POSITIVE_INFINITY;
-            for (int i = neighbors[0]; i < neighbors[1]; ++i) {
-                for (int j = neighbors[2]; j < neighbors[3]; ++j) {
-                    double pixelValue = tile.getElevationAtIndices(i, j);
-                    min = FastMath.min(min, pixelValue);
-                    max = FastMath.max(max, pixelValue);
+        for (int level = 0; level < tile.getLevels(); level++) {
+            for (int row = 0; row < nbRows; row++) {
+                for (int column = 0; column < nbColumns; column++) {
+
+                    // reference min and max
+                    int[] neighbors = neighbors(row, column, nbRows, nbColumns, tile.getLevels() - level);
+                    double min = Double.POSITIVE_INFINITY;
+                    double max = Double.NEGATIVE_INFINITY;
+                    for (int i = neighbors[0]; i < neighbors[1]; ++i) {
+                        for (int j = neighbors[2]; j < neighbors[3]; ++j) {
+                            double pixelValue = tile.getElevationAtIndices(i, j);
+                            min = FastMath.min(min, pixelValue);
+                            max = FastMath.max(max, pixelValue);
+                        }
+                    }
+
+                    Assert.assertEquals(min, tile.getMinElevation(row, column, level), 1.0e-10 * min);
+                    Assert.assertEquals(max, tile.getMaxElevation(row, column, level), 1.0e-10 * max);
                 }
             }
-
-            Assert.assertEquals(min, tile.getMinElevation(row, column, level), 1.0e-10 * min);
-            Assert.assertEquals(max, tile.getMaxElevation(row, column, level), 1.0e-10 * max);
-
         }
 
     }
 
-    private int[] neighbors(int row, int column, int nbRows, int nbColumns, int level) {
+    private int[] neighbors(int row, int column, int nbRows, int nbColumns, int stages) {
 
         // poor man identification of neighbors cells merged together with specified cell
-        int rMin = 0;
-        int rMax = row;
-        int cMin = 0;
-        int cMax = column;
+        int rMin  = row;
+        int rN    = 1;
+        int rMask = -1;
+        int cMin  = column;
+        int cMask = -1;
+        int cN    = 1;
 
         boolean mergeColumns = true;
-        for (int i = 0; i <= level; ++i) {
+        for (int i = 0; i < stages; ++i) {
             if (mergeColumns) {
-                int split = (nbColumns + 1) / 2;
-                if (column < split) {
-                    cMax = split;
-                } else {
-                    cMin = split;
-                }
-                nbColumns = cMax - cMin;
+                cMask = cMask << 1;
+                cMin  = cMin & cMask;
+                cN    = cN * 2;
             } else {
-                int split = (nbRows + 1) / 2;
-                if (row < split) {
-                    rMax = split;
-                } else {
-                    rMin = split;
-                }
-                nbRows = rMax - rMin;
+                rMask = rMask << 1;
+                rMin  = rMin & rMask;
+                rN    = rN * 2;
             }
             mergeColumns = !mergeColumns;
         }
 
-        return new int[] { rMin, rMax, cMin, cMax };
+        return new int[] {
+            rMin, FastMath.min(rMin + rN, nbRows),
+            cMin, FastMath.min(cMin + cN, nbColumns)
+        };
 
     }