diff --git a/.gitignore b/.gitignore
index 7e99e367f8443d86e5e8825b9fda39dfbb39630d..83658ec52733073084336058333361a36e6c8de6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-*.pyc
\ No newline at end of file
+*.pyc
+*.log
diff --git a/Archive.py b/Archive.py
index 04d24254705a04dd56a335eec985a3089baa3947..55f948ee8fc367d2b00b6456fd05aed972e6d26e 100644
--- a/Archive.py
+++ b/Archive.py
@@ -18,43 +18,44 @@
 # along with PHYMOBAT 3.0.  If not, see <http://www.gnu.org/licenses/>.
 
 import os, sys, glob, re, shutil, time
-import math, subprocess, json, urllib # urllib2
+import math, subprocess, json
+import urllib.request
 import tarfile, zipfile
 
 try :
     import ogr
 except :
-    from osgeo import ogr
+    import osgeo.ogr as org
 
-# import UserDict
 import numpy as np
-from lxml import etree
+import lxml
 from collections import defaultdict, UserDict
+import Constantes, Satellites, Outils
 
-from RasterSat_by_date import RasterSat_by_date
+import RasterSat_by_date
 
 class Archive():
     """
-    Class to list, download and unpack Theia image archive because of a shapefile (box).
-    This shapefile get extent of the area.
-            
-    :param captor: Name of the satellite (ex: Landsat or SpotWorldHeritage ...). 
-                                
-                            Name used to the url on website Theia Land
-    :type captor: str
-    :param list_year: Processing's year (string for one year)
-    :type list_year: list of str
-    :param box: Path of the study area
-    :type box: str
-    :param folder: Path of the source folder
-    :type folder: str
-    :param repertory: Name of the archive's folder
-    :type repertory: str
+        Class to list, download and unpack Theia image archive because of a shapefile (box).
+        This shapefile get extent of the area.
+                
+        :param captor: Name of the satellite (ex: Landsat or SpotWorldHeritage ...). 
+                                    
+                                Name used to the url on website Theia Land
+        :type captor: str
+        :param list_year: Processing's year (string for one year)
+        :type list_year: list of str
+        :param box: Path of the study area
+        :type box: str
+        :param folder: Path of the source folder
+        :type folder: str
+        :param repertory: Name of the archive's folder
+        :type repertory: str
     """
     
     def __init__(self, captor, list_year, box, folder, repertory, proxy_enabled):
-        """Create a new 'Archive' instance
-        
+        """
+            Create a new 'Archive' instance
         """
         self._captor = captor
         self._list_year = list_year.split(";")
@@ -67,38 +68,31 @@ class Archive():
         # 1. List of the website path archives
         # 2. List of the local path archives
         self.list_archive = []
-        self.server = '' # Host
-        self.resto =''
-        # Info from Theia-land website or Olivier Hagolle blog
-        if self._captor == 'SENTINEL2':
-            self.server = 'https://theia.cnes.fr/atdistrib'
-            self.resto = 'resto2'
-            self.token_type = 'text'
-        else:
-            self.server = 'https://theia-landsat.cnes.fr'
-            self.resto = 'resto'
-            self.token_type = 'json'
+
+        self.logger = Outils.Log("Log", "archive")
+
+        self.server = Satellites.SATELLITE[self._captor]["server"]
+        self.resto = Satellites.SATELLITE[self._captor]["resto"]
+        self.token_type = Satellites.SATELLITE[self._captor]["token_type"]
+
         self.url = '' # str : complete website JSON database
         
         self.list_img = [] # List (dim 5) to get year, month, day, path of multispectral's images and path of cloud's images
         self.single_date = [] # date list without duplication
-        
-    def __str__(self) :
-        return 'Year\'s list : ', self._list_year
-    
+            
     def set_list_archive_to_try(self, few_list_archive):
         """
-        Test function to download a few archives
-        
-        :param few_list_archive: [archive_download, out_archive]
-                    
-                    with :
-        
-                    * archive_dowload : Archives downloaded
-                    
-                    * out_archive : Output archives path
-                    
-        :type few_list_archive: list dimension 2
+            Test function to download a few archives
+            
+            :param few_list_archive: [archive_download, out_archive]
+                        
+                        with :
+            
+                        * archive_dowload : Archives downloaded
+                        
+                        * out_archive : Output archives path
+                        
+            :type few_list_archive: list dimension 2
         """
         
         _few_list_archive = np.array(few_list_archive)
@@ -110,21 +104,20 @@ class Archive():
         
     def utm_to_latlng(self, zone, easting, northing, northernHemisphere=True):
         """
-        Function to convert UTM to geographic coordinates 
-        
-        :param zone: UTM zone
-        :type zone: int
-        :param easting: Coordinates UTM in x
-        :type easting: float
-        :param northing: Coordinates UTM in y
-        :type northing: float
-        :param northernHemisphere: North hemisphere or not
-        :type northernHemisphere: boolean
-        
-        :returns: tuple -- integer on the **longitude** and **latitude**
-        
-        Source : http://www.ibm.com/developerworks/java/library/j-coordconvert/index.html
-        
+            Function to convert UTM to geographic coordinates 
+            
+            :param zone: UTM zone
+            :type zone: int
+            :param easting: Coordinates UTM in x
+            :type easting: float
+            :param northing: Coordinates UTM in y
+            :type northing: float
+            :param northernHemisphere: North hemisphere or not
+            :type northernHemisphere: boolean
+            
+            :returns: tuple -- integer on the **longitude** and **latitude**
+            
+            Source : http://www.ibm.com/developerworks/java/library/j-coordconvert/index.html
         """
         
         if not northernHemisphere:
@@ -179,18 +172,18 @@ class Archive():
 
     def coord_box_dd(self):
         """
-        Function to get area's coordinates of shapefile
+            Function to get area's coordinates of shapefile
 
-        :returns: str -- **area_coord_corner** : Area coordinates corner
-        
-                    --> Left bottom on x, Left bottom on y, Right top on x, Right top on y
-        :Example:
-        
-        >>> import Archive
-        >>> test = Archive(captor, list_year, box, folder, repertory, proxy_enabled) 
-        >>> coor_test = test.coord_box_dd()
-        >>> coor_test
-        '45.52, 2.25, 46.71, 3.27'
+            :returns: str -- **area_coord_corner** : Area coordinates corner
+            
+                        --> Left bottom on x, Left bottom on y, Right top on x, Right top on y
+            :Example:
+            
+            >>> import Archive
+            >>> test = Archive(captor, list_year, box, folder, repertory, proxy_enabled) 
+            >>> coor_test = test.coord_box_dd()
+            >>> coor_test
+            '45.52, 2.25, 46.71, 3.27'
         """
         
         # Processus to convert the UTM shapefile in decimal degrees shapefile with ogr2ogr in command line 
@@ -208,7 +201,7 @@ class Archive():
         data_source = driver.Open(utm_outfile, 0)
         
         if data_source is None:
-            print ('Could not open file')
+            self.logger.error('Could not open file')
             sys.exit(1)
         
         shp_ogr = data_source.GetLayer()
@@ -230,56 +223,45 @@ class Archive():
     
     def listing(self):
         """
-        Function to list available archive on plateform Theia Land, and on the area
-
+            Function to list available archive on plateform Theia Land, and on the area
         """
         
         # Loop on the years
-        print ("Images availables")
+        self.logger.info("Images availables")
         for year in self._list_year:
             
             first_date = year.split(',')[0]
             # Tricks to put whether a year or a date (year-month-day)
             try:
                 end_date = year.split(',')[1]
-                print ("=============== " + str(first_date) + " to " + str(end_date) + " ===============")
-                self.url = self.server + '/' + self.resto + '/api/collections/' + self._captor + '/search.json?lang=fr&_pretty=true&completionDate=' + str(end_date) + '&box=' + self.coord_box_dd() + '&maxRecord=500&startDate=' + str(first_date)
-
+                self.logger.info("=============== {0} to {1} ===============".format(first_date, end_date))
+                self.url = "{0}/{1}/api/collections/{2}/search.json?lang=fr&_pretty=true&completionDate={3}&box={4}&maxRecord=500&startDate={5}".format(self.server, self.resto, self._captor, end_date, self.coord_box_dd(), first_date) 
             except IndexError:
-                print ("=============== " + str(first_date) + " ===============" )
-                self.url = self.server + '/' + self.resto + '/api/collections/' + self._captor + '/search.json?lang=fr&_pretty=true&q=' + str(year) + '&box=' + self.coord_box_dd() + '&maxRecord=500'
+                self.logger.info("=============== {0} ===============".format(first_date))
+                self.url =  "{0}/{1}/api/collections/{2}/search.json?lang=fr&_pretty=true&q={3}&box={4}&maxRecord=500".format(self.server, self.resto, self._captor, year, self.coord_box_dd())
 
-            print (self.url)
-            # Link to connect in the database JSON of the Theia plateform
-#             self.url = r'https://theia.cnes.fr/resto/api/collections/' + self._captor + '/search.json?lang=fr&_pretty=true&q=' + str(year) + '&box=' + self.coord_box_dd() + '&maxRecord=500'
-            # Temporary link
-#             if self._captor == 'SENTINEL2':
-#                 self.url = r'https://theia.cnes.fr/atdistrib/resto2/api/collections/'
-#             else:
-#                 self.url = r'https://theia-landsat.cnes.fr/resto/api/collections/'
-            
             # Initialisation variable for a next page 
             # There is a next page, next = 1
             # There isn't next page, next = 0
             next_ = 1
-            if not os.path.exists(self._folder + '/' + self._repertory):
-                os.mkdir(self._folder + '/' + self._repertory)
+            if not os.path.exists("{0}/{1}".format(self._folder ,self._repertory)):
+                os.mkdir("{0}/{1}".format(self._folder ,self._repertory))
                 
             # To know path to download images
             while next_ == 1:
                 
                 try :
-                    request_headers = {"User-Agent": "Firefox/48.0"}
-                    req = urllib.Request(str(self.url), headers = request_headers) # Connexion in the database
-                    data = urllib.urlopen(req).read() # Read in the database
-                    
-                    new_data = re.sub("null", "'null'", data) # Remove "null" because Python don't like
-                    new_data = re.sub("false", "False", new_data) # Remove "false" and replace by False (Python know False with a capital letter F)
-                    
+                    request_headers = {"User-Agent": "Magic-browser"}
+                    req = urllib.request.Request(self.url, headers = request_headers) # Connexion in the database
+                    data = urllib.request.urlopen(req).read() # Read in the database
+
+                    new_data = re.sub(b"null", b"'null'", data) # Remove "null" because Python don't like
+                    new_data = re.sub(b"false", b"False", new_data) # Remove "false" and replace by False (Python know False with a capital letter F)
+
                     # Transform the data in dictionary
                     data_Dict = defaultdict(list)
-                    data_Dict = UserDict.UserDict(eval(new_data))    
-                    
+                    data_Dict = UserDict(eval(new_data))  
+    
                     # Select archives to download
                     for d in range(len(data_Dict['features'])):
                         name_archive = data_Dict['features'][d]['properties']['productIdentifier']    
@@ -288,29 +270,31 @@ class Archive():
                         url_archive = link_archive.replace(self.resto, "rocket/#")
                         archive_download = url_archive.replace("/download", "") # Path to download
                         out_archive = self._folder + '/' + self._repertory + '/' + name_archive + '.tgz' # Name after download
-                        self.list_archive.append([archive_download, out_archive, feature_id])  
+                        if len(self.list_archive) == 0 : self.list_archive.append([archive_download, out_archive, feature_id]) 
                     
                     # Verify if there is another page (next)
                     if data_Dict['properties']['links'][len(data_Dict['properties']['links'])-1]['title'] == 'suivant':
                         self.url = data_Dict['properties']['links'][len(data_Dict['properties']['links'])-1]['href'].replace("\\", "")
                     else:
                         next_ = 0
-                except:
-                    print ("Error connexion or error variable !")
+
+                except Exception as e:
+                    self.logger.error("Error connexion or error variable : {0}".format(e))
                     sys.exit(1)
 
-        print ("There is " + str(len(self.list_archive)) + " images to download !")
+        self.logger.info("{0} image(s) matched the criteria.".format(len(self.list_archive)))
+
+        return len(self.list_archive)
 
     def download_auto(self, user_theia, password_theia):
         """
-        Function to download images archive automatically on Theia land data center.
-        Source : https://github.com/olivierhagolle/theia_download
-        
-        :param user_theia: Username Theia Land data center
-        :type user_theia: str
-        :param password_theia: Password Theia Land data center
-        :type password_theia: str
-        
+            Function to download images archive automatically on Theia land data center.
+            Source : https://github.com/olivierhagolle/theia_download
+            
+            :param user_theia: Username Theia Land data center
+            :type user_theia: str
+            :param password_theia: Password Theia Land data center
+            :type password_theia: str
         """
         #=====================
         # Proxy
@@ -331,7 +315,7 @@ class Archive():
         #=============================================================
         if os.path.exists('token.json'):
             os.remove('token.json')
-#         get_token='curl -k -s -X POST --data-urlencode "ident=%s" --data-urlencode "pass=%s" https://theia.cnes.fr/services/authenticate/>token.json'%(curl_proxy,user_theia, password_theia)
+
         get_token='curl -k -s -X POST %s --data-urlencode "ident=%s" --data-urlencode "pass=%s" %s/services/authenticate/>token.json'%(curl_proxy, user_theia, password_theia, self.server)
         os.system(get_token)
         
@@ -342,8 +326,8 @@ class Archive():
                     token = token_json["access_token"]
                 elif self.token_type=="text":
                     token=data_file.readline()
-            except :
-                print ("Authentification is probably wrong")
+            except Exception as e:
+                self.logger.error("Authentification is probably wrong : {0}".format(e))
                 sys.exit(-1)
 
         #====================
@@ -353,25 +337,19 @@ class Archive():
         for d in range(len(self.list_archive)):
             # Download if not exist
             if not os.path.exists(self.list_archive[d][1]):
-                 
-                print (str(round(100*float(d)/len(self.list_archive),2)) + "%") # Print loading bar
-                print (os.path.split(str(self.list_archive[d][1]))[1])
-                
-#                 get_product='curl -o %s -k -H "Authorization: Bearer %s" https://theia.cnes.fr/resto/collections/Landsat/%s/download/?issuerId=theia'%(curl_proxy,self.list_archive[d][1], token, self.list_archive[d][2])
                 get_product='curl %s -o %s -k -H "Authorization: Bearer %s" %s/%s/collections/%s/%s/download/?issuerId=theia'%(curl_proxy, self.list_archive[d][1], token, self.server, self.resto, self._captor, self.list_archive[d][2])
-                print (get_product)
+                self.logger.debug(get_product)
                 os.system(get_product)
                 
         os.remove('token.json')
-        print ("100%")
-        print ("END OF DOWNLOAD !"   )
+        self.logger.info("All images have been downloaded !")
         
     def decompress(self):
         """
