diff --git a/scenes/core.py b/scenes/core.py
index 29335bbda58638c80408b9dd7fd2da77015ad24f..dde5c63b5b6f5191a0f9303435d30c04322e2045 100644
--- a/scenes/core.py
+++ b/scenes/core.py
@@ -78,7 +78,7 @@ class Source(pyotb.Output):
         """
         for new_app in args:
             self._app_stack.append(new_app)
-        return Source(root_imagery=self.root_imagery, out=self._app_stack[-1], parent=self)
+        return self.__class__(root_imagery=self.root_imagery, out=self._app_stack[-1], parent=self)
 
     def drilled(self, msk_vec_file, inside=True, nodata=0):
         """
diff --git a/scenes/dates.py b/scenes/dates.py
index 22cdf07e93ba5957638ab740f0d45fff765ea18b..7c63b28c77791d17b839d90198906b69d2602ab7 100644
--- a/scenes/dates.py
+++ b/scenes/dates.py
@@ -1,6 +1,34 @@
 # -*- coding: utf-8 -*-
 """
-This module aims to deal with dates
+This module aims to deal with dates.
+
+---
+
+The `datetime.datetime` class is used as internal date type.
+```
+#!python
+dt = datetime.datetime(year=2020, month=12, day=2)
+```
+Is equivalent to:
+```
+dt = str2datetime("02-12-2020")
+dt = str2datetime("2020-12-02")
+dt = str2datetime("02/12/2020")
+```
+
+The `any2datetime` method returns a `datetime.datetime` instance, whatever the input is (`str` or
+`datetime.datetime`).
+```
+dt1 = datetime.datetime(year=2020, month=12, day=2)
+dt2 = str2datetime("02-12-2020")
+dt1_2 = any2datetime(dt1)  # same
+dt2_2 = any2datetime("02-12-2020")  # same
+```
+
+The `get_timestamp` method converts a `datetime.datetime` instance into a number of seconds (int).
+```
+ts = get_timestamp(dt)  # 1606780800.0
+```
 """
 import datetime
 
diff --git a/scenes/deepnets.py b/scenes/deepnets.py
index c0e063871da5ae71ebb26b82dc80a589dc77c00b..a69cc2aa430461a62518885408b5326667fba410 100644
--- a/scenes/deepnets.py
+++ b/scenes/deepnets.py
@@ -1,7 +1,24 @@
 """
 This module provides tools to easily interact with deep learning models.
 
-It is based on OTBTF.
+OTBTF is needed to use this module.
+
+---
+
+# Super-resolution
+
+The SR4RS model can be applied over any `scenes.core.Source` instance.
+We recall that this model is intended to be used over Sentinel-2 optical images.
+For example, here is how we perform the super-resolution of a Theia S2 product.
+```
+#!python
+import scenes
+archive = "SENTINEL2B_..._T31TEJ_D_V1-8.zip"
+s2_scene = scenes.sentinel.Sentinel22AScene(archive)
+s2_image = s2_scene.get_imagery().get_10m_bands()
+sr = scenes.deepnets.sr4rs(s2_image)  # pyotb.core.otbObject
+sr.write("sr.tif")
+```
 """
 import os
 import zipfile
diff --git a/scenes/download.py b/scenes/download.py
index 7dc533129eeb4da94761a7dbdde31c3840b1b25e..d2b95f6055e88eff8a19168e9fd05999e1e010ee 100644
--- a/scenes/download.py
+++ b/scenes/download.py
@@ -1,6 +1,65 @@
 # -*- coding: utf-8 -*-
 """
 This module handles the download of Sentinel-2 images from Theia (L2A or L3A).
+
+The `scenes.download.TheiaDownloader` uses Theia credentials.
+Those must be stored in a file looking like this:
+
+```
+serveur = https://theia.cnes.fr/atdistrib
+resto = resto2
+token_type = text
+login_theia = remi.cresson@irstea.fr
+password_theia = thisisnotmyrealpassword
+```
+
+To instantiate the `scenes.download.TheiaDownloader`:
+```
+#!python
+import scenes
+cfg_file = "config.txt"  # Theia config file
+theia = scenes.download.TheiaDownloader(cfg_file)
+```
+
+# Bounding box + temporal range
+
+The following example shows how to use the `scenes.download.TheiaDownloader` to search
+or download all Sentinel-2 images in a bounding box within a temporal range.
+
+## Search
+
+When the `download_dir` is not set, the download is not performed, and only the search results
+are returned from the function.
+```
+bbox = scenes.spatial.BoundingBox(43.706, 43.708, 4.317, 4.420)
+trange = ("01/01/2020", "O1/O1/2022")
+results = theia.download_in_range(bbox, trange, level="LEVEL2A")
+print(results)
+```
+
+## Download
+
+To download the files, the `download_dir` must be specified:
+```
+theia.download_in_range(bbox, trange, "/tmp/download/", "LEVEL2A")
+```
+When files already exist, the md5sum is computed and compared with the one in the catalog,
+in order to determine if it has to be downloaded again. If the file is already downloaded and
+is complete according to the md5sum, its download is skipped.
+
+# Bounding box + single date
+
+In the same manner, the downloader can search or download the closest images from a specific date.
+The returned dict from the function is updated with a "delta" key storing the value of the number of
+days from the specific date.
+```
+# For searching only
+results = theia.download_in_range(bbox, trange, "LEVEL2A")
+
+# For downloading
+theia.download_in_range(bbox, trange, "/tmp/download/", "LEVEL2A")
+```
+
 """
 import datetime
 import hashlib
diff --git a/scenes/indexation.py b/scenes/indexation.py
index 9e65553e34606507b7223fd9cb4a8e8d77419544..e8919e531ed67ce3705cfb75e77076b00e9b6eb1 100644
--- a/scenes/indexation.py
+++ b/scenes/indexation.py
@@ -1,5 +1,47 @@
 """
-This module contains stuff for the spatio-temporal indexation of scenes
+This module contains stuff for the spatio-temporal indexation of scenes.
+
+The `scenes.indexation.Index` uses an R-Tree to perform the indexation of objects in the (x, y, t) domain.
+
+---
+
+Example: spatio-temporal indexation of multiple `scenes.core.Scene` instances.
+
+# Build a spatio temporal index
+
+```
+#!python
+import scenes
+scenes_list = [...]  # a list of various `scenes.core.Scene` instances.
+index = scenes.indexation.Index(scenes_list)  # build the index
+```
+
+# Search from a `BoundingBox`
+
+The `find_indices()` method returns the indices of the indexed `scenes.core.Scene` instances matching
+the query.
+The `find()` method returns the indexed `scenes.core.Scene` instances matching the query.
+```
+bbox = BoundingBox(43.706, 43.708, 4.317, 4.420)
+indices_results = index.find_indices(bbox)  # spatial query returning scenes indices
+scenes_results = index.find(bbox)  # spatial query returning scenes instances
+```
+
+# Spatio-temporal search
+
+A date min and/or a date max can be added in the query.
+```
+scenes_results = index.find(bbox, "01/01/2020" "01/01/2022")
+```
+
+# Search from a vector data file
+
+The search can also be performed with a vector data file.
+```
+vec = "/path/to/vector.gpkg"
+scenes_results = index.find(vec, "01/01/2020" "01/01/2022")
+```
+
 """
 import datetime
 import rtree
@@ -27,7 +69,8 @@ def _bbox(bbox_wgs84, date_min, date_max):
 
 class Index:
     """
-    Stores an indexation structures for a list of Scenes"""
+    Stores an indexation structure for a list of Scenes
+    """
     def __init__(self, scenes_list):
         """
         Args:
diff --git a/scenes/sentinel.py b/scenes/sentinel.py
index f2b617209eb1def18fae1e1e36e3fc66543534a2..462a60c93024347d74e08070c9a1fb861dd91e23 100644
--- a/scenes/sentinel.py
+++ b/scenes/sentinel.py
@@ -2,6 +2,97 @@
 This module contains Sentinel-2 classes (sources, imagery, and scenes).
 
 Right now everything is ready to use THEIA L2A and L3A products.
