diff --git a/km3io/tools.py b/km3io/tools.py
index fbc7b1b2815b8922e9bc940591fa4be05312d3fc..910d24c893e5d00983738a779a36433b6b42b27b 100644
--- a/km3io/tools.py
+++ b/km3io/tools.py
@@ -240,6 +240,33 @@ def get_multiplicity(tracks, rec_stages):
 
 
 def best_track(tracks, start=None, end=None, stages=None):
+    """Best track selection.
+
+    Parameters
+    ----------
+    tracks : class km3io.offline.OfflineBranch
+        tracks of interest. tracks can be from multiple events, or from one event, or a slice of tracks.
+    start : None, optional
+        the exact starting step of rec_stages, as in tracks.rec_stages.
+    end : None, optional
+        the exact ending step of rec_stages, as in tracks.rec_stages.
+    stages : None, optional
+        either a list or a set of stages:
+        - if stages is a list, the order of the rec_stages is conserved.
+        - if stages in a set, the order is irrelevant.
+
+    Returns
+    -------
+    class km3io.offline.OfflineBranch
+        the best tracks based on the rec_stages selection. The logest track and the highest likelihood track is returned.
+
+    Raises
+    ------
+    ValueError
+        valueError raised when:
+            - too many inputs specified.
+            - no inputs are specified.
+    """
     if (start is None) and (end is None) and (stages is not None):
         selected_tracks = tracks[mask(tracks, stages=stages)]
 
@@ -256,6 +283,7 @@ def best_track(tracks, start=None, end=None, stages=None):
 
 
 def _longest_tracks(tracks):
+    """ select the longest reconstructed track"""
     if tracks.is_single:
         stages_nesting_level = 1
         tracks_nesting_level = 0
@@ -272,6 +300,7 @@ def _longest_tracks(tracks):
 
 
 def _max_lik_track(tracks):
+    """ select the track with the highest likelihood """
     if tracks.is_single:
         tracks_nesting_level = 0
     else:
@@ -281,20 +310,33 @@ def _max_lik_track(tracks):
 
 
 def mask(tracks, stages=None, start=None, end=None):
-    """create a mask on tracks.rec_stages .
+    """create a mask for tracks.rec_stages .
 
     Parameters
     ----------
-    rec_stages : awkward1 Array
-        tracks.rec_stages .
-    stages : list
-        reconstruction stages of interest.
+    tracks : class km3io.offline.OfflineBranch
+        tracks, or one track, or slice of tracks, or slice of one track.
+    stages : list or set
+        reconstruction stages of interest:
+        - if stages is a list: the order of rec_stages in conserved.
+        - if stages is a set: the order of rec_stages in irrelevant.
+    start : None, optional
+        the exact starting step of rec_stages, as in tracks.rec_stages.
+    end : None, optional
+        the exact ending step of rec_stages, as in tracks.rec_stages.
 
     Returns
     -------
     awkward1 Array
         an awkward1 Array mask where True corresponds to the positions
         where stages were found. False otherwise.