-        Function to unpack archives and store informations of the images (date, path, ...)
+            Function to unpack archives and store informations of the images (date, path, ...)
         """
         
-        print ("Unpack archives")
+        self.logger.info("Unpack archives")
         
         for annee in self._list_year:
             
@@ -379,29 +357,23 @@ class Archive():
             # Tricks to put whether a year or a date (year-month-day)
             try:
                 end_date = annee.split(',')[1]
-                print ("=============== " + str(first_date) + " to " + str(end_date) + " ===============")
+                self.logger.info("=============== {0} to {1} ===============".format(first_date, end_date))
             except IndexError:
-                print ("=============== " + str(first_date) + " ===============")
+                self.logger.info ("=============== {0} ===============".format(first_date))
             
-            img_in_glob = []
-            img_in_glob = glob.glob(str(self._folder) + '/'+ str(self._repertory) + '/*gz')
+            img_in_glob = sorted(glob.glob("{0}/{1}/*gz".format(self._folder, self._repertory)))
             
-            if img_in_glob == []:
-                print ("There isn't tgzfile in the folder")
-                sys.exit()
+            if not img_in_glob :
+                self.logger.error("There isn't tgzfile in the folder")
+                sys.exit(1)
             else:
                 # Create a folder "Unpack"
-                folder_unpack = self._folder + '/' + self._repertory + '/Unpack'
+                folder_unpack = "{0}/{1}/Unpack".format(self._folder, self._repertory)
                 
-                if os.path.isdir(folder_unpack):
-                    print('The folder already exists')
-            #        shutil.rmtree(FolderOut) # Remove the folder that it contains if exists ...
-                else:
-                    process_tocall = ['mkdir', folder_unpack]
-                    subprocess.call(process_tocall)
+                if not os.path.isdir(folder_unpack):
+                    os.mkdir(folder_unpack)
                 
                 for img in img_in_glob:
-                    
                     # Unpack the archives if they aren't again!
                     if self._captor == 'Landsat':
                         out_folder_unpack = folder_unpack + '/' + os.path.split(img)[1][:len(os.path.split(img)[1])-4]
@@ -411,7 +383,7 @@ class Archive():
                             tfile.extractall(str(folder_unpack))
                     
                         # On xmlfile, extract dates, path of images, cloud's images
-                        xmlfile = etree.parse(str(out_folder_unpack) + '/' + os.path.split(img)[1][:len(os.path.split(img)[1])-4] + '.xml')
+                        xmlfile = lxml.etree.parse(str(out_folder_unpack) + '/' + os.path.split(img)[1][:len(os.path.split(img)[1])-4] + '.xml')
                         
                         # Date images
                         # Exemple : '2015-09-27 10:41:25.956749'
@@ -442,7 +414,7 @@ class Archive():
                                 tzip.extract(str(z_out), str(folder_unpack))
                                                  
                         # On xmlfile, extract dates, path of images, cloud's images
-                        xmlfile = etree.parse(str(extraction_img[4]))
+                        xmlfile = lxml.etree.parse(str(extraction_img[4]))
                         # Date images
                         di = xmlfile.xpath("/Muscate_Metadata_Document/Product_Characteristics/ACQUISITION_DATE")[0].text.split('T')[0].split('-')
                         # Multispectral images
@@ -450,7 +422,7 @@ class Archive():
                         if not os.path.exists(hi):
                             # For Sentinel2 from Theia plateform, we need to make a stack layer for rasters
                             # There is a function that make this in RasterSat_by_date class
-                            stack_img = RasterSat_by_date('', '', [0])
+                            stack_img = RasterSat_by_date.RasterSat_by_date('', '', [0])
                             input_stack = extraction_img[:4]
                             input_stack.insert(0,'-separate')
                             stack_img.vrt_translate_gdal('vrt', input_stack, hi[:-4] + '.VRT')
diff --git a/Constantes.py b/Constantes.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ec418553205a57943cb28340dcc2a75ff634c19
--- /dev/null
+++ b/Constantes.py
@@ -0,0 +1,6 @@
+
+SIMPLE_MODE = 0
+EXPERT_MODE = 1
+
+MULTIPROCESSING_ENABLE = True
+MULTIPROCESSING_DISABLE = False
diff --git a/Log/.gitkeep b/Log/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Outils.py b/Outils.py
new file mode 100644
index 0000000000000000000000000000000000000000..7500da87ef663f921b7f527cd1d6bbc260a7906a
--- /dev/null
+++ b/Outils.py
@@ -0,0 +1,81 @@
+#!/bin/env python
+# -*- coding: utf-8 -*-
+
+import argparse
+import logging
+from logging.handlers import RotatingFileHandler
+import signal
+from contextlib import contextmanager
+
+class Fusion(argparse.Action):
+	def __init__(self, option_strings, dest, nargs=None, **kwargs):
+		super(Fusion, self).__init__(option_strings, dest, nargs, **kwargs)
+	def __call__(self, parser, namespace, values, option_string=None):
+		setattr(namespace, self.dest, ' '.join(values).lower())
+
+class Log(object):
+
+	def __init__(self, dossier, nomFichier, niveau=logging.DEBUG):
+		super(Log, self).__init__()
+
+		self.__logger__ = logging.getLogger(nomFichier)
+		self.__logger__.setLevel(niveau)
+
+		format = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s', datefmt='%d-%m-%Y %H:%M:%S')
+		fichierLog = RotatingFileHandler("{0}/{1}.log".format(dossier, nomFichier), 'a', 1000000, 1)
+
+		fichierLog.setLevel(niveau)
+		fichierLog.setFormatter(format)
+		self.__logger__.addHandler(fichierLog)
+
+		console = logging.StreamHandler()
+		console.setLevel(niveau)
+		self.__logger__.addHandler(console)
+
+	def info(self, message):
+		self.__logger__.info(message)
+
+	def debug(self, message):
+		self.__logger__.debug(message)
+
+	def warning(self, message):
+		self.__logger__.warning(message)
+
+	def error(self, message):
+		self.__logger__.error(message)
+
+	def critical(self, message):
+		self.__logger__.critical(message)
+
+	def exception(self, message):
+		self.__logger__.exception(message)
+
+	def close(self):
+		for handler in  self.__logger__.handlers[:] :
+			handler.close()
+			self.__logger__.removeHandler(handler)
+
+
+class TimeoutException(Exception): pass
+
+@contextmanager
+def limitation_temporelle(secondes):
+    
+    def signal_handler(signum, frame):
+        raise TimeoutException
+
+    signal.signal(signal.SIGALRM, signal_handler)
+    signal.alarm(secondes)
+
+    try:
+        yield
+    finally:
+        signal.alarm(0)
+
+# Utilisation :
+#
+# try:
+#     with limitation_temporelle(temps_en_seconde):
+#         appel_fonction()
+# except TimeoutException:
+#     pass
\ No newline at end of file
diff --git a/PHYMOBAT.py b/PHYMOBAT.py
index a6505a033d41ed948001bc4178eb0c3ad7c457db..8278ebf5c743fb8c5b910b352353f723e8ba7a89 100644
--- a/PHYMOBAT.py
+++ b/PHYMOBAT.py
@@ -36,1503 +36,1383 @@ from PyQt5 import QtWidgets, QtCore
 from _collections import defaultdict
 
 try :
-    import ogr
+	import ogr
 except :
-    from osgeo import ogr
+	from osgeo import ogr
 
 import webbrowser
 import lxml.etree as ET
 import os.path
 
-from ui_A_propos_PHYMOBAT_window import Ui_About
-from ui_Warming_study_area import Ui_Warming_study_area
-from ui_Warming_forgetting import Ui_Warming_forgetting
-from ui_Proxy_window import Ui_Proxy_window
+import Popup
 from Processing import Processing
+import Constantes
+import Outils
 
 class PHYMOBAT(QtWidgets.QMainWindow, Processing):
-    """
-    Interface main class. It makes to link ``ui_PHYMOBAT_tab`` and ``Processing``.
-    """
-    
-    def __init__(self, mode = 0, parent=None):
-        super(PHYMOBAT, self).__init__(parent)
-        Processing.__init__(self)
+	"""
+		Interface main class. It makes to link ``ui_PHYMOBAT_tab`` and ``Processing``.
+	"""
+	
+	def __init__(self, mode = Constantes.SIMPLE_MODE, parent=None):
+		super(PHYMOBAT, self).__init__(parent)
+		Processing.__init__(self)
 
-        self.apropos = None # For the "About PHYMOBAT" window
-        self.w_study_area = None # For the "Warming : forget study area" window
-        self.w_forget = None # For the "Warming : forgetting" window
-        
-        self.simpli = None # For the "PHYMOBATs" window
-        self.expert = None # For the "PHYMOBATe" window
-        self.mode = mode # For the mode simple (0 by default) or expert (1)
-        
-        # To select interface's parameters        
-        if self.mode == 1:
-            print ("Expert")
-            global Ui_PHYMOBAT, _translate
-            from ui_PHYMOBATe_tab import Ui_PHYMOBAT, _translate
-        elif self.mode == 0:
-            print ("Simple")
-            global Ui_PHYMOBAT, _translate
-            from ui_PHYMOBATs_tab import Ui_PHYMOBAT, _translate
-            
-        self.initUI()
-        
-    def initUI(self):
-        
-        """
-        Get initial values from interface after a click button.
-        
-        There is :
-        
-        - Connect browser button to search a path
-            * Main folder path
-            * Study area shapefile path
-            * VHRS image path
-            * MNT image path
-            * Segmentation shapefile path
-            * Output classification shapefile path
-            * Sample shapefile path
-            * Image path for samples if the first processing image hasn't been launched
-            
-        - Connect button to add sample in the memory list
-        - Connect button to clear sample record. Clear in the interface and in the memory list
-        - Connect close|ok button
-        - Connect menu bar tab (Open backup, save in a xml file, close, help, About PHYMOBAT, mode)
-        - Initialize backup variable
-        
-        """
-                    
-        # Initial interface
-        self.ui = Ui_PHYMOBAT()
-        self.ui.setupUi(self)
+		self.apropos = Popup.about() # For the "About PHYMOBAT" window
+		self.w_study_area = Popup.warming_study_area() # For the "Warming : forget study area" window
+		self.w_forget = Popup.warming_forgetting() # For the "Warming : forgetting" window
 
-        # Connect browser button to search a path
-        ##########################################
-        # Main folder path
-        self.ui.lineEdit_principal_folder.clear()
-        self.ui.pushButton_browser_principal_folder.clicked.connect(self.f_path_folder_dpt)
-        
-        # Block other function if SpotWorldHeritage is chose
-        try :
-            self.ui.comboBox_captor.currentIndexChanged.connect(self.block_for_swh)
-        except AttributeError:
-            pass
-        
-        # VHRS image path
-        self.ui.lineEdit_VHRS.clear()
-        self.ui.pushButton_browser_VHRS.clicked.connect(self.f_path_ortho)
-        
-        # Study area shapefile path
-        self.ui.lineEdit_area_path.clear()
-        self.ui.pushButton_browser_area_path.clicked.connect(self.f_path_area)
-        
-        # Proxy
-        self.ui.proxy.clicked.connect(self.f_proxy)
-        
-        # Segmentation shapefile path
-        self.ui.lineEdit_segmentation.clear()
-        self.ui.pushButton_browser_segmentation.clicked.connect(self.f_path_segm)
-        
-        # MNT image path
-        self.ui.lineEdit_MNT.clear()
-        self.ui.pushButton_browser_MNT.clicked.connect(self.f_path_mnt)
-        
-        # Output classification shapefile path
-        self.ui.lineEdit_output.clear()
-        self.ui.pushButton_browser_output.clicked.connect(self.f_output_name_moba)
-        
-        # Sample shapefile path.
-        # For the simply mode, RPG file sample.
-        self.ui.lineEdit_sample_path.clear()
-        self.ui.pushButton_browser_sample_path.clicked.connect(self.enter_sample_name)
-    
-        if self.mode == 0:
-            # For the simply mode, grass/wooden file sample.
-            self.ui.lineEdit_sample_path_2.clear()
-            self.ui.pushButton_browser_sample_path_2.clicked.connect(self.enter_sample_name_hl)
-            # For the simply mode, wooden file sample.
-            self.ui.lineEdit_sample_path_3.clear()
-            self.ui.pushButton_browser_sample_path_3.clicked.connect(self.enter_sample_name_ll)
-            
-        # Image path  for samples if the first processing image hasn't been launched
-        try:
-            self.ui.pushButton_img_sample.clicked.connect(self.img_sample_name)
-        except AttributeError:
-            pass # Simple mode
-        ##########################################
+		self.window = None # The "PHYMOBAT" window
+		self.current_mode = mode
 
-        # Connect button to add sample in the memory list
-        try:
-            self.ui.pushButton_add_sample.clicked.connect(self.add_sample)
-        except AttributeError:
-            pass # Simple mode
-        
-        # Connect button to clear sample record. Clear in the interface and in the memory list
-        try:
-            self.ui.pushButton_clear_sample.clicked.connect(self.clear_sample)
-        except AttributeError:
-            pass # Simple mode
-        
-        # Connect close|ok button
-        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(self.close_button)
-        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.ok_button)
-        
-        # Connect Menu bar
-        self.ui.actionOuvrir.triggered.connect(self.open_backup) # Open backup
-        self.ui.actionSauver.triggered.connect(self.save_backup) # Save field name on the interface
-        self.ui.actionQuiter.triggered.connect(self.close_button) # Close
-        self.ui.actionAide_de_PHYMOBAT.triggered.connect(self.help_tools) # Help
-        self.ui.actionA_propos_de_PHYMOBAT.triggered.connect(self.about_PHYMOBA) # About PHYMOBA
-        self.ui.actionMode_Simplifi.triggered.connect(self.mode_simpli) # To open the simple apply
-        self.ui.actionMode_expert.triggered.connect(self.mode_expert) # To open the expert apply
-        
-        self.rpg_tchek = [] # To backup rpg mode
-        self.img_sample = [] # To backup
-        
-        # Connect change line edit on sample path to extract fieldnames. For the simply mode, this
-        # is with RPG sample
-        self.ui.lineEdit_select_sample_fieldname_1.textChanged.connect(self.field_display_1)
-        self.ui.lineEdit_select_sample_fieldname_2.textChanged.connect(self.field_display_2)
-        
-        # To choose the classification method
-        if self.mode == 1:
-            if self.ui.radioButton_rf.isChecked():
-                self.ui.checkBox_classifier_1.setEnabled(False)
-                self.ui.checkBox_classifier_2.setEnabled(False)
-            
-            self.ui.radioButton_rf.toggled.connect(self.activate_level)   
-            self.ui.radioButton_s.toggled.connect(self.activate_level)
-        
-        if self.mode == 0:
-            # Connect change line edit to grass/wooden sample
-            self.ui.lineEdit_select_sample_fieldname_3.textChanged.connect(self.field_display_3)
-            self.ui.lineEdit_select_sample_fieldname_4.textChanged.connect(self.field_display_4)
-            self.ui.lineEdit_select_sample_fieldname_5.textChanged.connect(self.field_display_5)
-            self.ui.lineEdit_select_sample_fieldname_6.textChanged.connect(self.field_display_6)
-        
-        # Change connect for classification checkboxes
-        try:
-            self.ui.checkBox_classifier_1.stateChanged.connect(self.display_one_level)
-            self.ui.checkBox_classifier_2.stateChanged.connect(self.display_two_levels)
-            self.ui.checkBox_classifier_3.stateChanged.connect(self.display_all_levels)
-        except AttributeError:
-            pass # Simple mode
-        
-    def get_variable(self):
-        
-        """
-        Add a all system value like :
-        
-        - Main folder path by line edit
-        - Satellite captor name by combo box
-        - Classification year by line edit
-        - Study area shapefile path by line edit
-        - Connexion username and password by line edit
-        - VHRS image path by line edit
-        - MNT image path by line edit
-        - Segmentation shapefile path path by line edit
-        - Output classification shapefile path by line edit
-        - Output shapefile field name by line edit and field type by combo box
-        
-        """
-        # Main folder path by line edit.
-        self.path_folder_dpt = "%s" % self.ui.lineEdit_principal_folder.text()
-        
-        # Satellite captor name by combo box
-        try:
-            self.captor_project = self.ui.comboBox_captor.currentText()
-        except AttributeError:
-            self.captor_project = "Landsat"
-        
-        # Classification year by line edit
-        self.classif_year = "%s" % self.ui.lineEdit_year_images.text()
-        
-        # Study area shapefile path by line edit
-        self.path_area = "%s" % self.ui.lineEdit_area_path.text()
-        
-        # Connexion username and password by line edit
-        self.user = "%s" % self.ui.lineEdit_user.text()
-        self.password = "%s" % self.ui.lineEdit_password.text()
-        
-        # VHRS image path by line edit
-        self.path_ortho = "%s" % self.ui.lineEdit_VHRS.text()
-        
-        # MNT image path by line edit
-        self.path_mnt = "%s" % self.ui.lineEdit_MNT.text()        
-        
-        # Output shapefile field name by line edit and field type by combo box
-        try:
-            if self.ui.checkBox_classifier_1.isChecked() and self.ui.lineEdit_fieldname_1.text() != '':
-                self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_1.text())
-                self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_1.currentText()))
-                
-            if self.ui.checkBox_classifier_2.isChecked() and self.ui.lineEdit_fieldname_12.text() != '':
-                self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_12.text())
-                self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_12.currentText()))
-            
-                if self.ui.lineEdit_fieldname_2.text() != '':
-                    self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_2.text())
-                    self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_2.currentText()))
-                
-            if self.ui.checkBox_classifier_3.isChecked() and self.ui.lineEdit_fieldname_13.text() != '':
-                self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_13.text())
-                self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_13.currentText()))
-            
-                if self.ui.lineEdit_fieldname_23.text() != '':
-                    self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_23.text())
-                    self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_23.currentText()))
-             
-                    if self.ui.lineEdit_fieldname_3.text() != '':   
-                        self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_3.text())
-                        self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_3.currentText()))
-            
-                        if self.ui.lineEdit_fieldname_4.text() != '':    
-                            self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_4.text())
-                            self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_4.currentText()))
-        except AttributeError:
-            modes_fieldname = ["NIVEAU_1", "NIVEAU_2", "NIVEAU_3", "POURC"]
-            modes_fieldtype = [eval("ogr.OFTString"), eval("ogr.OFTString"), eval("ogr.OFTString"), eval("ogr.OFTReal")]
-            
-            for mf in range(len(modes_fieldname)):
-                
-                self.out_fieldname_carto.append(modes_fieldname[mf])
-                self.out_fieldtype_carto.append(modes_fieldtype[mf])
-        
-        # Segmentation shapefile path path by line edit
-        self.path_segm = "%s" % self.ui.lineEdit_segmentation.text()
-        
-        # Output shapefile field name by line edit and field type by combo box
-        self.output_name_moba = "%s" % self.ui.lineEdit_output.text()
-        
-    def set_variable(self):
-        """
-        Print number of available image from Theia's GeoJSON .
-        """
-        # self.ui.lineEdit_listing.setText(str(self.nb_avalaible_images))
-        try:
-            self.ui.label_listing.setText(str(self.nb_avalaible_images))
-        except AttributeError:
-            pass # Simple mode
-        
-    def f_path_folder_dpt(self):
-        """
-        Open a input browser box to select the main folder path by line edit.
-        """
-        infoldername = QtWidgets.QFileDialog.getExistingDirectory(self, "Principal folder path", os.getcwd(), QtWidgets.QFileDialog.ShowDirsOnly)
-        self.ui.lineEdit_principal_folder.setText(str(infoldername).replace('[','').replace(']','').replace(' ',''))
-    
-    def block_for_swh(self):
-        """
-        Function to block others function when SportWorldHeritage is selected in the comboxbox captor.
-        """
-        ind_captor = int(self.ui.comboBox_captor.currentIndex())
-        if ind_captor == 2:
-            self.ui.checkBox_processing.setEnabled(False)
-            self.ui.checkBox_MNT.setEnabled(False)
-            self.ui.lineEdit_MNT.setEnabled(False)
-            self.ui.pushButton_browser_MNT.setEnabled(False)
-            self.ui.checkBox_VHRS.setEnabled(False)
-            self.ui.lineEdit_VHRS.setEnabled(False)
-            self.ui.pushButton_browser_VHRS.setEnabled(False)
-            self.ui.tabWidget.setTabEnabled(1, False)
-            self.ui.tabWidget.setTabEnabled(2, False)
-        # If the user want, on the same moment, come back on other captor that SWH.
-        else:
-            self.ui.checkBox_processing.setEnabled(True)
-            self.ui.checkBox_MNT.setEnabled(True)
-            self.ui.lineEdit_MNT.setEnabled(True)
-            self.ui.pushButton_browser_MNT.setEnabled(True)
-            self.ui.checkBox_VHRS.setEnabled(True)
-            self.ui.lineEdit_VHRS.setEnabled(True)
-            self.ui.pushButton_browser_VHRS.setEnabled(True)
-            self.ui.tabWidget.setTabEnabled(1, True)
-            self.ui.tabWidget.setTabEnabled(2, True)
-    
-    def f_path_ortho(self):
-        """
-        Open a input browser box to select the VHRS image path by line edit.
-        """
-        orthofilename = QtWidgets.QFileDialog.getOpenFileName(self, "THRS image", self.ui.lineEdit_principal_folder.text(), '*.TIF *.tif')[0]
-        self.ui.lineEdit_VHRS.setText(str(orthofilename).replace('[','').replace(']','').replace(' ',''))   
-    
-    def f_path_mnt(self):
-        """
-        Open a input browser box to select the MNT image path by line edit.
-        """
-        mntfilename = QtWidgets.QFileDialog.getOpenFileName(self, "MNT image", self.ui.lineEdit_principal_folder.text(), '*.TIF *.tif')[0]
-        self.ui.lineEdit_MNT.setText(str(mntfilename).replace('[','').replace(']','').replace(' ',''))  
-        
-    def f_path_area(self):
-        """
-        Open a input browser box to select the study area shapefile path by line edit.
-        """        
-        areafilename = QtWidgets.QFileDialog.getOpenFileName(self, "Area shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
-        self.ui.lineEdit_area_path.setText(str(areafilename).replace('[','').replace(']','').replace(' ',''))
-        
-    def f_proxy(self):   
-        """
-        Function to open a popup in order to enter proxy ID
-        """ 
-        if self.w_proxy is None:
-            self.w_proxy = MyPopup_proxy_window()
-        self.w_proxy.show()
-        
-    def f_path_segm(self):
-        """
-        Open a input browser box to select segmentation shapefile path path by line edit.
-        """
-        segmfilename = QtWidgets.QFileDialog.getOpenFileName(self, "Segmentation shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
-        self.ui.lineEdit_segmentation.setText(str(segmfilename).replace('[','').replace(']','').replace(' ',''))
-    
-    def f_output_name_moba(self):
-        """
-        Set the output classification shapefile path by line edit.
-        """
-        outfilename = QtWidgets.QFileDialog.getSaveFileName(self, "FB file", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
-        # if the user has forgotten to put .shp at the end of the output shapefile
-        if outfilename[-4:] != '.shp':
-            outfilename = outfilename + '.shp'
-        self.ui.lineEdit_output.setText(outfilename)
-        
-    def enter_sample_name(self):
-        """
-        Open a input browser box to select the sample shapefile path by line edit. With :func:`add_sample` conditions for the expert mode.
-        For the simply mode, this function is used for the RPG shapefile.
-        """
-        samplefilename = QtWidgets.QFileDialog.getOpenFileName(self, "Sample shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
-        self.ui.lineEdit_sample_path.setText(str(samplefilename).replace('[','').replace(']','').replace(' ',''))
-    
-    def enter_sample_name_hl(self):
-        """
-        Open a input browser box to select the grass and wooden sample shapefile path by line edit. With :func:`add_sample` conditions 
-        for the simply mode.
-        """
-        samplefilename_hl = QtWidgets.QFileDialog.getOpenFileName(self, "Grass/Wooden sample shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
-        self.ui.lineEdit_sample_path_2.setText(str(samplefilename_hl).replace('[','').replace(']','').replace(' ',''))
-        
-    def enter_sample_name_ll(self):
-        """
-        Open a input browser box to select the wooden sample shapefile path by line edit. With :func:`add_sample` conditions for the simply mode.
-        """
-        samplefilename_ll = QtWidgets.QFileDialog.getOpenFileName(self, "Wooden sample shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
-        self.ui.lineEdit_sample_path_3.setText(str(samplefilename_ll).replace('[','').replace(']','').replace(' ',''))
-        
-    def img_sample_name(self):
-        """
-        Open a input browser box to select the image for samples path by line edit. With :func:`add_sample` conditions.
-        """
-        imgsamplefilename = QtWidgets.QFileDialog.getOpenFileName(self, "Sample image", self.ui.lineEdit_principal_folder.text(), '*.TIF')[0]
-        self.ui.lineEdit_img_sample.setText(str(imgsamplefilename).replace('[','').replace(']','').replace(' ',''))
-        
-    def add_sample(self):
-        """
-        Add sample information and location to compute optimal threshold :
-        
-        For the expert mode (mode=1) :
-        
-        - Append a sample name by line Edit. *This is a check box* ``RPG``, *if the sample is RPG file. It launch the Rpg class. And append a other sample from Rpg class*.
-        - Append two existent sample field names by combobox. It will be the same. 
-        - Append sample class names by line edit. One or more for every sample.
-        - Append number of polygons for every samples by line edit.
-        - Print in a plain text edit : sample name, two sample field names, sample class names and number of polygons.
-        - *This check box* ``Image echantillonee``, *image path for samples if the first processing image hasn't been launched*.
-            .. note:: This is for a image with one spectral band
-        - Clear all widget field at the end.
-        
-        For the simply mode (mode=0):
-        
-        - Append a sample name by a different line Edit (a line Edit for each sample).
-        - Append sample class names, existing sample fields and number of polygons (a different line Edit for each sample)
-        """
-        
-        nb_sample = len(self.sample_name)# Compute number of samples added. Condition : max three. 
-        # Study area shapefile path by line edit if no processing other
-        # Because the function "Vector" need study area
-        self.path_area = "%s" % self.ui.lineEdit_area_path.text()
-        if self.path_area == '':
-            self.forget_study_area()
-        
-        if self.mode == 1:
-            # Expert mode
-            if nb_sample < 3 and not self.ui.lineEdit_sample_path.text().isEmpty() and  \
-                    not self.ui.lineEdit_select_sample_fieldname_1.text().isEmpty() and not self.ui.lineEdit_select_sample_fieldname_2.text().isEmpty() and \
-                    not self.ui.lineEdit_select_sample_class_1.text().isEmpty() and not self.ui.lineEdit_select_sample_class_2.text().isEmpty() and \
-                    not self.ui.lineEdit_select_sample_nb_poly.text().isEmpty() and not self.ui.lineEdit_area_path.text().isEmpty():
-                
-                # Append a sample name by line Edit.
-                if self.ui.checkBox_RPG.isChecked():
-                    # Check box, if the sample of the RPG file. It launch the Rpg class. And append a other sample from Rpg class 
-                    self.sample_name.append(self.i_rpg("%s" % self.ui.lineEdit_sample_path.text()))
-                    self.rpg_tchek.append(1) # To backup
-                    self.ui.checkBox_RPG.setChecked(False)
-                else:
-                    self.sample_name.append("%s" % self.ui.lineEdit_sample_path.text())
-                    self.rpg_tchek.append(0)
-                
-                # Append two sample field names by line edit. It must be the same.
-                self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_1.text())
-                self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_2.text())
-                # Append sample class names by line edit. One or more for every sample
-                self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_1.text())
-                self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_2.text())
-                # Append number of polygons for every samples by line edit.
-                self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly.text())
-                
-                nb_sample = len(self.sample_name) # Number of samples added
-                # Print in a plain text edit : sample name, two sample field names, sample class names and number of polygons.
-                cursor = self.ui.plainTextEdit_sample.textCursor()
-                cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
-                self.ui.plainTextEdit_sample.setTextCursor(cursor)
-                self.ui.plainTextEdit_sample.insertPlainText(str(self.sample_name[nb_sample-1]) + "\n")
-                cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor)
-                self.ui.plainTextEdit_sample.setTextCursor(cursor)
-                self.ui.plainTextEdit_sample.insertPlainText(str(self.fieldname_args[(nb_sample-1)*2]) + '    ' + str(self.fieldname_args[((nb_sample-1)*2)+1]) + "\n")
-                cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor)
-                self.ui.plainTextEdit_sample.setTextCursor(cursor)
-                self.ui.plainTextEdit_sample.insertPlainText(str(self.class_args[(nb_sample-1)*2]) + '    ' + str(self.class_args[(nb_sample-1)*2+1]) + "\n")
-                cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor)
-                self.ui.plainTextEdit_sample.setTextCursor(cursor)
-                self.ui.plainTextEdit_sample.insertPlainText(str(self.list_nb_sample[nb_sample-1]) + "\n")
-                
-                # Check box, image path for samples if the first processing image hasn't been launched
-                # Warming : This is for a image with one spectral band
-                if self.ui.checkBox_img_sample.isChecked():
-                    self.raster_path.append("%s" % self.ui.lineEdit_img_sample.text())
-                    self.list_band_outraster.append(1)
-                    self.ui.lineEdit_img_sample.clear()
-                    self.ui.checkBox_img_sample.setChecked(False)
-                    self.img_sample.append(1)
-                else: # To backup
-                    self.img_sample.append(0)
-    
-                # Clear all line edit after addition, ie after click add button.
-                self.ui.lineEdit_sample_path.clear()
-                self.ui.lineEdit_select_sample_fieldname_1.clear()
-                self.ui.lineEdit_select_sample_fieldname_2.clear()
-                self.ui.lineEdit_select_sample_class_1.clear()
-                self.ui.lineEdit_select_sample_class_2.clear()
-                self.ui.lineEdit_select_sample_nb_poly.clear()
-                
-        elif self.mode == 0:
-            
-            # Simple mode
-            # Append a sample name by line Edit.
-            # For the sample of the RPG file. It launch the Rpg class. And append a other sample from Rpg class 
-            self.sample_name.append(self.i_rpg("%s" % self.ui.lineEdit_sample_path.text()))
-            
-            # Append two sample field names by line edit. It must be the same.
-            self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_1.text())
-            self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_2.text())
-            # Append sample class names by line edit. One or more for every sample
-            self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_1.text())
-            self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_2.text())
-            # Append number of polygons for every samples by line edit.
-            self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly.text())
-            
-            # Same process that the RPG process except the start of the RPG class.
-            # To Grass/wooden
-            self.sample_name.append("%s" % self.ui.lineEdit_sample_path_2.text())
-            self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_3.text())
-            self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_4.text())
-            self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_3.text())
-            self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_4.text())
-            self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly_2.text())
-            
-            # To wooden
-            self.sample_name.append("%s" % self.ui.lineEdit_sample_path_3.text())
-            self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_5.text())
-            self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_6.text())
-            self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_5.text())
-            self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_6.text())
-            self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly_3.text())
-            
-            nb_sample = 3
-    
-    def clear_sample(self):
-        """
-        Function to clear sample record. Clear in the interface and in the memory list.
-        """
-        self.sample_name = []
-        self.fieldname_args = []
-        self.class_args = []
-        self.list_nb_sample = []
-        self.rpg_tchek = []
-        self.img_sample = []
-        
-        self.ui.lineEdit_sample_path.clear()
-        self.ui.lineEdit_select_sample_fieldname_1.clear()
-        self.ui.lineEdit_select_sample_fieldname_2.clear()
-        self.ui.lineEdit_select_sample_class_1.clear()
-        self.ui.lineEdit_select_sample_class_2.clear()
-        self.ui.lineEdit_select_sample_nb_poly.clear()
-        self.ui.checkBox_RPG.setChecked(False)
-        self.ui.lineEdit_img_sample.clear()
-        self.ui.checkBox_img_sample.setChecked(False)
-        self.ui.plainTextEdit_sample.clear()
-        self.ui.plainTextEdit_sample.insertPlainText("1 - Végétation non naturelle / Semi-naturelle\n")
-        self.ui.plainTextEdit_sample.insertPlainText("2 - Herbacés / Ligneux\n")
-        self.ui.plainTextEdit_sample.insertPlainText("3 - Lingeux mixtes / denses\n")
-        self.ui.plainTextEdit_sample.insertPlainText("\n")
-        self.ui.plainTextEdit_sample.insertPlainText("\n")
-        self.ui.plainTextEdit_sample.insertPlainText("")            
-        
-    def field_display_1(self):
-        """
-        Function to display fieldname class 1 in the other fieldname class 2 when text changed.
-        For the simply mode, this is RPG sample.
-        """
-        
-        self.ui.lineEdit_select_sample_fieldname_2.setText("%s" % self.ui.lineEdit_select_sample_fieldname_1.text())
-            
-    def field_display_2(self):
-        """
-        Function to display fieldname class 2 in the other fieldname class 2 when text changed.
-        For the simply mode, this is RPG sample.
-        """
-        
-        self.ui.lineEdit_select_sample_fieldname_1.setText("%s" % self.ui.lineEdit_select_sample_fieldname_2.text())    
-        
-    def field_display_3(self):
-        """
-        For the grass/wooden sample, a function to display fieldname class 1 in the other fieldname class 2 when text changed.
-        """
-        
-        self.ui.lineEdit_select_sample_fieldname_4.setText("%s" % self.ui.lineEdit_select_sample_fieldname_3.text())
-            
-    def field_display_4(self):
-        """
-        For the grass/wooden sample, a function to display fieldname class 2 in the other fieldname class 2 when text changed.
-        """
-        
-        self.ui.lineEdit_select_sample_fieldname_3.setText("%s" % self.ui.lineEdit_select_sample_fieldname_4.text()) 
-        
-    def field_display_5(self):
-        """
-        For the wooden sample, a function to display fieldname class 1 in the other fieldname class 2 when text changed.
-        """
-        
-        self.ui.lineEdit_select_sample_fieldname_6.setText("%s" % self.ui.lineEdit_select_sample_fieldname_5.text())
-            
-    def field_display_6(self):
-        """
-        For the wooden sample, a function to display fieldname class 2 in the other fieldname class 2 when text changed.
-        """
-        
-        self.ui.lineEdit_select_sample_fieldname_5.setText("%s" % self.ui.lineEdit_select_sample_fieldname_6.text()) 
-    
-    def activate_level(self):
-        """
-        To activate the first levels with seath method. This is in pushing on the decision tree radio button.
-        Else it activates the last level to random forest method.
-        """
-        if self.ui.radioButton_s.isChecked() and not self.ui.radioButton_rf.isChecked():
-            self.ui.checkBox_classifier_1.setEnabled(True)
-            self.ui.checkBox_classifier_2.setEnabled(True)
-        else:
-            self.ui.checkBox_classifier_1.setEnabled(False)
-            self.ui.checkBox_classifier_2.setEnabled(False)
-            self.ui.checkBox_classifier_3.setChecked(True)
-            
-        
-    def display_one_level(self):
-        """
-        Function to display fieldnames option to classifier one level
-        """
-        if self.ui.checkBox_classifier_1.isChecked():
-            
-            # Don't checked others checkboxes
-            self.ui.checkBox_classifier_2.setChecked(False)
-            self.ui.checkBox_classifier_3.setChecked(False)
-            
-            # Display options filednames
-            self.ui.label_chps_1 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_1.setObjectName("label_chps_1")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_1, 10, 0, 2, 2)
-            self.ui.label_chps_name_1 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_name_1.setObjectName("label_chps_name_1")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_name_1, 10, 2, 1, 1)
-            self.ui.label_chps_type_1 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_type_1.setObjectName("label_chps_type_1")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_type_1, 11, 2, 1, 1)
-            self.ui.lineEdit_fieldname_1 = QLineEdit(self.ui.tab_3)
-            self.ui.lineEdit_fieldname_1.setObjectName("lineEdit_fieldname_1")
-            self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_1, 10, 3, 1, 1)
-            self.ui.comboBox_fieldname_1 = QComboBox(self.ui.tab_3)
-            self.ui.comboBox_fieldname_1.setObjectName("comboBox_fieldname_1")
-            self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_1, 11, 3, 1, 1)
-    
-            self.ui.lineEdit_fieldname_1.setText(_translate("PHYMOBAT", "NIVEAU_1", None))
-            self.ui.comboBox_fieldname_1.addItem("String")
-            self.ui.comboBox_fieldname_1.addItem("Real")
-    
-            self.ui.label_chps_1.setText(_translate("PHYMOBAT", "    Champs\n"+" des entités", None))
-            self.ui.label_chps_name_1.setText(_translate("PHYMOBAT", "Nom :", None))   
-            self.ui.label_chps_type_1.setText(_translate("PHYMOBAT", "Type :", None)) 
-         
-        if not self.ui.checkBox_classifier_1.isChecked(): 
-            # Clear options filednames
-            try:
-                self.ui.label_chps_1.deleteLater()
-                self.ui.label_chps_name_1.deleteLater()
-                self.ui.label_chps_type_1.deleteLater()  
-                self.ui.lineEdit_fieldname_1.deleteLater()
-                self.ui.comboBox_fieldname_1.deleteLater()
-            except AttributeError:      
-                pass
-    
-    def display_two_levels(self):
-        """
-        Function to display fieldnames option to classifier two first levels
-        """
-        
-        if self.ui.checkBox_classifier_2.isChecked():
-            
-            # Don't checked others checkboxes
-            self.ui.checkBox_classifier_1.setChecked(False)
-            self.ui.checkBox_classifier_3.setChecked(False)
-        
-            self.ui.label_chps_2 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_2.setObjectName("label_chps_2")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_2, 13, 0, 2, 2)
-            self.ui.lineEdit_fieldname_12 = QLineEdit(self.ui.tab_3)
-            self.ui.lineEdit_fieldname_12.setObjectName("lineEdit_fieldname_12")
-            self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_12, 13, 3, 1, 1)
-            self.ui.lineEdit_fieldname_2 = QLineEdit(self.ui.tab_3)
-            self.ui.lineEdit_fieldname_2.setObjectName("lineEdit_fieldname_2")
-            self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_2, 13, 4, 1, 1)    
-            self.ui.label_chps_type_2 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_type_2.setObjectName("label_chps_type_2")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_type_2, 14, 2, 1, 1)
-            self.ui.comboBox_fieldname_12 = QComboBox(self.ui.tab_3)
-            self.ui.comboBox_fieldname_12.setObjectName("comboBox_fieldname_12")
-            self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_12, 14, 3, 1, 1)
-            self.ui.comboBox_fieldname_2 = QComboBox(self.ui.tab_3)
-            self.ui.comboBox_fieldname_2.setObjectName("comboBox_fieldname_2")
-            self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_2, 14, 4, 1, 1)
-            self.ui.label_chps_name_2 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_name_2.setObjectName("label_chps_name_2")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_name_2, 13, 2, 1, 1)
-            
-            self.ui.lineEdit_fieldname_12.setText(_translate("PHYMOBAT", "NIVEAU_1", None))
-            self.ui.comboBox_fieldname_12.addItem("String")
-            self.ui.comboBox_fieldname_12.addItem("Real")
-            self.ui.lineEdit_fieldname_2.setText(_translate("PHYMOBAT", "NIVEAU_2", None))
-            self.ui.comboBox_fieldname_2.addItem("String")
-            self.ui.comboBox_fieldname_2.addItem("Real")
-            
-            self.ui.label_chps_type_2.setText(_translate("PHYMOBAT", "Type :", None))
-            self.ui.label_chps_2.setText(_translate("PHYMOBAT", "    Champs\n"+" des entités", None))
-            self.ui.label_chps_name_2.setText(_translate("PHYMOBAT", "Nom :", None))
-        
-        if not self.ui.checkBox_classifier_2.isChecked(): 
-            # Clear options filednames
-            try:
-                self.ui.label_chps_2.deleteLater()
-                self.ui.label_chps_name_2.deleteLater()
-                self.ui.label_chps_type_2.deleteLater()  
-                self.ui.lineEdit_fieldname_12.deleteLater()
-                self.ui.comboBox_fieldname_12.deleteLater()
-                self.ui.lineEdit_fieldname_2.deleteLater()
-                self.ui.comboBox_fieldname_2.deleteLater()
-            except AttributeError:      
-                pass
-        
-    def display_all_levels(self):
-        """
-        Function to display fieldnames option to launch complete classification
-        """
-        
-        if self.ui.checkBox_classifier_3.isChecked():
-            
-            # Don't checked others checkboxes
-            self.ui.checkBox_classifier_1.setChecked(False)
-            self.ui.checkBox_classifier_2.setChecked(False)
-        
-            self.ui.label_chps_name_3 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_name_3.setObjectName("label_chps_name_3")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_name_3, 16, 2, 1, 1)
-            self.ui.label_chps_3 = QLabel(self.ui.tab_3)    
-            self.ui.label_chps_3.setObjectName("label_chps_3")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_3, 16, 0, 2, 2)
-            self.ui.label_chps_type_3 = QLabel(self.ui.tab_3)
-            self.ui.label_chps_type_3.setObjectName("label_chps_type_3")
-            self.ui.gridLayout_2.addWidget(self.ui.label_chps_type_3, 17, 2, 1, 1)
-            self.ui.lineEdit_fieldname_13 = QLineEdit(self.ui.tab_3)
-            self.ui.lineEdit_fieldname_13.setObjectName("lineEdit_fieldname_13")
-            self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_13, 16, 3, 1, 1)
-            self.ui.lineEdit_fieldname_23 = QLineEdit(self.ui.tab_3)
-            self.ui.lineEdit_fieldname_23.setObjectName("lineEdit_fieldname_23")
-            self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_23, 16, 4, 1, 1)
-            self.ui.lineEdit_fieldname_3 = QLineEdit(self.ui.tab_3)
-            self.ui.lineEdit_fieldname_3.setObjectName("lineEdit_fieldname_3")
-            self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_3, 16, 5, 1, 1)
-            self.ui.lineEdit_fieldname_4 = QLineEdit(self.ui.tab_3)
-            self.ui.lineEdit_fieldname_4.setObjectName("lineEdit_fieldname_4")
-            self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_4, 16, 6, 1, 1)
-            self.ui.comboBox_fieldname_13 = QComboBox(self.ui.tab_3)
-            self.ui.comboBox_fieldname_13.setObjectName("comboBox_fieldname_13")
-            self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_13, 17, 3, 1, 1)
-            self.ui.comboBox_fieldname_23 = QComboBox(self.ui.tab_3)
-            self.ui.comboBox_fieldname_23.setObjectName("comboBox_fieldname_23")
-            self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_23, 17, 4, 1, 1)
-            self.ui.comboBox_fieldname_3 = QComboBox(self.ui.tab_3)
-            self.ui.comboBox_fieldname_3.setObjectName("comboBox_fieldname_3")
-            self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_3, 17, 5, 1, 1)
-            self.ui.comboBox_fieldname_4 = QComboBox(self.ui.tab_3)
-            self.ui.comboBox_fieldname_4.setObjectName("comboBox_fieldname_4")
-            self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_4, 17, 6, 1, 1)
-            
-            self.ui.lineEdit_fieldname_13.setText(_translate("PHYMOBAT", "NIVEAU_1", None))
-            self.ui.comboBox_fieldname_13.addItem("String")
-            self.ui.comboBox_fieldname_13.addItem("Real")
-            self.ui.lineEdit_fieldname_23.setText(_translate("PHYMOBAT", "NIVEAU_2", None))
-            self.ui.comboBox_fieldname_23.addItem("String")
-            self.ui.comboBox_fieldname_23.addItem("Real")
-            self.ui.lineEdit_fieldname_3.setText(_translate("PHYMOBAT", "NIVEAU_3", None))
-            self.ui.comboBox_fieldname_3.addItem("String")
-            self.ui.comboBox_fieldname_3.addItem("Real")
-            self.ui.lineEdit_fieldname_4.setText(_translate("PHYMOBAT", "POURC", None))
-            self.ui.comboBox_fieldname_4.addItem("Real")  
-            self.ui.comboBox_fieldname_4.addItem("String")
-            
-            self.ui.label_chps_3.setText(_translate("PHYMOBAT", "    Champs\n"+" des entités", None))
-            self.ui.label_chps_type_3.setText(_translate("PHYMOBAT", "Type :", None))
-            self.ui.label_chps_name_3.setText(_translate("PHYMOBAT", "Nom :", None))
-        
-        if not self.ui.checkBox_classifier_3.isChecked(): 
-            # Clear options filednames
-            try:
-                self.ui.label_chps_3.deleteLater()
-                self.ui.label_chps_name_3.deleteLater()
-                self.ui.label_chps_type_3.deleteLater()  
-                self.ui.lineEdit_fieldname_13.deleteLater()
-                self.ui.comboBox_fieldname_13.deleteLater()
-                self.ui.lineEdit_fieldname_23.deleteLater()
-                self.ui.comboBox_fieldname_23.deleteLater()
-                self.ui.lineEdit_fieldname_3.deleteLater()
-                self.ui.comboBox_fieldname_3.deleteLater()
-                self.ui.lineEdit_fieldname_4.deleteLater()
-                self.ui.comboBox_fieldname_4.deleteLater()
-            except AttributeError:      
-                pass
-            
-    def ok_button(self):
-        
-        """
-        Function to launch the processing. This function take account :
-        
-        - The ``Multi-processing`` check box if the processing has launched with multi process. By default, this is checked. It need a computer with minimum 12Go memory.
-        - Append a few system value with :func:`get_variable`.
-        - There are 3 principal check boxes :
-            - to get number download available images
-            - for downloading and processing on theia platform
-            - to compute optimal threshold.
-            - to compute slope raster
-            - for classification processing.
-        """
-        
-        # Start the processus
-        startTime = time.time()
-        
-        # To know if the processing must be launch on several thread
-        if self.ui.checkBox_multiprocess.isChecked():
-            self.mp = 1
-        else:
-            self.mp = 0
-        
-        self.get_variable() # Append a few system value
-        vs = 0 # Variable to launch VHRS texture processing
-        dd = 0 # Variable to launch image downloading 
-        ok = 1 # Variable to verify informations -> 0 not ok, 1 ok
-        
-        if self.mode == 1:
-            # if download check box is checked only
-            if not self.ui.checkBox_listing.isChecked() and self.ui.checkBox_download.isChecked():
-                
-                self.ui.checkBox_listing.setChecked(True)
-                
-    #         # if processing check box is checked only
-    #         if not self.ui.checkBox_listing.isChecked() and not self.ui.checkBox_download.isChecked() and self.ui.checkBox_processing.isChecked():
-    #             
-    #             self.ui.checkBox_listing.setChecked(True) 
-    #             self.ui.checkBox_download.setChecked(True) 
-                
-            # Verify raster or sample to launch a good processing classification tab
-            # If not ok, there will appear a message windows to enter the miss information
-    #         if self.ui.checkBox_classifier_1.isChecked():
-    #             if not self.ui.checkBox_processing.isChecked() or (len(self.raster_path) < 1 and len(self.sample_name) > 0) or \
-    #             len(self.sample_name) < 1:
-    #                 self.forget_raster_sample()
-    #                 ok = 0
-    #         if self.ui.checkBox_classifier_2.isChecked():
-    #             if (not self.ui.checkBox_processing.isChecked() and not self.ui.checkBox_MNT.isChecked() and \
-    #             not self.ui.checkBox_VHRS.isChecked()) or (len(self.raster_path) < 2 and len(self.sample_name) > 0) or \
-    #             len(self.sample_name) < 2:
-    #                 self.forget_raster_sample()
-    #                 ok = 0
-    #         if self.ui.checkBox_classifier_3.isChecked():
-    #             if (not self.ui.checkBox_processing.isChecked() and not self.ui.checkBox_MNT.isChecked() and \
-    #             not self.ui.checkBox_VHRS.isChecked()) or (len(self.raster_path) != 6 and len(self.sample_name) > 0) or \
-    #             len(self.sample_name) != 3:
-    #                 self.forget_raster_sample() 
-    #                 ok = 0
-            
-            if ok == 1:       
-                # Compute a output slope raster 
-                if self.ui.checkBox_MNT.isChecked():
-                
-                    self.i_slope()       
-                
-                # Downloading and processing on theia platform
-                # A check box to get number download available images
-                if self.ui.checkBox_listing.isChecked():
-                    
-                    if self.ui.checkBox_download.isChecked():
-                        # To launch the downloading
-                        dd = 1
-                    
-                    self.i_download(dd) # Launch image listing and downloading if dd = 1
-                    self.set_variable() # to write in the line edit about number download available images
-                    
-                    # Check box to launch the image processing
-                    if self.ui.checkBox_processing.isChecked():
-                        # Another check box to launch VHRS texture processing. If checked, vs = 1.
-                        if self.ui.checkBox_VHRS.isChecked():
-                            vs = 1
-                        self.i_images_processing(vs) # function to launch the image processing            
-                
-                # To launch the image processing without dowloading but with the images in a main folder
-                # Without internet connection
-                if not self.ui.checkBox_download.isChecked() and self.ui.checkBox_processing.isChecked():
-                    
-                    # Launch pre-processing without downloading
-                    self.i_glob()
-                    # Another check box to launch VHRS texture processing. If checked, vs = 1.
-                    if self.ui.checkBox_VHRS.isChecked():
-                        vs = 1
-                    self.i_images_processing(vs) # function to launch the image processing            
-                
-                # To launch texture processing only
-                if not self.ui.checkBox_listing.isChecked() and not self.ui.checkBox_processing.isChecked() and self.ui.checkBox_VHRS.isChecked():
-                    
-                    self.i_vhrs()
-                
-                # Compute optimal threshold  
-                if self.ui.checkBox_threshold.isChecked():
-                    
-                    if self.ui.radioButton_rf.isChecked():
-                        self.i_sample_rf()
-                    elif self.ui.radioButton_s.isChecked():
-                        self.i_sample()
-                
-                # Classification processing 
-                if self.ui.radioButton_rf.isChecked():
-                    
-                    if self.ui.checkBox_classifier_3.isChecked():
-                        
-                        self.out_fieldname_carto = self.out_fieldname_carto
-                        self.out_fieldtype_carto = self.out_fieldtype_carto             
-                        self.i_classifier_rf()
-                        self.i_validate()
-                        
-                elif self.ui.radioButton_s.isChecked():
-                    
-                    if self.ui.checkBox_classifier_1.isChecked() :         
-                        
-                        self.out_fieldname_carto = self.out_fieldname_carto[:3]
-                        self.out_fieldtype_carto = self.out_fieldtype_carto[:3]
-                        self.i_classifier_s()
-                        self.i_validate()
-                        
-                    if self.ui.checkBox_classifier_2.isChecked() :
-                        
-                        self.out_fieldname_carto = self.out_fieldname_carto[:4]
-                        self.out_fieldtype_carto = self.out_fieldtype_carto[:4]             
-                        self.i_classifier_s()
-                        self.i_validate()
-                        
-                    if self.ui.checkBox_classifier_3.isChecked():
-                        
-                        self.out_fieldname_carto = self.out_fieldname_carto
-                        self.out_fieldtype_carto = self.out_fieldtype_carto             
-                        self.i_classifier_s()
-                        self.i_validate()
-                    
-        if self.mode == 0:
-            
-            # Compute a output slope raster 
-            if self.path_mnt != '':
-                self.i_slope()
-            
-            # Save the sample features
-            self.add_sample()
-            try:
-                # Look at if the the images has been already downlaoded
-                self.i_glob()
-            except:
-                # Else the processus download it
-                self.i_download(1)
-            
-            # function to launch the image processing    
-            self.i_images_processing(1)
-            # To launch texture processing only
-            self.i_vhrs()
-            # Compute optimal threshold 
-            self.i_sample_rf()
-                    
-            # Classification processing 
-            self.out_fieldname_carto = self.out_fieldname_carto
-            self.out_fieldtype_carto = self.out_fieldtype_carto 
-            self.i_classifier_rf()
-            self.i_validate()
-            
-            
-#         # Clear variables after processing
-#         self.clear_sample()
-        self.out_fieldname_carto = ['ID', 'AREA']
-        self.out_fieldtype_carto = [ogr.OFTString, ogr.OFTReal]
-        # Images after processing images
-        self.out_ndvistats_folder_tab = defaultdict(list)
-        
-        Processing.__init__(self)# Initialize variable without to close and launch again the application
-        
-        # End of the processus
-        endTime = time.time() # Tps : Terminé
-        print ('...........' + ' Outputted to File in ' + str(endTime - startTime) + ' secondes')
-        nb_day_processing = int(time.strftime('%d', time.gmtime(endTime - startTime))) - 1
-        print ("That is, " + str(nb_day_processing) + ' day(s) ' + time.strftime('%Hh %Mmin%S', time.gmtime(endTime - startTime)))
-        
-    def open_backup(self):
-        """
-        Function to load input text in every fields. The input file must be a XML file.
-        """
-        
-        in_backup = QtWidgets.QFileDialog.getOpenFileName(self, "Open backup", os.getcwd(), '*.xml')[0]
-        
-        if in_backup != None and len(in_backup) > 0 :
+		self.logger = Outils.Log("Log", "Phymobat")
+		
+		# To select interface's parameters		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			self.logger.info("Expert mode.")
+			global Ui_PHYMOBAT, _translate
+			from ui_PHYMOBATe_tab import Ui_PHYMOBAT, _translate
+		elif self.current_mode == Constantes.SIMPLE_MODE:
+			self.logger.info("Simple mode.")
+			global Ui_PHYMOBAT, _translate
+			from ui_PHYMOBATs_tab import Ui_PHYMOBAT, _translate
+			
+		self.initUI()
 
-            # Parse the xml file if the user choose a file
-            tree = ET.parse(str(in_backup))
-            
-            if tree.find("Multi_process").text == '1':
-                self.ui.checkBox_multiprocess.setChecked(True)
-            else:
-                self.ui.checkBox_multiprocess.setChecked(False)
-            
-            pr = tree.find("Tab[@id='Processing_raster']")
+		# Chargement et lancement automatique pour les tests à supprimer
+		self.open_backup("/home/commandre/Documents/data_test_2/2018.xml")
+		# self.ok_button()
+		
+	def initUI(self):
+		
+		"""
+		Get initial values from interface after a click button.
+		
+		There is :
+		
+		- Connect browser button to search a path
+			* Main folder path
+			* Study area shapefile path
+			* VHRS image path
+			* MNT image path
+			* Segmentation shapefile path
+			* Output classification shapefile path
+			* Sample shapefile path
+			* Image path for samples if the first processing image hasn't been launched
+			
+		- Connect button to add sample in the memory list
+		- Connect button to clear sample record. Clear in the interface and in the memory list
+		- Connect close|ok button
+		- Connect menu bar tab (Open backup, save in a xml file, close, help, About PHYMOBAT, mode)
+		- Initialize backup variable
+		
+		"""
+					
+		# Initial interface
+		self.ui = Ui_PHYMOBAT()
+		self.ui.setupUi(self)
 
-            try:
-                self.ui.lineEdit_principal_folder.setText(pr.find("Principal_folder").text)
-            except:
-                print('Not principal folder')
+		# Connect browser button to search a path
+		##########################################
+		# Main folder path
+		self.ui.lineEdit_principal_folder.clear()
+		self.ui.pushButton_browser_principal_folder.clicked.connect(self.f_path_folder_dpt)
+		
+		# Block other function if SpotWorldHeritage is chose
+		try :
+			self.ui.comboBox_captor.currentIndexChanged.connect(self.block_for_swh)
+		except AttributeError:
+			pass
+		
+		# VHRS image path
+		self.ui.lineEdit_VHRS.clear()
+		self.ui.pushButton_browser_VHRS.clicked.connect(self.f_path_ortho)
+		
+		# Study area shapefile path
+		self.ui.lineEdit_area_path.clear()
+		self.ui.pushButton_browser_area_path.clicked.connect(self.f_path_area)
+		
+		# Proxy
+		self.ui.proxy.clicked.connect(self.f_proxy)
+		
+		# Segmentation shapefile path
+		self.ui.lineEdit_segmentation.clear()
+		self.ui.pushButton_browser_segmentation.clicked.connect(self.f_path_segm)
+		
+		# MNT image path
+		self.ui.lineEdit_MNT.clear()
+		self.ui.pushButton_browser_MNT.clicked.connect(self.f_path_mnt)
+		
+		# Output classification shapefile path
+		self.ui.lineEdit_output.clear()
+		self.ui.pushButton_browser_output.clicked.connect(self.f_output_name_moba)
+		
+		# Sample shapefile path.
+		# For the simply mode, RPG file sample.
+		self.ui.lineEdit_sample_path.clear()
+		self.ui.pushButton_browser_sample_path.clicked.connect(self.enter_sample_name)
+	
+		if self.current_mode == Constantes.SIMPLE_MODE:
+			# For the simply mode, grass/wooden file sample.
+			self.ui.lineEdit_sample_path_2.clear()
+			self.ui.pushButton_browser_sample_path_2.clicked.connect(self.enter_sample_name_hl)
+			# For the simply mode, wooden file sample.
+			self.ui.lineEdit_sample_path_3.clear()
+			self.ui.pushButton_browser_sample_path_3.clicked.connect(self.enter_sample_name_ll)
+			
+		# Image path for samples if the first processing image hasn't been launched
+		try:
+			self.ui.pushButton_img_sample.clicked.connect(self.img_sample_name)
+		except AttributeError:
+			pass # Simple mode
+		##########################################
 
-            if self.mode == 1:
-                index_captor = self.ui.comboBox_captor.findText(pr.find("Captor").text) # To find combo box index
-                self.ui.comboBox_captor.setCurrentIndex(index_captor)
+		# Connect button to add sample in the memory list
+		try:
+			self.ui.pushButton_add_sample.clicked.connect(self.add_sample)
+		except AttributeError:
+			pass # Simple mode
+		
+		# Connect button to clear sample record. Clear in the interface and in the memory list
+		try:
+			self.ui.pushButton_clear_sample.clicked.connect(self.clear_sample)
+		except AttributeError:
+			pass # Simple mode
+		
+		# Connect close|ok button
+		# self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(self.close_button)
+		self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(self.close_button)
+		self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.ok_button)
+		
+		# Connect Menu bar
+		self.ui.actionOuvrir.triggered.connect(self.open_backup) # Open backup
+		self.ui.actionSauver.triggered.connect(self.save_backup) # Save field name on the interface
+		self.ui.actionQuiter.triggered.connect(self.close_button) # Close
+		self.ui.actionAide_de_PHYMOBAT.triggered.connect(self.help_tools) # Help
+		self.ui.actionA_propos_de_PHYMOBAT.triggered.connect(self.about_PHYMOBA) # About PHYMOBA
+		self.ui.actionMode_Simplifi.triggered.connect(lambda checked, mode=Constantes.SIMPLE_MODE: self.change_mode(mode)) # To open the simple apply
+		self.ui.actionMode_expert.triggered.connect(lambda checked, mode=Constantes.EXPERT_MODE: self.change_mode(mode)) # To open the expert apply
+		
+		self.rpg_tchek = [] # To backup rpg mode
+		self.img_sample = [] # To backup
+		
+		# Connect change line edit on sample path to extract fieldnames. For the simply mode, this
+		# is with RPG sample
+		self.ui.lineEdit_select_sample_fieldname_1.textChanged.connect(self.field_display_1)
+		self.ui.lineEdit_select_sample_fieldname_2.textChanged.connect(self.field_display_2)
+		
+		# To choose the classification method
+		if self.current_mode == Constantes.EXPERT_MODE:
+			if self.ui.radioButton_rf.isChecked():
+				self.ui.checkBox_classifier_1.setEnabled(False)
+				self.ui.checkBox_classifier_2.setEnabled(False)
+			
+			self.ui.radioButton_rf.toggled.connect(self.activate_level)   
+			self.ui.radioButton_s.toggled.connect(self.activate_level)
+		
+		if self.current_mode == Constantes.SIMPLE_MODE:
+			# Connect change line edit to grass/wooden sample
+			self.ui.lineEdit_select_sample_fieldname_3.textChanged.connect(self.field_display_3)
+			self.ui.lineEdit_select_sample_fieldname_4.textChanged.connect(self.field_display_4)
+			self.ui.lineEdit_select_sample_fieldname_5.textChanged.connect(self.field_display_5)
+			self.ui.lineEdit_select_sample_fieldname_6.textChanged.connect(self.field_display_6)
+		
+		# Change connect for classification checkboxes
+		try:
+			self.ui.checkBox_classifier_1.stateChanged.connect(self.display_one_level)
+			self.ui.checkBox_classifier_2.stateChanged.connect(self.display_two_levels)
+			self.ui.checkBox_classifier_3.stateChanged.connect(self.display_all_levels)
+		except AttributeError:
+			pass # Simple mode
+		
+	def get_variable(self):		
+		"""
+			Add a all system value like :
+		
+			- Main folder path by line edit
+			- Satellite captor name by combo box
+			- Classification year by line edit
+			- Study area shapefile path by line edit
+			- Connexion username and password by line edit
+			- VHRS image path by line edit
+			- MNT image path by line edit
+			- Segmentation shapefile path path by line edit
+			- Output classification shapefile path by line edit
+			- Output shapefile field name by line edit and field type by combo box
+		
+		"""
+		# Main folder path by line edit.
+		self.path_folder_dpt = "%s" % self.ui.lineEdit_principal_folder.text()
+		
+		# Satellite captor name by combo box
+		try:
+			self.captor_project = self.ui.comboBox_captor.currentText()
+		except AttributeError:
+			self.captor_project = "Landsat"
+		
+		# Classification year by line edit
+		self.classif_year = "%s" % self.ui.lineEdit_year_images.text()
+		
+		# Study area shapefile path by line edit
+		self.path_area = "%s" % self.ui.lineEdit_area_path.text()
+		
+		# Connexion username and password by line edit
+		self.user = "%s" % self.ui.lineEdit_user.text()
+		self.password = "%s" % self.ui.lineEdit_password.text()
+		
+		# VHRS image path by line edit
+		self.path_ortho = "%s" % self.ui.lineEdit_VHRS.text()
+		
+		# MNT image path by line edit
+		self.path_mnt = "%s" % self.ui.lineEdit_MNT.text()		
+		
+		# Output shapefile field name by line edit and field type by combo box
+		try:
+			if self.ui.checkBox_classifier_1.isChecked() and self.ui.lineEdit_fieldname_1.text() != '':
+				self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_1.text())
+				self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_1.currentText()))
+				
+			if self.ui.checkBox_classifier_2.isChecked() and self.ui.lineEdit_fieldname_12.text() != '':
+				self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_12.text())
+				self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_12.currentText()))
+			
+				if self.ui.lineEdit_fieldname_2.text() != '':
+					self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_2.text())
+					self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_2.currentText()))
+				
+			if self.ui.checkBox_classifier_3.isChecked() and self.ui.lineEdit_fieldname_13.text() != '':
+				self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_13.text())
+				self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_13.currentText()))
+			
+				if self.ui.lineEdit_fieldname_23.text() != '':
+					self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_23.text())
+					self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_23.currentText()))
+			 
+					if self.ui.lineEdit_fieldname_3.text() != '':   
+						self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_3.text())
+						self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_3.currentText()))
+			
+						if self.ui.lineEdit_fieldname_4.text() != '':	
+							self.out_fieldname_carto.append("%s" % self.ui.lineEdit_fieldname_4.text())
+							self.out_fieldtype_carto.append(eval("ogr.OFT%s" % self.ui.comboBox_fieldname_4.currentText()))
+		except AttributeError:
+			modes_fieldname = ["NIVEAU_1", "NIVEAU_2", "NIVEAU_3", "POURC"]
+			modes_fieldtype = [eval("ogr.OFTString"), eval("ogr.OFTString"), eval("ogr.OFTString"), eval("ogr.OFTReal")]
+			
+			for mf in range(len(modes_fieldname)):
+				
+				self.out_fieldname_carto.append(modes_fieldname[mf])
+				self.out_fieldtype_carto.append(modes_fieldtype[mf])
+		
+		# Segmentation shapefile path path by line edit
+		self.path_segm = "%s" % self.ui.lineEdit_segmentation.text()
+		
+		# Output shapefile field name by line edit and field type by combo box
+		self.output_name_moba = "%s" % self.ui.lineEdit_output.text()
+		
+	def set_variable(self):
+		"""
+			Print number of available image from Theia's GeoJSON .
+		"""
 
-            try:
-                self.ui.lineEdit_year_images.setText(pr.find("Year_images").text)
-            except:
-                print('Not year images')
+		# self.ui.lineEdit_listing.setText(str(self.nb_avalaible_images))
+		try:
+			self.ui.label_listing.setText(str(self.nb_avalaible_images))
+		except AttributeError:
+			pass # Simple mode
+		
+	def f_path_folder_dpt(self):
+		"""
+			Open a input browser box to select the main folder path by line edit.
+		"""
+		infoldername = QtWidgets.QFileDialog.getExistingDirectory(self, "Principal folder path", os.getcwd(), QtWidgets.QFileDialog.ShowDirsOnly)
+		self.ui.lineEdit_principal_folder.setText(str(infoldername).replace('[','').replace(']','').replace(' ',''))
+	
+	def block_for_swh(self):
+		"""
+			Function to block others function when SportWorldHeritage is selected in the comboxbox captor.
+		"""
+		ind_captor = int(self.ui.comboBox_captor.currentIndex())
+		if ind_captor == 2:
+			self.ui.checkBox_processing.setEnabled(False)
+			self.ui.checkBox_MNT.setEnabled(False)
+			self.ui.lineEdit_MNT.setEnabled(False)
+			self.ui.pushButton_browser_MNT.setEnabled(False)
+			self.ui.checkBox_VHRS.setEnabled(False)
+			self.ui.lineEdit_VHRS.setEnabled(False)
+			self.ui.pushButton_browser_VHRS.setEnabled(False)
+			self.ui.tabWidget.setTabEnabled(1, False)
+			self.ui.tabWidget.setTabEnabled(2, False)
+		# If the user want, on the same moment, come back on other captor that SWH.
+		else:
+			self.ui.checkBox_processing.setEnabled(True)
+			self.ui.checkBox_MNT.setEnabled(True)
+			self.ui.lineEdit_MNT.setEnabled(True)
+			self.ui.pushButton_browser_MNT.setEnabled(True)
+			self.ui.checkBox_VHRS.setEnabled(True)
+			self.ui.lineEdit_VHRS.setEnabled(True)
+			self.ui.pushButton_browser_VHRS.setEnabled(True)
+			self.ui.tabWidget.setTabEnabled(1, True)
+			self.ui.tabWidget.setTabEnabled(2, True)
+	
+	def f_path_ortho(self):
+		"""
+			Open a input browser box to select the VHRS image path by line edit.
+		"""
+		orthofilename = QtWidgets.QFileDialog.getOpenFileName(self, "THRS image", self.ui.lineEdit_principal_folder.text(), '*.TIF *.tif')[0]
+		self.ui.lineEdit_VHRS.setText(str(orthofilename).replace('[','').replace(']','').replace(' ',''))   
+	
+	def f_path_mnt(self):
+		"""
+			Open a input browser box to select the MNT image path by line edit.
+		"""
+		mntfilename = QtWidgets.QFileDialog.getOpenFileName(self, "MNT image", self.ui.lineEdit_principal_folder.text(), '*.TIF *.tif')[0]
+		self.ui.lineEdit_MNT.setText(str(mntfilename).replace('[','').replace(']','').replace(' ',''))  
+		
+	def f_path_area(self):
+		"""
+			Open a input browser box to select the study area shapefile path by line edit.
+		"""		
+		areafilename = QtWidgets.QFileDialog.getOpenFileName(self, "Area shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
+		self.ui.lineEdit_area_path.setText(str(areafilename).replace('[','').replace(']','').replace(' ',''))
+		
+	def f_proxy(self):   
+		"""
+			Function to open a popup in order to enter proxy ID
+		""" 
+		if self.w_proxy is None:
+			self.w_proxy = Popup.proxy_window()
+		self.w_proxy.show()
+		
+	def f_path_segm(self):
+		"""
+			Open a input browser box to select segmentation shapefile path path by line edit.
+		"""
+		segmfilename = QtWidgets.QFileDialog.getOpenFileName(self, "Segmentation shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
+		self.ui.lineEdit_segmentation.setText(str(segmfilename).replace('[','').replace(']','').replace(' ',''))
+	
+	def f_output_name_moba(self):
+		"""
+			Set the output classification shapefile path by line edit.
+		"""
+		outfilename = QtWidgets.QFileDialog.getSaveFileName(self, "FB file", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
+		# if the user has forgotten to put .shp at the end of the output shapefile
+		if outfilename[-4:] != '.shp':
+			outfilename = outfilename + '.shp'
+		self.ui.lineEdit_output.setText(outfilename)
+		
+	def enter_sample_name(self):
+		"""
+			Open a input browser box to select the sample shapefile path by line edit. With :func:`add_sample` conditions for the expert mode.
+			For the simply mode, this function is used for the RPG shapefile.
+		"""
+		samplefilename = QtWidgets.QFileDialog.getOpenFileName(self, "Sample shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
+		self.ui.lineEdit_sample_path.setText(str(samplefilename).replace('[','').replace(']','').replace(' ',''))
+	
+	def enter_sample_name_hl(self):
+		"""
+			Open a input browser box to select the grass and wooden sample shapefile path by line edit. With :func:`add_sample` conditions 
+			for the simply mode.
+		"""
+		samplefilename_hl = QtWidgets.QFileDialog.getOpenFileName(self, "Grass/Wooden sample shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
+		self.ui.lineEdit_sample_path_2.setText(str(samplefilename_hl).replace('[','').replace(']','').replace(' ',''))
+		
+	def enter_sample_name_ll(self):
+		"""
+			Open a input browser box to select the wooden sample shapefile path by line edit. With :func:`add_sample` conditions for the simply mode.
+		"""
+		samplefilename_ll = QtWidgets.QFileDialog.getOpenFileName(self, "Wooden sample shapefile", self.ui.lineEdit_principal_folder.text(), '*.shp')[0]
+		self.ui.lineEdit_sample_path_3.setText(str(samplefilename_ll).replace('[','').replace(']','').replace(' ',''))
+		
+	def img_sample_name(self):
+		"""
+			Open a input browser box to select the image for samples path by line edit. With :func:`add_sample` conditions.
+		"""
+		imgsamplefilename = QtWidgets.QFileDialog.getOpenFileName(self, "Sample image", self.ui.lineEdit_principal_folder.text(), '*.TIF')[0]
+		self.ui.lineEdit_img_sample.setText(str(imgsamplefilename).replace('[','').replace(']','').replace(' ',''))
+		
+	def add_sample(self):
+		"""
+			Add sample information and location to compute optimal threshold :
+		
+			For the expert mode (mode=1) :
+		
+			- Append a sample name by line Edit. *This is a check box* ``RPG``, *if the sample is RPG file. It launch the Rpg class. And append a other sample from Rpg class*.
+			- Append two existent sample field names by combobox. It will be the same. 
+			- Append sample class names by line edit. One or more for every sample.
+			- Append number of polygons for every samples by line edit.
+			- Print in a plain text edit : sample name, two sample field names, sample class names and number of polygons.
+			- *This check box* ``Image echantillonee``, *image path for samples if the first processing image hasn't been launched*.
+				.. note:: This is for a image with one spectral band
+			- Clear all widget field at the end.
+			
+			For the simply mode (mode=0):
+		
+			- Append a sample name by a different line Edit (a line Edit for each sample).
+			- Append sample class names, existing sample fields and number of polygons (a different line Edit for each sample)
+		"""
+		
+		nb_sample = len(self.sample_name)# Compute number of samples added. Condition : max three. 
+		# Study area shapefile path by line edit if no processing other
+		# Because the function "Vector" need study area
+		self.path_area = "%s" % self.ui.lineEdit_area_path.text()
+		if self.path_area == '':
+			self.forget_study_area()
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			# Expert mode
+			if nb_sample < 3 and not self.ui.lineEdit_sample_path.text().isEmpty() and  \
+					not self.ui.lineEdit_select_sample_fieldname_1.text().isEmpty() and not self.ui.lineEdit_select_sample_fieldname_2.text().isEmpty() and \
+					not self.ui.lineEdit_select_sample_class_1.text().isEmpty() and not self.ui.lineEdit_select_sample_class_2.text().isEmpty() and \
+					not self.ui.lineEdit_select_sample_nb_poly.text().isEmpty() and not self.ui.lineEdit_area_path.text().isEmpty():
+				
+				# Append a sample name by line Edit.
+				if self.ui.checkBox_RPG.isChecked():
+					# Check box, if the sample of the RPG file. It launch the Rpg class. And append a other sample from Rpg class 
+					self.sample_name.append(self.i_rpg("%s" % self.ui.lineEdit_sample_path.text()))
+					self.rpg_tchek.append(1) # To backup
+					self.ui.checkBox_RPG.setChecked(False)
+				else:
+					self.sample_name.append("%s" % self.ui.lineEdit_sample_path.text())
+					self.rpg_tchek.append(0)
+				
+				# Append two sample field names by line edit. It must be the same.
+				self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_1.text())
+				self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_2.text())
+				# Append sample class names by line edit. One or more for every sample
+				self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_1.text())
+				self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_2.text())
+				# Append number of polygons for every samples by line edit.
+				self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly.text())
+				
+				nb_sample = len(self.sample_name) # Number of samples added
+				# Print in a plain text edit : sample name, two sample field names, sample class names and number of polygons.
+				cursor = self.ui.plainTextEdit_sample.textCursor()
+				cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor)
+				self.ui.plainTextEdit_sample.setTextCursor(cursor)
+				self.ui.plainTextEdit_sample.insertPlainText(str(self.sample_name[nb_sample-1]) + "\n")
+				cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor)
+				self.ui.plainTextEdit_sample.setTextCursor(cursor)
+				self.ui.plainTextEdit_sample.insertPlainText(str(self.fieldname_args[(nb_sample-1)*2]) + '	' + str(self.fieldname_args[((nb_sample-1)*2)+1]) + "\n")
+				cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor)
+				self.ui.plainTextEdit_sample.setTextCursor(cursor)
+				self.ui.plainTextEdit_sample.insertPlainText(str(self.class_args[(nb_sample-1)*2]) + '	' + str(self.class_args[(nb_sample-1)*2+1]) + "\n")
+				cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor)
+				self.ui.plainTextEdit_sample.setTextCursor(cursor)
+				self.ui.plainTextEdit_sample.insertPlainText(str(self.list_nb_sample[nb_sample-1]) + "\n")
+				
+				# Check box, image path for samples if the first processing image hasn't been launched
+				# Warming : This is for a image with one spectral band
+				if self.ui.checkBox_img_sample.isChecked():
+					self.raster_path.append("%s" % self.ui.lineEdit_img_sample.text())
+					self.list_band_outraster.append(1)
+					self.ui.lineEdit_img_sample.clear()
+					self.ui.checkBox_img_sample.setChecked(False)
+					self.img_sample.append(1)
+				else: # To backup
+					self.img_sample.append(0)
+	
+				# Clear all line edit after addition, ie after click add button.
+				self.ui.lineEdit_sample_path.clear()
+				self.ui.lineEdit_select_sample_fieldname_1.clear()
+				self.ui.lineEdit_select_sample_fieldname_2.clear()
+				self.ui.lineEdit_select_sample_class_1.clear()
+				self.ui.lineEdit_select_sample_class_2.clear()
+				self.ui.lineEdit_select_sample_nb_poly.clear()
+				
+		elif self.current_mode == Constantes.SIMPLE_MODE:
+			
+			# Simple mode
+			# Append a sample name by line Edit.
+			# For the sample of the RPG file. It launch the Rpg class. And append a other sample from Rpg class 
+			self.sample_name.append(self.i_rpg("%s" % self.ui.lineEdit_sample_path.text()))
+			
+			# Append two sample field names by line edit. It must be the same.
+			self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_1.text())
+			self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_2.text())
+			# Append sample class names by line edit. One or more for every sample
+			self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_1.text())
+			self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_2.text())
+			# Append number of polygons for every samples by line edit.
+			self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly.text())
+			
+			# Same process that the RPG process except the start of the RPG class.
+			# To Grass/wooden
+			self.sample_name.append("%s" % self.ui.lineEdit_sample_path_2.text())
+			self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_3.text())
+			self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_4.text())
+			self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_3.text())
+			self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_4.text())
+			self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly_2.text())
+			
+			# To wooden
+			self.sample_name.append("%s" % self.ui.lineEdit_sample_path_3.text())
+			self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_5.text())
+			self.fieldname_args.append("%s" % self.ui.lineEdit_select_sample_fieldname_6.text())
+			self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_5.text())
+			self.class_args.append("%s" % self.ui.lineEdit_select_sample_class_6.text())
+			self.list_nb_sample.append("%s" % self.ui.lineEdit_select_sample_nb_poly_3.text())
+			
+			nb_sample = 3
+	
+	def clear_sample(self):
+		"""
+			Function to clear sample record. Clear in the interface and in the memory list.
+		"""
+		self.sample_name = []
+		self.fieldname_args = []
+		self.class_args = []
+		self.list_nb_sample = []
+		self.rpg_tchek = []
+		self.img_sample = []
+		
+		self.ui.lineEdit_sample_path.clear()
+		self.ui.lineEdit_select_sample_fieldname_1.clear()
+		self.ui.lineEdit_select_sample_fieldname_2.clear()
+		self.ui.lineEdit_select_sample_class_1.clear()
+		self.ui.lineEdit_select_sample_class_2.clear()
+		self.ui.lineEdit_select_sample_nb_poly.clear()
+		self.ui.checkBox_RPG.setChecked(False)
+		self.ui.lineEdit_img_sample.clear()
+		self.ui.checkBox_img_sample.setChecked(False)
+		self.ui.plainTextEdit_sample.clear()
+		self.ui.plainTextEdit_sample.insertPlainText("1 - Végétation non naturelle / Semi-naturelle\n")
+		self.ui.plainTextEdit_sample.insertPlainText("2 - Herbacés / Ligneux\n")
+		self.ui.plainTextEdit_sample.insertPlainText("3 - Lingeux mixtes / denses\n")
+		self.ui.plainTextEdit_sample.insertPlainText("\n")
+		self.ui.plainTextEdit_sample.insertPlainText("\n")
+		self.ui.plainTextEdit_sample.insertPlainText("")			
+		
+	def field_display_1(self):
+		"""
+			Function to display fieldname class 1 in the other fieldname class 2 when text changed.
+			For the simply mode, this is RPG sample.
+		"""
+		self.ui.lineEdit_select_sample_fieldname_2.setText("%s" % self.ui.lineEdit_select_sample_fieldname_1.text())
+			
+	def field_display_2(self):
+		"""
+			Function to display fieldname class 2 in the other fieldname class 2 when text changed.
+			For the simply mode, this is RPG sample.
+		"""
+		self.ui.lineEdit_select_sample_fieldname_1.setText("%s" % self.ui.lineEdit_select_sample_fieldname_2.text())	
+		
+	def field_display_3(self):
+		"""
+			For the grass/wooden sample, a function to display fieldname class 1 in the other fieldname class 2 when text changed.
+		"""
+		self.ui.lineEdit_select_sample_fieldname_4.setText("%s" % self.ui.lineEdit_select_sample_fieldname_3.text())
+			
+	def field_display_4(self):
+		"""
+			For the grass/wooden sample, a function to display fieldname class 2 in the other fieldname class 2 when text changed.
+		"""
+		self.ui.lineEdit_select_sample_fieldname_3.setText("%s" % self.ui.lineEdit_select_sample_fieldname_4.text()) 
+		
+	def field_display_5(self):
+		"""
+			For the wooden sample, a function to display fieldname class 1 in the other fieldname class 2 when text changed.
+		"""
+		self.ui.lineEdit_select_sample_fieldname_6.setText("%s" % self.ui.lineEdit_select_sample_fieldname_5.text())
+			
+	def field_display_6(self):
+		"""
+			For the wooden sample, a function to display fieldname class 2 in the other fieldname class 2 when text changed.
+		"""
+		self.ui.lineEdit_select_sample_fieldname_5.setText("%s" % self.ui.lineEdit_select_sample_fieldname_6.text()) 
+	
+	def activate_level(self):
+		"""
+			To activate the first levels with seath method. This is in pushing on the decision tree radio button.
+			Else it activates the last level to random forest method.
+		"""
+		if self.ui.radioButton_s.isChecked() and not self.ui.radioButton_rf.isChecked():
+			self.ui.checkBox_classifier_1.setEnabled(True)
+			self.ui.checkBox_classifier_2.setEnabled(True)
+		else:
+			self.ui.checkBox_classifier_1.setEnabled(False)
+			self.ui.checkBox_classifier_2.setEnabled(False)
+			self.ui.checkBox_classifier_3.setChecked(True)
+			  
+	def display_one_level(self):
+		"""
+			Function to display fieldnames option to classifier one level
+		"""
+		if self.ui.checkBox_classifier_1.isChecked():
+			
+			# Don't checked others checkboxes
+			self.ui.checkBox_classifier_2.setChecked(False)
+			self.ui.checkBox_classifier_3.setChecked(False)
+			
+			# Display options filednames
+			self.ui.label_chps_1 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_1.setObjectName("label_chps_1")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_1, 10, 0, 2, 2)
+			self.ui.label_chps_name_1 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_name_1.setObjectName("label_chps_name_1")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_name_1, 10, 2, 1, 1)
+			self.ui.label_chps_type_1 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_type_1.setObjectName("label_chps_type_1")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_type_1, 11, 2, 1, 1)
+			self.ui.lineEdit_fieldname_1 = QtWidgets.QLineEdit(self.ui.tab_3)
+			self.ui.lineEdit_fieldname_1.setObjectName("lineEdit_fieldname_1")
+			self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_1, 10, 3, 1, 1)
+			self.ui.comboBox_fieldname_1 = QtWidgets.QComboBox(self.ui.tab_3)
+			self.ui.comboBox_fieldname_1.setObjectName("comboBox_fieldname_1")
+			self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_1, 11, 3, 1, 1)
+	
+			self.ui.lineEdit_fieldname_1.setText(_translate("PHYMOBAT", "NIVEAU_1", None))
+			self.ui.comboBox_fieldname_1.addItem("String")
+			self.ui.comboBox_fieldname_1.addItem("Real")
+	
+			self.ui.label_chps_1.setText(_translate("PHYMOBAT", "	Champs\n"+" des entités", None))
+			self.ui.label_chps_name_1.setText(_translate("PHYMOBAT", "Nom :", None))   
+			self.ui.label_chps_type_1.setText(_translate("PHYMOBAT", "Type :", None)) 
+		 
+		if not self.ui.checkBox_classifier_1.isChecked(): 
+			# Clear options filednames
+			try:
+				self.ui.label_chps_1.deleteLater()
+				self.ui.label_chps_name_1.deleteLater()
+				self.ui.label_chps_type_1.deleteLater()  
+				self.ui.lineEdit_fieldname_1.deleteLater()
+				self.ui.comboBox_fieldname_1.deleteLater()
+			except AttributeError:	  
+				pass
+	
+	def display_two_levels(self):
+		"""
+			Function to display fieldnames option to classifier two first levels
+		"""
+		if self.ui.checkBox_classifier_2.isChecked():
+			
+			# Don't checked others checkboxes
+			self.ui.checkBox_classifier_1.setChecked(False)
+			self.ui.checkBox_classifier_3.setChecked(False)
+		
+			self.ui.label_chps_2 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_2.setObjectName("label_chps_2")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_2, 13, 0, 2, 2)
+			self.ui.lineEdit_fieldname_12 = QtWidgets.QLineEdit(self.ui.tab_3)
+			self.ui.lineEdit_fieldname_12.setObjectName("lineEdit_fieldname_12")
+			self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_12, 13, 3, 1, 1)
+			self.ui.lineEdit_fieldname_2 = QtWidgets.QLineEdit(self.ui.tab_3)
+			self.ui.lineEdit_fieldname_2.setObjectName("lineEdit_fieldname_2")
+			self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_2, 13, 4, 1, 1)	
+			self.ui.label_chps_type_2 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_type_2.setObjectName("label_chps_type_2")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_type_2, 14, 2, 1, 1)
+			self.ui.comboBox_fieldname_12 = QtWidgets.QComboBox(self.ui.tab_3)
+			self.ui.comboBox_fieldname_12.setObjectName("comboBox_fieldname_12")
+			self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_12, 14, 3, 1, 1)
+			self.ui.comboBox_fieldname_2 = QtWidgets.QComboBox(self.ui.tab_3)
+			self.ui.comboBox_fieldname_2.setObjectName("comboBox_fieldname_2")
+			self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_2, 14, 4, 1, 1)
+			self.ui.label_chps_name_2 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_name_2.setObjectName("label_chps_name_2")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_name_2, 13, 2, 1, 1)
+			
+			self.ui.lineEdit_fieldname_12.setText(_translate("PHYMOBAT", "NIVEAU_1", None))
+			self.ui.comboBox_fieldname_12.addItem("String")
+			self.ui.comboBox_fieldname_12.addItem("Real")
+			self.ui.lineEdit_fieldname_2.setText(_translate("PHYMOBAT", "NIVEAU_2", None))
+			self.ui.comboBox_fieldname_2.addItem("String")
+			self.ui.comboBox_fieldname_2.addItem("Real")
+			
+			self.ui.label_chps_type_2.setText(_translate("PHYMOBAT", "Type :", None))
+			self.ui.label_chps_2.setText(_translate("PHYMOBAT", "	Champs\n"+" des entités", None))
+			self.ui.label_chps_name_2.setText(_translate("PHYMOBAT", "Nom :", None))
+		
+		if not self.ui.checkBox_classifier_2.isChecked(): 
+			# Clear options filednames
+			try:
+				self.ui.label_chps_2.deleteLater()
+				self.ui.label_chps_name_2.deleteLater()
+				self.ui.label_chps_type_2.deleteLater()  
+				self.ui.lineEdit_fieldname_12.deleteLater()
+				self.ui.comboBox_fieldname_12.deleteLater()
+				self.ui.lineEdit_fieldname_2.deleteLater()
+				self.ui.comboBox_fieldname_2.deleteLater()
+			except AttributeError:	  
+				pass
+		
+	def display_all_levels(self):
+		"""
+			Function to display fieldnames option to launch complete classification
+		"""
+		
+		if self.ui.checkBox_classifier_3.isChecked():
+			
+			# Don't checked others checkboxes
+			self.ui.checkBox_classifier_1.setChecked(False)
+			self.ui.checkBox_classifier_2.setChecked(False)
+		
+			self.ui.label_chps_name_3 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_name_3.setObjectName("label_chps_name_3")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_name_3, 16, 2, 1, 1)
+			self.ui.label_chps_3 = QtWidgets.QLabel(self.ui.tab_3)	
+			self.ui.label_chps_3.setObjectName("label_chps_3")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_3, 16, 0, 2, 2)
+			self.ui.label_chps_type_3 = QtWidgets.QLabel(self.ui.tab_3)
+			self.ui.label_chps_type_3.setObjectName("label_chps_type_3")
+			self.ui.gridLayout_2.addWidget(self.ui.label_chps_type_3, 17, 2, 1, 1)
+			self.ui.lineEdit_fieldname_13 = QtWidgets.QLineEdit(self.ui.tab_3)
+			self.ui.lineEdit_fieldname_13.setObjectName("lineEdit_fieldname_13")
+			self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_13, 16, 3, 1, 1)
+			self.ui.lineEdit_fieldname_23 = QtWidgets.QLineEdit(self.ui.tab_3)
+			self.ui.lineEdit_fieldname_23.setObjectName("lineEdit_fieldname_23")
+			self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_23, 16, 4, 1, 1)
+			self.ui.lineEdit_fieldname_3 = QtWidgets.QLineEdit(self.ui.tab_3)
+			self.ui.lineEdit_fieldname_3.setObjectName("lineEdit_fieldname_3")
+			self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_3, 16, 5, 1, 1)
+			self.ui.lineEdit_fieldname_4 = QtWidgets.QLineEdit(self.ui.tab_3)
+			self.ui.lineEdit_fieldname_4.setObjectName("lineEdit_fieldname_4")
+			self.ui.gridLayout_2.addWidget(self.ui.lineEdit_fieldname_4, 16, 6, 1, 1)
+			self.ui.comboBox_fieldname_13 = QtWidgets.QComboBox(self.ui.tab_3)
+			self.ui.comboBox_fieldname_13.setObjectName("comboBox_fieldname_13")
+			self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_13, 17, 3, 1, 1)
+			self.ui.comboBox_fieldname_23 = QtWidgets.QComboBox(self.ui.tab_3)
+			self.ui.comboBox_fieldname_23.setObjectName("comboBox_fieldname_23")
+			self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_23, 17, 4, 1, 1)
+			self.ui.comboBox_fieldname_3 = QtWidgets.QComboBox(self.ui.tab_3)
+			self.ui.comboBox_fieldname_3.setObjectName("comboBox_fieldname_3")
+			self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_3, 17, 5, 1, 1)
+			self.ui.comboBox_fieldname_4 = QtWidgets.QComboBox(self.ui.tab_3)
+			self.ui.comboBox_fieldname_4.setObjectName("comboBox_fieldname_4")
+			self.ui.gridLayout_2.addWidget(self.ui.comboBox_fieldname_4, 17, 6, 1, 1)
+			
+			self.ui.lineEdit_fieldname_13.setText(_translate("PHYMOBAT", "NIVEAU_1", None))
+			self.ui.comboBox_fieldname_13.addItem("String")
+			self.ui.comboBox_fieldname_13.addItem("Real")
+			self.ui.lineEdit_fieldname_23.setText(_translate("PHYMOBAT", "NIVEAU_2", None))
+			self.ui.comboBox_fieldname_23.addItem("String")
+			self.ui.comboBox_fieldname_23.addItem("Real")
+			self.ui.lineEdit_fieldname_3.setText(_translate("PHYMOBAT", "NIVEAU_3", None))
+			self.ui.comboBox_fieldname_3.addItem("String")
+			self.ui.comboBox_fieldname_3.addItem("Real")
+			self.ui.lineEdit_fieldname_4.setText(_translate("PHYMOBAT", "POURC", None))
+			self.ui.comboBox_fieldname_4.addItem("Real")  
+			self.ui.comboBox_fieldname_4.addItem("String")
+			
+			self.ui.label_chps_3.setText(_translate("PHYMOBAT", "	Champs\n"+" des entités", None))
+			self.ui.label_chps_type_3.setText(_translate("PHYMOBAT", "Type :", None))
+			self.ui.label_chps_name_3.setText(_translate("PHYMOBAT", "Nom :", None))
+		
+		if not self.ui.checkBox_classifier_3.isChecked(): 
+			# Clear options filednames
+			try:
+				self.ui.label_chps_3.deleteLater()
+				self.ui.label_chps_name_3.deleteLater()
+				self.ui.label_chps_type_3.deleteLater()  
+				self.ui.lineEdit_fieldname_13.deleteLater()
+				self.ui.comboBox_fieldname_13.deleteLater()
+				self.ui.lineEdit_fieldname_23.deleteLater()
+				self.ui.comboBox_fieldname_23.deleteLater()
+				self.ui.lineEdit_fieldname_3.deleteLater()
+				self.ui.comboBox_fieldname_3.deleteLater()
+				self.ui.lineEdit_fieldname_4.deleteLater()
+				self.ui.comboBox_fieldname_4.deleteLater()
+			except AttributeError:	  
+				pass
+			
+	def ok_button(self):
+		"""
+			Function to launch the processing. This function take account :
+			
+			- The ``Multi-processing`` check box if the processing has launched with multi process. By default, this is checked. It need a computer with minimum 12Go memory.
+			- Append a few system value with :func:`get_variable`.
+			- There are 3 principal check boxes :
+				- to get number download available images
+				- for downloading and processing on theia platform
+				- to compute optimal threshold.
+				- to compute slope raster
+				- for classification processing.
+		"""
+		
+		# Start the processus
+		startTime = time.time()
+		
+		# To know if the processing must be launch on several thread
+		self.mp = Constantes.MULTIPROCESSING_ENABLE if self.ui.checkBox_multiprocess.isChecked() else Constantes.MULTIPROCESSING_DISABLE 
+		
+		self.get_variable() # Append a few system value
+		vs = 0 # Variable to launch VHRS texture processing
+		dd = 0 # Variable to launch image downloading 
+		ok = 1 # Variable to verify informations -> 0 not ok, 1 ok
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			# if download check box is checked only
+			if not self.ui.checkBox_listing.isChecked() and self.ui.checkBox_download.isChecked():		   
+				self.ui.checkBox_listing.setChecked(True)
+				 
+			if ok == 1:	   
+				# Compute a output slope raster 
+				if self.ui.checkBox_MNT.isChecked():
+				
+					self.i_slope()	   
+				
+				# Downloading and processing on theia platform
+				# A check box to get number download available images
+				if self.ui.checkBox_listing.isChecked():
+					
+					if self.ui.checkBox_download.isChecked():
+						# To launch the downloading
+						dd = 1
+					
+					self.i_download(dd) # Launch image listing and downloading if dd = 1
+					self.set_variable() # to write in the line edit about number download available images
+					
+					# Check box to launch the image processing
+					if self.ui.checkBox_processing.isChecked():
+						# Another check box to launch VHRS texture processing. If checked, vs = 1.
+						if self.ui.checkBox_VHRS.isChecked():
+							vs = 1
+						self.i_images_processing(vs) # function to launch the image processing			
+				
+				# To launch the image processing without dowloading but with the images in a main folder
+				# Without internet connection
+				if not self.ui.checkBox_download.isChecked() and self.ui.checkBox_processing.isChecked():
+					
+					# Launch pre-processing without downloading
+					self.i_glob()
+					# Another check box to launch VHRS texture processing. If checked, vs = 1.
+					if self.ui.checkBox_VHRS.isChecked():
+						vs = 1
+					self.i_images_processing(vs) # function to launch the image processing			
+				
+				# To launch texture processing only
+				if not self.ui.checkBox_listing.isChecked() and not self.ui.checkBox_processing.isChecked() and self.ui.checkBox_VHRS.isChecked():
+					
+					self.i_vhrs()
+				
+				# Compute optimal threshold  
+				if self.ui.checkBox_threshold.isChecked():
+					
+					if self.ui.radioButton_rf.isChecked():
+						self.i_sample_rf()
+					elif self.ui.radioButton_s.isChecked():
+						self.i_sample()
+				
+				# Classification processing 
+				if self.ui.radioButton_rf.isChecked():
+					
+					if self.ui.checkBox_classifier_3.isChecked():
+						
+						self.out_fieldname_carto = self.out_fieldname_carto
+						self.out_fieldtype_carto = self.out_fieldtype_carto			 
+						self.i_classifier_rf()
+						self.i_validate()
+						
+				elif self.ui.radioButton_s.isChecked():
+					
+					if self.ui.checkBox_classifier_1.isChecked() :		 
+						
+						self.out_fieldname_carto = self.out_fieldname_carto[:3]
+						self.out_fieldtype_carto = self.out_fieldtype_carto[:3]
+						self.i_classifier_s()
+						self.i_validate()
+						
+					if self.ui.checkBox_classifier_2.isChecked() :
+						
+						self.out_fieldname_carto = self.out_fieldname_carto[:4]
+						self.out_fieldtype_carto = self.out_fieldtype_carto[:4]			 
+						self.i_classifier_s()
+						self.i_validate()
+						
+					if self.ui.checkBox_classifier_3.isChecked():
+						
+						self.out_fieldname_carto = self.out_fieldname_carto
+						self.out_fieldtype_carto = self.out_fieldtype_carto			 
+						self.i_classifier_s()
+						self.i_validate()
+					
+		if self.current_mode == Constantes.SIMPLE_MODE:
+			
+			# Compute a output slope raster 
 
-            self.ui.lineEdit_area_path.setText(pr.find("Area_path").text)
-            
-            if self.mode == 1:
-                if pr.find("Images_available").text == '1':
-                    self.ui.checkBox_listing.setChecked(True)
-                else:
-                    self.ui.checkBox_listing.setChecked(False)
-                if pr.find("Download").text == '1':
-                    self.ui.checkBox_download.setChecked(True)
-                else:
-                    self.ui.checkBox_download.setChecked(False)
-                
-            try:
-                self.ui.lineEdit_user.setText(pr.find("Username").text)
-                self.ui.lineEdit_password.setText(pr.find("Password").text)
-            except:
-                print('Not username or password Theia')
-            
-            self.f_proxy()
-            try:
-                pp = pr.find("Proxy[@id='Proxy']")
-                self.w_proxy.w_proxy.lineEdit_proxy.setText(pp.find("Proxy_adress").text)
-                try:
-                    self.w_proxy.w_proxy.lineEdit_password_proxy.setText(pp.find("Proxy_login").text)
-                except TypeError:
-                    pass
-                try:
-                    self.w_proxy.w_proxy.lineEdit_login_proxy.setText(pp.find("Proxy_password").text)
-                except TypeError:
-                    pass
-                self.w_proxy.id_proxy()
-            except AttributeError:
-                print('Not proxy')
-            self.w_proxy.close_window()
-                
-            if self.mode == 1:
-                if pr.find("Img_processing").text == '1':
-                    self.ui.checkBox_processing.setChecked(True)
-                else:
-                    self.ui.checkBox_processing.setChecked(False)
-                if pr.find("VHRS_checked").text == '1':
-                    self.ui.checkBox_VHRS.setChecked(True)
-                else:
-                    self.ui.checkBox_VHRS.setChecked(False)    
-                
-            try:
-                self.ui.lineEdit_VHRS.setText(pr.find("VHRS").text)
-            except:
-                print('Not VHRS image')
-                
-            if self.mode == 1:
-                if pr.find("MNT_checked").text == '1':
-                    self.ui.checkBox_MNT.setChecked(True)
-                else:
-                    self.ui.checkBox_MNT.setChecked(False)    
-                
-            try:
-                self.ui.lineEdit_MNT.setText(pr.find("MNT").text)
-            except:
-                print('Not MNT')
-                
-            ps = tree.find("Tab[@id='Processing_sample']")  
-            if self.mode == 1:
-                try:
-                    for sple_n in ps.iter("Sample"):
-                        self.ui.lineEdit_sample_path.setText(sple_n.find("Sample_path").text)
-                        self.ui.lineEdit_select_sample_fieldname_1.setText(sple_n.find("Fieldname_1").text)
-                        self.ui.lineEdit_select_sample_fieldname_2.setText(sple_n.find("Fieldname_2").text)
-                        self.ui.lineEdit_select_sample_class_1.setText(sple_n.find("Classname_1").text)
-                        self.ui.lineEdit_select_sample_class_2.setText(sple_n.find("Classname_2").text)
-                        self.ui.lineEdit_select_sample_nb_poly.setText(sple_n.find("Nb_polygones").text)
-                        # Launch rpg method if the box is checked and if the shapefile hasn't go through rpg method (with prefix MONO_)
-                        if sple_n.find("RPG").text == '1' and os.path.split(sple_n.find("Sample_path").text)[1][:5] != 'MONO_':
-                            self.ui.checkBox_RPG.setChecked(True)
-                        try:
-                            if sple_n.find("Img_sample").text != "":
-                                self.ui.lineEdit_img_sample.setText(sple_n.find("Img_sample").text)
-                                self.ui.checkBox_img_sample.setChecked(True)
-                        except:
-                            print('Not sample raster only !')
-                        self.add_sample()
-                except:
-                    print('Not sample')
-            elif self.mode ==0:
-                # RPG
-                sple_n = ps[0]
-                self.ui.lineEdit_sample_path.setText(sple_n.find("Sample_path").text)
-                self.ui.lineEdit_select_sample_fieldname_1.setText(sple_n.find("Fieldname_1").text)
-                self.ui.lineEdit_select_sample_fieldname_2.setText(sple_n.find("Fieldname_2").text)
-                self.ui.lineEdit_select_sample_class_1.setText(sple_n.find("Classname_1").text)
-                self.ui.lineEdit_select_sample_class_2.setText(sple_n.find("Classname_2").text)
-                self.ui.lineEdit_select_sample_nb_poly.setText(sple_n.find("Nb_polygones").text)
-                
-                # To Grass/wooden
-                sple_n = ps[1]
-                self.ui.lineEdit_sample_path_2.setText(sple_n.find("Sample_path").text)
-                self.ui.lineEdit_select_sample_fieldname_3.setText(sple_n.find("Fieldname_1").text)
-                self.ui.lineEdit_select_sample_fieldname_4.setText(sple_n.find("Fieldname_2").text)
-                self.ui.lineEdit_select_sample_class_3.setText(sple_n.find("Classname_1").text)
-                self.ui.lineEdit_select_sample_class_4.setText(sple_n.find("Classname_2").text)
-                self.ui.lineEdit_select_sample_nb_poly_2.setText(sple_n.find("Nb_polygones").text)        
-                
-                # To wooden
-                sple_n = ps[2]
-                self.ui.lineEdit_sample_path_3.setText(sple_n.find("Sample_path").text)
-                self.ui.lineEdit_select_sample_fieldname_5.setText(sple_n.find("Fieldname_1").text)
-                self.ui.lineEdit_select_sample_fieldname_6.setText(sple_n.find("Fieldname_2").text)
-                self.ui.lineEdit_select_sample_class_5.setText(sple_n.find("Classname_1").text)
-                self.ui.lineEdit_select_sample_class_6.setText(sple_n.find("Classname_2").text)
-                self.ui.lineEdit_select_sample_nb_poly_3.setText(sple_n.find("Nb_polygones").text)
-                    
-            if self.mode == 1:
-                if ps.find("Threshold_checked").text == '1':
-                    self.ui.checkBox_threshold.setChecked(True)
-                else:
-                    self.ui.checkBox_threshold.setChecked(False) 
-             
-            c = tree.find("Tab[@id='Classification']")
-            try:
-                self.ui.lineEdit_segmentation.setText(c.find("Segmentation_path").text)
-            except:
-                print('Not segmentation')
-            try:
-                self.ui.lineEdit_output.setText(c.find("Output_path").text)
-            except:
-                print('Not output file')
-            if self.mode == 1:
-                if len(c) == 5:
-                    self.ui.checkBox_classifier_1.setChecked(True)
-                    self.ui.lineEdit_fieldname_1.setText(c.find("Output_fieldname_1").text)
-                    index_fieldname_1 = self.ui.comboBox_fieldname_1.findText(c.find("Output_type_1").text)        
-                    self.ui.comboBox_fieldname_1.setCurrentIndex(index_fieldname_1)
-                elif len(c) == 7:
-                    self.ui.checkBox_classifier_2.setChecked(True)
-                    self.ui.lineEdit_fieldname_12.setText(c.find("Output_fieldname_1").text)
-                    self.ui.lineEdit_fieldname_2.setText(c.find("Output_fieldname_2").text)
-                    index_fieldname_12 = self.ui.comboBox_fieldname_12.findText(c.find("Output_type_1").text)        
-                    self.ui.comboBox_fieldname_12.setCurrentIndex(index_fieldname_12)
-                    index_fieldname_2 = self.ui.comboBox_fieldname_2.findText(c.find("Output_type_2").text)        
-                    self.ui.comboBox_fieldname_2.setCurrentIndex(index_fieldname_2)
-                elif len(c) == 11:
-                    self.ui.checkBox_classifier_3.setChecked(True)
-                    self.ui.lineEdit_fieldname_13.setText(c.find("Output_fieldname_1").text)
-                    self.ui.lineEdit_fieldname_23.setText(c.find("Output_fieldname_2").text)
-                    self.ui.lineEdit_fieldname_3.setText(c.find("Output_fieldname_3").text)
-                    self.ui.lineEdit_fieldname_4.setText(c.find("Output_fieldname_4").text)
-                    index_fieldname_13 = self.ui.comboBox_fieldname_13.findText(c.find("Output_type_1").text)        
-                    self.ui.comboBox_fieldname_13.setCurrentIndex(index_fieldname_13)
-                    index_fieldname_23 = self.ui.comboBox_fieldname_23.findText(c.find("Output_type_2").text)        
-                    self.ui.comboBox_fieldname_23.setCurrentIndex(index_fieldname_23)
-                    index_fieldname_3 = self.ui.comboBox_fieldname_3.findText(c.find("Output_type_3").text)        
-                    self.ui.comboBox_fieldname_3.setCurrentIndex(index_fieldname_3)
-                    index_fieldname_4 = self.ui.comboBox_fieldname_4.findText(c.find("Output_type_4").text)        
-                    self.ui.comboBox_fieldname_4.setCurrentIndex(index_fieldname_4)
-                
-                # Classification mode
-                if c.find("Classification_method").text == '1':
-                    self.ui.radioButton_rf.setChecked(True)
-                else:
-                    self.ui.radioButton_s.setChecked(True)
-                       
-    def save_backup(self):
-        """
-        Function to save input text in every fields. The output file must be a XML file.
-        """
-        
-        out_backup = QtWidgets.QFileDialog.getSaveFileName(self, "Save backup", os.getcwd(), '*.xml')[0]
+			if self.path_mnt != "":
+				self.i_slope()
+		
+			# Save the sample features
+			self.add_sample()
+			
+			# Look at if the the images has been already downloaded, download them otherwise
+			# Commenté pour ne traiter qu'une image
+			self.i_download()
+			
+			# function to launch the image processing	
+			self.i_images_processing()
 
-        # if the user has forgotten to put .shp at the end of the output xml
-        if out_backup[-4:] != '.xml':
-            out_backup = out_backup + '.xml'
-        
-        root = ET.Element("Data_filled")
-        
-        if self.ui.checkBox_multiprocess.isChecked():
-            ET.SubElement(root, "Multi_process", type = "int").text = str(1)
-        else:
-            ET.SubElement(root, "Multi_process", type = "int").text = str(0)
-        
-        doc = ET.SubElement(root, "Tab", id="Processing_raster")
-        ET.SubElement(doc, "Principal_folder", type = "str").text = "%s" % self.ui.lineEdit_principal_folder.text()
-        if self.mode == 1:
-            ET.SubElement(doc, "Captor", type = "str").text = "%s" % self.ui.comboBox_captor.currentText()
-        else:
-            ET.SubElement(doc, "Captor", type = "str").text = "Landsat"
-        ET.SubElement(doc, "Year_images", type = "str").text = "%s" % self.ui.lineEdit_year_images.text()
-        ET.SubElement(doc, "Area_path", type = "str").text = "%s" % self.ui.lineEdit_area_path.text()
-        
-        if self.mode == 1:
-            if self.ui.checkBox_listing.isChecked():
-                ET.SubElement(doc, "Images_available", type = "int").text = str(1)
-            else:
-                ET.SubElement(doc, "Images_available", type = "int").text = str(0)
-            if self.ui.checkBox_download.isChecked():
-                ET.SubElement(doc, "Download", type = "int").text = str(1)
-            else:
-                ET.SubElement(doc, "Download", type = "int").text = str(0)
-        else:
-            ET.SubElement(doc, "Images_available", type = "int").text = str(0)
-            ET.SubElement(doc, "Download", type = "int").text = str(0)
-            
-        ET.SubElement(doc, "Username", type = "str").text = "%s" % self.ui.lineEdit_user.text()
-        ET.SubElement(doc, "Password", type = "str").text = "%s" % self.ui.lineEdit_password.text()
-        if self.w_proxy is None:
-            sub_proxy = ET.SubElement(doc, "Proxy", id="No_proxy")
-            ET.SubElement(sub_proxy, "Proxy_adress", type = "str").text = ""
-            ET.SubElement(sub_proxy, "Proxy_login", type = "str").text = ""
-            ET.SubElement(sub_proxy, "Proxy_password", type = "str").text = ""
-        elif self.w_proxy.proxy == "":
-            sub_proxy = ET.SubElement(doc, "Proxy", id="No_proxy")
-            ET.SubElement(sub_proxy, "Proxy_adress", type = "str").text = ""
-            ET.SubElement(sub_proxy, "Proxy_login", type = "str").text = ""
-            ET.SubElement(sub_proxy, "Proxy_password", type = "str").text = ""
-        else:
-            sub_proxy = ET.SubElement(doc, "Proxy", id="Proxy")
-            ET.SubElement(sub_proxy, "Proxy_adress", type = "str").text = "%s" % self.w_proxy.proxy
-            ET.SubElement(sub_proxy, "Proxy_login", type = "str").text = "%s" % self.w_proxy.login_proxy
-            ET.SubElement(sub_proxy, "Proxy_password", type = "str").text = "%s" % self.w_proxy.password_proxy
-        
-        if self.mode == 1:
-            if self.ui.checkBox_processing.isChecked():
-                ET.SubElement(doc, "Img_processing", type = "int").text = str(1)
-            else:
-                ET.SubElement(doc, "Img_processing", type = "int").text = str(0)
-            
-            if self.ui.checkBox_VHRS.isChecked():
-                ET.SubElement(doc, "VHRS_checked", type = "int").text = str(1)
-            else:
-                ET.SubElement(doc, "VHRS_checked", type = "int").text = str(0)
-        else:
-            ET.SubElement(doc, "Img_processing", type = "int").text = str(1)
-            ET.SubElement(doc, "VHRS_checked", type = "int").text = str(1)
-            
-        ET.SubElement(doc, "VHRS", type = "str").text = "%s" % self.ui.lineEdit_VHRS.text()
-        
-        if self.mode == 1:
-            if self.ui.checkBox_MNT.isChecked():
-                ET.SubElement(doc, "MNT_checked", type = "int").text = str(1)
-            else:
-                ET.SubElement(doc, "MNT_checked", type = "int").text = str(0)
-        else:
-            if "%s" % self.ui.lineEdit_MNT.text() != '':
-                ET.SubElement(doc, "MNT_checked", type = "int").text = str(1)
-            else:
-                ET.SubElement(doc, "MNT_checked", type = "int").text = str(0)
-            
-        ET.SubElement(doc, "MNT", type = "str").text = "%s" % self.ui.lineEdit_MNT.text()
-        
-        doc = ET.SubElement(root, "Tab", id="Processing_sample")
-        if self.mode == 1:
-            for sa in range(len(self.sample_name)):
-                sub_doc = ET.SubElement(doc, "Sample", id="Sample_" + str(sa))
-                ET.SubElement(sub_doc, "Sample_path", type = "str").text = self.sample_name[sa]
-                ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = self.fieldname_args[2*sa]
-                ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = self.fieldname_args[2*sa+1]
-                ET.SubElement(sub_doc, "Classname_1", type = "str").text = self.class_args[2*sa]
-                ET.SubElement(sub_doc, "Classname_2", type = "str").text = self.class_args[2*sa+1]
-                ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = self.list_nb_sample[sa]
-                ET.SubElement(sub_doc, "RPG", type = "int").text = str(self.rpg_tchek[sa])
-                try:
-                    # To enter a sample raster if the first tab doesn't launch before 
-                    if self.img_sample[sa] == 1:
-                        ET.SubElement(sub_doc, "Img_sample", type = "str").text = self.raster_path[sa]
-                except:
-                    print('Not sample raster only !')   
-        else:
-            # RPG
-            sub_doc = ET.SubElement(doc, "Sample", id="Sample_0")
-            ET.SubElement(sub_doc, "Sample_path", type = "str").text = "%s" % self.ui.lineEdit_sample_path.text()
-            ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_1.text()
-            ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_2.text()
-            ET.SubElement(sub_doc, "Classname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_1.text()
-            ET.SubElement(sub_doc, "Classname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_2.text()
-            ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = "%s" % self.ui.lineEdit_select_sample_nb_poly.text()
-            ET.SubElement(sub_doc, "RPG", type = "int").text = str(1)
-            
-            # To Grass/wooden
-            sub_doc = ET.SubElement(doc, "Sample", id="Sample_1")
-            ET.SubElement(sub_doc, "Sample_path", type = "str").text = "%s" % self.ui.lineEdit_sample_path_2.text()
-            ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_3.text()
-            ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_4.text()
-            ET.SubElement(sub_doc, "Classname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_3.text()
-            ET.SubElement(sub_doc, "Classname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_4.text()
-            ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = "%s" % self.ui.lineEdit_select_sample_nb_poly_2.text()
-            ET.SubElement(sub_doc, "RPG", type = "int").text = str(0)
-            
-            # To wooden  
-            sub_doc = ET.SubElement(doc, "Sample", id="Sample_2")
-            ET.SubElement(sub_doc, "Sample_path", type = "str").text = "%s" % self.ui.lineEdit_sample_path_3.text()
-            ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_5.text()
-            ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_6.text()
-            ET.SubElement(sub_doc, "Classname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_5.text()
-            ET.SubElement(sub_doc, "Classname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_6.text()
-            ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = "%s" % self.ui.lineEdit_select_sample_nb_poly_3.text()
-            ET.SubElement(sub_doc, "RPG", type = "int").text = str(0) 
-        
-        if self.mode == 1:
-            if self.ui.checkBox_threshold.isChecked():
-                ET.SubElement(doc, "Threshold_checked", type = "int").text = str(1)
-            else:
-                ET.SubElement(doc, "Threshold_checked", type = "int").text = str(0)
-        else:
-            ET.SubElement(doc, "Threshold_checked", type = "int").text = str(1)
-            
-        doc = ET.SubElement(root, "Tab", id="Classification")
-        ET.SubElement(doc, "Segmentation_path", type = "str").text = "%s" % self.ui.lineEdit_segmentation.text()
-        ET.SubElement(doc, "Output_path", type = "str").text = "%s" % self.ui.lineEdit_output.text()
-        
-        if self.mode == 1:
-                
-            if self.ui.checkBox_classifier_1.isChecked():
-                ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_fieldname_1.text()
-                ET.SubElement(doc, "Output_type_1", type = "str").text = "%s" % self.ui.comboBox_fieldname_1.currentText()
-             
-            if self.ui.checkBox_classifier_2.isChecked():
-                ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_fieldname_12.text()
-                ET.SubElement(doc, "Output_type_1", type = "str").text = "%s" % self.ui.comboBox_fieldname_12.currentText()    
-                ET.SubElement(doc, "Output_fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_fieldname_2.text()
-                ET.SubElement(doc, "Output_type_2", type = "str").text = "%s" % self.ui.comboBox_fieldname_2.currentText()
-            
-            if self.ui.checkBox_classifier_3.isChecked():
-                ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_fieldname_13.text()
-                ET.SubElement(doc, "Output_type_1", type = "str").text = "%s" % self.ui.comboBox_fieldname_13.currentText()    
-                ET.SubElement(doc, "Output_fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_fieldname_23.text()
-                ET.SubElement(doc, "Output_type_2", type = "str").text = "%s" % self.ui.comboBox_fieldname_23.currentText()
-                ET.SubElement(doc, "Output_fieldname_3", type = "str").text = "%s" % self.ui.lineEdit_fieldname_3.text()
-                ET.SubElement(doc, "Output_type_3", type = "str").text = "%s" % self.ui.comboBox_fieldname_3.currentText()
-                ET.SubElement(doc, "Output_fieldname_4", type = "str").text = "%s" % self.ui.lineEdit_fieldname_4.text()
-                ET.SubElement(doc, "Output_type_4", type = "str").text = "%s" % self.ui.comboBox_fieldname_4.currentText()
-            
-            # Classification mode
-            if self.ui.radioButton_rf.isChecked():
-                ET.SubElement(doc, "Classification_method", type = "int").text = str(1)
-            elif self.ui.radioButton_s.isChecked():
-                ET.SubElement(doc, "Classification_method", type = "int").text = str(0)
-        else:
-            ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "NIVEAU_1"
-            ET.SubElement(doc, "Output_type_1", type = "str").text = "String"   
-            ET.SubElement(doc, "Output_fieldname_2", type = "str").text = "NIVEAU_2"
-            ET.SubElement(doc, "Output_type_2", type = "str").text = "String"
-            ET.SubElement(doc, "Output_fieldname_3", type = "str").text = "NIVEAU_3"
-            ET.SubElement(doc, "Output_type_3", type = "str").text = "String"
-            ET.SubElement(doc, "Output_fieldname_4", type = "str").text = "POURC"
-            ET.SubElement(doc, "Output_type_4", type = "str").text = "Real"
-            ET.SubElement(doc, "Classification_method", type = "int").text = str(1)
-            
-        tree = ET.ElementTree(root)
-        # Write in a xml file
-        tree.write(str(out_backup), encoding="UTF-8",xml_declaration=True, pretty_print=True)
-        
-    def about_PHYMOBA(self):
-        """
-        Function to open a new window "About PHYMOBAT"
-        """
-        if self.apropos is None:
-            self.apropos = MyPopup_about()
-        self.apropos.show()
-        
-    def help_tools(self):
-        """
-        Function to open html help
-        """
-        webbrowser.open('file://' + os.getcwd() + '/Documentation/methode_tuto.html#tutoriels-interface')
-    
-    def mode_simpli(self):
-        """
-        Function to open a new window in simple mode "PHYMOBATs"
-        """
-        if self.simpli is None:
-            print ("Simplify mode")
-            self.close()
-            self.simpli = PHYMOBAT(mode = 0)
-            
-        self.simpli.show()
-    
-    def mode_expert(self):
-        """
-        Function to open a new window in expert mode "PHYMOBATe"
-        """
-        if self.expert is None:
-            print ("Expert mode")
-            self.close()
-            self.expert = PHYMOBAT(mode = 1)
-            
-        self.expert.show()
-        
-    def forget_study_area(self):
-        """
-        Function to open a new window 'Alert' because user forgotten to declare study area.
-        """
-        if self.w_study_area is None:
-            self.w_study_area = MyPopup_warming_study_area()
-        self.w_study_area.show()
-        
-    def forget_raster_sample(self):
-        """
-        Function to open a new window 'Alert' because user forgotten to declare rasters or samples.
-        """
-        if self.w_forget is None:
-            self.w_forget = MyPopup_warming_forgetting()
-        self.w_forget.show()
-                
-    def close_button(self):
-        """
-        Function to close the interface.
-        """
-        self.close()
+			# To launch texture processing only
+			self.i_vhrs()
 
-class MyPopup_about(QtWidgets.QWidget):
-    """
-    Popup to display "About PHYMOBAT". In this windows, it prints informations on the processing, license
-    and version.
-    """
-    def __init__(self, parent=None):
-        QtWidgets.QWidget.__init__(self, parent)
-        self.prop = Ui_About()
-        self.prop.setupUi(self)
-        
-        self.prop.close_newWindow.clicked.connect(self.close_window)
-    
-    def close_window(self):
-        """
-        Function to close the "A propos PHYMOBAT".
-        """
-        self.close()
-        
-class MyPopup_warming_study_area(QtWidgets.QWidget):
-    """
-    Popup to display a message to say there isn't declared study area file.
-    """
-    def __init__(self, parent=None):
-        QtWidgets.QWidget.__init__(self, parent)
-        self.w_study_a = Ui_Warming_study_area()
-        self.w_study_a.setupUi(self)
-        
-        self.w_study_a.pushButton_ok_window_warning_study_area.clicked.connect(self.close_window)
-    
-    def close_window(self):
-        """
-        Function to close the popup.
-        """
-        self.close() 
-        
-class MyPopup_warming_forgetting(QtWidgets.QWidget):
-    """
-    Popup to display a message to tell you if you fogotten to enter a raster or a sample.
-    """
-    def __init__(self, parent=None):
-        QtWidgets.QWidget.__init__(self, parent)
-        self.w_forget = Ui_Warming_forgetting()
-        self.w_forget.setupUi(self)
-        
-        self.w_forget.pushButton_ok_forget.clicked.connect(self.close_window)
-    
-    def close_window(self):
-        """
-        Function to close the popup.
-        """
-        self.close() 
-        
-class MyPopup_proxy_window(QtWidgets.QWidget):
-    """
-    Popup to display a message to tell you if you fogotten to enter a raster or a sample.
-    """
-    def __init__(self, parent=None):
-        QtWidgets.QWidget.__init__(self, parent)
-        self.w_proxy = Ui_Proxy_window()
-        self.w_proxy.setupUi(self)
-        
-        # Proxy ID
-        self.proxy = ""
-        self.login_proxy = ""
-        self.password_proxy = ""
-        
-        # Connect Apply|Close button
-        self.w_proxy.buttonBox_proxy.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(self.close_window)
-        self.w_proxy.buttonBox_proxy.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self.id_proxy)
-    
-    def id_proxy(self):
-        """
-        Function to use input proxy id
-        """
-        self.login_proxy = "%s" % self.w_proxy.lineEdit_login_proxy.text()
-        self.password_proxy = "%s" % self.w_proxy.lineEdit_password_proxy.text()
-        self.proxy = "%s" % self.w_proxy.lineEdit_proxy.text()
-    
-    def close_window(self):
-        """
-        Function to close the popup.
-        """
-        self.close()
-        
+			# Compute optimal threshold 
+			self.i_sample_rf()
+					
+			# Classification processing 
+			self.out_fieldname_carto = self.out_fieldname_carto
+			self.out_fieldtype_carto = self.out_fieldtype_carto 
+			self.i_classifier_rf()
+			self.i_validate()
+			
+		# Clear variables after processing
+		#self.clear_sample()
+		self.out_fieldname_carto = ['ID', 'AREA']
+		self.out_fieldtype_carto = [ogr.OFTString, ogr.OFTReal]
+		# Images after processing images
+		self.out_ndvistats_folder_tab = defaultdict(list)
+		
+		Processing.__init__(self)# Initialize variable without to close and launch again the application
+		
+		# End of the processus
+		endTime = time.time() # Tps : Terminé
+		self.logger.info('...........' + ' Outputted to File in ' + str(endTime - startTime) + ' secondes')
+		nb_day_processing = int(time.strftime('%d', time.gmtime(endTime - startTime))) - 1
+		self.logger.info("That is, " + str(nb_day_processing) + ' day(s) ' + time.strftime('%Hh %Mmin%S', time.gmtime(endTime - startTime)))
+		
+	def open_backup(self, test=None):
+		"""
+		Function to load input text in every fields. The input file must be a XML file.
+		"""
+		if test is None :
+			in_backup = QtWidgets.QFileDialog.getOpenFileName(self, "Open backup", os.getcwd(), '*.xml')[0]
+		else :
+			in_backup = test
+		
+		if in_backup != None and len(in_backup) > 0 :
+
+			# Parse the xml file if the user choose a file
+			tree = ET.parse(str(in_backup))
+			
+			if tree.find("Multi_process").text == '1':
+				self.ui.checkBox_multiprocess.setChecked(True)
+			else:
+				self.ui.checkBox_multiprocess.setChecked(False)
+			
+			pr = tree.find("Tab[@id='Processing_raster']")
+
+			try:
+				self.ui.lineEdit_principal_folder.setText(pr.find("Principal_folder").text)
+			except:
+				self.info.debug('Not principal folder')
+
+			if self.current_mode == Constantes.EXPERT_MODE:
+				index_captor = self.ui.comboBox_captor.findText(pr.find("Captor").text) # To find combo box index
+				self.ui.comboBox_captor.setCurrentIndex(index_captor)
+
+			try:
+				self.ui.lineEdit_year_images.setText(pr.find("Year_images").text)
+			except:
+				self.logger.debug('Not year images')
+
+			self.ui.lineEdit_area_path.setText(pr.find("Area_path").text)
+			
+			if self.current_mode == Constantes.EXPERT_MODE:
+				if pr.find("Images_available").text == '1':
+					self.ui.checkBox_listing.setChecked(True)
+				else:
+					self.ui.checkBox_listing.setChecked(False)
+				if pr.find("Download").text == '1':
+					self.ui.checkBox_download.setChecked(True)
+				else:
+					self.ui.checkBox_download.setChecked(False)
+				
+			try:
+				self.ui.lineEdit_user.setText(pr.find("Username").text)
+				self.ui.lineEdit_password.setText(pr.find("Password").text)
+			except:
+				self.logger.debug('Not username or password Theia')
+			
+			self.f_proxy()
+			try:
+				pp = pr.find("Proxy[@id='Proxy']")
+				self.w_proxy.w_proxy.lineEdit_proxy.setText(pp.find("Proxy_adress").text)
+				try:
+					self.w_proxy.w_proxy.lineEdit_password_proxy.setText(pp.find("Proxy_login").text)
+				except TypeError:
+					pass
+				try:
+					self.w_proxy.w_proxy.lineEdit_login_proxy.setText(pp.find("Proxy_password").text)
+				except TypeError:
+					pass
+				self.w_proxy.id_proxy()
+			except AttributeError:
+				self.logger.debug('Not proxy')
+			self.w_proxy.close_window()
+				
+			if self.current_mode == Constantes.EXPERT_MODE:
+				if pr.find("Img_processing").text == '1':
+					self.ui.checkBox_processing.setChecked(True)
+				else:
+					self.ui.checkBox_processing.setChecked(False)
+				if pr.find("VHRS_checked").text == '1':
+					self.ui.checkBox_VHRS.setChecked(True)
+				else:
+					self.ui.checkBox_VHRS.setChecked(False)	
+				
+			try:
+				self.ui.lineEdit_VHRS.setText(pr.find("VHRS").text)
+			except:
+				self.logger.debug('Not VHRS image')
+				
+			if self.current_mode == Constantes.EXPERT_MODE:
+				if pr.find("MNT_checked").text == '1':
+					self.ui.checkBox_MNT.setChecked(True)
+				else:
+					self.ui.checkBox_MNT.setChecked(False)	
+				
+			try:
+				self.ui.lineEdit_MNT.setText(pr.find("MNT").text)
+			except:
+				self.logger.debug('Not MNT')
+				
+			ps = tree.find("Tab[@id='Processing_sample']")  
+			if self.current_mode == Constantes.EXPERT_MODE:
+				try:
+					for sple_n in ps.iter("Sample"):
+						self.ui.lineEdit_sample_path.setText(sple_n.find("Sample_path").text)
+						self.ui.lineEdit_select_sample_fieldname_1.setText(sple_n.find("Fieldname_1").text)
+						self.ui.lineEdit_select_sample_fieldname_2.setText(sple_n.find("Fieldname_2").text)
+						self.ui.lineEdit_select_sample_class_1.setText(sple_n.find("Classname_1").text)
+						self.ui.lineEdit_select_sample_class_2.setText(sple_n.find("Classname_2").text)
+						self.ui.lineEdit_select_sample_nb_poly.setText(sple_n.find("Nb_polygones").text)
+						# Launch rpg method if the box is checked and if the shapefile hasn't go through rpg method (with prefix MONO_)
+						if sple_n.find("RPG").text == '1' and os.path.split(sple_n.find("Sample_path").text)[1][:5] != 'MONO_':
+							self.ui.checkBox_RPG.setChecked(True)
+						try:
+							if sple_n.find("Img_sample").text != "":
+								self.ui.lineEdit_img_sample.setText(sple_n.find("Img_sample").text)
+								self.ui.checkBox_img_sample.setChecked(True)
+						except:
+							self.logger.debug('Not sample raster only !')
+
+						self.add_sample()
+				except:
+					self.logger.debug('Not sample')
+			
+			elif self.current_mode == Constantes.SIMPLE_MODE:
+				# RPG
+				sple_n = ps[0]
+				self.ui.lineEdit_sample_path.setText(sple_n.find("Sample_path").text)
+				self.ui.lineEdit_select_sample_fieldname_1.setText(sple_n.find("Fieldname_1").text)
+				self.ui.lineEdit_select_sample_fieldname_2.setText(sple_n.find("Fieldname_2").text)
+				self.ui.lineEdit_select_sample_class_1.setText(sple_n.find("Classname_1").text)
+				self.ui.lineEdit_select_sample_class_2.setText(sple_n.find("Classname_2").text)
+				self.ui.lineEdit_select_sample_nb_poly.setText(sple_n.find("Nb_polygones").text)
+				
+				# To Grass/wooden
+				sple_n = ps[1]
+				self.ui.lineEdit_sample_path_2.setText(sple_n.find("Sample_path").text)
+				self.ui.lineEdit_select_sample_fieldname_3.setText(sple_n.find("Fieldname_1").text)
+				self.ui.lineEdit_select_sample_fieldname_4.setText(sple_n.find("Fieldname_2").text)
+				self.ui.lineEdit_select_sample_class_3.setText(sple_n.find("Classname_1").text)
+				self.ui.lineEdit_select_sample_class_4.setText(sple_n.find("Classname_2").text)
+				self.ui.lineEdit_select_sample_nb_poly_2.setText(sple_n.find("Nb_polygones").text)		
+				
+				# To wooden
+				sple_n = ps[2]
+				self.ui.lineEdit_sample_path_3.setText(sple_n.find("Sample_path").text)
+				self.ui.lineEdit_select_sample_fieldname_5.setText(sple_n.find("Fieldname_1").text)
+				self.ui.lineEdit_select_sample_fieldname_6.setText(sple_n.find("Fieldname_2").text)
+				self.ui.lineEdit_select_sample_class_5.setText(sple_n.find("Classname_1").text)
+				self.ui.lineEdit_select_sample_class_6.setText(sple_n.find("Classname_2").text)
+				self.ui.lineEdit_select_sample_nb_poly_3.setText(sple_n.find("Nb_polygones").text)
+					
+			if self.current_mode == Constantes.EXPERT_MODE:
+				if ps.find("Threshold_checked").text == '1':
+					self.ui.checkBox_threshold.setChecked(True)
+				else:
+					self.ui.checkBox_threshold.setChecked(False) 
+			 
+			c = tree.find("Tab[@id='Classification']")
+
+			try:
+				self.ui.lineEdit_segmentation.setText(c.find("Segmentation_path").text)
+			except:
+				self.logger.debug('Not segmentation')
+
+			try:
+				self.ui.lineEdit_output.setText(c.find("Output_path").text)
+			except:
+				self.logger.debug('Not output file')
+
+			if self.current_mode == Constantes.EXPERT_MODE:
+				if len(c) == 5:
+					self.ui.checkBox_classifier_1.setChecked(True)
+					self.ui.lineEdit_fieldname_1.setText(c.find("Output_fieldname_1").text)
+					index_fieldname_1 = self.ui.comboBox_fieldname_1.findText(c.find("Output_type_1").text)		
+					self.ui.comboBox_fieldname_1.setCurrentIndex(index_fieldname_1)
+				elif len(c) == 7:
+					self.ui.checkBox_classifier_2.setChecked(True)
+					self.ui.lineEdit_fieldname_12.setText(c.find("Output_fieldname_1").text)
+					self.ui.lineEdit_fieldname_2.setText(c.find("Output_fieldname_2").text)
+					index_fieldname_12 = self.ui.comboBox_fieldname_12.findText(c.find("Output_type_1").text)		
+					self.ui.comboBox_fieldname_12.setCurrentIndex(index_fieldname_12)
+					index_fieldname_2 = self.ui.comboBox_fieldname_2.findText(c.find("Output_type_2").text)		
+					self.ui.comboBox_fieldname_2.setCurrentIndex(index_fieldname_2)
+				elif len(c) == 11:
+					self.ui.checkBox_classifier_3.setChecked(True)
+					self.ui.lineEdit_fieldname_13.setText(c.find("Output_fieldname_1").text)
+					self.ui.lineEdit_fieldname_23.setText(c.find("Output_fieldname_2").text)
+					self.ui.lineEdit_fieldname_3.setText(c.find("Output_fieldname_3").text)
+					self.ui.lineEdit_fieldname_4.setText(c.find("Output_fieldname_4").text)
+					index_fieldname_13 = self.ui.comboBox_fieldname_13.findText(c.find("Output_type_1").text)		
+					self.ui.comboBox_fieldname_13.setCurrentIndex(index_fieldname_13)
+					index_fieldname_23 = self.ui.comboBox_fieldname_23.findText(c.find("Output_type_2").text)		
+					self.ui.comboBox_fieldname_23.setCurrentIndex(index_fieldname_23)
+					index_fieldname_3 = self.ui.comboBox_fieldname_3.findText(c.find("Output_type_3").text)		
+					self.ui.comboBox_fieldname_3.setCurrentIndex(index_fieldname_3)
+					index_fieldname_4 = self.ui.comboBox_fieldname_4.findText(c.find("Output_type_4").text)		
+					self.ui.comboBox_fieldname_4.setCurrentIndex(index_fieldname_4)
+				
+				# Classification mode
+				if c.find("Classification_method").text == '1':
+					self.ui.radioButton_rf.setChecked(True)
+				else:
+					self.ui.radioButton_s.setChecked(True)
+					   
+	def save_backup(self):
+		"""
+		Function to save input text in every fields. The output file must be a XML file.
+		"""
+		
+		out_backup = QtWidgets.QFileDialog.getSaveFileName(self, "Save backup", os.getcwd(), '*.xml')[0]
+
+		# if the user has forgotten to put .shp at the end of the output xml
+		if out_backup[-4:] != '.xml':
+			out_backup = out_backup + '.xml'
+		
+		root = ET.Element("Data_filled")
+		
+		if self.ui.checkBox_multiprocess.isChecked():
+			ET.SubElement(root, "Multi_process", type = "int").text = str(1)
+		else:
+			ET.SubElement(root, "Multi_process", type = "int").text = str(0)
+		
+		doc = ET.SubElement(root, "Tab", id="Processing_raster")
+		ET.SubElement(doc, "Principal_folder", type = "str").text = "%s" % self.ui.lineEdit_principal_folder.text()
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			ET.SubElement(doc, "Captor", type = "str").text = "%s" % self.ui.comboBox_captor.currentText()
+		else:
+			ET.SubElement(doc, "Captor", type = "str").text = "Landsat"
+
+		ET.SubElement(doc, "Year_images", type = "str").text = "%s" % self.ui.lineEdit_year_images.text()
+		ET.SubElement(doc, "Area_path", type = "str").text = "%s" % self.ui.lineEdit_area_path.text()
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			if self.ui.checkBox_listing.isChecked():
+				ET.SubElement(doc, "Images_available", type = "int").text = str(1)
+			else:
+				ET.SubElement(doc, "Images_available", type = "int").text = str(0)
+			if self.ui.checkBox_download.isChecked():
+				ET.SubElement(doc, "Download", type = "int").text = str(1)
+			else:
+				ET.SubElement(doc, "Download", type = "int").text = str(0)
+		else:
+			ET.SubElement(doc, "Images_available", type = "int").text = str(0)
+			ET.SubElement(doc, "Download", type = "int").text = str(0)
+			
+		ET.SubElement(doc, "Username", type = "str").text = "%s" % self.ui.lineEdit_user.text()
+		ET.SubElement(doc, "Password", type = "str").text = "%s" % self.ui.lineEdit_password.text()
+		if self.w_proxy is None:
+			sub_proxy = ET.SubElement(doc, "Proxy", id="No_proxy")
+			ET.SubElement(sub_proxy, "Proxy_adress", type = "str").text = ""
+			ET.SubElement(sub_proxy, "Proxy_login", type = "str").text = ""
+			ET.SubElement(sub_proxy, "Proxy_password", type = "str").text = ""
+		elif self.w_proxy.proxy == "":
+			sub_proxy = ET.SubElement(doc, "Proxy", id="No_proxy")
+			ET.SubElement(sub_proxy, "Proxy_adress", type = "str").text = ""
+			ET.SubElement(sub_proxy, "Proxy_login", type = "str").text = ""
+			ET.SubElement(sub_proxy, "Proxy_password", type = "str").text = ""
+		else:
+			sub_proxy = ET.SubElement(doc, "Proxy", id="Proxy")
+			ET.SubElement(sub_proxy, "Proxy_adress", type = "str").text = "%s" % self.w_proxy.proxy
+			ET.SubElement(sub_proxy, "Proxy_login", type = "str").text = "%s" % self.w_proxy.login_proxy
+			ET.SubElement(sub_proxy, "Proxy_password", type = "str").text = "%s" % self.w_proxy.password_proxy
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			if self.ui.checkBox_processing.isChecked():
+				ET.SubElement(doc, "Img_processing", type = "int").text = str(1)
+			else:
+				ET.SubElement(doc, "Img_processing", type = "int").text = str(0)
+			
+			if self.ui.checkBox_VHRS.isChecked():
+				ET.SubElement(doc, "VHRS_checked", type = "int").text = str(1)
+			else:
+				ET.SubElement(doc, "VHRS_checked", type = "int").text = str(0)
+		else:
+			ET.SubElement(doc, "Img_processing", type = "int").text = str(1)
+			ET.SubElement(doc, "VHRS_checked", type = "int").text = str(1)
+			
+		ET.SubElement(doc, "VHRS", type = "str").text = "%s" % self.ui.lineEdit_VHRS.text()
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			if self.ui.checkBox_MNT.isChecked():
+				ET.SubElement(doc, "MNT_checked", type = "int").text = str(1)
+			else:
+				ET.SubElement(doc, "MNT_checked", type = "int").text = str(0)
+		else:
+			if "%s" % self.ui.lineEdit_MNT.text() != '':
+				ET.SubElement(doc, "MNT_checked", type = "int").text = str(1)
+			else:
+				ET.SubElement(doc, "MNT_checked", type = "int").text = str(0)
+			
+		ET.SubElement(doc, "MNT", type = "str").text = "%s" % self.ui.lineEdit_MNT.text()
+		
+		doc = ET.SubElement(root, "Tab", id="Processing_sample")
+		if self.current_mode == Constantes.EXPERT_MODE:
+			for sa in range(len(self.sample_name)):
+				sub_doc = ET.SubElement(doc, "Sample", id="Sample_" + str(sa))
+				ET.SubElement(sub_doc, "Sample_path", type = "str").text = self.sample_name[sa]
+				ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = self.fieldname_args[2*sa]
+				ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = self.fieldname_args[2*sa+1]
+				ET.SubElement(sub_doc, "Classname_1", type = "str").text = self.class_args[2*sa]
+				ET.SubElement(sub_doc, "Classname_2", type = "str").text = self.class_args[2*sa+1]
+				ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = self.list_nb_sample[sa]
+				ET.SubElement(sub_doc, "RPG", type = "int").text = str(self.rpg_tchek[sa])
+				try:
+					# To enter a sample raster if the first tab doesn't launch before 
+					if self.img_sample[sa] == 1:
+						ET.SubElement(sub_doc, "Img_sample", type = "str").text = self.raster_path[sa]
+				except:
+					self.logger.debug('Not sample raster only !')   
+		else:
+			# RPG
+			sub_doc = ET.SubElement(doc, "Sample", id="Sample_0")
+			ET.SubElement(sub_doc, "Sample_path", type = "str").text = "%s" % self.ui.lineEdit_sample_path.text()
+			ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_1.text()
+			ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_2.text()
+			ET.SubElement(sub_doc, "Classname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_1.text()
+			ET.SubElement(sub_doc, "Classname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_2.text()
+			ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = "%s" % self.ui.lineEdit_select_sample_nb_poly.text()
+			ET.SubElement(sub_doc, "RPG", type = "int").text = str(1)
+			
+			# To Grass/wooden
+			sub_doc = ET.SubElement(doc, "Sample", id="Sample_1")
+			ET.SubElement(sub_doc, "Sample_path", type = "str").text = "%s" % self.ui.lineEdit_sample_path_2.text()
+			ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_3.text()
+			ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_4.text()
+			ET.SubElement(sub_doc, "Classname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_3.text()
+			ET.SubElement(sub_doc, "Classname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_4.text()
+			ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = "%s" % self.ui.lineEdit_select_sample_nb_poly_2.text()
+			ET.SubElement(sub_doc, "RPG", type = "int").text = str(0)
+			
+			# To wooden  
+			sub_doc = ET.SubElement(doc, "Sample", id="Sample_2")
+			ET.SubElement(sub_doc, "Sample_path", type = "str").text = "%s" % self.ui.lineEdit_sample_path_3.text()
+			ET.SubElement(sub_doc, "Fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_5.text()
+			ET.SubElement(sub_doc, "Fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_fieldname_6.text()
+			ET.SubElement(sub_doc, "Classname_1", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_5.text()
+			ET.SubElement(sub_doc, "Classname_2", type = "str").text = "%s" % self.ui.lineEdit_select_sample_class_6.text()
+			ET.SubElement(sub_doc, "Nb_polygones", type = "str").text = "%s" % self.ui.lineEdit_select_sample_nb_poly_3.text()
+			ET.SubElement(sub_doc, "RPG", type = "int").text = str(0) 
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+			if self.ui.checkBox_threshold.isChecked():
+				ET.SubElement(doc, "Threshold_checked", type = "int").text = str(1)
+			else:
+				ET.SubElement(doc, "Threshold_checked", type = "int").text = str(0)
+		else:
+			ET.SubElement(doc, "Threshold_checked", type = "int").text = str(1)
+			
+		doc = ET.SubElement(root, "Tab", id="Classification")
+		ET.SubElement(doc, "Segmentation_path", type = "str").text = "%s" % self.ui.lineEdit_segmentation.text()
+		ET.SubElement(doc, "Output_path", type = "str").text = "%s" % self.ui.lineEdit_output.text()
+		
+		if self.current_mode == Constantes.EXPERT_MODE:
+				
+			if self.ui.checkBox_classifier_1.isChecked():
+				ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_fieldname_1.text()
+				ET.SubElement(doc, "Output_type_1", type = "str").text = "%s" % self.ui.comboBox_fieldname_1.currentText()
+			 
+			if self.ui.checkBox_classifier_2.isChecked():
+				ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_fieldname_12.text()
+				ET.SubElement(doc, "Output_type_1", type = "str").text = "%s" % self.ui.comboBox_fieldname_12.currentText()	
+				ET.SubElement(doc, "Output_fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_fieldname_2.text()
+				ET.SubElement(doc, "Output_type_2", type = "str").text = "%s" % self.ui.comboBox_fieldname_2.currentText()
+			
+			if self.ui.checkBox_classifier_3.isChecked():
+				ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "%s" % self.ui.lineEdit_fieldname_13.text()
+				ET.SubElement(doc, "Output_type_1", type = "str").text = "%s" % self.ui.comboBox_fieldname_13.currentText()	
+				ET.SubElement(doc, "Output_fieldname_2", type = "str").text = "%s" % self.ui.lineEdit_fieldname_23.text()
+				ET.SubElement(doc, "Output_type_2", type = "str").text = "%s" % self.ui.comboBox_fieldname_23.currentText()
+				ET.SubElement(doc, "Output_fieldname_3", type = "str").text = "%s" % self.ui.lineEdit_fieldname_3.text()
+				ET.SubElement(doc, "Output_type_3", type = "str").text = "%s" % self.ui.comboBox_fieldname_3.currentText()
+				ET.SubElement(doc, "Output_fieldname_4", type = "str").text = "%s" % self.ui.lineEdit_fieldname_4.text()
+				ET.SubElement(doc, "Output_type_4", type = "str").text = "%s" % self.ui.comboBox_fieldname_4.currentText()
+			
+			# Classification mode
+			if self.ui.radioButton_rf.isChecked():
+				ET.SubElement(doc, "Classification_method", type = "int").text = str(1)
+			elif self.ui.radioButton_s.isChecked():
+				ET.SubElement(doc, "Classification_method", type = "int").text = str(0)
+		else:
+			ET.SubElement(doc, "Output_fieldname_1", type = "str").text = "NIVEAU_1"
+			ET.SubElement(doc, "Output_type_1", type = "str").text = "String"   
+			ET.SubElement(doc, "Output_fieldname_2", type = "str").text = "NIVEAU_2"
+			ET.SubElement(doc, "Output_type_2", type = "str").text = "String"
+			ET.SubElement(doc, "Output_fieldname_3", type = "str").text = "NIVEAU_3"
+			ET.SubElement(doc, "Output_type_3", type = "str").text = "String"
+			ET.SubElement(doc, "Output_fieldname_4", type = "str").text = "POURC"
+			ET.SubElement(doc, "Output_type_4", type = "str").text = "Real"
+			ET.SubElement(doc, "Classification_method", type = "int").text = str(1)
+			
+		tree = ET.ElementTree(root)
+		# Write in a xml file
+		tree.write(str(out_backup), encoding="UTF-8",xml_declaration=True, pretty_print=True)
+		
+	def help_tools(self):
+		"""
+			Function to open html help
+		"""
+		webbrowser.open('file://' + os.getcwd() + '/Documentation/methode_tuto.html#tutoriels-interface')
+	
+
+	def change_mode(self, new_mode):
+		"""
+			Function to switch between SIMPLE and EXPERT mode of "PHYMOBAT"
+		"""
+		if new_mode != self.current_mode :
+			if new_mode == Constantes.SIMPLE_MODE :
+				self.logger.info("Simplify mode")
+				self.close()
+				self.window = PHYMOBAT(mode = Constantes.SIMPLE_MODE)
+			else :
+				self.logger.info("Expert mode")
+				self.close()
+				self.window = PHYMOBAT(mode = Constantes.EXPERT_MODE)
+
+			self.window.show()
+
+	def about_PHYMOBA(self):
+		"""
+			Function to open a new window "About PHYMOBAT"
+		"""
+		self.apropos.show()
+
+	def forget_study_area(self):
+		"""
+			Function to open a new window 'Alert' because user forgotten to declare study area.
+		"""
+		self.w_study_area.show()
+		
+	def forget_raster_sample(self):
+		"""
+			Function to open a new window 'Alert' because user forgotten to declare rasters or samples.
+		"""			
+		self.w_forget.show()
+				
+	def close_button(self):
+		"""
+			Function to close the interface.
+		"""
+		self.close()
+		
 if __name__ == "__main__":
-    
-    app = QtWidgets.QApplication(sys.argv)
-    myapp = PHYMOBAT()
-    myapp.show()
-        
-    sys.exit(app.exec_())
+	
+	app = QtWidgets.QApplication(sys.argv)
+	myapp = PHYMOBAT()
+	myapp.show()
+		
+	sys.exit(app.exec_())
diff --git a/Popup.py b/Popup.py
new file mode 100644
index 0000000000000000000000000000000000000000..ea9e1a04a70842d0d7c6f343fa26af285babfb36
--- /dev/null
+++ b/Popup.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os, sys, time
+from PyQt5 import QtWidgets, QtCore
+
+from ui_A_propos_PHYMOBAT_window import Ui_About
+from ui_Warming_study_area import Ui_Warming_study_area
+from ui_Warming_forgetting import Ui_Warming_forgetting
+from ui_Proxy_window import Ui_Proxy_window
+
+class about(QtWidgets.QWidget):
+	"""
+		Popup to display "About PHYMOBAT". In this windows, it prints informations on the processing, license
+		and version.
+	"""
+	def __init__(self, parent=None):
+		QtWidgets.QWidget.__init__(self, parent)
+		self.prop = Ui_About()
+		self.prop.setupUi(self)
+		
+		self.prop.close_newWindow.clicked.connect(self.close_window)
+	
+	def close_window(self):
+		"""
+			Function to close the "A propos PHYMOBAT".
+		"""
+		self.close()
+		
+class warming_study_area(QtWidgets.QWidget):
+	"""
+		Popup to display a message to say there isn't declared study area file.
+	"""
+	def __init__(self, parent=None):
+		QtWidgets.QWidget.__init__(self, parent)
+		self.w_study_a = Ui_Warming_study_area()
+		self.w_study_a.setupUi(self)
+		
+		self.w_study_a.pushButton_ok_window_warning_study_area.clicked.connect(self.close_window)
+	
+	def close_window(self):
+		"""
+			Function to close the popup.
+		"""
+		self.close() 
+		
+class warming_forgetting(QtWidgets.QWidget):
+	"""
+		Popup to display a message to tell you if you fogotten to enter a raster or a sample.
+	"""
+	def __init__(self, parent=None):
+		QtWidgets.QWidget.__init__(self, parent)
+		self.w_forget = Ui_Warming_forgetting()
+		self.w_forget.setupUi(self)
+		
+		self.w_forget.pushButton_ok_forget.clicked.connect(self.close_window)
+	
+	def close_window(self):
+		"""
+			Function to close the popup.
+		"""
+		self.close() 
+		
+class proxy_window(QtWidgets.QWidget):
+	"""
+		Popup to display a message to tell you if you fogotten to enter a raster or a sample.
+	"""
+	def __init__(self, parent=None):
+		QtWidgets.QWidget.__init__(self, parent)
+		self.w_proxy = Ui_Proxy_window()
+		self.w_proxy.setupUi(self)
+		
+		# Proxy ID
+		self.proxy = ""
+		self.login_proxy = ""
+		self.password_proxy = ""
+		
+		# Connect Apply|Close button
+		self.w_proxy.buttonBox_proxy.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(self.close_window)
+		self.w_proxy.buttonBox_proxy.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self.id_proxy)
+	
+	def id_proxy(self):
+		"""
+			Function to use input proxy id
+		"""
+		self.login_proxy = "%s" % self.w_proxy.lineEdit_login_proxy.text()
+		self.password_proxy = "%s" % self.w_proxy.lineEdit_password_proxy.text()
+		self.proxy = "%s" % self.w_proxy.lineEdit_proxy.text()
+	
+	def close_window(self):
+		"""
+			Function to close the popup.
+		"""
+		self.close()
diff --git a/Precision_moba.py b/Precision_moba.py
index 244ab4e17513da38c58ae5fb211ba3098b115e61..ff3e1ddb7b6eeddac0bad4469f9dc1d4e378ebc0 100644
--- a/Precision_moba.py
+++ b/Precision_moba.py
@@ -115,53 +115,52 @@ class Precision_moba():
         data_val = data_val.flatten()
         
         # Add pixel value in a list without no data
-        fb_stats_2 = [[data_class[x],data_val[x]] for x in range(len(data_val)) if data_val[x] != -10000]
-        fb_stats_2 = map(list, zip(*fb_stats_2))# transpose list
+        fb_stats_2 = [[int(data_class[x]),int(data_val[x])] for x in range(len(data_val)) if data_val[x] != -10000]
+        fb_stats_2 = list(map(list, zip(*fb_stats_2)))# transpose list
+
         fb_stats_in = fb_stats_2[0]
         fb_stats_val = fb_stats_2[1]
         
         # Open a file (txt) to save results
-        f = open(self.path_save + "/ConfusionMatrix.txt", "wb")
-        
-        # Compute statistics on the classification
-        cm = confusion_matrix(fb_stats_val, fb_stats_in)
-        f.write("Confusion Matrix :\n")
-        for out in cm:
-            f.write(str(out) + "\n")
-        
-        all_pr = classification_report(fb_stats_val, fb_stats_in)
-        f.write("\n")
-        f.write(all_pr)    
-        
-        accur = accuracy_score(fb_stats_val, fb_stats_in)
-        f.write("\n")
-        f.write("Accuracy : " + str(accur) + "\n")
-        
-        recall = recall_score(fb_stats_val, fb_stats_in)
-        f.write("\n")
-        f.write("Recall : " + str(recall) + "\n")
-        
-        pr = precision_score(fb_stats_val, fb_stats_in)
-        f.write("\n")
-        f.write("Precision : " + str(pr) + "\n")
-        
-        f_scor = f1_score(fb_stats_val, fb_stats_in)
-        f.write("\n")
-        f.write("F_score : " + str(f_scor) + "\n")
-        
-        kappa = self.cohen_kappa_score(fb_stats_val, fb_stats_in)
-        f.write("\n")
-        f.write("Kappa : " + str(kappa) + "\n")
-        print('')
-        print('')
-        print('Accuracy : %f, Kappa : %f, Recall : %f, Precision : %f, F_score : %f' % (accur, kappa, recall, pr, f_scor))
-        print('')
-        print (all_pr)
-        print('')
-        print('Confusion matrix :')
-        print (cm)
-        
-        f.close()
+        with open(self.path_save + "/ConfusionMatrix.txt", "w") as f :
+            # Compute statistics on the classification
+            cm = confusion_matrix(fb_stats_val, fb_stats_in)
+            f.write("Confusion Matrix :\n")
+            for out in cm:
+                f.write(str(out) + "\n")
+            
+            all_pr = classification_report(fb_stats_val, fb_stats_in)
+            f.write("\n")
+            f.write(all_pr)    
+            
+            accur = accuracy_score(fb_stats_val, fb_stats_in)
+            f.write("\n")
+            f.write("Accuracy : " + str(accur) + "\n")
+            
+            recall = recall_score(fb_stats_val, fb_stats_in)
+            f.write("\n")
+            f.write("Recall : " + str(recall) + "\n")
+            
+            pr = precision_score(fb_stats_val, fb_stats_in)
+            f.write("\n")
+            f.write("Precision : " + str(pr) + "\n")
+            
+            f_scor = f1_score(fb_stats_val, fb_stats_in)
+            f.write("\n")
+            f.write("F_score : " + str(f_scor) + "\n")
+            
+            kappa = self.cohen_kappa_score(fb_stats_val, fb_stats_in)
+            f.write("\n")
+            f.write("Kappa : " + str(kappa) + "\n")
+            print('')
+            print('')
+            print('Accuracy : %f, Kappa : %f, Recall : %f, Precision : %f, F_score : %f' % (accur, kappa, recall, pr, f_scor))
+            print('')
+            print (all_pr)
+            print('')
+            print('Confusion matrix :')
+            print (cm)
+        
         
     def cohen_kappa_score(self, y1, y2, labels=None):
         """
