diff --git a/app/Archive.py b/app/Archive.py
index cb9596b57f1b5e483b315302723fe7537284b750..058bba0467453724b4272566d3df484b1dd857e6 100644
--- a/app/Archive.py
+++ b/app/Archive.py
@@ -15,6 +15,7 @@ from uuid import uuid4
 from collections import defaultdict, UserDict
 import app.Satellites as Satellites
 import app.Outils as Outils
+import app.Constantes as Constantes
 
 class Archive():
     """
@@ -39,14 +40,23 @@ class Archive():
         :type annee_fin: Entier
     """
 
-    def __init__(self, capteur, extensions, niveau, emprise, sortie, annee_debut, annee_fin):
+    def __init__(self, capteur, bandes, niveau, emprise, zone_etude, sortie, annee_debut, annee_fin, seuil):
         """
             Créé une instance de la classe 'Archive'.
         """
 
         self._capteur = capteur
         self.niveau = niveau
-        self.extent_img = extensions
+       
+        if bandes == "RGB" :
+            self.extent_img = Satellites.SATELLITE[self._capteur][niveau][:-1]
+        else :
+            self.extent_img = Satellites.SATELLITE[self._capteur][niveau]
+
+        if self.niveau == "LEVEL2A" :
+            self.nuage = Satellites.SATELLITE[self._capteur]["NUAGE"]
+        else : 
+            self.nuage = None
 
         self.liste_annees = []
 
@@ -56,9 +66,10 @@ class Archive():
         self.liste_annees.append(annee_fin)
 
         self.emprise = emprise
+        self.zone_etude = zone_etude
         self.dossier_sortie = sortie
-        self.emprise = emprise
-    
+        self.seuil_nuage = seuil
+
         self.liste_archive = []
 
         self.logger = Outils.Log("log", "Archive")
@@ -392,6 +403,43 @@ class Archive():
 
         self.logger.info("All images have been downloaded !")
 