+
+# Scene
+
+The `Sentinel22AScene` and `Sentinel23AScene` classes carry metadata and imagery
+respectively for Sentinel-2 Level 2A and Level 3A products. They both inherit from
+the generic abstract `Sentinel2SceneBase` class.
+
+## Instantiation
+
+`Sentinel22AScene` and `Sentinel23AScene` are instantiated from the archive (.zip file)
+or the product folder.
+```
+#!python
+import scenes
+sc_2a = scenes.sentinel.Sentinel22AScene("SENTINEL2B_..._T31TEJ_D_V1-8.zip")
+sc_3a = scenes.sentinel.Sentinel23AScene("SENTINEL2X_...L3A_T31TEJ_D_V1-0.zip")
+```
+
+## Metadata
+
+The scene metadata can be accessed with the `get_metadata()` method, like any
+`scenes.core.Scene` instance.
+```
+md_dict = sc_2a.get_metadata()
+for key, value in md_dict.items():
+    print(f"{key}: {value}")
+```
+
+## Imagery
+
+The imagery can be accessed with the `get_imagery()` method, which returns a
+`Sentinel22AImagery` or a `Sentinel23AImagery` instance.
+There is a single kind of imagery in `Sentinel22AScene` and `Sentinel23AScene`.
+```
+imagery_2a = sc_2a.get_imagery()
+imagery_3a = sc_3a.get_imagery()
+```
+
+## Sources
+
+The `Sentinel22AImagery` (and `Sentinel23AImagery`) both deliver two kind of `Sentinel22ASource`
+ (and `Sentinel23ASource`) instances:
+
+- The 10m spacing channels, in the following order: 4, 3, 2, 8
+- The 20m spacing channels, in the following order: 5, 6, 7, 8a, 11, 12
+
+```
+bands_10m_2a = imagery_2a.get_10m_bands()
+bands_20m_2a = imagery_2a.get_20m_bands()
+bands_10m_3a = imagery_3a.get_10m_bands()
+bands_20m_3a = imagery_3a.get_20m_bands()
+```
+
+The `Sentinel22ASource` implements the `Sentinel22ASource.cld_msk_drilled` method, that
+enable to mask the cloud masks over the root source, with the specified
+no-data value (default is 0).
+The following example show how to derive a child source replacing the
+pixels that are in the clouds with pixels at -10000 (which is the no-data
+value in Theia products):
+```
+drilled = bands_10m_2a.cld_msk_drilled()
+```
+
+The `Sentinel23ASource` implements the `Sentinel23ASource.flg_msk_drilled` method, that
+enable to mask the pixels on a selection of labels of the quality mask.
+The following example shows how to mask pixels of anything other that land with -10000:
+```
+drilled = bands_10m_3a.flg_msk_drilled(keep_flags_values=(4,))
+```
+
+`Sentinel22ASource` and `Sentinel23ASource` inherit from `scenes.core.Source`,
+hence implemented sources transformations (e.g. `scenes.core.Source.masked`,
+`scenes.core.Source.clip_over_img`, `scenes.core.Source.resample_over`,
+`scenes.core.Source.reproject`, etc.
+```
+clipped = drilled.clip_over_img(roi)
+reprojected = clipped.reproject(epsg=4328)
+```
+Note that the resulting transformed `Sentinel22ASource` and `Sentinel23ASource` are still
+instances of `Sentinel22ASource` and `Sentinel23ASource` even after generic operations
+implemented in `scenes.core.Source`.
+
+# Usage with pyotb
+
+As `scenes.core.Source`, it also can be used like any `pyotb.core.otbObject`.
+The following example show how to use an OTB application with a source at input.
+```
+rgb_nice = pyotb.DynamicConvert(reprojected)
+rgb_nice.write("image.tif", pixel_type="uint8")
+```
+
 """
 import datetime
 from abc import abstractmethod
@@ -60,12 +151,13 @@ class Sentinel23ASource(Sentinel2Source):
 
         Args:
             keep_flags_values: flags values to keep (Default value = (3, 4)). Can be:
-                               0 = No data
-                               1 = Cloud
-                               2 = Snow
-                               3 = Water
-                               4 = Land
-                               (source: https://labo.obs-mip.fr/multitemp/theias-l3a-product-format/)
+
+               - 0 = No data
+               - 1 = Cloud
+               - 2 = Snow
+               - 3 = Water
+               - 4 = Land
+               (source: https://labo.obs-mip.fr/multitemp/theias-l3a-product-format/)
             nodata: nodata value inside holes (Default value = -10000)
 
         Returns:
diff --git a/scenes/spatial.py b/scenes/spatial.py
index 98facf352f820d5852b73eafa5e7523c39cfd342..607ff9884ab0388e236ddec218bb6cc885d6a22b 100644
--- a/scenes/spatial.py
+++ b/scenes/spatial.py
@@ -1,5 +1,6 @@
 """
-This module provides classes and functions to help with light geospatial objects (projections, bounding boxes, etc)
+This module provides classes and functions to help with light geospatial objects
+(projections, bounding boxes, etc).
 """
 import math
 from osgeo import osr, ogr
diff --git a/scenes/spot.py b/scenes/spot.py
index 84bd623db348252f3c81ffdd49ae59cc4b29671a..9765172a89ef00087df0380948e235c4042e5676 100644
--- a/scenes/spot.py
+++ b/scenes/spot.py
@@ -1,5 +1,88 @@
 """
-This module contains Spot 6/7 classes. It implements sources, imagery and scene.
+This module contains classes to work with Spot 6/7 products.
+In particular, it specializes `scenes.core.Source`, `scenes.core.Imagery`
+and `scenes.core.Scene` for Spot 6/7 products.
+
+---
+
+# Scene
+
+The `Spot67Scene` class carries metadata and imagery for Spot-6/7 sensors.
+
+## Instantiation
+
+A `Spot67Scene` is instantiated from the .XML DIMAP files of PAN and XS:
+```
+#!python
+import scenes
+sc = scenes.spot.Spot67Scene(dimap_file_xs="DIM_SPOT6_MS..._1.XML",
+                             dimap_file_pan="DIM_SPOT6_P..._1.XML")
+```
+
+## Metadata
+
+The scene metadata can be accessed with the `get_metadata()` method, like any
+`scenes.core.Scene` instance.
+```
+md_dict = sc.get_metadata()
+for key, value in md_dict.items():
+    print(f"{key}: {value}")
+```
+
+## Imagery
+
+The imagery can be accessed with the `get_imagery()` method, which returns a
+`Spot67Imagery` instance.
+Two kind of imagery exist:
+
+- DN (Digital Number): raw sensor values
+- TOA (Top Of Atmosphere): calibrated reflectance
+```
+imagery_dn = sc.get_imagery(reflectance="dn")  # uncalibrated
+imagery_toa = sc.get_imagery(reflectance="toa")  # TOA reflectance
+```
+
+## Sources
+
+The `Spot67Imagery` delivers three kind of `Spot67Source` instances:
+
+- The multispectral image
+- The Panchromatic image
+- The pansharpenend image
+```
+xs = imagery.get_xs()  # Multispectral image Source
+pan = imagery.get_pan()  # Panchromatic image Source
+pxs = imagery.get_pxs(method="bayes")  # Pansharpened Source
+```
+
+The `Spot67Source` implements the `Spot67Source.cld_msk_drilled` method, that
+enable to mask the cloud masks over the root source, with the specified
+no-data value (default is 0).
+The following example show how to derive a child source replacing the
+pixels that are in the clouds with zero-valued pixels:
+```
+pxs_drilled = pxs.cld_msk_drilled()
+```
+
+The `Spot67Source` inherits from `scenes.core.Source`, hence implemented
+sources transformations (e.g. `scenes.core.Source.masked()`, `scenes.core.Source.clip_over_img()`,
+`scenes.core.Source.resample_over()`, `scenes.core.Source.reproject()`, etc.
+```
+clipped = pxs_drilled.clip_over_img(roi)
+reprojected = clipped.reproject(epsg=4328)
+```
+Note that the resulting transformed `Spot67Source` is still an instance of
+`Spot67Source` even after generic operations implemented in `scenes.core.Source`.
+
+# Usage with pyotb
+
+As `scenes.core.Source`, it also can be used like any `pyotb.core.otbObject`.
+The following example show how to use an OTB application with a source at input.
+```
+rgb_nice = pyotb.DynamicConvert(reprojected)
+rgb_nice.write("image.tif", pixel_type="uint8")
+```
+
 """
 import datetime
 import xml.etree.ElementTree as ET
@@ -13,13 +96,13 @@ from scenes.spatial import extent_overlap
 
 def find_all_dimaps(pth):
     """
-    Return the list of DIMAPS that are inside all subdirectories of the root directory
+    Return the list of DIMAPS XML files that are inside all subdirectories of the root directory.
 
     Args:
         pth: root directory
 
     Returns:
-        list of DIMAPS
+        list of DIMAPS XML files
 
     """
     return utils.find_files_in_all_subdirs(pth=pth, pattern="DIM_*.XML")
@@ -27,7 +110,8 @@ def find_all_dimaps(pth):
 
 def get_spot67_scenes(root_dir):
     """
-    Return the list of pairs of PAN/XS DIMAPS
+    Return the list of scenes that can be instantiated from a root directory containing
+    a "PAN" and a "MS" subdirectories.
 
     Args:
         root_dir: directory containing "MS" and "PAN" subdirectories
@@ -100,7 +184,11 @@ class Spot67Imagery(Imagery):
     """
     Spot 6/7 imagery class.
 
-    This class carry the base image source, which can be radiometrically or geometrically corrected.
+    A `Spot67Imagery` instance carries the following `Spot67Source` instances:
+
+    - xs: the multispectral channels (Red, Gree, Blue, Near infrared @ 6.0 meters spacing)
+    - pan: the panchromatic channel (Visible domain @ 1.5 meters spacing)
+    - pxs: the pansharpened channels (Red, Gree, Blue, Near infrared @ 1.5 meters spacing)
 
     """
 
@@ -126,20 +214,34 @@ class Spot67Imagery(Imagery):
             self.pan = _toa(self.pan)
 
     def get_xs(self):
-        """Returns XS source"""
+        """
+        Returns the MS source
+
+        Returns:
+            A Spot67Source instance for the MS image
+
+        """
         return Spot67Source(self, self.xs)
 
     def get_pan(self):
-        """Returns PAN source"""
+        """
+        Returns PAN source
+
+        Returns:
+            A Spot67Source instance for the PAN image
+
+        """
         return Spot67Source(self, self.pan)
 
     def get_pxs(self, method="bayes"):
         """
+        Returns the pansharpened source
+
         Args:
             method: one of rcs, lmvm, bayes (Default value = "bayes")
 
         Returns:
-            Pansharpened XS source
+            A Spot67Source instance for the pansharpened image
 
         """
         xs = self.get_xs()
@@ -153,7 +255,8 @@ class Spot67Scene(Scene):
     """
     Spot 6/7 root_scene class.
 
-    The class carries all the metadata from the root_scene, and can be used to retrieve its imagery.
+    The Spot67Scene class carries all metadata and imagery from the scene.
+    A Spot67Scene object can be instantiated from the XS and PAN DIMAPS (.XML) file.
 
     """
     PXS_OVERLAP_THRESH = 0.995
@@ -161,8 +264,9 @@ class Spot67Scene(Scene):
     def __init__(self, dimap_file_xs, dimap_file_pan):
         """
         Args:
-            dimap_file_xs: DIMAP file for XS
-            dimap_file_pan: DIMAP file for PAN
+            dimap_file_xs: XML DIMAP file for the XS product
+            dimap_file_pan: XML DIMAP file for the PAN product
+
         """
 
         # DIMAP files
@@ -298,7 +402,9 @@ class Spot67Scene(Scene):
 
     def get_metadata(self):
         """
-        Get metadata
+        Get metadata.
+
+        The metadata is stored in a dict().
 
         Returns:
             metadata: dict