diff --git a/Processing.py b/Processing.py
index 5ffbbbf19b72f7def198d66c2be44a8ac44e8bbe..af90bb46500dc869cabdbab24830fd405f64934d 100644
--- a/Processing.py
+++ b/Processing.py
@@ -23,13 +23,14 @@ import subprocess
 from sklearn.ensemble import RandomForestClassifier
 from sklearn import tree
 try :
-    import ogr, gdal
+	import ogr, gdal
 except :
-    from osgeo import ogr, gdal
+	from osgeo import ogr, gdal
 
 from Toolbox import Toolbox
 from Seath import Seath
 from Precision_moba import Precision_moba
+
 # Class group image
 from Archive import Archive
 from RasterSat_by_date import RasterSat_by_date
@@ -42,835 +43,815 @@ from Sample import Sample
 from Segmentation import Segmentation
 from Rpg import Rpg
 
+import Constantes
+
 from collections import defaultdict
 from multiprocessing import Process
 from multiprocessing.managers import BaseManager, DictProxy
 
 class Processing():
-    
-    """
-    Main processing. This class launch the others system classes. It take into account
-    CarHab classification method MOBA. 
-    
-    This way is broken down into 3 parts :
-        - Image Processing (Search, download and processing)
-        - Vector Processing (Optimal threshold, Sample processing)
-        - Classification 
-        - Validation 
-    
-    **Main parameters**
-    
-    :param captor_project: Satellite captor name
-    :type captor_project: str
-    :param classif_year: Classification year
-    :type classif_year: str
-    :param nb_avalaible_images: Number download available images
-    :type nb_avalaible_images: int
-    :param path_folder_dpt: Main folder path
-    :type path_folder_dpt: str
-    :param folder_archive: Archive downloaded folder path
-    :type folder_archive: str
-    :param folder_processing: Processing folder name. By default : 'Traitement'
-    :type folder_processing: str
-    :param path_area: Study area shapefile
-    :type path_area: str
-    :param path_ortho: VHRS image path
-    :type path_ortho: str
-    :param path_mnt: MNT image path
-    :type path_mnt: str
-    :param path_segm: Segmentation shapefile
-    :type path_segm: str
-    
-    **Id information to download on theia platform**
-    
-    :param user: Connexion Username
-    :type user: str
-    :param password: Connexion Password
-    :type password: str
-    
-    **Output parameters**
-    
-    :param output_name_moba: Output classification shapefile 
-    :type output_name_moba: str
-    :param out_fieldname_carto: Output shapefile field name
-    :type out_fieldname_carto: list of str
-    :param out_fieldtype_carto: Output shapefile field type
-    :type out_fieldtype_carto: list of str (eval ogr pointer)
-    
-    **Sample parameters**
-    
-    :param fieldname_args: Sample field names 2 by 2
-    :type fieldname_args: list of str
-    :param class_args: Sample class names 2 by 2
-    :type class_args: list of str
-    :param sample_name: List of sample name (path)
-    :type sample_name: list of str
-    :param list_nb_sample: Number of polygons for every sample
-    :type list_nb_sample: list of int
-    
-    **Multi-processing parameters**
-    
-    :param mp: Boolean variable -> 0 or 1.
-    
-            - 0 means, not multi-processing
-            - 1 means, launch process with multi-processing
-    :type mp: int
-    """
-    
-    def __init__(self):
-        
-        # Used variables
-        self.captor_project = ''
-        self.classif_year = ''
-        self.path_folder_dpt = ''
-        self.folder_archive = ''
-        self.folder_processing = 'Traitement'
-        self.path_area = ''
-        self.path_ortho = ''
-        self.path_mnt = ''
-        self.path_segm = ''
-        self.output_name_moba = ''
-        
-        self.w_proxy = None # For the "Proxy window"
-        
-        # Id information to download on theia platform
-        self.user = ''
-        self.password = ''
+	
+	"""
+		Main processing. This class launch the others system classes. It take into account
+		CarHab classification method MOBA. 
+		
+		This way is broken down into 3 parts :
+			- Image Processing (Search, download and processing)
+			- Vector Processing (Optimal threshold, Sample processing)
+			- Classification 
+			- Validation 
+		
+		**Main parameters**
+		
+		:param captor_project: Satellite captor name
+		:type captor_project: str
+		:param classif_year: Classification year
+		:type classif_year: str
+		:param nb_avalaible_images: Number download available images
+		:type nb_avalaible_images: int
+		:param path_folder_dpt: Main folder path
+		:type path_folder_dpt: str
+		:param folder_processing: Processing folder name. By default : 'Traitement'
+		:type folder_processing: str
+		:param path_area: Study area shapefile
+		:type path_area: str
+		:param path_ortho: VHRS image path
+		:type path_ortho: str
+		:param path_mnt: MNT image path
+		:type path_mnt: str
+		:param path_segm: Segmentation shapefile
+		:type path_segm: str
+		
+		**Id information to download on theia platform**
+		
+		:param user: Connexion Username
+		:type user: str
+		:param password: Connexion Password
+		:type password: str
+		
+		**Output parameters**
+		
+		:param output_name_moba: Output classification shapefile 
+		:type output_name_moba: str
+		:param out_fieldname_carto: Output shapefile field name
+		:type out_fieldname_carto: list of str
+		:param out_fieldtype_carto: Output shapefile field type
+		:type out_fieldtype_carto: list of str (eval ogr pointer)
+		
+		**Sample parameters**
+		
+		:param fieldname_args: Sample field names 2 by 2
+		:type fieldname_args: list of str
+		:param class_args: Sample class names 2 by 2
+		:type class_args: list of str
+		:param sample_name: List of sample name (path)
+		:type sample_name: list of str
+		:param list_nb_sample: Number of polygons for every sample
+		:type list_nb_sample: list of int
+		
+		**Multi-processing parameters**
+		
+		:param mp: Boolean variable -> 0 or 1.
+		
+				- 0 means, not multi-processing
+				- 1 means, launch process with multi-processing
+		:type mp: int
+	"""
+	
+	def __init__(self):
+		
+		# Used variables
+		self.captor_project = ''
+		self.classif_year = ''
+		self.path_folder_dpt = ''
+		self.folder_processing = 'Traitement'
+		self.path_area = ''
+		self.path_ortho = ''
+		self.path_mnt = ''
+		self.path_segm = ''
+		self.output_name_moba = ''
+		
+		self.w_proxy = None # For the "Proxy window"
+		
+		# Id information to download on theia platform
+		self.user = ''
+		self.password = ''
+
+		# List of output raster path
+		self.raster_path = []
+		self.list_band_outraster = []
+		
+		# Class name
+		
+		# TODO : Change index of the classes -> Harbacées 6 / Ligneux 7 by Agriculuture 4 / Eboulis 5
+		
+		self.in_class_name = ['Non Vegetation semi-naturelle', 'Vegetation semi-naturelle',\
+						 'Herbacees', 'Ligneux', \
+						 'Ligneux mixtes', 'Ligneux denses',\
+						 'Agriculture', 'Eboulis', \
+						 'Forte phytomasse', 'Moyenne phytomasse', 'Faible phytomasse']
+		# Sample field names 2 by 2
+		self.fieldname_args = []
+#								'CODE_GROUP', 'CODE_GROUP',\
+#						   'echant', 'echant',\
+#						   'echant', 'echant']
+		# Sample class names 2 by 2
+		self.class_args = []
+#							'1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 20, 21, 22, 23, 24, 26, 28', '18',\
+#					   'H','LF, LO',\
+#					   'LF', 'LO']
+		
+		# Decision tree combination
+		self.tree_direction = [[0],\
+						  [0],\
+						  [1, 3, 4],\
+						  [1, 3, 5],\
+						  [1, 2, 8],\
+						  [1, 2, 9],\
+						  [1, 2, 10]] # [['Cultures'],['Semi-naturelles', 'Herbacees', 'Forte phytomasse'], ...
+									# ..., ['Semi-naturelles', 'Ligneux', 'Ligneux denses']]
+		# Slope degrees
+		self.slope_degree = 30
+		
+		# Output shapefile field name
+		self.out_fieldname_carto = ['ID', 'AREA'] #, 'NIVEAU_1', 'NIVEAU_2', 'NIVEAU_3', 'POURC']
+		# Output shapefile field type
+		self.out_fieldtype_carto = [ogr.OFTString, ogr.OFTReal] #, ogr.OFTString, ogr.OFTString, ogr.OFTString, ogr.OFTReal]
+		
+		# List of sample name path
+		self.sample_name = []
+		# List of number sample
+		self.list_nb_sample = []
+		# Number download available images
+		self.nb_avalaible_images = 0
+		
+		# Multi-processing variable
+		self.mp = Constantes.MULTIPROCESSING_DISABLE
+		
+		# Function followed
+		self.check_download = ''
+		self.decis = {}
+		# Images after processing images
+		self.out_ndvistats_folder_tab = defaultdict(list)
+		
+		# Validation shapefiles information
+		self.valid_shp = []
+		
+		# Radom Forest Model
+		# Set the parameters of this random forest from the estimator 
+		self.rf = RandomForestClassifier(n_estimators=500, criterion='gini', max_depth=None, min_samples_split=2, \
+										min_samples_leaf=1, max_features='auto', \
+										bootstrap=True, oob_score=True)
+		
+	def i_tree_direction(self):	
+		"""
+			Interface function to can extract one level or two levels of the final classification 
+		"""
+
+		if len(self.out_fieldname_carto) == 3:
+			self.tree_direction = [[0], [1]]
+			
+		if len(self.out_fieldname_carto) == 4:
+			self.tree_direction = [[0], [0], [1, 2], [1, 3]]
+		
+	def i_download(self):
+		"""
+			Interface function to download archives on the website Theia Land. This function extract 
+			the number of downloadable image with :func:`Archive.Archive.listing`.
+			
+			Then, this function download :func:`Archive.Archive.download` and unzip :func:`Archive.Archive.decompress` images
+			in the archive folder (**folder_archive**).
+		"""
+		
+		folder_archive = self.captor_project + '_PoleTheia'
 
-        # List of output raster path
-        self.raster_path = []
-        self.list_band_outraster = []
-        
-        # Class name
-        
-        # TODO : Change index of the classes -> Harbacées 6 / Ligneux 7 by Agriculuture 4 / Eboulis 5
-        
-        self.in_class_name = ['Non Vegetation semi-naturelle', 'Vegetation semi-naturelle',\
-                         'Herbacees', 'Ligneux', \
-                         'Ligneux mixtes', 'Ligneux denses',\
-                         'Agriculture', 'Eboulis', \
-                         'Forte phytomasse', 'Moyenne phytomasse', 'Faible phytomasse']
-        # Sample field names 2 by 2
-        self.fieldname_args = []
-#                                'CODE_GROUP', 'CODE_GROUP',\
-#                           'echant', 'echant',\
-#                           'echant', 'echant']
-        # Sample class names 2 by 2
-        self.class_args = []
-#                            '1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 15, 20, 21, 22, 23, 24, 26, 28', '18',\
-#                       'H','LF, LO',\
-#                       'LF', 'LO']
-        
-        # Decision tree combination
-        self.tree_direction = [[0],\
-                          [0],\
-                          [1, 3, 4],\
-                          [1, 3, 5],\
-                          [1, 2, 8],\
-                          [1, 2, 9],\
-                          [1, 2, 10]] # [['Cultures'],['Semi-naturelles', 'Herbacees', 'Forte phytomasse'], ...
-                                    # ..., ['Semi-naturelles', 'Ligneux', 'Ligneux denses']]
-        # Slope degrees
-        self.slope_degree = 30
-        
-        # Output shapefile field name
-        self.out_fieldname_carto = ['ID', 'AREA'] #, 'NIVEAU_1', 'NIVEAU_2', 'NIVEAU_3', 'POURC']
-        # Output shapefile field type
-        self.out_fieldtype_carto = [ogr.OFTString, ogr.OFTReal] #, ogr.OFTString, ogr.OFTString, ogr.OFTString, ogr.OFTReal]
-        
-        # List of sample name path
-        self.sample_name = []
-        # List of number sample
-        self.list_nb_sample = []
-        # Number download available images
-        self.nb_avalaible_images = 0
-        # Multi-processing variable
-        self.mp = 1
-        
-        # Function followed
-        self.check_download = ''
-        self.decis = {}
-        # Images after processing images
-        self.out_ndvistats_folder_tab = defaultdict(list)
-        
-        # Validation shapefiles information
-        self.valid_shp = []
-        
-        # Radom Forest Model
-        # Set the parameters of this random forest from the estimator 
-        self.rf = RandomForestClassifier(n_estimators=500, criterion='gini', max_depth=None, min_samples_split=2, \
-                                        min_samples_leaf=1, max_features='auto', \
-                                        bootstrap=True, oob_score=True)
-        
-    def i_tree_direction(self):
-        
-        """
-        Interface function to can extract one level or two levels of the final classification 
-        """
+		self.check_download = Archive(self.captor_project, self.classif_year, self.path_area, self.path_folder_dpt, folder_archive, self.w_proxy)
+		self.nb_avalaible_images = self.check_download.listing()
+		self.check_download.download_auto(self.user, self.password)
+		self.check_download.decompress()
+		 
+	def i_img_sat(self):
+		
+		"""
+		Interface function to processing satellite images:
+		
+			1. Clip archive images and modify Archive class to integrate clip image path.
+			With :func:`Toolbox.clip_raster` in ``Toolbox`` module.
+		
+			2. Search cloud's percentage :func:`RasterSat_by_date.RasterSat_by_date.pourc_cloud`, select 
+			image and compute ndvi index :func:`RasterSat_by_date.RasterSat_by_date.calcul_ndvi`. If cloud's percentage is 
+			greater than 40%, then not select and compute ndvi index.
+		
+			3. Compute temporal stats on ndvi index [min, max, std, min-max]. With :func:`Toolbox.calc_serie_stats` 
+			in ``Toolbox`` module.
+			
+			4. Create stats ndvi raster and stats cloud raster.
+			
+			>>> import RasterSat_by_date
+			>>> stats_test = RasterSat_by_date(class_archive, big_folder, one_date)
+			>>> stats_test.complete_raster(stats_test.create_raster(in_raster, stats_data, in_ds), stats_data)
+		"""
 
-        if len(self.out_fieldname_carto) == 3:
-            self.tree_direction = [[0], [1]]
-            
-        if len(self.out_fieldname_carto) == 4:
-            self.tree_direction = [[0], [0], [1, 2], [1, 3]]
-        
-    def i_download(self, dd):
-        
-        """
-        Interface function to download archives on the website Theia Land. This function extract 
-        the number of downloadable image with :func:`Archive.Archive.listing`.
-        
-        Then, this function download :func:`Archive.Archive.download` and unzip :func:`Archive.Archive.decompress` images
-        in the archive folder (**folder_archive**).
-        
-        :param dd: Boolean variable to launch download images -> 0 or 1.
-    
-            - 0 means, not downloading
-            - 1 means, launch downloading
-        :type dd: int
-        """
-        
-        self.folder_archive = self.captor_project + '_PoleTheia'
-        self.check_download = Archive(self.captor_project, self.classif_year, self.path_area, self.path_folder_dpt, self.folder_archive, self.w_proxy)
-        self.check_download.listing()
-        self.nb_avalaible_images = len(self.check_download.list_archive)
-        # check_download.set_list_archive_to_try(check_download.list_archive[:3])
-        if dd == 1:
-#             self.check_download.download_auto(self.user, self.password)
-            self.check_download.download_auto(self.user, self.password)
-            self.check_download.decompress()
-    
-    def i_glob(self):
-        """
-        Function to load existing images to launch the processing. 
-        It need to archives. Then, to select processing images, select archives 
-        
-        """
-        
-        self.folder_archive = self.captor_project + '_PoleTheia'
-        self.check_download = Archive(self.captor_project, self.classif_year, self.path_area, self.path_folder_dpt, self.folder_archive, self.w_proxy)
-        self.check_download.decompress()
-     
-    def i_img_sat(self):
-        
-        """
-        Interface function to processing satellite images:
-        
-            1. Clip archive images and modify Archive class to integrate clip image path.
-            With :func:`Toolbox.clip_raster` in ``Toolbox`` module.
-        
-            2. Search cloud's percentage :func:`RasterSat_by_date.RasterSat_by_date.pourc_cloud`, select 
-            image and compute ndvi index :func:`RasterSat_by_date.RasterSat_by_date.calcul_ndvi`. If cloud's percentage is 
-            greater than 40%, then not select and compute ndvi index.
-        
-            3. Compute temporal stats on ndvi index [min, max, std, min-max]. With :func:`Toolbox.calc_serie_stats` 
-            in ``Toolbox`` module.
-            
-            4. Create stats ndvi raster and stats cloud raster.
-            
-            >>> import RasterSat_by_date
-            >>> stats_test = RasterSat_by_date(class_archive, big_folder, one_date)
-            >>> stats_test.complete_raster(stats_test.create_raster(in_raster, stats_data, in_ds), stats_data)
-        """
+		# Clip archive images and modify Archive class to integrate clip image path
+		for clip in self.check_download.list_img:
+			clip_index = self.check_download.list_img.index(clip)
+			
+			current_list = Toolbox()
+			current_list.imag = clip[3]
+			current_list.vect = self.path_area
+			current_list.check_proj() # Check if projection is RFG93 
+			self.check_download.list_img[clip_index][3] = current_list.clip_raster() # Multispectral images
+			
+			current_list.imag = clip[4]
+			current_list.check_proj() # Check if projection is RFG93 
+			self.check_download.list_img[clip_index][4] = current_list.clip_raster() # Cloud images
+		   
+		# Images pre-processing
+		spectral_out = []
+		for date in self.check_download.single_date:
+			   
+			check_L8 = RasterSat_by_date(self.check_download, self.folder_processing, date)
+			check_L8.mosaic_by_date()
+			 
+			# Search cloud's percentage, select image and compute ndvi index if > cl
+			cl = check_L8.pourc_cloud(check_L8._one_date[3], check_L8._one_date[4])
+			if cl > 0.60:
+				check_L8.calcul_ndvi(check_L8._one_date[3])
+				spectral_out.append(check_L8._one_date)
 