+    def calcul_ennuagement(self, tuiles_nuage):
+
+        option_warp     = gdal.WarpOptions(format='Mem', cropToCutline=True, outputType=gdal.GDT_Float32,\
+        								   cutlineDSName=self.emprise, dstNodata="NaN")
+        mosaic_nuage    = gdal.Warp("", tuiles_nuage, options=option_warp)
+
+        rows = mosaic_nuage.RasterYSize # Rows number
+        cols = mosaic_nuage.RasterXSize # Columns number
+
+        data = mosaic_nuage.GetRasterBand(1).ReadAsArray(0, 0, cols, rows)
+
+        nombre_pixel_zone = 0
+        nombre_pixel_null = 0
+        nombre_pixel_non_nuage = 0
+
+        for donnees in data :
+            d = donnees.tolist()
+            nombre_pixel_zone += len(d)
+            nombre_pixel_null += d.count(-10000) + np.isnan(d).sum()
+            nombre_pixel_non_nuage += d.count(0)
+
+        nombre_pixel_non_null = nombre_pixel_zone - nombre_pixel_null
+
+        # self.logger.debug("nombre_pixel_non_null : {}".format(nombre_pixel_non_null))
+        # self.logger.debug("nombre_pixel_null : {}".format(nombre_pixel_null))
+        # self.logger.debug("nombre_pixel_non_nuage : {}".format(nombre_pixel_non_nuage))
+
+        del data
+
+        ennuagement = (float(nombre_pixel_non_nuage)/float(nombre_pixel_non_null)) if nombre_pixel_non_null != 0 else 0.0
+        self.logger.debug("Ennuagement : {}%".format(100 - round(ennuagement*100, 2)))
+   
+        # Computer cloud's percentage with dist (sum of cloud) by sum of the image's extent
+        # return mosaic_nuage, 1.0 - (float(dist)/(np.sum(mask_spec)) if np.sum(mask_spec) != 0 else 0)
+        return 1.0 - ennuagement
+
+
     def calcul_aire(self, tuiles_image):
         """
             Méthode pour fusionner un ensemble d'images et calculer l'aire de l'image obtenue.
@@ -409,10 +457,10 @@ class Archive():
         cols = mosaic_image.RasterXSize # Columns number
 
         data        = mosaic_image.GetRasterBand(1).ReadAsArray(0, 0, cols, rows).astype(np.float16)
-        mask_spec   = np.isin(data, [-10000, math.isnan], invert=True)
+        mask_spec   = ~(np.isnan(data) | np.isin(data, [-10000]))
 
         area = float((np.sum(mask_spec) * mosaic_image.GetGeoTransform()[1] * abs(mosaic_image.GetGeoTransform()[-1]) )/10000)
-        self.logger.info("Aire = {0} ha".format(area))
+        # self.logger.info("Aire = {0} ha".format(area))
 
         return mosaic_image, area
 
@@ -458,10 +506,11 @@ class Archive():
         self.logger.info("Date : {0} -> {1} image(s)".format(date, len(liste_content)))
 
         tuiles_image = []
+        tuiles_nuage = []
 
         # Options Gdal pour la fusion des bandes
-        options_vrt         = gdal.BuildVRTOptions(separate=True)
-        options_translate   = gdal.TranslateOptions(format="Mem")
+        options_vrt     	= gdal.ParseCommandLine('-resolution highest -srcnodata -10000 -vrtnodata NaN -separate')
+        options_translate   = gdal.ParseCommandLine('-of Mem -ot Float32 -a_nodata NaN')
 
         self.logger.info("Extraction des images")
 
@@ -493,12 +542,32 @@ class Archive():
             # on découpe l'image selon l'emprise
             # et on conserve l'image obtenue
             vrt = gdal.BuildVRT("", liste_bandes, options=options_vrt)
-            tuiles_image.append(Outils.clip(gdal.Translate("", vrt, options=options_translate), self.emprise))
 
-            # On libère la mémoire
+            image = Outils.clip(vrt, self.zone_etude)
+            _, aire = self.calcul_aire(image)
+
+            if aire > 0.0 :
+                tuiles_image.append(vrt)
+
+                # On libère la mémoire
+                for mmap_name in liste_mem :
+                    gdal.Unlink(mmap_name)
+
+                liste_mem = []
+
+                if self.nuage is not None :
+                    image_nuage = [f for f in zip_img if self.nuage[0] in f][0]
+                    mmap_name = "/vsimem/"+uuid4().hex
+
+                    gdal.FileFromMemBuffer(mmap_name, tzip.read(image_nuage))
+                    liste_mem.append(mmap_name)
+                    tuiles_nuage.append(Outils.clip(gdal.Open(mmap_name), self.zone_etude))
+
             for mmap_name in liste_mem :
                 gdal.Unlink(mmap_name)
 
+            liste_mem = []
+
             liste_bandes = None
 
             del tzip
@@ -506,21 +575,22 @@ class Archive():
 
         del liste_content
 
-        # On effectue une mosaïque des images qu'on découpe selon l'emprise,
-        # puis on calcule l'aire de l'image ainsi obtenue
-        self.logger.info("Calcul de l'aire")
-        image, aire = self.calcul_aire(tuiles_image)
-        del tuiles_image
+        if len(tuiles_image) > 0 :          
+
+            if len(tuiles_nuage) == 0 or self.calcul_ennuagement(tuiles_nuage) <= self.seuil_nuage:
+
+                # On effectue une mosaïque des images qu'on découpe selon l'emprise.
+                image = Outils.clip(tuiles_image, self.emprise)
 
-        # Si l'aire est positive on enregistre l'image
-        if aire > 0.0 :
+                self.logger.info("Sauvegarde des images")
 
-            self.logger.info("Sauvegarde des images")
+                dossier = "{0}/{1}/Images".format(self.dossier_sortie, date[:4])
 
-            dossier = "{0}/{1}/Images".format(self.dossier_sortie, date[:4])
+                self.logger.debug("Dossier image : {0}".format(dossier))
 
-            self.logger.debug("Dossier image : {0}".format(dossier))
+                self.ecriture_geotiff(image, "{0}/{1}.tif".format(dossier,date))
 
-            self.ecriture_geotiff(image, "{0}/{1}.tif".format(dossier,date))
+                del tuiles_nuage
 
-        del image
\ No newline at end of file
+            del tuiles_image
+            del image
\ No newline at end of file
diff --git a/app/Constantes.py b/app/Constantes.py
index e7b1d076377aa234c53b8b073febdc3564fd1e10..7307edc7106f46dd1d856445a11ee8f22a3681d6 100644
--- a/app/Constantes.py
+++ b/app/Constantes.py
@@ -4,13 +4,4 @@
 import logging
 
 NIVEAU_DEFAUT 	= logging.DEBUG
-
-CLOUD_THRESHOLD = 0.0
-
 EPSG_PHYMOBAT 	= 2154
-
-# Extensions des bandes bleue, verte et rouge
-BANDES_RGB = ['_FRC_B2.tif', '_FRC_B3.tif', '_FRC_B4.tif']
-
-# Extensions des bandes bleue, verte et rouge + proche infra-rouge
-BANDES_RGBI = ['_FRC_B2.tif', '_FRC_B3.tif', '_FRC_B4.tif', '_FRC_B8.tif']
diff --git a/app/Outils.py b/app/Outils.py
index bda1c573b7e9792e7d050b92cbc34c3ddcae6241..efec4bc9f938a84ed13cd076876ce555958f6e33 100644
--- a/app/Outils.py
+++ b/app/Outils.py
@@ -97,7 +97,7 @@ def limitation_temporelle(secondes):
 # except TimeoutException:
 #     pass
 
-def clip(image, cut, form="Mem", dst=""):
+def clip(image, cut, form="Mem", dst="", type=gdal.GDT_Float32, nodata="NaN"):
 	"""
 		Découpe une image selon un shapefile donné. Si le type de l'image en sortie
 		n'est pas spécifié, l'image sera retournée en pointeur mémoire et ne sera pas sauvegardée.