+
+    Raises
+    ------
+    ValueError
+        valueError raised when:
+            - too many inputs specified.
+            - no inputs are specified.
     """
     if (stages is None) and (start is None) and (end is None):
         raise ValueError("either stages or (start and end) must be specified")
@@ -308,32 +350,16 @@ def mask(tracks, stages=None, start=None, end=None):
             return _mask_explicit_rec_stages(tracks, stages)
         if isinstance(stages, set):
             # order of stages is no longer conserved
-            s = min(stages)
-            e = max(stages)
-            return _mask_rec_stages_in_range_start_end(tracks, s, e)
+            mini = min(stages)
+            maxi = max(stages)
+            return _mask_rec_stages_in_range_min_max(tracks, mini, maxi)
 
     if (stages is None) and (start is not None) and (end is not None):
         return _mask_rec_stages_between_start_end(tracks, start, end)
 
 
 def _mask_rec_stages_between_start_end(tracks, start, end):
-    """mask tracks where tracks.rec_stages  are between start and end .
-
-    Parameters
-    ----------
-    rec_stages : awkward1 Array
-        tracks.rec_stages .
-    start : int
-        start of reconstruction stages of interest.
-    end : int
-        end of reconstruction stages of interest.
-
-    Returns
-    -------
-    awkward1 Array
-        an awkward1 Array mask where True corresponds to the positions
-        where stages were found. False otherwise.
-    """
+    """ mask tracks.rec_stages that start exactly with start and end exactly with end. ie [start, a, b ...,z , end] """
     builder = ak1.ArrayBuilder()
     if tracks.is_single:
         _find_between_single(tracks.rec_stages, start, end, builder)
@@ -345,21 +371,7 @@ def _mask_rec_stages_between_start_end(tracks, start, end):
 
 @nb.jit(nopython=True)
 def _find_between(rec_stages, start, end, builder):
-    """construct an awkward1 array with the same structure as tracks.rec_stages.
-    When stages are between start and end, the Array is filled with value 1, otherwise it is filled
-    with value 0.
-
-    Parameters
-    ----------
-    rec_stages : awkward1 Array
-        tracks.rec_stages .
-    start : int
-        start of reconstruction stages of interest.
-    end : int
-        end of reconstruction stages of interest.
-    builder : awkward1.highlevel.ArrayBuilder
-        awkward1 Array builder.
-    """
+    """ find tracks.rec_stages where rec_stages[0] == start and rec_stages[-1] == end."""
 
     for s in rec_stages:
         builder.begin_list()
@@ -377,21 +389,7 @@ def _find_between(rec_stages, start, end, builder):
 
 @nb.jit(nopython=True)
 def _find_between_single(rec_stages, start, end, builder):
-    """construct an awkward1 array with the same structure as tracks.rec_stages.
-    When stages are between start and end, the Array is filled with value 1, otherwise it is filled
-    with value 0.
-
-    Parameters
-    ----------
-    rec_stages : awkward1 Array
-        tracks.rec_stages .
-    start : int
-        start of reconstruction stages of interest.
-    end : int
-        end of reconstruction stages of interest.
-    builder : awkward1.highlevel.ArrayBuilder
-        awkward1 Array builder.
-    """
+    """ find tracks.rec_stages where rec_stages[0] == start and rec_stages[-1] == end in a single track. """
 
     builder.begin_list()
     for s in rec_stages:
@@ -407,14 +405,14 @@ def _find_between_single(rec_stages, start, end, builder):
 
 
 def _mask_explicit_rec_stages(tracks, stages):
-    """create a mask on tracks.rec_stages .
+    """mask explicit rec_stages .
 
     Parameters
     ----------
-    rec_stages : awkward1 Array
-        tracks.rec_stages .
+    tracks : class km3io.offline.OfflineBranch
+        tracks or one track, or slice of tracks.
     stages : list
-        reconstruction stages of interest.
+        reconstruction stages of interest. The order of stages is conserved.
 
     Returns
     -------
@@ -422,7 +420,7 @@ def _mask_explicit_rec_stages(tracks, stages):
         an awkward1 Array mask where True corresponds to the positions
         where stages were found. False otherwise.
     """
-    # rec_stages = tracks.rec_stages
+
     builder = ak1.ArrayBuilder()
     if tracks.is_single:
         _find_single(tracks.rec_stages, ak1.Array(stages), builder)
@@ -441,7 +439,7 @@ def _find(rec_stages, stages, builder):
     Parameters
     ----------
     rec_stages : awkward1 Array
-        tracks.rec_stages .
+        tracks.rec_stages from multiple events.
     stages : awkward1 Array
         reconstruction stages of interest.
     builder : awkward1.highlevel.ArrayBuilder
@@ -474,7 +472,7 @@ def _find_single(rec_stages, stages, builder):
     Parameters
     ----------
     rec_stages : awkward1 Array
-        tracks.rec_stages .
+        tracks.rec_stages from a SINGLE event.
     stages : awkward1 Array
         reconstruction stages of interest.
     builder : awkward1.highlevel.ArrayBuilder
@@ -498,44 +496,92 @@ def _find_single(rec_stages, stages, builder):
 
 
 def best_jmuon(tracks):
-    mask = _mask_rec_stages_in_range_start_end(tracks, krec.JMUONBEGIN,
-                                               krec.JMUONEND)
+    """select the best JMUON track.
+
+    Parameters
+    ----------
+    tracks : class km3io.offline.OfflineBranch
+        tracks, or one track, or slice of tracks, or slices of tracks.
+
+    Returns
+    -------
+    km3io.offline.OfflineBranch
+        the longest + highest likelihood track reconstructed with JMUON.
+    """
+    mask = _mask_rec_stages_in_range_min_max(tracks, krec.JMUONBEGIN,
+                                             krec.JMUONEND)
 
     return _max_lik_track(_longest_tracks(tracks[mask]))
 
 
 def best_jshower(tracks):
-    mask = _mask_rec_stages_in_range_start_end(tracks, krec.JSHOWERBEGIN,
-                                               krec.JSHOWEREND)
+    """select the best JSHOWER track.
+
+    Parameters
+    ----------
+    tracks : class km3io.offline.OfflineBranch
+        tracks, or one track, or slice of tracks, or slices of tracks.
+
+    Returns
+    -------
+    km3io.offline.OfflineBranch
+        the longest + highest likelihood track reconstructed with JSHOWER.
+    """
+    mask = _mask_rec_stages_in_range_min_max(tracks, krec.JSHOWERBEGIN,
+                                             krec.JSHOWEREND)
 
     return _max_lik_track(_longest_tracks(tracks[mask]))
 
 
 def best_aashower(tracks):