-        # Clip archive images and modify Archive class to integrate clip image path
-        for clip in self.check_download.list_img:
-            clip_index = self.check_download.list_img.index(clip)
-            
-            current_list = Toolbox()
-            current_list.imag = clip[3]
-            current_list.vect = self.path_area
-            current_list.check_proj() # Check if projection is RFG93 
-            self.check_download.list_img[clip_index][3] = current_list.clip_raster() # Multispectral images
-            
-            current_list.imag = clip[4]
-            current_list.check_proj() # Check if projection is RFG93 
-            self.check_download.list_img[clip_index][4] = current_list.clip_raster() # Cloud images
-           
-        # Images pre-processing
-        spectral_out = []
-        for date in self.check_download.single_date:
-               
-            check_L8 = RasterSat_by_date(self.check_download, self.folder_processing, date)
-            check_L8.mosaic_by_date()
-             
-            # Search cloud's percentage, select image and compute ndvi index if > cl
-            cl = check_L8.pourc_cloud(check_L8._one_date[3], check_L8._one_date[4])
-            if cl > 0.60:
-                check_L8.calcul_ndvi(check_L8._one_date[3])
-                spectral_out.append(check_L8._one_date)
+		# Compute temporal stats on ndvi index [min, max, std, min-max]
+		spectral_trans = np.transpose(np.array(spectral_out, dtype=object))
+		stats_name = ['Min', 'Date', 'Max', 'Std', 'MaxMin']
+		stats_ndvi, stats_cloud = current_list.calc_serie_stats(spectral_trans)
+		
+		# Create stats ndvi raster and stats cloud raster
+		stats_L8 = RasterSat_by_date(self.check_download, self.folder_processing, [0])
+		
+		# Stats cloud raster
+		out_cloud_folder = stats_L8._class_archive._folder + '/' + stats_L8._big_folder + '/' + self.captor_project + '/Cloud_number_' + self.captor_project + '.TIF'
+		
+		stats_L8.complete_raster(*stats_L8.create_raster(out_cloud_folder, stats_cloud, stats_L8.raster_data(self.check_download.list_img[0][4])[1]), stats_cloud)
+		
+		# Stats ndvi rasters		
+		for stats_index in range(len(stats_ndvi)):
+			out_ndvistats_folder = stats_L8._class_archive._folder + '/' + stats_L8._big_folder + '/' + self.captor_project + '/' + stats_name[stats_index] + '_' + self.captor_project + '.TIF'
+			self.out_ndvistats_folder_tab[stats_index] = out_ndvistats_folder
+			stats_L8.complete_raster(*stats_L8.create_raster(out_ndvistats_folder, stats_ndvi[stats_index], stats_L8.raster_data(self.check_download.list_img[0][4])[1]), stats_ndvi[stats_index])
+		
+	def i_slope(self):
+		"""
+			Interface function to processing slope raster. From a MNT, and with a command line gdal,
+			this function compute slope in degrees :func:`Slope.Slope`.
+		"""
+		
+		current_path_mnt = Toolbox()
+		current_path_mnt.imag = self.path_mnt
+		current_path_mnt.vect = self.path_area
+		path_mnt = current_path_mnt.clip_raster()
+		
+		study_slope = Slope(path_mnt)
+		study_slope.extract_slope()# Call this function to compute slope raster
+		self.path_mnt = study_slope.out_mnt
+	
+	def i_vhrs(self):#, vs):
+		"""
+			Interface function to processing VHRS images. It create two OTB texture images :func:`Vhrs.Vhrs` : SFS Texture and Haralick Texture
+		"""
+
+		# Create texture image
+		# Clip orthography image 
+		current_path_ortho = Toolbox()
+		current_path_ortho.imag = self.path_ortho
+		current_path_ortho.vect = self.path_area
+		path_ortho = current_path_ortho.clip_raster()
+		
+		texture_irc = Vhrs(path_ortho, self.mp)
+		self.out_ndvistats_folder_tab['sfs'] = texture_irc.out_sfs
+		self.out_ndvistats_folder_tab['haralick'] = texture_irc.out_haralick
+		
+	def i_images_processing(self, vs=1): 
+		
+		"""
+			Interface function to launch processing VHRS images :func:`i_vhrs` and satellite images :func:`i_img_sat` in multi-processing.
+			
+			:param vs: Boolean variable to launch texture processing because of interface checkbox -> 0 or 1.
+			
+				- 0 means, not texture processing
+				- 1 means, launch texture processing
+			:type vs: int
+		"""
+		
+		######################### Multiprocessing #########################
+
+		mgr = BaseManager()
+		mgr.register('defaultdict', defaultdict, DictProxy)
+		mgr.start()
 
-        # Compute temporal stats on ndvi index [min, max, std, min-max]
-        spectral_trans = np.transpose(np.array(spectral_out, dtype=object))
-        stats_name = ['Min', 'Date', 'Max', 'Std', 'MaxMin']
-        stats_ndvi, stats_cloud = current_list.calc_serie_stats(spectral_trans)
-        
-        # Create stats ndvi raster and stats cloud raster
-        stats_L8 = RasterSat_by_date(self.check_download, self.folder_processing, [0])
-        # Stats cloud raster
-        out_cloud_folder = stats_L8._class_archive._folder + '/' + stats_L8._big_folder + '/' + self.captor_project + \
-                           '/Cloud_number_' + self.captor_project + '.TIF'
-        stats_L8.complete_raster(stats_L8.create_raster(out_cloud_folder, stats_cloud, \
-                                                         stats_L8.raster_data(self.check_download.list_img[0][4])[1]), \
-                                 stats_cloud)
-        
-        # Stats ndvi rasters        
-        for stats_index in range(len(stats_ndvi)):
-            out_ndvistats_folder = stats_L8._class_archive._folder + '/' + stats_L8._big_folder + '/' + self.captor_project + \
-                           '/' + stats_name[stats_index] + '_' + self.captor_project + '.TIF'
-            self.out_ndvistats_folder_tab[stats_index] = out_ndvistats_folder
-            stats_L8.complete_raster(stats_L8.create_raster(out_ndvistats_folder, stats_ndvi[stats_index], \
-                                                            stats_L8.raster_data(self.check_download.list_img[0][4])[1]), \
-                                     stats_ndvi[stats_index])
-        
-    def i_slope(self):
-        """
-        Interface function to processing slope raster. From a MNT, and with a command line gdal,
-        this function compute slope in degrees :func:`Slope.Slope`.
- 
-        """
-        
-        current_path_mnt = Toolbox()
-        current_path_mnt.imag = self.path_mnt
-        current_path_mnt.vect = self.path_area
-        path_mnt = current_path_mnt.clip_raster()
-        
-        study_slope = Slope(path_mnt)
-        study_slope.extract_slope()# Call this function to compute slope raster
-        self.path_mnt = study_slope.out_mnt
-    
-    def i_vhrs(self):#, vs):
-        """
-        Interface function to processing VHRS images. It create two OTB texture images :func:`Vhrs.Vhrs` : SFS Texture and Haralick Texture
+		self.out_ndvistats_folder_tab = mgr.defaultdict(list)
+		
+		p_img_sat = Process(target=self.i_img_sat)
+		p_img_sat.start()
+
+		if self.mp == Constantes.MULTIPROCESSING_DISABLE:
+			p_img_sat.join()
+		
+		if vs == 1:
+			p_vhrs = Process(target=self.i_vhrs)
+			p_vhrs.start()
+			p_vhrs.join()
+		
+		if self.mp == Constantes.MULTIPROCESSING_ENABLE:
+			p_img_sat.join()
+
+		###################################################################
+		
+		# List of output raster path
+		self.raster_path.append(self.out_ndvistats_folder_tab[0])
+		# List of output raster band
+		self.list_band_outraster.append(1)
+		
+		if vs == 1:
+			self.raster_path.append(self.out_ndvistats_folder_tab['sfs'])
+			self.list_band_outraster.append(4)
+			self.raster_path.append(self.out_ndvistats_folder_tab['haralick'])
+			self.list_band_outraster.append(2)
+		
+		# To slope, to extract scree
+		if self.path_mnt != '':
+			self.raster_path.append(self.path_mnt)
+			self.list_band_outraster.append(1)
+			
+		self.raster_path.append(self.out_ndvistats_folder_tab[2])
+		# example raster path tab :
+		#				[path_folder_dpt + '/' + folder_processing + '/' + classif_year + '/Min_2014.TIF',\
+		#				os.path.dirname(path_ortho) + '/Clip_buffer_surface_dep_18_IRCOrtho65_2m_sfs.TIF',\
+		#				os.path.dirname(path_ortho) + '/Clip_buffer_surface_dep_18_IRCOrtho65_2m_haralick.TIF',\
+		#				path_folder_dpt + '/' + folder_processing + '/' + classif_year + '/Max_2014.TIF']
+		
+		# List of output raster band
+		self.list_band_outraster.append(1) #[1, 4, 2, 1]
+		
+		self.logger.info("End of images processing !")
+		
+	def i_rpg(self, path_rpg): 
+		"""
+		Interface function to extract mono rpg crops.
+		
+		:param path_rpg: Input RPG shapefile.
+		:type path_rpg: str
+		
+		:returns: str -- variable **Rpg.vector_used**, output no duplicated crops shapefile (path).
+		"""
+			   
+		# Extract mono rpg crops
+		mono_sample = Rpg(path_rpg, self.path_area)
+		# If exists, do not create a mono rpg file
+		if os.path.basename(str(path_rpg))[:5]!='MONO_':
+			mono_sample.mono_rpg()
+			mono_sample.create_new_rpg_files()
+		else:
+			print('MONO RPG file exists already !!!')
+		print('End of RPG processing')
+		
+		return mono_sample.vector_used
+		 
+	def i_sample(self):
+		"""
+		Interface function to compute threshold with various sample. It also extract a list of validation layer (shapefile) 
+		to compute the precision of the next classification :func:`i_validate`. 
+		
+		It create samples 2 by 2 with kwargs field names and class :func:`Sample.Sample.create_sample`. 
+		Then, it compute zonal statistics by polygons :func:`Vector.Sample.zonal_stats`.
+		
+		With zonal statistics computed, a optimal threshold is determined :func:`Seath.Seath.separability_and_threshold` that
+		will print in a text file .lg in the main folder.
+		
+		.. warning:: :func:`Seath.Seath.separability_and_threshold` does not always allow to discriminate optimal threshold. 
+					Then, this function will be launch at least ten time until it reaches a optimal threshold.
+		"""
+		
+		# Compute threshold with various sample
+		i_s = 0
+		while i_s < 10:
+			try :
+				self.valid_shp = []
+				sample_rd = {}
+				for sple in range(len(self.sample_name) * 2):
+					kwargs = {}
+					kwargs['fieldname'] = self.fieldname_args[sple]
+					kwargs['class'] = self.class_args[sple]
+					sample_rd[sple] = Sample(self.sample_name[sple/2], self.path_area, self.list_nb_sample[sple/2])
+					sample_rd[sple].create_sample(**kwargs)
+					sample_rd[sple].zonal_stats((self.raster_path[sple/2], self.list_band_outraster[sple/2]))
+					
+					# Add the validation shapefile
+					self.valid_shp.append([sample_rd[sple].vector_val, kwargs['fieldname'], kwargs['class']])
+				
+				# Search the optimal threshold by class 
+				# Open a text file to print stats of Seath method
+				file_J = self.path_folder_dpt + '/log_J.lg'
+				f = open(file_J, "wb")
+				for th_seath in range(len(self.sample_name)):
+					self.decis[th_seath] = Seath()
+					self.decis[th_seath].value_1 = sample_rd[th_seath*2].stats_dict
+					self.decis[th_seath].value_2 = sample_rd[th_seath*2 + 1].stats_dict
+					self.decis[th_seath].separability_and_threshold()
+					
+					# Print the J value in the text file .lg
+					f.write('For ' + str(self.sample_name[th_seath]) + ' :\n')
+					f.write('J = ' + str(self.decis[th_seath].J[0]) +'\n')
+					f.write('The class 1 ' + str(self.decis[th_seath].threshold[0]) +'\n')
+					
+				f.close()	
+				i_s = 20
+			except:
+				i_s = i_s + 1
+		# Method to stop the processus if there is not found a valid threshold
+		if i_s != 20:
+			print ('Problem in the sample processing !!!')
+			sys.exit(1)
 	
-        """
+	def i_sample_rf(self):
+		"""
+		This function build a random forest trees like model to create a final classification.
+		All of This using the method described in the :func:`i_validate` function and because
+		of sklearn module.
+		"""
+		
+		X_rf = []
+		y_rf = []
+		sample_rd = {}			
+		# Tricks to add all textural indexes
+		rm_index = 1
+		self.raster_path.remove(self.raster_path[rm_index]) # Remove SFS layer
+		self.raster_path.remove(self.raster_path[rm_index]) # Remove Haralick layer
+		self.list_band_outraster.remove(self.list_band_outraster[rm_index]) # Remove band of the layer
+		self.list_band_outraster.remove(self.list_band_outraster[rm_index]) # Remove band of the layer
+		# Add all layers in the simple index haralick
+		for add_layer in range(8):
+			self.raster_path.insert(add_layer+1, self.out_ndvistats_folder_tab['haralick'])
+			self.list_band_outraster.insert(add_layer+1, add_layer+1)
+		# Add all layers in the SFS index
+		for add_layer in range(6):
+			self.raster_path.insert(add_layer+1, self.out_ndvistats_folder_tab['sfs'])
+			self.list_band_outraster.insert(add_layer+1, add_layer+1)
+			
+		# Extract value mean from polygons
+		for sple in range(len(self.sample_name) * 2):
+			kwargs = {}
+			kwargs['fieldname'] = self.fieldname_args[sple]
+			kwargs['class'] = self.class_args[sple]
+			sample_rd[sple] = Sample(self.sample_name[round(sple/2)], self.path_area, self.list_nb_sample[round(sple/2)])
+
+			sample_rd[sple].create_sample(**kwargs)
+			
+			# Add the validation shapefile
+			self.valid_shp.append([sample_rd[sple].vector_val, kwargs['fieldname'], kwargs['class']])
 
-        # Create texture image
-        # Clip orthography image 
-        current_path_ortho = Toolbox()
-        current_path_ortho.imag = self.path_ortho
-        current_path_ortho.vect = self.path_area
-        path_ortho = current_path_ortho.clip_raster()
-        
-        texture_irc = Vhrs(path_ortho, self.mp)
-        self.out_ndvistats_folder_tab['sfs'] = texture_irc.out_sfs
-        self.out_ndvistats_folder_tab['haralick'] = texture_irc.out_haralick
-        
-    def i_images_processing(self, vs): 
-        
-        """
-        Interface function to launch processing VHRS images :func:`i_vhrs` and satellite images :func:`i_img_sat` in multi-processing.
-        
-        :param vs: Boolean variable to launch processing because of interface checkbox -> 0 or 1.
-        
-            - 0 means, not texture processing
-            - 1 means, launch texture processing
-        :type vs: int
-        """
-        
-        # Multiprocessing
-        mgr = BaseManager()
-        mgr.register('defaultdict', defaultdict, DictProxy)
-        mgr.start()
-        self.out_ndvistats_folder_tab = mgr.defaultdict(list)
-        
-        p_img_sat = Process(target=self.i_img_sat)
-        p_img_sat.start()
-        if self.mp == 0:
-            p_img_sat.join()
-        
-        if vs == 1:
-            p_vhrs = Process(target=self.i_vhrs)#, args=(vs, ))
-            p_vhrs.start()
-            p_vhrs.join()
-        
-        if self.mp == 1:
-            p_img_sat.join()
-        
-        # List of output raster path
-        self.raster_path.append(self.out_ndvistats_folder_tab[0])
-        # List of output raster band
-        self.list_band_outraster.append(1)
-        
-        if vs == 1:
-            self.raster_path.append(self.out_ndvistats_folder_tab['sfs'])
-            self.list_band_outraster.append(4)
-            self.raster_path.append(self.out_ndvistats_folder_tab['haralick'])
-            self.list_band_outraster.append(2)
-        
-        # To slope, to extract scree
-        if self.path_mnt != '':
-            self.raster_path.append(self.path_mnt)
-            self.list_band_outraster.append(1)
-            
-        self.raster_path.append(self.out_ndvistats_folder_tab[2])
-        # example raster path tab :
-        #                [path_folder_dpt + '/' + folder_processing + '/' + classif_year + '/Min_2014.TIF',\
-        #                os.path.dirname(path_ortho) + '/Clip_buffer_surface_dep_18_IRCOrtho65_2m_sfs.TIF',\
-        #                os.path.dirname(path_ortho) + '/Clip_buffer_surface_dep_18_IRCOrtho65_2m_haralick.TIF',\
-        #                path_folder_dpt + '/' + folder_processing + '/' + classif_year + '/Max_2014.TIF']
-        
-        # List of output raster band
-        self.list_band_outraster.append(1) #[1, 4, 2, 1]
-        
-        print("End of images processing !")
-        
-    def i_rpg(self, path_rpg): 
-        """
-        Interface function to extract mono rpg crops.
-        
-        :param path_rpg: Input RPG shapefile.
-        :type path_rpg: str
-        
-        :returns: str -- variable **Rpg.vector_used**, output no duplicated crops shapefile (path).
-        """
-               
-        # Extract mono rpg crops
-        mono_sample = Rpg(path_rpg, self.path_area)
-        # If exists, do not create a mono rpg file
-        if os.path.basename(str(path_rpg))[:5]!='MONO_':
-            mono_sample.mono_rpg()
-            mono_sample.create_new_rpg_files()
-        else:
-            print('MONO RPG file exists already !!!')
-        print('End of RPG processing')
-        
-        return mono_sample.vector_used
-         
-    def i_sample(self):
-        """
-        Interface function to compute threshold with various sample. It also extract a list of validation layer (shapefile) 
-        to compute the precision of the next classification :func:`i_validate`. 
-        
-        It create samples 2 by 2 with kwargs field names and class :func:`Sample.Sample.create_sample`. 
-        Then, it compute zonal statistics by polygons :func:`Vector.Sample.zonal_stats`.
-        
-        With zonal statistics computed, a optimal threshold is determined :func:`Seath.Seath.separability_and_threshold` that
-        will print in a text file .lg in the main folder.
-        
-        .. warning:: :func:`Seath.Seath.separability_and_threshold` does not always allow to discriminate optimal threshold. 
-                    Then, this function will be launch at least ten time until it reaches a optimal threshold.
-        """
-        
-        # Compute threshold with various sample
-        i_s = 0
-        while i_s < 10:
-            try :
-                self.valid_shp = []
-                sample_rd = {}
-                for sple in range(len(self.sample_name) * 2):
-                    kwargs = {}
-                    kwargs['fieldname'] = self.fieldname_args[sple]
-                    kwargs['class'] = self.class_args[sple]
-                    sample_rd[sple] = Sample(self.sample_name[sple/2], self.path_area, self.list_nb_sample[sple/2])
-                    sample_rd[sple].create_sample(**kwargs)
-                    sample_rd[sple].zonal_stats((self.raster_path[sple/2], self.list_band_outraster[sple/2]))
-                    
-                    # Add the validation shapefile
-                    self.valid_shp.append([sample_rd[sple].vector_val, kwargs['fieldname'], kwargs['class']])
-                
-                # Search the optimal threshold by class 
-                # Open a text file to print stats of Seath method
-                file_J = self.path_folder_dpt + '/log_J.lg'
-                f = open(file_J, "wb")
-                for th_seath in range(len(self.sample_name)):
-                    self.decis[th_seath] = Seath()
-                    self.decis[th_seath].value_1 = sample_rd[th_seath*2].stats_dict
-                    self.decis[th_seath].value_2 = sample_rd[th_seath*2 + 1].stats_dict
-                    self.decis[th_seath].separability_and_threshold()
-                    
-                    # Print the J value in the text file .lg
-                    f.write('For ' + str(self.sample_name[th_seath]) + ' :\n')
-                    f.write('J = ' + str(self.decis[th_seath].J[0]) +'\n')
-                    f.write('The class 1 ' + str(self.decis[th_seath].threshold[0]) +'\n')
-                    
-                f.close()    
-                i_s = 20
-            except:
-                i_s = i_s + 1
-        # Method to stop the processus if there is not found a valid threshold
-        if i_s != 20:
-            print ('Problem in the sample processing !!!')
-            sys.exit(1)
-    
-    def i_sample_rf(self):
-        """
-        This function build a random forest trees like model to create a final classification.
-        All of This using the method described in the :func:`i_validate` function and because
-        of sklearn module.
-        """
-        
-        X_rf = []
-        y_rf = []
-        sample_rd = {}            
-        # Tricks to add all textural indexes
-        rm_index = 1
-        self.raster_path.remove(self.raster_path[rm_index]) # Remove SFS layer
-        self.raster_path.remove(self.raster_path[rm_index]) # Remove Haralick layer
-        self.list_band_outraster.remove(self.list_band_outraster[rm_index]) # Remove band of the layer
-        self.list_band_outraster.remove(self.list_band_outraster[rm_index]) # Remove band of the layer
-        # Add all layers in the simple index haralick
-        for add_layer in range(8):
-            self.raster_path.insert(add_layer+1, self.out_ndvistats_folder_tab['haralick'])
-            self.list_band_outraster.insert(add_layer+1, add_layer+1)
-        # Add all layers in the SFS index
-        for add_layer in range(6):
-            self.raster_path.insert(add_layer+1, self.out_ndvistats_folder_tab['sfs'])
-            self.list_band_outraster.insert(add_layer+1, add_layer+1)
-            
-        # Extract value mean from polygons
-        for sple in range(len(self.sample_name) * 2):
-            kwargs = {}
-            kwargs['fieldname'] = self.fieldname_args[sple]
-            kwargs['class'] = self.class_args[sple]
-            sample_rd[sple] = Sample(self.sample_name[sple/2], self.path_area, self.list_nb_sample[sple/2])
-            sample_rd[sple].create_sample(**kwargs)
-            
-            # Add the validation shapefile
-            self.valid_shp.append([sample_rd[sple].vector_val, kwargs['fieldname'], kwargs['class']])
+			for lbo in range(len(self.raster_path)):
+				kwargs['rank'] = lbo
+				kwargs['nb_img'] = len(self.raster_path)
+				sample_rd[sple].zonal_stats(self.raster_path[lbo], self.list_band_outraster[lbo], **kwargs)
+			
+			# To convert the dictionnary in a list
+			# for key, value in sample_rd[sple].stats_dict.iteritems():
+			for key, value in sample_rd[sple].stats_dict.items():
+#				 X_rf.append([-10000 if (math.isnan(x) or math.isinf(x)) else x for x in value])
+				# To set the grassland class of the RPG and PIAO (same class)			
+				if sple == 2:
+#					 y_rf.append(1)
+					pass
+				elif sple == 3:
+#					 y_rf.append(4)
+					pass
+				else:
+					y_rf.append(sple)
+					X_rf.append([-10000 if (x is None or math.isnan(x) or math.isinf(x)) else x for x in value])
+					
+		# Build a forest of trees from the samples				 
+		self.rf = self.rf.fit(X_rf, y_rf)
+		
+		# Print in a file feature important
+		importance = self.rf.feature_importances_
+		importance = [(importance[x],x+1) for x in range(len(importance))]
+		importance.sort()
+		
+		file_feat_import = os.path.dirname(str(self.raster_path[0])) + '/Feature_important_RF.ft'
+		if os.path.exists(file_feat_import):
+			os.remove(file_feat_import)
+		
+		with open(file_feat_import, "w") as f_out :
+			f_out.write(str(importance))
+		
+		# Print in a file decision tree
+		file_decisiontree = os.path.dirname(str(self.raster_path[0])) + '/Decision_tree.dot'
+		
+		if os.path.exists(file_decisiontree):
+			os.remove(file_decisiontree)
+		
+		tree_in_forest = self.rf.estimators_[499]
+		with open(file_decisiontree, 'w') as my_file:
+			my_file = tree.export_graphviz(tree_in_forest, out_file = my_file)
 
-            for lbo in range(len(self.raster_path)):
-                kwargs['rank'] = lbo
-                kwargs['nb_img'] = len(self.raster_path)
-                sample_rd[sple].zonal_stats((self.raster_path[lbo], self.list_band_outraster[lbo]), **kwargs)
-            
-            # To convert the dictionnary in a list
-            for key, value in sample_rd[sple].stats_dict.iteritems():
-#                 X_rf.append([-10000 if (math.isnan(x) or math.isinf(x)) else x for x in value])
-                # To set the grassland class of the RPG and PIAO (same class)            
-                if sple == 2:
-#                     y_rf.append(1)
-                    pass
-                elif sple == 3:
-#                     y_rf.append(4)
-                    pass
-                else:
-                    y_rf.append(sple)
-                    X_rf.append([-10000 if (math.isnan(x) or math.isinf(x)) else x for x in value])
-                    
-        # Build a forest of trees from the samples                 
-        self.rf = self.rf.fit(X_rf, y_rf)
-        
-        # Print in a file feature important
-        importance = self.rf.feature_importances_
-        importance = [(importance[x],x+1) for x in range(len(importance))]
-        importance.sort()
-        
-        file_feat_import = os.path.dirname(str(self.raster_path[0])) + '/Feature_important_RF.ft'
-        if os.path.exists(file_feat_import):
-            os.remove(file_feat_import)
-        f_out = open(file_feat_import, "wb")
-        f_out.write(str(importance))
-        # Close the output file
-        f_out.close()
-        
-        # Print in a file decision tree
-        file_decisiontree = os.path.dirname(str(self.raster_path[0])) + '/Decision_tree.dot'
-        if os.path.exists(file_decisiontree):
-            os.remove(file_decisiontree)
-        
-        tree_in_forest = self.rf.estimators_[499]
-        with open(file_decisiontree, 'w') as my_file:
-            my_file = tree.export_graphviz(tree_in_forest, out_file = my_file)
+	def i_classifier_rf(self): 
+		"""
+			Interface function to launch random forest classification with a input segmentation :func:`Segmentation.Segmentation`.
+		
+			This function use the sklearn module to build the best of decision tree to extract classes.
+			The optimal threshold are stored by class **rf** variable in :func:`Processing.i_sample_rf`. Then it computes zonal statistics by polygons
+			for every images in multi-processing (if **mp** = 1).
+		"""
+		
+		# Multiprocessing
+		mgr = BaseManager()
+		mgr.register('defaultdict', defaultdict, DictProxy)
+		mgr.start()
+		multi_process_var = [] # Multi processing variable
+		  
+		# Extract final cartography
+		out_carto = Segmentation(self.path_segm, self.path_area) 
+		out_carto.output_file = self.output_name_moba
+		out_carto.out_class_name = self.in_class_name
+#		 out_carto.out_threshold = []
 
-    def i_classifier_rf(self): 
-        """
-        Interface function to launch random forest classification with a input segmentation :func:`Segmentation.Segmentation`.
-        
-        This function use the sklearn module to build the best of decision tree to extract classes.
-        The optimal threshold are stored by class **rf** variable in :func:`Processing.i_sample_rf`. Then it computes zonal statistics by polygons
-        for every images in multi-processing (if **mp** = 1).
-        """
-        
-        # Multiprocessing
-        mgr = BaseManager()
-        mgr.register('defaultdict', defaultdict, DictProxy)
-        mgr.start()
-        multi_process_var = [] # Multi processing variable
-          
-        # Extract final cartography
-        out_carto = Segmentation(self.path_segm, self.path_area) 
-        out_carto.output_file = self.output_name_moba
-        out_carto.out_class_name = self.in_class_name
-#         out_carto.out_threshold = []
-        for ind_th in range(len(self.raster_path)):
-            multi_process_var.append([self.raster_path[ind_th], self.list_band_outraster[ind_th]])
+		for ind_th in range(len(self.raster_path)):
+			multi_process_var.append([self.raster_path[ind_th], self.list_band_outraster[ind_th]])
 
-        # Compute zonal stats with multi processing
-        exist_stats = 1 # By default, the stats file exists already
-        file_stats = os.path.dirname(str(self.raster_path[0])) + '/Stats_raster_spectral_texture.stats' # Stats backup file
-        if not os.path.exists(file_stats):
-            exist_stats = 0 # The sats file doesn't exist
-            # Open a stats backup to avoid computing again (Gain of time)
-            f_out = open(file_stats, "wb")
-        
-        p = []
-        kwargs = {}
-        X_out_rf = [] # Variable list to compute decision tree with random forest method
-        if exist_stats == 0:
-            out_carto.stats_dict = mgr.defaultdict(list)
-            for i in range(len(multi_process_var)):
-                kwargs['rank'] = i
-                kwargs['nb_img'] = len(multi_process_var)
-                p.append(Process(target=out_carto.zonal_stats, args=(multi_process_var[i], ), kwargs=kwargs))
-                p[i].start()
-                
-                if self.mp == 0:
-                    p[i].join()
-            
-            if self.mp == 1:       
-                for i in range(len(multi_process_var)):
-                    p[i].join()
-                    
-            for key, value_seg in out_carto.stats_dict.items():
-                true_value = [-10000 if (math.isnan(x) or math.isinf(x)) else x for x in value_seg]
-                X_out_rf.append(true_value)
-                
-                # Print rasters stats value in the text file .lg
-                f_out.write(str(true_value) + '\n')
-            
-            # Close the output file
-            f_out.close()
-            
-        else:
-            # If the stats file exists already, open this file and append in the stats_dict variable
-            out_carto.stats_dict = defaultdict(list)
-            with open(file_stats, "r") as f_in:
-                index_in_stats=-1
-                for x_in in f_in.readlines():
-                    index_in_stats = index_in_stats + 1
-                    out_carto.stats_dict[index_in_stats] = eval(x_in.strip('\n'))
-                    X_out_rf.append(eval(x_in.strip('\n')))
-        
-        predicted_rf = self.rf.predict(X_out_rf)
-             
-        # For the higher than level 1
-        if len(self.sample_name) > 2:
-            # Compute the biomass and density distribution
-            # Use 'out_carto.out_threshold' to konw predicted in the segmentation class
-            out_carto.out_threshold = predicted_rf
-            # In the compute_biomass_density function, this variable used normally to define 
-            # threshold of the classification with SEATH method is initialized
-            out_carto.compute_biomass_density('RF')
-        
-        out_carto.class_tab_final = defaultdict(list)
-        for i_polyg in range(len(predicted_rf)):
-            i_final = 0
-            class_final = []
-            # Initialize the predicted output format
-            # For example : predicted => 4, formatted => [1,3,4]
-            while i_final < len(self.tree_direction):
-                if self.tree_direction[i_final][len(self.tree_direction[i_final])-1] == predicted_rf[i_polyg]:
-                    class_final = self.tree_direction[i_final]
-                    i_final = len(self.tree_direction)
-                i_final = i_final + 1
-            
-            if class_final == []:
-                class_final = [1, 2]
-            # Set the class name because of predicted output formatted         
-            out_carto.class_tab_final[i_polyg] = [self.in_class_name[f] for f in class_final] + \
-                                                [predicted_rf[i_polyg]] + [predicted_rf[i_polyg]]
-            
-            # For the output line with one level, add a phantom level
-            # TODO : Replace constant by a variable in the condition 'while'
-            while len(out_carto.class_tab_final[i_polyg]) < 5:
-                out_carto.class_tab_final[i_polyg].insert(len(out_carto.class_tab_final[i_polyg])-2,'')
-        
-        # If there is more one fieldnames line edit fulled in classification tab
-        if len(self.sample_name) > 2:
-            # Compute biomass and density scale
-            out_carto.append_scale(self.in_class_name[2], 'self.stats_dict[ind_stats][3]/self.max_bio')
-            out_carto.append_scale(self.in_class_name[3], 'self.stats_dict[ind_stats][2]/self.max_wood_idm')
-        
-        # Rasterize RPG shapefile to complete the final shapefile
-        opt = {}
-        opt['Remove'] = 1
-        rpg_tif = Vector(self.sample_name[0], self.path_area, **opt)
-#         if not os.path.exists(str(rpg_tif.vector_used[:-3]+'TIF')): 
-        kwargs['choice_nb_b'] = 1
-        out_carto.stats_rpg_tif = out_carto.zonal_stats_pp(rpg_tif.layer_rasterization(self.path_ortho, 'CODE_GROUP', **kwargs))
+		# Compute zonal stats with multi processing
+		exist_stats = 1 # By default, the stats file exists already
+		file_stats = os.path.dirname(str(self.raster_path[0])) + '/Stats_raster_spectral_texture.stats' # Stats backup file
+		if not os.path.exists(file_stats):
+			exist_stats = 0 # The sats file doesn't exist
+			# Open a stats backup to avoid computing again (Gain of time)
+			f_out = open(file_stats, "w")
+		
+		p = []
+		kwargs = {}
+		X_out_rf = [] # Variable list to compute decision tree with random forest method
+		if exist_stats == 0:
+			out_carto.stats_dict = mgr.defaultdict(list)
+			
+			for i in range(len(multi_process_var)):
+				kwargs['rank'] = i
+				kwargs['nb_img'] = len(multi_process_var)
+				p.append(Process(target=out_carto.zonal_stats, args=(*multi_process_var[i], ), kwargs=kwargs))
+				p[i].start()
+				
+				if self.mp == Constantes.MULTIPROCESSING_DISABLE:
+					p[i].join()
+			
+			if self.mp == Constantes.MULTIPROCESSING_ENABLE:	   
+				for i in range(len(multi_process_var)):
+					p[i].join()
+					
+			for key, value_seg in out_carto.stats_dict.items():
+				true_value = [-10000 if (x == None or math.isnan(x) or math.isinf(x)) else x for x in value_seg]
+				X_out_rf.append(true_value)
+				
+				# Print rasters stats value in the text file .lg
+				f_out.write(str(true_value) + '\n')
+			
+			# Close the output file
+			f_out.close()
+			
+		else:
+			# If the stats file exists already, open this file and append in the stats_dict variable
+			out_carto.stats_dict = defaultdict(list)
+			with open(file_stats, "r") as f_in:
+				index_in_stats=-1
+				for x_in in f_in.readlines():
+					index_in_stats = index_in_stats + 1
+					out_carto.stats_dict[index_in_stats] = eval(x_in.strip('\n'))
+					X_out_rf.append(eval(x_in.strip('\n')))
+		
+		predicted_rf = self.rf.predict(X_out_rf)
+			 
+		# For the higher than level 1
+		if len(self.sample_name) > 2:
+			# Compute the biomass and density distribution
+			# Use 'out_carto.out_threshold' to konw predicted in the segmentation class
+			out_carto.out_threshold = predicted_rf
+			# In the compute_biomass_density function, this variable used normally to define 
+			# threshold of the classification with SEATH method is initialized
+			out_carto.compute_biomass_density('RF')
+		
+		out_carto.class_tab_final = defaultdict(list)
+		for i_polyg in range(len(predicted_rf)):
+			i_final = 0
+			class_final = []
+			# Initialize the predicted output format
+			# For example : predicted => 4, formatted => [1,3,4]
+			while i_final < len(self.tree_direction):
+				if self.tree_direction[i_final][len(self.tree_direction[i_final])-1] == predicted_rf[i_polyg]:
+					class_final = self.tree_direction[i_final]
+					i_final = len(self.tree_direction)
+				i_final = i_final + 1
+			
+			if class_final == []:
+				class_final = [1, 2]
+			# Set the class name because of predicted output formatted		 
+			out_carto.class_tab_final[i_polyg] = [self.in_class_name[f] for f in class_final] + \
+												[predicted_rf[i_polyg]] + [predicted_rf[i_polyg]]
+			
+			# For the output line with one level, add a phantom level
+			# TODO : Replace constant by a variable in the condition 'while'
+			while len(out_carto.class_tab_final[i_polyg]) < 5:
+				out_carto.class_tab_final[i_polyg].insert(len(out_carto.class_tab_final[i_polyg])-2,'')
+		
+		# If there is more one fieldnames line edit fulled in classification tab
+		if len(self.sample_name) > 2:
+			# Compute biomass and density scale
+			out_carto.append_scale(self.in_class_name[2], 'self.stats_dict[ind_stats][3]/self.max_bio')
+			out_carto.append_scale(self.in_class_name[3], 'self.stats_dict[ind_stats][2]/self.max_wood_idm')
+		
+		# Rasterize RPG shapefile to complete the final shapefile
+		opt = {}
+		opt['Remove'] = 1
+		rpg_tif = Vector(self.sample_name[0], self.path_area, **opt)
+#		 if not os.path.exists(str(rpg_tif.vector_used[:-3]+'TIF')): 
+		kwargs['choice_nb_b'] = 1
+		out_carto.stats_rpg_tif = out_carto.zonal_stats_pp(rpg_tif.layer_rasterization(self.path_ortho, 'CODE_GROUP', **kwargs))
 
-        # Final cartography
-        out_carto.create_cartography(self.out_fieldname_carto, self.out_fieldtype_carto)
-        
-    def i_classifier_s(self): 
-        """
-        Interface function to launch decision tree classification with a input segmentation :func:`Segmentation.Segmentation`.
-        
-        This function store optimal threshold by class **Segmentation.out_threshold**. Then it computes zonal statistics by polygons
-        for every images in multi-processing (if **mp** = 1).
-        """ 
-        
-        # Multiprocessing
-        mgr = BaseManager()
-        mgr.register('defaultdict', defaultdict, DictProxy)
-        mgr.start()
-        multi_process_var = [] # Multi processing variable
-          
-        # Extract final cartography
-        out_carto = Segmentation(self.path_segm, self.path_area) 
-        out_carto.output_file = self.output_name_moba
-        out_carto.out_class_name = self.in_class_name
-        out_carto.out_threshold = []
-        for ind_th in range(len(self.sample_name)):
-            out_carto.out_threshold.append(self.decis[ind_th].threshold[0])
-            if '>' in self.decis[ind_th].threshold[0]:
-                out_carto.out_threshold.append(self.decis[ind_th].threshold[0].replace('>', '<='))
-            elif '<' in self.decis[ind_th].threshold[0]:
-                out_carto.out_threshold.append(self.decis[ind_th].threshold[0].replace('<', '>='))
-        #     out_carto.zonal_stats((raster_path[ind_th], list_band_outraster[ind_th]))
-            multi_process_var.append([self.raster_path[ind_th], self.list_band_outraster[ind_th]])
-         
-        # Compute zonal stats on slope raster
-        multi_process_var.append([self.raster_path[ind_th+1], self.list_band_outraster[ind_th+1]])
-        out_carto.out_threshold.append('<'+str(self.slope_degree)) # To agriculture
-        out_carto.out_threshold.append('>='+str(self.slope_degree)) # To scree
-        if self.path_mnt != '':
-            # Add class indexes
-            self.tree_direction[0].append(6)
-            self.tree_direction[0].append(7)
-            
-        # Compute zonal stats on Max NDVI raster  
-        try:
-            # out_carto.zonal_stats((raster_path[ind_th+1], list_band_outraster[ind_th+1]))
-            multi_process_var.append([self.raster_path[ind_th+2], self.list_band_outraster[ind_th+2]])
-            # Compute stats twice, because there is 3 classes and not 2
-            # out_carto.zonal_stats((raster_path[ind_th+1], list_band_outraster[ind_th+1]))
-            multi_process_var.append([self.raster_path[ind_th+2], self.list_band_outraster[ind_th+2]])
-        except:
-            print('Not MNT on the 3rd step')
-            multi_process_var.append([self.raster_path[ind_th+1], self.list_band_outraster[ind_th+1]])
-            multi_process_var.append([self.raster_path[ind_th+1], self.list_band_outraster[ind_th+1]])
+		# Final cartography
+		out_carto.create_cartography(self.out_fieldname_carto, self.out_fieldtype_carto)
+		
+	def i_classifier_s(self): 
+		"""
+		Interface function to launch decision tree classification with a input segmentation :func:`Segmentation.Segmentation`.
+		
+		This function store optimal threshold by class **Segmentation.out_threshold**. Then it computes zonal statistics by polygons
+		for every images in multi-processing (if **mp** = 1).
+		""" 
+		
+		# Multiprocessing
+		mgr = BaseManager()
+		mgr.register('defaultdict', defaultdict, DictProxy)
+		mgr.start()
+		multi_process_var = [] # Multi processing variable
+		  
+		# Extract final cartography
+		out_carto = Segmentation(self.path_segm, self.path_area) 
+		out_carto.output_file = self.output_name_moba
+		out_carto.out_class_name = self.in_class_name
+		out_carto.out_threshold = []
+		for ind_th in range(len(self.sample_name)):
+			out_carto.out_threshold.append(self.decis[ind_th].threshold[0])
+			if '>' in self.decis[ind_th].threshold[0]:
+				out_carto.out_threshold.append(self.decis[ind_th].threshold[0].replace('>', '<='))
+			elif '<' in self.decis[ind_th].threshold[0]:
+				out_carto.out_threshold.append(self.decis[ind_th].threshold[0].replace('<', '>='))
+		#	 out_carto.zonal_stats((raster_path[ind_th], list_band_outraster[ind_th]))
+			multi_process_var.append([self.raster_path[ind_th], self.list_band_outraster[ind_th]])
+		 
+		# Compute zonal stats on slope raster
+		multi_process_var.append([self.raster_path[ind_th+1], self.list_band_outraster[ind_th+1]])
+		out_carto.out_threshold.append('<'+str(self.slope_degree)) # To agriculture
+		out_carto.out_threshold.append('>='+str(self.slope_degree)) # To scree
+		if self.path_mnt != '':
+			# Add class indexes
+			self.tree_direction[0].append(6)
+			self.tree_direction[0].append(7)
+			
+		# Compute zonal stats on Max NDVI raster  
+		try:
+			# out_carto.zonal_stats((raster_path[ind_th+1], list_band_outraster[ind_th+1]))
+			multi_process_var.append([self.raster_path[ind_th+2], self.list_band_outraster[ind_th+2]])
+			# Compute stats twice, because there is 3 classes and not 2
+			# out_carto.zonal_stats((raster_path[ind_th+1], list_band_outraster[ind_th+1]))
+			multi_process_var.append([self.raster_path[ind_th+2], self.list_band_outraster[ind_th+2]])
+		except:
+			print('Not MNT on the 3rd step')
+			multi_process_var.append([self.raster_path[ind_th+1], self.list_band_outraster[ind_th+1]])
+			multi_process_var.append([self.raster_path[ind_th+1], self.list_band_outraster[ind_th+1]])
 
-        # Compute zonal stats with multi processing
-        exist_stats = 1 # By default, the stats file exists already
-        file_stats = os.path.dirname(str(self.raster_path[0])) + '/Stats_raster_spectral_texture.stats' # Stats backup file
-        if not os.path.exists(file_stats):
-            exist_stats = 0 # The sats file doesn't exist
-            # Open a stats backup to avoid computing again (Gain of time)
-            f_out = open(file_stats, "wb")
-            
-        p = []
-        kwargs = {}
-        X_out_rf = [] # Variable list to compute decision tree with random forest method
-        if exist_stats == 0:
-            out_carto.stats_dict = mgr.defaultdict(list)
-            for i in range(len(multi_process_var)):
-                kwargs['rank'] = i
-                kwargs['nb_img'] = len(multi_process_var)
-                p.append(Process(target=out_carto.zonal_stats, args=(multi_process_var[i], ), kwargs=kwargs))
-                p[i].start()
-                
-                if self.mp == 0:
-                    p[i].join()
-            
-            if self.mp == 1:       
-                for i in range(len(multi_process_var)):
-                    p[i].join()
-                    
-            for key, value_seg in out_carto.stats_dict.items():
-                
-                true_value = [-10000 if (math.isnan(x) or math.isinf(x)) else x for x in value_seg]
-                # Print rasters stats value in the text file .lg
-                f_out.write(str(true_value) + '\n')
-            
-            # Close the output file
-            f_out.close()
-            
-        else:
-            # If the stats file exists already, open this file and append in the stats_dict variable
-            out_carto.stats_dict = defaultdict(list)
-            with open(file_stats, "r") as f_in:
-                index_in_stats=-1
-                for x_in in f_in.readlines():
-                    index_in_stats = index_in_stats + 1
-                    out_carto.stats_dict[index_in_stats] = eval(x_in.strip('\n'))
-                    X_out_rf.append(eval(x_in.strip('\n')))
-        
-        # For the higher than level 1 
-        if len(self.sample_name) > 2:
-            # Compute the biomass and density distribution
-            out_carto.compute_biomass_density()
-            
-        out_carto.class_tab_final = defaultdict(list)
-        self.i_tree_direction()
-        out_carto.decision_tree(self.tree_direction)
-        
-        # If there is more one fieldnames line edit fulled in classification tab
-        if len(self.sample_name) > 2:     
-            # Compute biomass and density scale
-            out_carto.append_scale(self.in_class_name[2], 'self.stats_dict[ind_stats][3]/self.max_bio')
-            out_carto.append_scale(self.in_class_name[3], 'self.stats_dict[ind_stats][2]/self.max_wood_idm')
-        
-        # Rasterize RPG shapefile to complete the final shapefile
-        opt = {}
-        opt['Remove'] = 1
-        rpg_tif = Vector(self.sample_name[0], self.path_area, **opt)
-        rpg_tif.layer_rasterization(self.path_ortho, 'CODE_GROUP')
-          
-        # Final cartography
-        out_carto.mono_rpg_tif = self.sample_name[0][:-4] + '.TIF'
-        out_carto.create_cartography(self.out_fieldname_carto, self.out_fieldtype_carto)
-       
-    def i_validate(self):
-        """
-        Interface to validate a classification. It going to rasterize the validation shapefile and the 
-        classification shapefile with :func:`layer_rasterization`. Next, to compare pixel by pixel, the classification
-        quality to built a confusion matrix in a csv file.
-        
-        """
-        # Variable to convert the input classname to an individual interger
-        # Only for the validate sample
-        class_validate = 0
-        complete_validate_shp = os.path.dirname(str(self.valid_shp[0][0])) + '/validate.shp'
+		# Compute zonal stats with multi processing
+		exist_stats = 1 # By default, the stats file exists already
+		file_stats = os.path.dirname(str(self.raster_path[0])) + '/Stats_raster_spectral_texture.stats' # Stats backup file
+		if not os.path.exists(file_stats):
+			exist_stats = 0 # The sats file doesn't exist
+			# Open a stats backup to avoid computing again (Gain of time)
+			f_out = open(file_stats, "wb")
+			
+		p = []
+		kwargs = {}
+		X_out_rf = [] # Variable list to compute decision tree with random forest method
+		if exist_stats == 0:
+			out_carto.stats_dict = mgr.defaultdict(list)
+			for i in range(len(multi_process_var)):
+				kwargs['rank'] = i
+				kwargs['nb_img'] = len(multi_process_var)
+				p.append(Process(target=out_carto.zonal_stats, args=(multi_process_var[i], ), kwargs=kwargs))
+				p[i].start()
+				
+				if self.mp == Constantes.MULTIPROCESSING_DISABLE:
+					p[i].join()
+			
+			if self.mp == Constantes.MULTIPROCESSING_ENABLE:	   
+				for i in range(len(multi_process_var)):
+					p[i].join()
+					
+			for key, value_seg in out_carto.stats_dict.items():
+				
+				true_value = [-10000 if (math.isnan(x) or math.isinf(x)) else x for x in value_seg]
+				# Print rasters stats value in the text file .lg
+				f_out.write(str(true_value) + '\n')
+			
+			# Close the output file
+			f_out.close()
+			
+		else:
+			# If the stats file exists already, open this file and append in the stats_dict variable
+			out_carto.stats_dict = defaultdict(list)
+			with open(file_stats, "r") as f_in:
+				index_in_stats=-1
+				for x_in in f_in.readlines():
+					index_in_stats = index_in_stats + 1
+					out_carto.stats_dict[index_in_stats] = eval(x_in.strip('\n'))
+					X_out_rf.append(eval(x_in.strip('\n')))
+		
+		# For the higher than level 1 
+		if len(self.sample_name) > 2:
+			# Compute the biomass and density distribution
+			out_carto.compute_biomass_density()
+			
+		out_carto.class_tab_final = defaultdict(list)
+		self.i_tree_direction()
+		out_carto.decision_tree(self.tree_direction)
+		
+		# If there is more one fieldnames line edit fulled in classification tab
+		if len(self.sample_name) > 2:	 
+			# Compute biomass and density scale
+			out_carto.append_scale(self.in_class_name[2], 'self.stats_dict[ind_stats][3]/self.max_bio')
+			out_carto.append_scale(self.in_class_name[3], 'self.stats_dict[ind_stats][2]/self.max_wood_idm')
+		
+		# Rasterize RPG shapefile to complete the final shapefile
+		opt = {}
+		opt['Remove'] = 1
+		rpg_tif = Vector(self.sample_name[0], self.path_area, **opt)
+		rpg_tif.layer_rasterization(self.path_ortho, 'CODE_GROUP')
+		  
+		# Final cartography
+		out_carto.mono_rpg_tif = self.sample_name[0][:-4] + '.TIF'
+		out_carto.create_cartography(self.out_fieldname_carto, self.out_fieldtype_carto)
+	   
+	def i_validate(self):
+		"""
+		Interface to validate a classification. It going to rasterize the validation shapefile and the 
+		classification shapefile with :func:`layer_rasterization`. Next, to compare pixel by pixel, the classification
+		quality to built a confusion matrix in a csv file.
+		
+		"""
+		# Variable to convert the input classname to an individual interger
+		# Only for the validate sample
+		class_validate = 0
+		complete_validate_shp = os.path.dirname(str(self.valid_shp[0][0])) + '/validate.shp'
 
-        # TODO: Set this method in the Precision_moba class
+		# TODO: Set this method in the Precision_moba class
 
-        
-        # Processing to rasterize the validate shapefile. 1) Merge sahpefiles 2) Rasterization
-        for val in self.valid_shp:
-            if class_validate != 2: 
-                # Grassland to 1
-                if (class_validate !=3 and len(self.out_fieldname_carto) != 4+2) or len(self.out_fieldname_carto) == 4+2:
-                    # To the level 3 with woodeen to 4 and 5
-                    #
-                    # Self.valid_shp is a list of list. In this variable there is :
-                    # [Shapefile path, fieldname classes, classnames]
-                    opt = {}
-                    opt['Remove'] = 1 # To overwrite 
-        
-                    # Create a raster to valide the classification
-                    # First time, create a new shapefile with a new field integer
-                    sample_val = Sample(val[0], self.path_area, 1, **opt)
-                    opt['add_fieldname'] = 1 
-                    opt['fieldname'] = 'CLASS_CODE'
-                    opt['class'] = str(class_validate) # Add integer classes
-                    # Set the new shapefile
-                    val[0] = val[0][:-4] + '_.shp'
-                    val[1] = opt['fieldname']
-                    val[2] = opt['class']
-                    # Complete the new shapefile
-                    sample_val.fill_sample(val[0], 0, **opt)
-                    # Second time, merge the validate shapefile
-                    if class_validate == 0:
-                        process_tocall_merge =  ['ogr2ogr', '-overwrite', complete_validate_shp, val[0]]
-                    elif class_validate > 0:
-                        process_tocall_merge =  ['ogr2ogr', '-update', '-append', complete_validate_shp, \
-                                                 val[0], '-nln', os.path.basename(str(complete_validate_shp[:-4]))]
-                    subprocess.call(process_tocall_merge)
-            # Increrment variable
-            class_validate = self.valid_shp.index(val) + 1
-        
-        # Compute precision of the classification
-        valid = Precision_moba(self.path_area, self.path_folder_dpt)     
-        valid.complete_validation_shp = complete_validate_shp
-        valid.ex_raster = self.raster_path[0]
-        
-        # TODO: Call the RasterSat_by_Date class here instead of the Precision_moba class
-        
-        valid.preprocess_to_raster_precision(self.output_name_moba, 'FBPHY_CODE') # To the classification's data
-        valid.preprocess_to_raster_precision(complete_validate_shp, val[1]) # To the validation's data
-        
-        # Compute precision on the output classification
-        valid.confus_matrix(valid.complete_img[0].raster_data(valid.img_pr[0])[0], \
-                            valid.complete_img[1].raster_data(valid.img_pr[1])[0])
+		
+		# Processing to rasterize the validate shapefile. 1) Merge sahpefiles 2) Rasterization
+		for val in self.valid_shp:
+			if class_validate != 2: 
+				# Grassland to 1
+				if (class_validate !=3 and len(self.out_fieldname_carto) != 4+2) or len(self.out_fieldname_carto) == 4+2:
+					# To the level 3 with woodeen to 4 and 5
+					#
+					# Self.valid_shp is a list of list. In this variable there is :
+					# [Shapefile path, fieldname classes, classnames]
+					opt = {}
+					opt['Remove'] = 1 # To overwrite 
+		
+					# Create a raster to valide the classification
+					# First time, create a new shapefile with a new field integer
+					sample_val = Sample(val[0], self.path_area, 1, **opt)
+					opt['add_fieldname'] = 1 
+					opt['fieldname'] = 'CLASS_CODE'
+					opt['class'] = str(class_validate) # Add integer classes
+					# Set the new shapefile
+					val[0] = val[0][:-4] + '_.shp'
+					val[1] = opt['fieldname']
+					val[2] = opt['class']
+					# Complete the new shapefile
+					sample_val.fill_sample(val[0], 0, **opt)
+					# Second time, merge the validate shapefile
+					if class_validate == 0:
+						process_tocall_merge =  ['ogr2ogr', '-overwrite', complete_validate_shp, val[0]]
+					elif class_validate > 0:
+						process_tocall_merge =  ['ogr2ogr', '-update', '-append', complete_validate_shp, \
+												 val[0], '-nln', os.path.basename(str(complete_validate_shp[:-4]))]
+					subprocess.call(process_tocall_merge)
+			# Increrment variable
+			class_validate = self.valid_shp.index(val) + 1
+		
+		# Compute precision of the classification
+		valid = Precision_moba(self.path_area, self.path_folder_dpt)	 
+		valid.complete_validation_shp = complete_validate_shp
+		valid.ex_raster = self.raster_path[0]
+		
+		# TODO: Call the RasterSat_by_Date class here instead of the Precision_moba class
+		
+		valid.preprocess_to_raster_precision(self.output_name_moba, 'FBPHY_CODE') # To the classification's data
+		valid.preprocess_to_raster_precision(complete_validate_shp, val[1]) # To the validation's data
+		
+		# Compute precision on the output classification
+		valid.confus_matrix(valid.complete_img[0].raster_data(valid.img_pr[0])[0], valid.complete_img[1].raster_data(valid.img_pr[1])[0])
diff --git a/RasterSat_by_date.py b/RasterSat_by_date.py
index ef9489f417b9b7e4c556635abba9aaed4f147cbb..0f44f9670154e6c30dee28bc602eef592c70c06b 100644
--- a/RasterSat_by_date.py
+++ b/RasterSat_by_date.py
@@ -20,389 +20,389 @@
 import os, sys
 import math, subprocess
 try :
-    import gdal
+	import gdal
 except :
-    from osgeo import gdal
+	from osgeo import gdal
 
 import numpy as np
 
 class RasterSat_by_date():
-    """
-    Satellite image  processing's class. This class include several processes to group images by date, mosaic images by date,
-    extract images information, compute ndvi, compute cloud pourcent and create new rasters.
-    
-    :param class_archive: Archive class name with every information on downloaded images
-    :type class_archive: class
-    :param big_folder: Image processing folder
-    :type big_folder: str
-    :param one_date: [year, month, day] ...
-            This variable is modified in the function :func:`mosaic_by_date()`. 
-            To append mosaic image path, mosaic cloud image path, cloud pixel value table, mosaic ndvi image path and ndvi pixel value table.
-    :type one_date: list of str
-    :param choice_nb_b: A option to choice output image number of band :func:`layer_rasterization` in Vector's class. If this option is 0, it take input band. By default 0.
-    :type choice_nb_b: int
-    
-    """  
-    def __init__(self, class_archive, big_folder, one_date):
-        """Create a new 'Landsat_by_date' instance
-        
-        """
-        
-        self._class_archive = class_archive
-        self._big_folder = big_folder
-        self._one_date = one_date        
-        # Verify list of list of str
-        if one_date == []:
-            print ("Enter dates to mosaic images like [[str(year), str(month), str(day)], [str(year), str(month), str(day)], ...]")
-            sys.exit(1)
-        else:
-            self._one_date = one_date
-        
-        self.out_ds = None
-        self.choice_nb_b = 0
-           
-    def group_by_date(self, d_uni):
-        """
-        Function to extract images on a single date
-        
-        :param d_uni: [year, month, day]
-        :type d_uni: list of str
-        
-        :returns: list of str -- variable **group** = [year, month, day, multispectral image path, cloud image path]
-        """
-         
-        # Group of images with the same date
-        group = []
-         
-        # Take images with the same date
-        for d_dup in self._class_archive.list_img:
-            if d_dup[:3] == d_uni:
-                group.append(d_dup)
-         
-        return group
-    
-    def vrt_translate_gdal(self, vrt_translate, src_data, dst_data):
-        """
-        Function to launch gdal tools in command line. With ``gdalbuildvrt`` and ``gdal_translate``.
-        This function is used :func:`mosaic_by_date` to mosaic image by date.
-        
-        :param vrt_translate: ``vrt`` or ``translate``
-        :type vrt_translate: str
-        :param src_data: Data source. Several data for vrt process and one data (vrt data) for gdal_translate
-        :type src_data: list (process ``vrt``) or str (process ``translate``)  
-        :param dst_data: Output path
-        :type dst_data: str
-        """
-        
-        if os.path.exists(dst_data):
-            os.remove(dst_data)
-        
-        # Select process
-        if vrt_translate == 'vrt':
-            # Verify input data
-            if type(src_data) is not np.ndarray and type(src_data) is not list:
-                print ('VRT file ! The data source should be composed of several data. A list minimal of 2 dimensions')
-                sys.exit(1)
-                
-            print ('Build VRT file')
-            if not os.path.exists(dst_data):
-                process_tocall = ['gdalbuildvrt', '-srcnodata', '-10000', dst_data]
-                
-            # Copy rasters
-            for cp_image in src_data:
-                process_tocall.append(cp_image)
-                
-        elif vrt_translate == 'translate':
-            # Verify input data
-            try :
-                src_data = str(src_data)
-            except:# if type(src_data) is not str:
-                print ('Geotiff file ! The data source should be composed of path file. A character string !')
-                sys.exit(1)
-                
-            print ('Build Geotiff file')
-            if not os.path.exists(dst_data):
-                process_tocall = ['gdal_translate', '-a_nodata', '-10000', src_data, dst_data]
-            
-        # Launch vrt process
-        subprocess.call(process_tocall)
-        
-    def mosaic_by_date(self):
-        """
-        Function to merge images of the same date in a image group :func:`group_by_date`.
-        """
-        
-        # Create the processing images folder if not exists
-        if not os.path.exists(self._class_archive._folder + '/' + self._big_folder):
-            os.mkdir(self._class_archive._folder + '/' + self._big_folder)
-            
-        # Matrix multi images for a single date 
-        group = self.group_by_date(self._one_date) # Every images [year, month, day, multispectral image, cloud image]
-        group_ = np.transpose(np.array(group)) # Transpose matrix to extract path of images
-        
-        # Create a folder with images year if it doesn't exist
-        index_repertory_img = self._class_archive._captor
-        if not os.path.exists(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img):
-            os.mkdir(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img)
-        
-        index_repertory_img = index_repertory_img + '/'
-        # Create a folder with images date if it doesn't exist
-        for d_ in self._one_date:
-            index_repertory_img = index_repertory_img + d_
-        
-        if not os.path.exists(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img):
-            os.mkdir(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img)
-        
-        # Build VRT file with data images required
-        vrt_out = self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img + '/' \
-                    + self._class_archive._captor + index_repertory_img.split("/")[1] + '.VRT' # Multispectral VRT outfile
-        if not os.path.exists(vrt_out):
-            self.vrt_translate_gdal('vrt', group_[3], vrt_out)
-        
-        vrtcloud_out = self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img + '/' \
-                    + self._class_archive._captor + index_repertory_img.split("/")[1] + '_' + group_[4][0][-7:-4] + '.VRT' # Cloud TIF outfile
-        if not os.path.exists(vrtcloud_out):
-            self.vrt_translate_gdal('vrt', group_[4], vrtcloud_out)
-        
-        # Build Geotiff file with data images required
-        gtif_out = vrt_out[:-4] + '.TIF' # Multispectral VRT outfile
-        if not os.path.exists(gtif_out):
-            self.vrt_translate_gdal('translate', vrt_out, gtif_out)
-        self._one_date.append(gtif_out)
-        
-        gtifcloud_out = vrtcloud_out[:-4] + '.TIF' # Cloud TIF outfile
-        if not os.path.exists(gtifcloud_out):
-            self.vrt_translate_gdal('translate', vrtcloud_out, gtifcloud_out)
-        self._one_date.append(gtifcloud_out)
-    
-    def raster_data(self, img):
-        """
-        Function to extract raster information.
-        Return table of pixel values and raster information like line number, pixel size, ... (gdal pointer)
-        
-        :param img: Raster path
-        :type img: str
+	"""
+	Satellite image  processing's class. This class include several processes to group images by date, mosaic images by date,
+	extract images information, compute ndvi, compute cloud pourcent and create new rasters.
+	
+	:param class_archive: Archive class name with every information on downloaded images
+	:type class_archive: class
+	:param big_folder: Image processing folder
+	:type big_folder: str
+	:param one_date: [year, month, day] ...
+			This variable is modified in the function :func:`mosaic_by_date()`. 
+			To append mosaic image path, mosaic cloud image path, cloud pixel value table, mosaic ndvi image path and ndvi pixel value table.
+	:type one_date: list of str
+	:param choice_nb_b: A option to choice output image number of band :func:`layer_rasterization` in Vector's class. If this option is 0, it take input band. By default 0.
+	:type choice_nb_b: int
+	
+	"""  
+	def __init__(self, class_archive, big_folder, one_date):
+		"""Create a new 'Landsat_by_date' instance
+		
+		"""
+		
+		self._class_archive = class_archive
+		self._big_folder = big_folder
+		self._one_date = one_date		
+		# Verify list of list of str
+		if one_date == []:
+			print ("Enter dates to mosaic images like [[str(year), str(month), str(day)], [str(year), str(month), str(day)], ...]")
+			sys.exit(1)
+		else:
+			self._one_date = one_date
+		
+		self.out_ds = None
+		self.choice_nb_b = 0
+		   
+	def group_by_date(self, d_uni):
+		"""
+		Function to extract images on a single date
+		
+		:param d_uni: [year, month, day]
+		:type d_uni: list of str
+		
+		:returns: list of str -- variable **group** = [year, month, day, multispectral image path, cloud image path]
+		"""
+		 
+		# Group of images with the same date
+		group = []
+		 
+		# Take images with the same date
+		for d_dup in self._class_archive.list_img:
+			if d_dup[:3] == d_uni:
+				group.append(d_dup)
+		 
+		return group
+	
+	def vrt_translate_gdal(self, vrt_translate, src_data, dst_data):
+		"""
+		Function to launch gdal tools in command line. With ``gdalbuildvrt`` and ``gdal_translate``.
+		This function is used :func:`mosaic_by_date` to mosaic image by date.
+		
+		:param vrt_translate: ``vrt`` or ``translate``
+		:type vrt_translate: str
+		:param src_data: Data source. Several data for vrt process and one data (vrt data) for gdal_translate
+		:type src_data: list (process ``vrt``) or str (process ``translate``)  
+		:param dst_data: Output path
+		:type dst_data: str
+		"""
+		
+		if os.path.exists(dst_data):
+			os.remove(dst_data)
+		
+		# Select process
+		if vrt_translate == 'vrt':
+			# Verify input data
+			if type(src_data) is not np.ndarray and type(src_data) is not list:
+				print ('VRT file ! The data source should be composed of several data. A list minimal of 2 dimensions')
+				sys.exit(1)
+				
+			print ('Build VRT file')
+			if not os.path.exists(dst_data):
+				process_tocall = ['gdalbuildvrt', '-srcnodata', '-10000', dst_data]
+				
+			# Copy rasters
+			for cp_image in src_data:
+				process_tocall.append(cp_image)
+				
+		elif vrt_translate == 'translate':
+			# Verify input data
+			try :
+				src_data = str(src_data)
+			except:# if type(src_data) is not str:
+				print ('Geotiff file ! The data source should be composed of path file. A character string !')
+				sys.exit(1)
+				
+			print ('Build Geotiff file')
+			if not os.path.exists(dst_data):
+				process_tocall = ['gdal_translate', '-a_nodata', '-10000', src_data, dst_data]
+			
+		# Launch vrt process
+		subprocess.call(process_tocall)
+		
+	def mosaic_by_date(self):
+		"""
+		Function to merge images of the same date in a image group :func:`group_by_date`.
+		"""
+		
+		# Create the processing images folder if not exists
+		if not os.path.exists(self._class_archive._folder + '/' + self._big_folder):
+			os.mkdir(self._class_archive._folder + '/' + self._big_folder)
+			
+		# Matrix multi images for a single date 
+		group = self.group_by_date(self._one_date) # Every images [year, month, day, multispectral image, cloud image]
+		group_ = np.transpose(np.array(group)) # Transpose matrix to extract path of images
+		
+		# Create a folder with images year if it doesn't exist
+		index_repertory_img = self._class_archive._captor
+		if not os.path.exists(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img):
+			os.mkdir(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img)
+		
+		index_repertory_img = index_repertory_img + '/'
+		# Create a folder with images date if it doesn't exist
+		for d_ in self._one_date:
+			index_repertory_img = index_repertory_img + d_
+		
+		if not os.path.exists(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img):
+			os.mkdir(self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img)
+		
+		# Build VRT file with data images required
+		vrt_out = self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img + '/' \
+					+ self._class_archive._captor + index_repertory_img.split("/")[1] + '.VRT' # Multispectral VRT outfile
+		if not os.path.exists(vrt_out):
+			self.vrt_translate_gdal('vrt', group_[3], vrt_out)
+		
+		vrtcloud_out = self._class_archive._folder + '/' + self._big_folder + '/' + index_repertory_img + '/' \
+					+ self._class_archive._captor + index_repertory_img.split("/")[1] + '_' + group_[4][0][-7:-4] + '.VRT' # Cloud TIF outfile
+		if not os.path.exists(vrtcloud_out):
+			self.vrt_translate_gdal('vrt', group_[4], vrtcloud_out)
+		
+		# Build Geotiff file with data images required
+		gtif_out = vrt_out[:-4] + '.TIF' # Multispectral VRT outfile
+		if not os.path.exists(gtif_out):
+			self.vrt_translate_gdal('translate', vrt_out, gtif_out)
+		self._one_date.append(gtif_out)
+		
+		gtifcloud_out = vrtcloud_out[:-4] + '.TIF' # Cloud TIF outfile
+		if not os.path.exists(gtifcloud_out):
+			self.vrt_translate_gdal('translate', vrtcloud_out, gtifcloud_out)
+		self._one_date.append(gtifcloud_out)
+	
+	def raster_data(self, img):
+		"""
+		Function to extract raster information.
+		Return table of pixel values and raster information like line number, pixel size, ... (gdal pointer)
+		
+		:param img: Raster path
+		:type img: str
 
-        :returns: numpy.array -- variable **data**, Pixel value matrix of a raster.
-                  
-                  gdal pointer -- variable **_in_ds**, Raster information.
-        """
-        
-        # Load Gdal's drivers
-        gdal.AllRegister()
-        
-        # Loading input raster
-        print ('Loading input raster :', os.path.split(str(img))[1][:-4])
-        in_ds = gdal.Open(str(img), gdal.GA_ReadOnly)
-        
-        # if it doesn't exist
-        if in_ds is None:
-            print('could not open ')
-            sys.exit(1)
-        
-        # Information on the input raster 
-        if self.choice_nb_b == 0:
-            nbband = in_ds.RasterCount # Spectral band number
-        else:
-            nbband = self.choice_nb_b
-        rows = in_ds.RasterYSize # Rows number
-        cols = in_ds.RasterXSize # Columns number
-        
-        # Table's declaration 
-        data = [] # np.float32([[0]*cols for i in xrange(rows)])
-        for band in range(nbband):
-            
-            canal = in_ds.GetRasterBand(band + 1) # Select a band
-            if nbband == 1:
-                data = canal.ReadAsArray(0, 0, cols, rows).astype(np.float32) # Assign pixel values at the data
-            else:
-                data.append(canal.ReadAsArray(0, 0, cols, rows).astype(np.float32))
-#             print('Copie des pixels du raster ! Bande :',  (band + 1))
-        
-        ###################################
-        # Close input raster
-        _in_ds = in_ds
-        in_ds = None
-        
-        return data, _in_ds
-    
-    def pourc_cloud(self, img_spec, img_cloud):
-        """
-        Return clear pixel percentage on the image **img_spec** because of a cloud image **img_cloud**.
-        
-        :param img_spec: Spectral image path
-        :type img_spec: str
-        :param img_cloud: Cloud image path
-        :type img_cloud: str
-        
-        :returns: float -- variable **nb0**, clear pixel percentage.
-        :Example:
-        
-        >>> import RasterSat_by_date
-        >>> Landsat_test = RasterSat_by_date(class_archive, big_folder, one_date)
-        >>> nb0_test = Landsat_test.pourc_cloud(Landsat_test._one_date[3], Landsat_test._one_date[4])
-        >>> nb0_test
-        98
-        """
-        
-        # Extract raster's information
-        data_spec, info_spec = self.raster_data(img_spec)
-        data_cloud, info_cloud = self.raster_data(img_cloud)
-        self._one_date.append(data_cloud) # Add cloud pixel value table
-        
-        # Extent of the images
-        mask_spec = np.in1d(data_spec[0], [-10000, math.isnan], invert=True) # ex : array([ True,  True,  True,  True, False,  True,  True,  True,  True], dtype=bool) -> False where there is -10000 ou NaN
-        
-        # Print area account of the pixel size 'info_spec.GetGeoTransform()'
-        print ('Area = ' + str(float((np.sum(mask_spec)  * info_spec.GetGeoTransform()[1] * abs(info_spec.GetGeoTransform()[-1]) )/10000)) + 'ha' )
-        
-        # Cloud mask
-        mask_cloud = np.in1d(data_cloud, 0) # This is the same opposite False where there is 0
-        cloud = np.choose(mask_cloud, (False, mask_spec)) # If True in cloud mask, it take spectral image else False
-        dist = np.sum(cloud) # Sum of True. True is cloud
-        
-        # Computer cloud's percentage with dist (sum of cloud) by sum of the image's extent
-        try :
-            nb0 = float(dist)/(np.sum(mask_spec))
-            print('For ' + os.path.split(str(img_spec))[1][:-4] + ', cloudy cover ' + str(100 - round(nb0*100, 2)) + "%")
-        except ZeroDivisionError:
-            nb0 = 0
-            print("The raster isn\'t in the area !")
-        
-        return nb0
-    
-    def calcul_ndvi(self, img_spec):
-        """
-        Computer NDVI index for a Landsat image.
-        
-        NDVI = band4 - band3 / band4 + band3 with nb_captor = 0
-        
-        or for Sentinel 2 image (2A) : NDVI = band3 - band2 / band3 + band2 with nb_captor = -1
-        
-        :param img_spec: Spectral image path
-        :type img_spec: str
+		:returns: numpy.array -- variable **data**, Pixel value matrix of a raster.
+				  
+				  gdal pointer -- variable **_in_ds**, Raster information.
+		"""
+		
+		# Load Gdal's drivers
+		gdal.AllRegister()
+		
+		# Loading input raster
+		print ('Loading input raster :', os.path.split(str(img))[1][:-4])
+		in_ds = gdal.Open(str(img), gdal.GA_ReadOnly)
+		
+		# if it doesn't exist
+		if in_ds is None:
+			print('could not open ')
+			sys.exit(1)
+		
+		# Information on the input raster 
+		if self.choice_nb_b == 0:
+			nbband = in_ds.RasterCount # Spectral band number
+		else:
+			nbband = self.choice_nb_b
+		rows = in_ds.RasterYSize # Rows number
+		cols = in_ds.RasterXSize # Columns number
+		
+		# Table's declaration 
+		data = [] # np.float32([[0]*cols for i in xrange(rows)])
+		for band in range(nbband):
+			
+			canal = in_ds.GetRasterBand(band + 1) # Select a band
+			if nbband == 1:
+				data = canal.ReadAsArray(0, 0, cols, rows).astype(np.float32) # Assign pixel values at the data
+			else:
+				data.append(canal.ReadAsArray(0, 0, cols, rows).astype(np.float32))
+#			 print('Copie des pixels du raster ! Bande :',  (band + 1))
+		
+		###################################
+		# Close input raster
+		_in_ds = in_ds
+		in_ds = None
+		
+		return data, _in_ds
+	
+	def pourc_cloud(self, img_spec, img_cloud):
+		"""
+		Return clear pixel percentage on the image **img_spec** because of a cloud image **img_cloud**.
+		
+		:param img_spec: Spectral image path
+		:type img_spec: str
+		:param img_cloud: Cloud image path
+		:type img_cloud: str
+		
+		:returns: float -- variable **nb0**, clear pixel percentage.
+		:Example:
+		
+		>>> import RasterSat_by_date
+		>>> Landsat_test = RasterSat_by_date(class_archive, big_folder, one_date)
+		>>> nb0_test = Landsat_test.pourc_cloud(Landsat_test._one_date[3], Landsat_test._one_date[4])
+		>>> nb0_test
+		98
+		"""
+		
+		# Extract raster's information
+		data_spec, info_spec = self.raster_data(img_spec)
+		data_cloud, info_cloud = self.raster_data(img_cloud)
+		self._one_date.append(data_cloud) # Add cloud pixel value table
+		
+		# Extent of the images
+		mask_spec = np.in1d(data_spec[0], [-10000, math.isnan], invert=True) # ex : array([ True,  True,  True,  True, False,  True,  True,  True,  True], dtype=bool) -> False where there is -10000 ou NaN
+		
+		# Print area account of the pixel size 'info_spec.GetGeoTransform()'
+		print ('Area = ' + str(float((np.sum(mask_spec)  * info_spec.GetGeoTransform()[1] * abs(info_spec.GetGeoTransform()[-1]) )/10000)) + 'ha' )
+		
+		# Cloud mask
+		mask_cloud = np.in1d(data_cloud, 0) # This is the same opposite False where there is 0
+		cloud = np.choose(mask_cloud, (False, mask_spec)) # If True in cloud mask, it take spectral image else False
+		dist = np.sum(cloud) # Sum of True. True is cloud
+		
+		# Computer cloud's percentage with dist (sum of cloud) by sum of the image's extent
+		try :
+			nb0 = float(dist)/(np.sum(mask_spec))
+			print('For ' + os.path.split(str(img_spec))[1][:-4] + ', cloudy cover ' + str(100 - round(nb0*100, 2)) + "%")
+		except ZeroDivisionError:
+			nb0 = 0
+			print("The raster isn\'t in the area !")
+		
+		return nb0
+	
+	def calcul_ndvi(self, img_spec):
+		"""
+		Computer NDVI index for a Landsat image.
+		
+		NDVI = (band4 - band3) / (band4 + band3) with nb_captor = 0
+		
+		or for Sentinel 2 image (2A) : NDVI = band3 - band2 / band3 + band2 with nb_captor = -1
+		
+		:param img_spec: Spectral image path
+		:type img_spec: str
 
-        """
-        
-        # NDVI formula index for 2 captor (L8 or S2A Theia)
-        if self._class_archive._captor == 'SENTINEL2':
-            n_captor = -1
-        else :
-            n_captor = 0
-        
-        # Extract raster's information
-        data, in_ds = self.raster_data(img_spec)
-        
-        # Computer NDVI
-        mask = np.greater(data[0], -10000)
-        ndvi = np.choose(mask, (-10000, eval('(data[4+n_captor]-data[3+n_captor])') / eval('(data[4+n_captor]+data[3+n_captor])'))) # If True, -10000 (NaN) else compute mathematical operation
-        
-        # Outfile name
-        img_ndvi = img_spec[:-4] + '_ndvi.TIF'
-        self._one_date.append(img_ndvi) # Add ndvi image path
-        self._one_date.append(ndvi) # Add ndvi pixel value table
-        self.create_raster(img_ndvi, ndvi, in_ds)
-        
-    def create_raster(self, out_raster, data, in_ds):
-        """
-        Create a raster empty with the input raster property
-        
-        :param out_raster: Output image path
-        :type out_raster: str
-        :param data: Pixel value matrix. Matrix size equal to that of a raster.
-        :type data: numpy.array
-        :param in_ds: Raster information
-        :type in_ds: gdal pointer
-        
-        :returns: gdal pointer -- variable **out_ds**, Raster out information.
-                  
-                  int -- variable **nbband**, Band number of the out layer. 
-                  
-                  int -- variable **e**, Index to know if the raster exists. If it doesn't exists e = 0 else e = 1 (by default).
-        """
-        
-#         if os.path.exists(str(out_raster)):
-#             os.remove(str(out_raster))
-        e = 1 # Raster out exists by default 
-        # Verify if the processing take input band or one spectral band    
-        if data.ndim == 2 or self.choice_nb_b == 1:
-            nbband = 1
-        else:
-            nbband = in_ds.RasterCount 
-            
-        driver = gdal.GetDriverByName('GTiff')  
-        if not os.path.exists(str(out_raster)):
-            e = 0    
-            # Create outfile
-            self.out_ds = driver.Create(str(out_raster), in_ds.RasterXSize, in_ds.RasterYSize, nbband, gdal.GDT_Float32)
-            if self.out_ds is None:
-                print ('Could not create ' + os.path.split(str(out_raster))[1])
-                sys.exit(1)
-                
-            # Get extent coordinates and raster resolution
-            transform = in_ds.GetGeoTransform()
-            # print transform
-            
-            minX = transform[0]
-            maxY = transform[3]
-            pixelWidth = transform[1]
-            pixelHeight = transform[5]
-            
-            geotransform = [minX, pixelWidth, 0, maxY, 0, pixelHeight]
-            
-            # Record projection
-            def_projection = in_ds.GetProjection() 
+		"""
+		
+		# NDVI formula index for 2 captor (L8 or S2A Theia)
+		if self._class_archive._captor == 'SENTINEL2':
+			n_captor = -1
+		else :
+			n_captor = 0
+		
+		# Extract raster's information
+		data, in_ds = self.raster_data(img_spec)
+		
+		# Computer NDVI
+		mask = np.greater(data[0], -10000)
+		ndvi = np.choose(mask, (-10000, eval('(data[4+n_captor]-data[3+n_captor])') / eval('(data[4+n_captor]+data[3+n_captor])'))) # If True, -10000 (NaN) else compute mathematical operation
+		
+		# Outfile name
+		img_ndvi = img_spec[:-4] + '_ndvi.TIF'
+		self._one_date.append(img_ndvi) # Add ndvi image path
+		self._one_date.append(ndvi) # Add ndvi pixel value table
+		self.create_raster(img_ndvi, ndvi, in_ds)
+		
+	def create_raster(self, out_raster, data, in_ds):
+		"""
+		Create a raster empty with the input raster property
+		
+		:param out_raster: Output image path
+		:type out_raster: str
+		:param data: Pixel value matrix. Matrix size equal to that of a raster.
+		:type data: numpy.array
+		:param in_ds: Raster information
+		:type in_ds: gdal pointer
+		
+		:returns: gdal pointer -- variable **out_ds**, Raster out information.
+				  
+				  int -- variable **nbband**, Band number of the out layer. 
+				  
+				  int -- variable **e**, Index to know if the raster exists. If it doesn't exists e = 0 else e = 1 (by default).
+		"""
+		
+#		 if os.path.exists(str(out_raster)):
+#			 os.remove(str(out_raster))
+		e = 1 # Raster out exists by default 
+		# Verify if the processing take input band or one spectral band	
+		if data.ndim == 2 or self.choice_nb_b == 1:
+			nbband = 1
+		else:
+			nbband = in_ds.RasterCount 
+			
+		driver = gdal.GetDriverByName('GTiff')  
+		if not os.path.exists(str(out_raster)):
+			e = 0	
+			# Create outfile
+			self.out_ds = driver.Create(str(out_raster), in_ds.RasterXSize, in_ds.RasterYSize, nbband, gdal.GDT_Float32)
+			if self.out_ds is None:
+				print ('Could not create ' + os.path.split(str(out_raster))[1])
+				sys.exit(1)
+				
+			# Get extent coordinates and raster resolution
+			transform = in_ds.GetGeoTransform()
+			# print transform
+			
+			minX = transform[0]
+			maxY = transform[3]
+			pixelWidth = transform[1]
+			pixelHeight = transform[5]
+			
+			geotransform = [minX, pixelWidth, 0, maxY, 0, pixelHeight]
+			
+			# Record projection
+			def_projection = in_ds.GetProjection() 
 
-            # Set the geo-traking and outfile projection
-            self.out_ds.SetGeoTransform(geotransform)
-            self.out_ds.SetProjection(def_projection)
-        
-        else:
-            
-            self.out_ds = gdal.Open(str(out_raster), gdal.GA_ReadOnly)
-            
-        return nbband, e
-    
-    def complete_raster(self, nbband, e, data): 
-        """
-        This function complete the function above :func:`create_raster()`. It 
-        fills the raster table and close the layer.
-        
-        :param out_ds: Raster out information
-        :type out_ds: gdal pointer
-        :param nbband: Band number of the out layer
-        :type nbband: int
-        :param e: Index to know if the raster existed. If it didn't exist e = 0.
-        :type e: int
-        :param data: Pixel value matrix. Matrix size equal to that of a raster.
-        :type data: numpy.array
-        """
-        
-        # The e index to verify if the layer existed already because of the 
-        # function :func:`create_raster()`
-        if e == 0 :   
-            p = 0 # Increment for the number band
-            while p < nbband:
-                #Incrementation
-                p = p + 1
-            
-                print ("Copy on the band ", p)
-      
-                # Loading spectral band of outfile
-                out_band = self.out_ds.GetRasterBand(p) 
-                # write the data
-                if data.ndim == 2:
-                    out_band.WriteArray(data, 0, 0)
-                else:
-                    out_band.WriteArray(data[p-1], 0, 0)
-                
-                # Closing and statistics on output raster
-                out_band.FlushCache()
-                out_band.SetNoDataValue(-10000)
-                out_band.GetStatistics(-1, 1) 
-                out_band = None    
-            
-        # Close open data
-        self.out_ds = None
+			# Set the geo-traking and outfile projection
+			self.out_ds.SetGeoTransform(geotransform)
+			self.out_ds.SetProjection(def_projection)
+		
+		else:
+			
+			self.out_ds = gdal.Open(str(out_raster), gdal.GA_ReadOnly)
+			
+		return nbband, e
+	
+	def complete_raster(self, nbband, e, data): 
+		"""
+		  This function complete the function above :func:`create_raster()`. It 
+		  fills the raster table and close the layer.
+		
+		  :param out_ds: Raster out information
+		  :type out_ds: gdal pointer
+		  :param nbband: Band number of the out layer
+		  :type nbband: int
+		  :param e: Index to know if the raster existed. If it didn't exist e = 0.
+		  :type e: int
+		  :param data: Pixel value matrix. Matrix size equal to that of a raster.
+		  :type data: numpy.array
+		"""
+		
+		# The e index to verify if the layer existed already because of the 
+		# function :func:`create_raster()`
+		if e == 0 :   
+			p = 0 # Increment for the number band
+			while p < nbband:
+				#Incrementation
+				p = p + 1
+			
+				print ("Copy on the band ", p)
+	  
+				# Loading spectral band of outfile
+				out_band = self.out_ds.GetRasterBand(p) 
+				# write the data
+				if data.ndim == 2:
+					out_band.WriteArray(data, 0, 0)
+				else:
+					out_band.WriteArray(data[p-1], 0, 0)
+				
+				# Closing and statistics on output raster
+				out_band.FlushCache()
+				out_band.SetNoDataValue(-10000)
+				out_band.GetStatistics(-1, 1) 
+				out_band = None	
+			
+		# Close open data
+		self.out_ds = None
 
-            
\ No newline at end of file
+			
\ No newline at end of file
diff --git a/Rpg.py b/Rpg.py
index 580f1ec306249411b1f4e92ab1d3485111be6ffb..18c722c92d8e1d523826012528c0a145067339f8 100644
--- a/Rpg.py
+++ b/Rpg.py
@@ -150,7 +150,7 @@ class Rpg(Vector):
                 self.head_in_read.append(y)
             else:
                 self.head_in_read.append(y[:10])
-        body_in_read = map(list, zip(*in_read[1:])) # Transpose table [[e,e,e],[a,a,a]] -> [[e,a],[e,a],[e,a]]
+        body_in_read = list(map(list, zip(*in_read[1:]))) # Transpose table [[e,e,e],[a,a,a]] -> [[e,a],[e,a],[e,a]]
         
 #         self.rm_dupli = [[x, body_in_read[1][body_in_read[0].index(x)], body_in_read[2][body_in_read[0].index(x)]] \
 #                                 for x in body_in_read[0] if body_in_read[0].count(x) == 1]
diff --git a/Sample.py b/Sample.py
index 9b5409dad2722a4258e6d89ae4380c50de41a3c3..91ed7bc595b74c684b89ff2f7c8ffe215dca486a 100644
--- a/Sample.py
+++ b/Sample.py
@@ -22,195 +22,194 @@ import random
 import numpy as np
 from Vector import Vector
 try :
-    import ogr
+	import ogr
 except :
-    from osgeo import ogr
+	from osgeo import ogr
 
 class Sample(Vector):
-    
-    """
-    Vector class inherits the super vector class properties. This class create training sample.
-    
-    :param vector_used: Input/Output shapefile to clip (path)
-    :type vector_used: str
-    :param vector_cut: Area shapefile (path)
-    :type vector_cut: str
-    :param nb_sample: Number of polygons for every sample
-    :type nb_sample: int
-    :param vector_val: Output shapefile to validate the futur classification
-    :type vector_val: str
-    
-    :opt: Refer to the Vector class
-    """
-    
-    def __init__(self, used, cut, nb_sample, **opt):
-        """Create a new 'Sample' instance
-               
-        """
-        Vector.__init__(self, used, cut, **opt)
-        
-        self._nb_sample = nb_sample
-        self.vector_val = ''
-    
-    def create_sample(self, **kwargs):
-        """
-        Function to create a sample shapefile of a specific class
-        
-        :kwargs: **fieldname** (list of str) - Fieldname in the input shapefile (if the user want select polygons of the class names specific)
-                
-                **class** (list of str) - class names in the input shapefile (with fieldname index).
-                Can use one or several classes like this --> example : [classname1, classname2, ...]
-        """
-        
-        kw_field = kwargs['fieldname'] if kwargs.get('fieldname') else ''
-        kw_classes = kwargs['class'] if kwargs.get('class') else ''
-        
-        # If the users want select polygons with a certain class name
-        if kw_field and kw_classes:
-            # The random sample with class name selected only
-            random_sample = np.array(random.sample(self.select_random_sample(kw_field, kw_classes), int(self._nb_sample)))
-        else:
-            # The random sample without class name selected
-            random_sample = np.array(random.sample(range(self.data_source.GetLayer().GetFeatureCount()), self._nb_sample))
-            
-        # Output shapefile of the sample's polygons (path)
-        self.vector_used = self.vector_used[:-4] + '_' + kw_classes.replace(',','').replace(' ','') + 'rd.shp'
-        # Fill and create the sample shapefile
-        self.fill_sample(self.vector_used, random_sample[:len(random_sample)/2])
-        # Output shapefile of the validate polygon (path)
-        self.vector_val = self.vector_used[:-6] + 'val.shp'
-        # Fill and create the validate polygons shapefile
-        self.fill_sample(self.vector_val, random_sample[len(random_sample)/2:])
-       
-    def select_random_sample(self, kw_field, kw_classes):        
-        """
-        Function to select id with class name specific only. This function is used in :func:`create_sample`
+	
+	"""
+		Vector class inherits the super vector class properties. This class create training sample.
+	
+		:param vector_used: Input/Output shapefile to clip (path)
+		:type vector_used: str
+		:param vector_cut: Area shapefile (path)
+		:type vector_cut: str
+		:param nb_sample: Number of polygons for every sample
+		:type nb_sample: int
+		:param vector_val: Output shapefile to validate the futur classification
+		:type vector_val: str
+	
+		:opt: Refer to the Vector class
+	"""
+	
+	def __init__(self, used, cut, nb_sample, **opt):
+		"""
+			Create a new 'Sample' instance   
+		"""
+		Vector.__init__(self, used, cut, **opt)
+		
+		self._nb_sample = nb_sample
+		self.vector_val = ''
+	
+	def create_sample(self, **kwargs):
+		"""
+			Function to create a sample shapefile of a specific class
+		
+			:kwargs: **fieldname** (list of str) - Fieldname in the input shapefile (if the user want select polygons of the class names specific)
+				
+			**class** (list of str) - class names in the input shapefile (with fieldname index).
+			Can use one or several classes like this --> example : [classname1, classname2, ...]
+		"""
+		
+		kw_field = kwargs['fieldname'] if kwargs.get('fieldname') else ''
+		kw_classes = kwargs['class'] if kwargs.get('class') else ''
+		
+		# If the users want select polygons with a certain class name
+		if kw_field and kw_classes:
+			# The random sample with class name selected only
+			random_sample = np.array(random.sample(self.select_random_sample(kw_field, kw_classes), int(self._nb_sample)))
+		else:
+			# The random sample without class name selected
+			random_sample = np.array(random.sample(range(self.data_source.GetLayer().GetFeatureCount()), self._nb_sample))
+			
+		# Output shapefile of the sample's polygons (path)
+		self.vector_used = self.vector_used[:-4] + '_' + kw_classes.replace(',','').replace(' ','') + 'rd.shp'
+		# Fill and create the sample shapefile
+		self.fill_sample(self.vector_used, random_sample[:round(len(random_sample)/2)])
+		# Output shapefile of the validate polygon (path)
+		self.vector_val = self.vector_used[:-6] + 'val.shp'
+		# Fill and create the validate polygons shapefile
+		self.fill_sample(self.vector_val, random_sample[round(len(random_sample)/2):])
 
-        :param kw_field: Field name in the input shapefile
-        :type kw_field: str
-        :param kw_classes: Class names in the input shapefile like this --> 'classname1, classname2'
-        :type kw_classes: str
-        :returns: list -- variable **select_id**, List of id with a class name specific.
-        """
-        
-        # Convert string in a list. For that, it remove
-        # space and clip this string with comma (Add everywhere if the script modified
-        # because the process work with a input string chain)
-        kw_classes = kw_classes.replace(' ','').split(',')
-        
-        # List of class name id
-        select_id = []
-         
-        shp_ogr = self.data_source.GetLayer()
-        
-        # Loop on input polygons
-        in_feature = shp_ogr.SetNextByIndex(0) # Initialization
-        in_feature = shp_ogr.GetNextFeature()
-        while in_feature:
-            
-            # if polygon is a defined class name 
-            ## .replace('0','') to remove '0' in front of for example '1' (RPG -> '01')
-            table_name_class = in_feature.GetField(self.field_names[self.field_names.index(kw_field)])
-            # To avoid that the process crashed this part of the algorithm will be launch if the field is contains characters
-            if table_name_class != None :
-                if in_feature.GetField(self.field_names[self.field_names.index(kw_field)]).replace('0','') in kw_classes:
-                    
-                    # Add id in the extract list
-                    select_id.append(in_feature.GetFID())
-    
-                    in_feature.Destroy()
-                       
-            in_feature = shp_ogr.GetNextFeature()
-        return select_id
-    
-    def fill_sample(self, output_sample, polygon, **opt):
-        
-        """
-        Function to fill and create the output sample shapefile. This function is used in :func:`create_sample`
-        to create samples polygons and validated polygons (to the take out the precision of the classification)
+	def select_random_sample(self, kw_field, kw_classes):		
+		"""
+			Function to select id with class name specific only. This function is used in :func:`create_sample`
 
-        :param output_sample: Path of the output shapefile
-        :type output_sample: str
-        :param polygon: Identity of the selected random polygons. If this variable = 0, the processing will take all polygons 
-        :type polygon: list or int      
-        
-        :opt: **add_fieldname** (int) - Variable to kown if add a field. By default non (0), if it have to add (1)
-        
-                **fieldname** (str) - Fieldname to add in the input shapefile
-                
-                **class** (int) - class names in integer to add in the input shapefile
-        """
-        
-        # In option to add a integer field
-        add_field = opt['add_fieldname'] if opt.get('add_fieldname') else 0
-        opt_field = opt['fieldname'] if opt.get('fieldname') else ''
-        opt_class = opt['class'] if opt.get('class') else 0
-        
-        shp_ogr = self.data_source.GetLayer()
-        
-        # To take all polygon
-        if type(polygon) == int:
-            polygon = range(shp_ogr.GetFeatureCount())
-        
-        # Projection
-        # Import input shapefile projection
-        srsObj = shp_ogr.GetSpatialRef()
-        # Conversion to syntax ESRI
-        srsObj.MorphToESRI() 
-               
-        ## Remove the output shapefile if it exists
-        if os.path.exists(output_sample):
-            self.data_source.GetDriver().DeleteDataSource(output_sample)
-        out_ds = self.data_source.GetDriver().CreateDataSource(output_sample)
-        
-        if out_ds is None:
-            print('Could not create file')
-            sys.exit(1)
-            
-        #  Specific output layer
-        out_layer = out_ds.CreateLayer(str(output_sample), srsObj, geom_type=ogr.wkbMultiPolygon)
-        
-        # Add existing fields 
-        for i in range(0, len(self.field_names)):
-            # use the input FieldDefn to add a field to the output
-            fieldDefn = shp_ogr.GetFeature(0).GetFieldDefnRef(self.field_names[i])
-            out_layer.CreateField(fieldDefn)
-            
-        # In Option : Add a integer field
-        if add_field == 1:
-            new_field = ogr.FieldDefn(opt_field, 0)
-            out_layer.CreateField(new_field)
-        
-        # Feature for the ouput shapefile
-        featureDefn = out_layer.GetLayerDefn()
-        
-        # Loop on the input elements
-        # Create a existing polygons in random list    
-        for cnt in polygon:
-            
-            # Select input polygon by id
-            in_feature = shp_ogr.SetNextByIndex(cnt)
-            in_feature = shp_ogr.GetNextFeature()
-            
-            geom = in_feature.GetGeometryRef() # Extract input geometry
+			:param kw_field: Field name in the input shapefile
+			:type kw_field: str
+			:param kw_classes: Class names in the input shapefile like this --> 'classname1, classname2'
+			:type kw_classes: str
+			:returns: list -- variable **select_id**, List of id with a class name specific.
+		"""
+		
+		# Convert string in a list. For that, it remove
+		# space and clip this string with comma (Add everywhere if the script modified
+		# because the process work with a input string chain)
+		kw_classes = kw_classes.replace(' ','').split(',')
+		
+		# List of class name id
+		select_id = []
 
-            # Create a new polygon
-            out_feature = ogr.Feature(featureDefn)
+		shp_ogr = self.data_source.GetLayer()
 
-            # Set the polygon geometry and attribute
-            out_feature.SetGeometry(geom)
-            for i in range(0, len(self.field_names)):
-                out_feature.SetField(self.field_names[i], in_feature.GetField(self.field_names[i]))
-            # In Option : Add a integer field
-            if add_field == 1:
-                out_feature.SetField(opt_field, opt_class[0])
-                
-            # Append polygon to the output shapefile
-            out_layer.CreateFeature(out_feature)
-    
-            # Destroy polygons
-            out_feature.Destroy()    
-            in_feature.Destroy()
-            
-        # Close data
-        out_ds.Destroy()        
\ No newline at end of file
+		# Loop on input polygons
+		in_feature = shp_ogr.SetNextByIndex(0) # Initialization
+		in_feature = shp_ogr.GetNextFeature()
+		while in_feature:			
+			# if polygon is a defined class name 
+			## .replace('0','') to remove '0' in front of for example '1' (RPG -> '01')
+			table_name_class = in_feature.GetField(self.field_names[self.field_names.index(kw_field)])
+			# To avoid that the process crashed this part of the algorithm will be launch if the field is contains characters
+			if table_name_class != None :
+				if in_feature.GetField(self.field_names[self.field_names.index(kw_field)]).replace('0','') in kw_classes:
+					
+					# Add id in the extract list
+					select_id.append(in_feature.GetFID())
+	
+					in_feature.Destroy()
+					   
+			in_feature = shp_ogr.GetNextFeature()
+		return select_id
+	
+	def fill_sample(self, output_sample, polygon, **opt):
+		
+		"""
+			Function to fill and create the output sample shapefile. This function is used in :func:`create_sample`
+			to create samples polygons and validated polygons (to the take out the precision of the classification)
+
+			:param output_sample: Path of the output shapefile
+			:type output_sample: str
+			:param polygon: Identity of the selected random polygons. If this variable = 0, the processing will take all polygons 
+			:type polygon: list or int	  
+		
+			:opt: **add_fieldname** (int) - Variable to kown if add a field. By default non (0), if it have to add (1)
+		
+					**fieldname** (str) - Fieldname to add in the input shapefile
+				
+					**class** (int) - class names in integer to add in the input shapefile
+		"""
+		
+		# In option to add a integer field
+		add_field = opt['add_fieldname'] if opt.get('add_fieldname') else 0
+		opt_field = opt['fieldname'] if opt.get('fieldname') else ''
+		opt_class = opt['class'] if opt.get('class') else 0
+		
+		shp_ogr = self.data_source.GetLayer()
+		
+		# To take all polygon
+		if type(polygon) == int:
+			polygon = range(shp_ogr.GetFeatureCount())
+		
+		# Projection
+		# Import input shapefile projection
+		srsObj = shp_ogr.GetSpatialRef()
+		# Conversion to syntax ESRI
+		srsObj.MorphToESRI() 
+			   
+		## Remove the output shapefile if it exists
+		if os.path.exists(output_sample):
+			self.data_source.GetDriver().DeleteDataSource(output_sample)
+		out_ds = self.data_source.GetDriver().CreateDataSource(output_sample)
+		
+		if out_ds is None:
+			print('Could not create file')
+			sys.exit(1)
+			
+		#  Specific output layer
+		out_layer = out_ds.CreateLayer(str(output_sample), srsObj, geom_type=ogr.wkbMultiPolygon)
+		
+		# Add existing fields 
+		for i in range(0, len(self.field_names)):
+			# use the input FieldDefn to add a field to the output
+			fieldDefn = shp_ogr.GetFeature(0).GetFieldDefnRef(self.field_names[i])
+			out_layer.CreateField(fieldDefn)
+			
+		# In Option : Add a integer field
+		if add_field == 1:
+			new_field = ogr.FieldDefn(opt_field, 0)
+			out_layer.CreateField(new_field)
+		
+		# Feature for the ouput shapefile
+		featureDefn = out_layer.GetLayerDefn()
+		
+		# Loop on the input elements
+		# Create a existing polygons in random list	
+		for cnt in polygon:
+			
+			# Select input polygon by id
+			in_feature = shp_ogr.SetNextByIndex(cnt)
+			in_feature = shp_ogr.GetNextFeature()
+			
+			geom = in_feature.GetGeometryRef() # Extract input geometry
+
+			# Create a new polygon
+			out_feature = ogr.Feature(featureDefn)
+
+			# Set the polygon geometry and attribute
+			out_feature.SetGeometry(geom)
+			for i in range(0, len(self.field_names)):
+				out_feature.SetField(self.field_names[i], in_feature.GetField(self.field_names[i]))
+			# In Option : Add a integer field
+			if add_field == 1:
+				out_feature.SetField(opt_field, opt_class[0])
+				
+			# Append polygon to the output shapefile
+			out_layer.CreateFeature(out_feature)
+	
+			# Destroy polygons
+			out_feature.Destroy()	
+			in_feature.Destroy()
+			
+		# Close data
+		out_ds.Destroy()		
\ No newline at end of file
diff --git a/Satellites.py b/Satellites.py
new file mode 100644
index 0000000000000000000000000000000000000000..814082a83beba3b69af67512f979e330cafd51f6
--- /dev/null
+++ b/Satellites.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import collections
+
+SATELLITE = collections.defaultdict(dict)
+
+	# Info from Theia-land website or Olivier Hagolle blog
+
+########################## SENTINEL2 ###############################
+
+SATELLITE["SENTINEL2"]["server"] = "https://theia.cnes.fr/atdistrib"
+SATELLITE["SENTINEL2"]["resto"] = "resto2"
+SATELLITE["SENTINEL2"]["token_type"] = "text"
+
+########################## LANDSAT #################################
+
+SATELLITE["Landsat"]["server"] = "https://theia-landsat.cnes.fr"
+SATELLITE["Landsat"]["resto"] = "resto"
+SATELLITE["Landsat"]["token_type"] = "json"
+
+
+
diff --git a/Segmentation.py b/Segmentation.py
index 7e53b0768afaafcfaee54ecae1b6ceb836ceed10..18c3d8007a792f1e12ee6b0ed01fd754581d43d0 100644
--- a/Segmentation.py
+++ b/Segmentation.py
@@ -257,6 +257,7 @@ class Segmentation(Vector):
         :type method: str
         """
         
+        print("Calcul densité : ")
         if method == 'SEATH':
             distri = [v[1:] for k, v in self.stats_dict.items() if eval('v[0]' + self.out_threshold[1])]
             
@@ -268,6 +269,7 @@ class Segmentation(Vector):
                 else:
                     distri_den.append(b)
         elif method == 'RF':
+
             distri = [v[1:] for k, v in self.stats_dict.items() if not self.out_threshold[k] in [0,6,7]]
             
             distri_bio = []
@@ -280,21 +282,31 @@ class Segmentation(Vector):
 
             # Set this variable used normally to define threshold of the classification with SEATH method
             self.out_threshold = []
+
         # Transpose table        
         t_distri_bio = list(map(list, zip(*distri_bio)))
         t_distri_den = list(map(list, zip(*distri_den)))
-        
-        # Biomass threshold
-        stdmore =  (np.mean(t_distri_bio[2]) + np.std(t_distri_bio[2]))/np.max(t_distri_bio[2])
-        stdless =  (np.mean(t_distri_bio[2]) - np.std(t_distri_bio[2]))/np.max(t_distri_bio[2])
-        self.out_threshold.append('>'+str(stdmore))
-        self.out_threshold.append('')
-        self.out_threshold.append('<'+str(stdless))
-        
-        # Compute density and biomass maximum
-        self.max_wood_idm = np.max(t_distri_den[1])
-        self.max_wood_sfs = np.max(t_distri_den[0])
-        self.max_bio = np.max(t_distri_bio[2])
+       
+        try:
+            # Biomass threshold
+            stdmore =  (np.mean(t_distri_bio[2]) + np.std(t_distri_bio[2]))/np.max(t_distri_bio[2])
+            stdless =  (np.mean(t_distri_bio[2]) - np.std(t_distri_bio[2]))/np.max(t_distri_bio[2])
+            self.out_threshold.append('>'+str(stdmore))
+            self.out_threshold.append('')
+            self.out_threshold.append('<'+str(stdless))
+            
+        except Exception as e:
+            print("Bio : ", t_distri_bio)
+            print("Den : ", t_distri_den)
+
+        try:            
+            # Compute density and biomass maximum
+            self.max_wood_idm = np.max(t_distri_den[1])
+            self.max_wood_sfs = np.max(t_distri_den[0])
+            self.max_bio = np.max(t_distri_bio[2])
+        except Exception as e:
+            print(e)
+ 
         
     def append_scale(self, select_class, form):
         """
@@ -307,7 +319,7 @@ class Segmentation(Vector):
         :type form: str
         
         """
-        
+        print(self.max_wood_idm)
         for ind_stats in range(len(self.stats_dict)):
             # Only valid on the second level
             try:
diff --git a/Toolbox.py b/Toolbox.py
index 7f675bbb96e1473c1f26fd3560513be2f5c3b3ac..3ef37903cdfbce532851c822918fd7dd3700418f 100644
--- a/Toolbox.py
+++ b/Toolbox.py
@@ -24,30 +24,29 @@ import json
 
 class Toolbox():
     """
-    Class used to grouped small tools to cut raster or compute statistics on a raster. 
-        
-    :param imag: Input image (path)
-    :type imag: str
-    :param vect: Extent shapefile (path)
-    :type vect: str
+        Class used to grouped small tools to cut raster or compute statistics on a raster. 
+            
+        :param imag: Input image (path)
+        :type imag: str
+        :param vect: Extent shapefile (path)
+        :type vect: str
     """
     
     def __init__(self):
         """
-        Create a new 'Toolbox' instance
+            Create a new 'Toolbox' instance
         """
-        
         self.imag = ''
         self.vect = ''
     
     def clip_raster(self, **kwargs):
         """
-        Function to clip a raster with a vector. The raster created will be in the same folder than the input raster.
-        With a prefix *Clip_*.
-        
-        :kwargs: **rm_rast** (int) - 0 (by default) or 1. Variable to remove the output raster. 0 to keep and 1 to remove.
-        
-        :returns: str -- variable **outclip**, output raster clip (path).
+            Function to clip a raster with a vector. The raster created will be in the same folder than the input raster.
+            With a prefix *Clip_*.
+            
+            :kwargs: **rm_rast** (int) - 0 (by default) or 1. Variable to remove the output raster. 0 to keep and 1 to remove.
+            
+            :returns: str -- variable **outclip**, output raster clip (path).
         """    
         
         rm_rast = kwargs['rm_rast'] if kwargs.get('rm_rast') else 0
@@ -78,14 +77,14 @@ class Toolbox():
         
     def calc_serie_stats(self, table):
         """
-        Function to compute stats on temporal cloud and ndvi spectral table
-        Ndvi stats : min    max    std    max-min
-        
-        :param table: Spectral data, cloud raster and ndvi raster
-        :type table: numpy.ndarray
-        :returns: list of numpy.ndarray -- variable **account_stats**, list of temporal NDVI stats.
-                      
-                    numpy.ndarray -- variable **account_cloud**, pixel number clear on the area.
+            Function to compute stats on temporal cloud and ndvi spectral table
+            Ndvi stats : min    max    std    max-min
+            
+            :param table: Spectral data, cloud raster and ndvi raster
+            :type table: numpy.ndarray
+            :returns: list of numpy.ndarray -- variable **account_stats**, list of temporal NDVI stats.
+                          
+                        numpy.ndarray -- variable **account_cloud**, pixel number clear on the area.
         """ 
         
         # Compute stats on these indexes
@@ -129,8 +128,8 @@ class Toolbox():
     
     def check_proj(self):
         """
-        Function to check if raster's projection is RFG93. 
-        For the moment, PHYMOBAT works with one projection only Lambert 93 EPSG:2154 
+            Function to check if raster's projection is RFG93. 
+            For the moment, PHYMOBAT works with one projection only Lambert 93 EPSG:2154 
         """
 
         # Projection for PHYMOBAT
diff --git a/Vector.py b/Vector.py
index 737ea71e9a6f4e91cddfae500f478a68eafcb8b4..c97590cea85cb9159a2b409b9fd68c9075e9a736 100644
--- a/Vector.py
+++ b/Vector.py
@@ -25,7 +25,8 @@ try :
 except :
     from osgeo import ogr, gdal
     
-from rasterstats import *
+# from rasterstats import *
+import rasterstats
 from collections import *
 
 from RasterSat_by_date import RasterSat_by_date
@@ -106,8 +107,7 @@ class Vector():
 
     def close_data(self):
         """
-        Function to remove allocate memory 
-                
+        Function to remove allocate memory            
         """        
         
         # Close data sources
@@ -117,7 +117,7 @@ class Vector():
     
     def zonal_stats(self, inraster, band, **kwargs):
         """
-        Function to compute the average in every polygons for a raster
+        Function to compute the mean in every polygons for a raster
         because of package ``rasterstats`` in */usr/local/lib/python2.7/dist-packages/rasterstats-0.3.2-py2.7.egg/rasterstats/*
         
         :param (inraster,band): inraster -> Input image path, and band -> band number
@@ -130,9 +130,8 @@ class Vector():
         ranking = kwargs['rank'] if kwargs.get('rank') else 0
         nb_img = kwargs['nb_img'] if kwargs.get('nb_img') else 1
 
-        print('Compute ' + os.path.split(str(self.vector_used))[1] + ' stats on ' + os.path.split(str(inraster))[1])
-        stats = raster_stats(str(self.vector_used), str(inraster),  stats =['mean'], band_num=band)
-        
+        print('Compute ' + os.path.split(self.vector_used)[1] + ' stats on ' + os.path.split(inraster)[1])
+        stats = rasterstats.zonal_stats(self.vector_used, inraster,  stats =['mean'], nodata=float('nan'), band=band)
         for i in range(len(stats)):
             temp = defaultdict(lambda : [0]*nb_img)
             for j in range(nb_img):
@@ -140,22 +139,24 @@ class Vector():
                     temp[0][j] = self.stats_dict[i][j]
                 except IndexError:
                     pass
-            temp[0][ranking] = stats[i].values()[1]
+
+            # temp[0][ranking] = stats[i].values()[1]
+            temp[0][ranking] = list(stats)[i]['mean']
             self.stats_dict[i] = temp[0]
             
         print('End of stats on ' + os.path.split(str(inraster))[1])
 
     def zonal_stats_pp(self, inraster):
         """
-        A zonal statistics ++ to dertermine pxl percent in every polygon
+          A zonal statistics ++ to dertermine pxl percent in every polygon
         
-        :param inraster: Input image path
-        :type inraster: str 
-        :returns: dict -- **p_stats** : dictionnary with pxl percent in every polygon. Mainly 'Maj_count' (Majority Value) and 'Maj_count_perc' (Majority Percent)
+          :param inraster: Input image path
+          :type inraster: str 
+          :returns: dict -- **p_stats** : dictionnary with pxl percent in every polygon. Mainly 'Maj_count' (Majority Value) and 'Maj_count_perc' (Majority Percent)
         
         """
         
-        p_stats = raster_stats(str(self.vector_used), str(inraster), stats=['count'], copy_properties=True, categorical=True)
+        p_stats = rasterstats.zonal_stats(self.vector_used, inraster, stats=['count'], copy_properties=True, categorical=True)
         
         for i in range(len(p_stats)):
             percent = 0.0
@@ -216,7 +217,7 @@ class Vector():
         
         self.raster_ds = None
         # Complete the raster creation
-        example_raster.complete_raster(info_out, new_data)
+        example_raster.complete_raster(*info_out, new_data)
         
         return valid_raster
         
diff --git a/ui_PHYMOBATs_tab.py b/ui_PHYMOBATs_tab.py
index 9c512b1b40b2a0d738fe195f670d2d6fa343a793..bc5911b9ae0d5b083206e3b7d6ba770b3e8facf8 100644
--- a/ui_PHYMOBATs_tab.py
+++ b/ui_PHYMOBATs_tab.py
@@ -19,7 +19,7 @@ except AttributeError:
 
 class Ui_PHYMOBAT(object):
     """
-    Class to display “Simplify PHYMOBAT window”.
+        Class to display “Simplify PHYMOBAT window”.
     """
     
     def setupUi(self, PHYMOBAT):
@@ -36,7 +36,7 @@ class Ui_PHYMOBAT(object):
         self.gridLayout_4.addWidget(self.buttonBox, 5, 1, 1, 1)
         self.checkBox_multiprocess = QtWidgets.QCheckBox(self.centralwidget)
         self.checkBox_multiprocess.setCheckable(True)
-        self.checkBox_multiprocess.setChecked(True)
+        self.checkBox_multiprocess.setChecked(False)
         self.checkBox_multiprocess.setAutoRepeat(False)
         self.checkBox_multiprocess.setObjectName("checkBox_multiprocess")
         self.gridLayout_4.addWidget(self.checkBox_multiprocess, 5, 0, 1, 1)