@@ -116,6 +116,6 @@ def clip(image, cut, form="Mem", dst=""):
 	"""
         
 	option_clip = gdal.WarpOptions(cropToCutline=True,\
-	cutlineDSName=cut, outputType=gdal.GDT_Float32 , format=form,  dstNodata='NaN')
+	cutlineDSName=cut, outputType=type , format=form, dstNodata=nodata)
 
 	return gdal.Warp(dst, image, options=option_clip)
\ No newline at end of file
diff --git a/app/Processing.py b/app/Processing.py
index 04010fb4475d85f76870bc08917b27874600551d..3c72971bd47528e2db3e62a850446640cfac3ca3 100644
--- a/app/Processing.py
+++ b/app/Processing.py
@@ -27,7 +27,8 @@ class Processing(object):
 		if not self.annee_fin :
 			self.annee_fin = datetime.datetime.now().year
 
-		self.check_download = Archive.Archive(self.capteur, self.extensions, self.niveau, self.emprise, self.resultats, self.annee_debut, int(self.annee_fin))
+		self.check_download = Archive.Archive(self.capteur, self.bandes, self.niveau, self.emprise, self.zone_etude,\
+											  self.resultats, self.annee_debut, int(self.annee_fin), self.seuil_nuage)
 		self.check_download.listing()
 		self.check_download.download_auto(self.id, self.mdp, self.proxy)
 
@@ -99,5 +100,5 @@ class Processing(object):
 		"""
 			Calul le ndvi, fusionnne en une seule image puis lance le module OTBPhenology
 		"""
-		self.calcul_ndvi()
-		self.otbPhenologie()
\ No newline at end of file
+		# self.calcul_ndvi()
+		# self.otbPhenologie()
\ No newline at end of file
diff --git a/app/Satellites.py b/app/Satellites.py
index 2f3eb969221b7dc85e44fd96ca5970d4d7067b58..568009590cc76730b74d2c970a03d61b69435e39 100644
--- a/app/Satellites.py
+++ b/app/Satellites.py
@@ -14,6 +14,9 @@ SATELLITE["SENTINEL2"]["resto"] = "resto2"
 SATELLITE["SENTINEL2"]["token_type"] = "text"
 SATELLITE["SENTINEL2"]["R"] = 2
 SATELLITE["SENTINEL2"]["PIR"] = 3
+SATELLITE["SENTINEL2"]["LEVEL2A"] 	= ['_SRE_B2.tif', '_SRE_B3.tif', '_SRE_B4.tif', '_SRE_B8.tif']
+SATELLITE["SENTINEL2"]["NUAGE"] 	= ['_CLM_R1.tif']
+SATELLITE["SENTINEL2"]["LEVEL3A"] 	= ['_FRC_B2.tif', '_FRC_B3.tif', '_FRC_B4.tif', '_FRC_B8.tif']
 
 ########################## LANDSAT #################################
 
diff --git a/main.py b/main.py
index 8d616da9b10024769665ff1cd46e2d253067f61c..055fe537d3a8613070831911991f9671fc0d7ca1 100644
--- a/main.py
+++ b/main.py
@@ -34,11 +34,7 @@ class Telechargement(Processing):
 		# Capteur utilisé
 		self.capteur = "{}".format(configfile["satellite"]["capteur"])
 		self.niveau = "{}".format(configfile["satellite"]["processingLevel"])
-
-		if configfile["satellite"]["bandes"] == "RGB" :
-			self.extensions = Constantes.BANDES_RGB
-		else :
-			self.extensions = Constantes.BANDES_RGBI
+		self.bandes = "{}".format(configfile["satellite"]["bandes"])
 		
 		# Date de début et de fin de la recherche
 		try:
@@ -47,9 +43,14 @@ class Telechargement(Processing):
 			raise "L'année de départ est requise."
 		
 		self.annee_fin = "{}".format(configfile["donnees"]["annee_fin"])
+		self.seuil_nuage = float("{}".format(configfile["donnees"]["seuil_nuage"]))/100.0
 		
-		# Emprise de l'étude
-		self.emprise = "{}".format(configfile["donnees"]["chemin_emprise"])
+		# Emprise et zone de l'étude
+		self.emprise 	= "{}".format(configfile["donnees"]["chemin_emprise"])
+		self.zone_etude = "{}".format(configfile["donnees"]["chemin_zone_etude"])
+
+		if not self.zone_etude :
+			self.zone_etude = self.emprise
 		
 		# Identifiant, mot de passe et proxy pour le téléchargement des images Théia
 		self.id 	= "{}".format(configfile["theia"]["identifiant"])
@@ -60,9 +61,8 @@ class Telechargement(Processing):
 	def run(self):
 		"""
 			Fonction pour lancer le programme
-		"""
-		
-		# Début du processus
+		"""		
+		Début du processus
 		debut = time.time()
 		
 		# Recherche de nouvelles images non traitées et téléchargement de celles-ci le cas échéant
@@ -77,7 +77,16 @@ class Telechargement(Processing):
 		self.logger.info('Programme terminé en {} secondes'.format(fin - debut))
 		nb_jours = int(time.strftime('%d', time.gmtime(fin - debut))) - 1
 		self.logger.info("Cela représente {} jour(s) {}".format(nb_jours, time.strftime('%Hh %Mmin%S', time.gmtime(fin - debut))))
-		
+
 if __name__ == "__main__":
+
 	app = Telechargement()
-	sys.exit(app.run())
\ No newline at end of file
+
+	SUCCESS = False
+
+	while not SUCCESS :
+		try:
+			sys.exit(app.run())
+			SUCCESS = True
+		except Exception as e:
+			pass	
\ No newline at end of file