-    mask = _mask_rec_stages_in_range_start_end(tracks, krec.AASHOWERBEGIN,
-                                               krec.AASHOWEREND)
+    """select the best AASHOWER track.
+
+    Parameters
+    ----------
+    tracks : class km3io.offline.OfflineBranch
+        tracks, or one track, or slice of tracks, or slices of tracks.
+
+    Returns
+    -------
+    km3io.offline.OfflineBranch
+        the longest + highest likelihood track reconstructed with AASHOWER.
+    """
+    mask = _mask_rec_stages_in_range_min_max(tracks, krec.AASHOWERBEGIN,
+                                             krec.AASHOWEREND)
 
     return _max_lik_track(_longest_tracks(tracks[mask]))
 
 
 def best_dusjshower(tracks):
-    mask = _mask_rec_stages_in_range_start_end(tracks, krec.DUSJSHOWERBEGIN,
-                                               krec.DUSJSHOWEREND)
+    """select the best DISJSHOWER track.
+
+    Parameters
+    ----------
+    tracks : class km3io.offline.OfflineBranch
+        tracks, or one track, or slice of tracks, or slices of tracks.
+
+    Returns
+    -------
+    km3io.offline.OfflineBranch
+        the longest + highest likelihood track reconstructed with DUSJSHOWER.
+    """
+    mask = _mask_rec_stages_in_range_min_max(tracks, krec.DUSJSHOWERBEGIN,
+                                             krec.DUSJSHOWEREND)
 
     return _max_lik_track(_longest_tracks(tracks[mask]))
 
 
-def _mask_rec_stages_in_range_start_end(tracks, start, end):
-    """mask tracks where tracks.rec_stages  are between start and end .
+def _mask_rec_stages_in_range_min_max(tracks, min, max):
+    """mask tracks where rec_stages are withing the range(min, max).
 
     Parameters
     ----------
-    rec_stages : awkward1 Array
-        tracks.rec_stages .
-    start : int
-        start of reconstruction stages of interest.
-    end : int
-        end of reconstruction stages of interest.
+    tracks : class km3io.offline.OfflineBranch
+        tracks, or one track, or slice of tracks, or slices of tracks.
+    min : int
+        minimum range of rec_stages.
+    max : int
+        maximum range of rec_stages.
 
     Returns
     -------
@@ -545,31 +591,31 @@ def _mask_rec_stages_in_range_start_end(tracks, start, end):
     """
     builder = ak1.ArrayBuilder()
     if tracks.is_single:
-        _find_in_range_single(tracks.rec_stages, start, end, builder)
+        _find_in_range_single(tracks.rec_stages, min, max, builder)
         return (builder.snapshot() == 1)[0]
     else:
-        _find_in_range(tracks.rec_stages, start, end, builder)
+        _find_in_range(tracks.rec_stages, min, max, builder)
         return builder.snapshot() == 1
 
 
 @nb.jit(nopython=True)
-def _find_in_range(rec_stages, start, end, builder):
+def _find_in_range(rec_stages, min, max, builder):
     """construct an awkward1 array with the same structure as tracks.rec_stages.
-    When stages are between start and end, the Array is filled with value 1, otherwise it is filled
+    When stages are within the range(min, max), the Array is filled with value 1, otherwise it is filled
     with value 0.
 
     Parameters
     ----------
     rec_stages : awkward1 Array
-        tracks.rec_stages .
-    start : int
-        start of reconstruction stages of interest.
-    end : int
-        end of reconstruction stages of interest.
+        tracks.rec_stages of MULTILPLE events.
+    min : int
+        minimum range of rec_stages.
+    max : int
+        maximum range of rec_stages.
     builder : awkward1.highlevel.ArrayBuilder
         awkward1 Array builder.
     """
-    valid_stages = set(range(start, end + 1))
+    valid_stages = set(range(min, max + 1))
     for s in rec_stages:
         builder.begin_list()
         for i in s:
@@ -589,25 +635,25 @@ def _find_in_range(rec_stages, start, end, builder):
 
 
 @nb.jit(nopython=True)
-def _find_in_range_single(rec_stages, start, end, builder):
+def _find_in_range_single(rec_stages, min, max, builder):
     """construct an awkward1 array with the same structure as tracks.rec_stages.
-    When stages are between start and end, the Array is filled with value 1, otherwise it is filled
+    When stages are within the range(min, max), the Array is filled with value 1, otherwise it is filled
     with value 0.
 
     Parameters
     ----------
     rec_stages : awkward1 Array
-        tracks.rec_stages .
-    start : int
-        start of reconstruction stages of interest.
-    end : int
-        end of reconstruction stages of interest.
+        tracks.rec_stages of a SINGLE event.
+    min : int
+        minimum range of rec_stages.
+    max : int
+        maximum range of rec_stages.
     builder : awkward1.highlevel.ArrayBuilder
         awkward1 Array builder.
     """
 
     builder.begin_list()
-    valid_stages = set(range(start, end + 1))
+    valid_stages = set(range(min, max + 1))
     for s in rec_stages:
         num_stages = len(s)
         if num_stages != 0: